mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
wasm gc: implement intrinsics for Long and Class classes
This commit is contained in:
parent
a97e6574ac
commit
5eb1e7d9bc
|
@ -117,7 +117,20 @@ public final class TClass<T> extends TObject implements TAnnotatedElement, TType
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
if (PlatformDetector.isLowLevel()) {
|
if (PlatformDetector.isWebAssemblyGC()) {
|
||||||
|
var result = getNameImpl();
|
||||||
|
if (result == null) {
|
||||||
|
if (isArray()) {
|
||||||
|
var componentType = getComponentType();
|
||||||
|
String componentName = componentType.getName();
|
||||||
|
if (componentName != null) {
|
||||||
|
result = componentType.isArray() ? "[" + componentName : "[L" + componentName + ";";
|
||||||
|
setNameImpl(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} else if (PlatformDetector.isLowLevel()) {
|
||||||
String result = getNameCache(this);
|
String result = getNameCache(this);
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
result = Platform.getName(platformClass);
|
result = Platform.getName(platformClass);
|
||||||
|
@ -141,6 +154,10 @@ public final class TClass<T> extends TObject implements TAnnotatedElement, TType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private native String getNameImpl();
|
||||||
|
|
||||||
|
private native void setNameImpl(String name);
|
||||||
|
|
||||||
public String getSimpleName() {
|
public String getSimpleName() {
|
||||||
String simpleName = getSimpleNameCache(this);
|
String simpleName = getSimpleNameCache(this);
|
||||||
if (simpleName == null) {
|
if (simpleName == null) {
|
||||||
|
@ -274,6 +291,9 @@ public final class TClass<T> extends TObject implements TAnnotatedElement, TType
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isArray() {
|
public boolean isArray() {
|
||||||
|
if (PlatformDetector.isWebAssemblyGC()) {
|
||||||
|
return getComponentType() != null;
|
||||||
|
}
|
||||||
return Platform.getArrayItem(platformClass) != null;
|
return Platform.getArrayItem(platformClass) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package org.teavm.backend.wasm.gc;
|
package org.teavm.backend.wasm.gc;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
import org.teavm.backend.wasm.WasmRuntime;
|
import org.teavm.backend.wasm.WasmRuntime;
|
||||||
import org.teavm.backend.wasm.runtime.WasmGCSupport;
|
import org.teavm.backend.wasm.runtime.WasmGCSupport;
|
||||||
import org.teavm.dependency.DependencyAnalyzer;
|
import org.teavm.dependency.DependencyAnalyzer;
|
||||||
|
@ -29,6 +30,7 @@ public class WasmGCDependencies {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void contribute() {
|
public void contribute() {
|
||||||
|
contributeWasmRuntime();
|
||||||
contributeMathUtils();
|
contributeMathUtils();
|
||||||
contributeExceptionUtils();
|
contributeExceptionUtils();
|
||||||
contributeInitializerUtils();
|
contributeInitializerUtils();
|
||||||
|
@ -52,6 +54,21 @@ public class WasmGCDependencies {
|
||||||
.use();
|
.use();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void contributeWasmRuntime() {
|
||||||
|
for (var cls : List.of(int.class, long.class, float.class, double.class)) {
|
||||||
|
analyzer.linkMethod(new MethodReference(WasmRuntime.class, "lt", cls, cls, boolean.class)).use();
|
||||||
|
analyzer.linkMethod(new MethodReference(WasmRuntime.class, "gt", cls, cls, boolean.class)).use();
|
||||||
|
}
|
||||||
|
for (var cls : List.of(int.class, long.class)) {
|
||||||
|
analyzer.linkMethod(new MethodReference(WasmRuntime.class, "ltu", cls, cls, boolean.class)).use();
|
||||||
|
analyzer.linkMethod(new MethodReference(WasmRuntime.class, "gtu", cls, cls, boolean.class)).use();
|
||||||
|
}
|
||||||
|
for (var cls : List.of(float.class, double.class)) {
|
||||||
|
analyzer.linkMethod(new MethodReference(WasmRuntime.class, "min", cls, cls, cls)).use();
|
||||||
|
analyzer.linkMethod(new MethodReference(WasmRuntime.class, "max", cls, cls, cls)).use();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void contributeMathUtils() {
|
private void contributeMathUtils() {
|
||||||
for (var type : Arrays.asList(int.class, long.class, float.class, double.class)) {
|
for (var type : Arrays.asList(int.class, long.class, float.class, double.class)) {
|
||||||
var method = new MethodReference(WasmRuntime.class, "compare", type, type, int.class);
|
var method = new MethodReference(WasmRuntime.class, "compare", type, type, int.class);
|
||||||
|
|
|
@ -455,6 +455,7 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
var intrinsic = context.intrinsics().get(expr.getMethod());
|
var intrinsic = context.intrinsics().get(expr.getMethod());
|
||||||
if (intrinsic != null) {
|
if (intrinsic != null) {
|
||||||
var resultExpr = intrinsic.apply(expr, intrinsicContext);
|
var resultExpr = intrinsic.apply(expr, intrinsicContext);
|
||||||
|
resultExpr.setLocation(expr.getLocation());
|
||||||
if (resultConsumer != null) {
|
if (resultConsumer != null) {
|
||||||
if (willDrop) {
|
if (willDrop) {
|
||||||
var drop = new WasmDrop(resultExpr);
|
var drop = new WasmDrop(resultExpr);
|
||||||
|
|
|
@ -36,9 +36,6 @@ public class ClassGenerators implements WasmGCCustomGenerator {
|
||||||
case "isInstance":
|
case "isInstance":
|
||||||
generateIsInstance(function, context);
|
generateIsInstance(function, context);
|
||||||
break;
|
break;
|
||||||
case "getName":
|
|
||||||
generateGetName(function, context);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unsupported method: " + method);
|
throw new IllegalArgumentException("Unsupported method: " + method);
|
||||||
}
|
}
|
||||||
|
@ -69,13 +66,4 @@ public class ClassGenerators implements WasmGCCustomGenerator {
|
||||||
function.getBody().add(new WasmReturn(conditional));
|
function.getBody().add(new WasmReturn(conditional));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateGetName(WasmFunction function, WasmGCCustomGeneratorContext context) {
|
|
||||||
var classCls = context.classInfoProvider().getClassInfo("java.lang.Class");
|
|
||||||
var thisVar = new WasmLocal(classCls.getType());
|
|
||||||
function.add(thisVar);
|
|
||||||
|
|
||||||
var nameRef = new WasmStructGet(classCls.getStructure(), new WasmGetLocal(thisVar),
|
|
||||||
context.classInfoProvider().getClassNameOffset());
|
|
||||||
function.getBody().add(new WasmReturn(nameRef));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,6 @@ public class WasmGCCustomGenerators implements WasmGCCustomGeneratorProvider {
|
||||||
private void fillClass() {
|
private void fillClass() {
|
||||||
var classGenerators = new ClassGenerators();
|
var classGenerators = new ClassGenerators();
|
||||||
generators.put(new MethodReference(Class.class, "isInstance", Object.class, boolean.class), classGenerators);
|
generators.put(new MethodReference(Class.class, "isInstance", Object.class, boolean.class), classGenerators);
|
||||||
generators.put(new MethodReference(Class.class, "getName", String.class), classGenerators);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillStringPool() {
|
private void fillStringPool() {
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.teavm.backend.wasm.intrinsics.gc;
|
||||||
import org.teavm.ast.InvocationExpr;
|
import org.teavm.ast.InvocationExpr;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmStructGet;
|
import org.teavm.backend.wasm.model.expression.WasmStructGet;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmStructSet;
|
||||||
|
|
||||||
public class ClassIntrinsics implements WasmGCIntrinsic {
|
public class ClassIntrinsics implements WasmGCIntrinsic {
|
||||||
@Override
|
@Override
|
||||||
|
@ -30,8 +31,26 @@ public class ClassIntrinsics implements WasmGCIntrinsic {
|
||||||
context.classInfoProvider().getClassArrayItemOffset());
|
context.classInfoProvider().getClassArrayItemOffset());
|
||||||
result.setLocation(invocation.getLocation());
|
result.setLocation(invocation.getLocation());
|
||||||
return result;
|
return result;
|
||||||
|
case "getNameImpl":
|
||||||
|
return generateGetName(invocation, context);
|
||||||
|
case "setNameImpl":
|
||||||
|
return generateSetName(invocation, context);
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unsupported invocation method: " + invocation.getMethod());
|
throw new IllegalArgumentException("Unsupported invocation method: " + invocation.getMethod());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private WasmExpression generateGetName(InvocationExpr invocation, WasmGCIntrinsicContext context) {
|
||||||
|
var classCls = context.classInfoProvider().getClassInfo("java.lang.Class");
|
||||||
|
var arg = context.generate(invocation.getArguments().get(0));
|
||||||
|
return new WasmStructGet(classCls.getStructure(), arg, context.classInfoProvider().getClassNameOffset());
|
||||||
|
}
|
||||||
|
|
||||||
|
private WasmExpression generateSetName(InvocationExpr invocation, WasmGCIntrinsicContext context) {
|
||||||
|
var classCls = context.classInfoProvider().getClassInfo("java.lang.Class");
|
||||||
|
var arg = context.generate(invocation.getArguments().get(0));
|
||||||
|
var value = context.generate(invocation.getArguments().get(1));
|
||||||
|
return new WasmStructSet(classCls.getStructure(), arg, context.classInfoProvider().getClassNameOffset(),
|
||||||
|
value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.backend.wasm.intrinsics.gc;
|
||||||
|
|
||||||
|
import org.teavm.ast.InvocationExpr;
|
||||||
|
import org.teavm.backend.wasm.WasmRuntime;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmCall;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmIntBinary;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmIntBinaryOperation;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmIntType;
|
||||||
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
|
public class LongIntrinsic implements WasmGCIntrinsic {
|
||||||
|
private static final MethodReference COMPARE_UNSIGNED = new MethodReference(WasmRuntime.class,
|
||||||
|
"compareUnsigned", long.class, long.class, int.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WasmExpression apply(InvocationExpr invocation, WasmGCIntrinsicContext context) {
|
||||||
|
switch (invocation.getMethod().getName()) {
|
||||||
|
case "divideUnsigned":
|
||||||
|
return new WasmIntBinary(WasmIntType.INT64, WasmIntBinaryOperation.DIV_UNSIGNED,
|
||||||
|
context.generate(invocation.getArguments().get(0)),
|
||||||
|
context.generate(invocation.getArguments().get(1)));
|
||||||
|
case "remainderUnsigned":
|
||||||
|
return new WasmIntBinary(WasmIntType.INT64, WasmIntBinaryOperation.REM_UNSIGNED,
|
||||||
|
context.generate(invocation.getArguments().get(0)),
|
||||||
|
context.generate(invocation.getArguments().get(1)));
|
||||||
|
case "compareUnsigned":
|
||||||
|
return new WasmCall(context.functions().forStaticMethod(COMPARE_UNSIGNED),
|
||||||
|
context.generate(invocation.getArguments().get(0)),
|
||||||
|
context.generate(invocation.getArguments().get(1)));
|
||||||
|
default:
|
||||||
|
throw new AssertionError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,9 @@
|
||||||
package org.teavm.backend.wasm.intrinsics.gc;
|
package org.teavm.backend.wasm.intrinsics.gc;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import org.teavm.backend.wasm.WasmRuntime;
|
||||||
import org.teavm.backend.wasm.generate.gc.methods.WasmGCIntrinsicProvider;
|
import org.teavm.backend.wasm.generate.gc.methods.WasmGCIntrinsicProvider;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
|
@ -24,9 +26,27 @@ public class WasmGCIntrinsics implements WasmGCIntrinsicProvider {
|
||||||
private Map<MethodReference, WasmGCIntrinsic> intrinsics = new HashMap<>();
|
private Map<MethodReference, WasmGCIntrinsic> intrinsics = new HashMap<>();
|
||||||
|
|
||||||
public WasmGCIntrinsics() {
|
public WasmGCIntrinsics() {
|
||||||
|
fillWasmRuntime();
|
||||||
fillObject();
|
fillObject();
|
||||||
fillClass();
|
fillClass();
|
||||||
fillSystem();
|
fillSystem();
|
||||||
|
fillLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fillWasmRuntime() {
|
||||||
|
var intrinsic = new WasmRuntimeIntrinsic();
|
||||||
|
for (var cls : List.of(int.class, long.class, float.class, double.class)) {
|
||||||
|
intrinsics.put(new MethodReference(WasmRuntime.class, "lt", cls, cls, boolean.class), intrinsic);
|
||||||
|
intrinsics.put(new MethodReference(WasmRuntime.class, "gt", cls, cls, boolean.class), intrinsic);
|
||||||
|
}
|
||||||
|
for (var cls : List.of(int.class, long.class)) {
|
||||||
|
intrinsics.put(new MethodReference(WasmRuntime.class, "ltu", cls, cls, boolean.class), intrinsic);
|
||||||
|
intrinsics.put(new MethodReference(WasmRuntime.class, "gtu", cls, cls, boolean.class), intrinsic);
|
||||||
|
}
|
||||||
|
for (var cls : List.of(float.class, double.class)) {
|
||||||
|
intrinsics.put(new MethodReference(WasmRuntime.class, "min", cls, cls, cls), intrinsic);
|
||||||
|
intrinsics.put(new MethodReference(WasmRuntime.class, "max", cls, cls, cls), intrinsic);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillObject() {
|
private void fillObject() {
|
||||||
|
@ -35,8 +55,10 @@ public class WasmGCIntrinsics implements WasmGCIntrinsicProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillClass() {
|
private void fillClass() {
|
||||||
var classIntrinsics = new ClassIntrinsics();
|
var intrinsic = new ClassIntrinsics();
|
||||||
intrinsics.put(new MethodReference(Class.class, "getComponentType", Class.class), classIntrinsics);
|
intrinsics.put(new MethodReference(Class.class, "getComponentType", Class.class), intrinsic);
|
||||||
|
intrinsics.put(new MethodReference(Class.class, "getNameImpl", String.class), intrinsic);
|
||||||
|
intrinsics.put(new MethodReference(Class.class, "setNameImpl", String.class, void.class), intrinsic);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillSystem() {
|
private void fillSystem() {
|
||||||
|
@ -44,6 +66,16 @@ public class WasmGCIntrinsics implements WasmGCIntrinsicProvider {
|
||||||
int.class, int.class, void.class), new SystemArrayCopyIntrinsic());
|
int.class, int.class, void.class), new SystemArrayCopyIntrinsic());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void fillLong() {
|
||||||
|
var intrinsic = new LongIntrinsic();
|
||||||
|
intrinsics.put(new MethodReference(Long.class, "divideUnsigned", long.class, long.class, long.class),
|
||||||
|
intrinsic);
|
||||||
|
intrinsics.put(new MethodReference(Long.class, "remainderUnsigned", long.class, long.class, long.class),
|
||||||
|
intrinsic);
|
||||||
|
intrinsics.put(new MethodReference(Long.class, "compareUnsigned", long.class, long.class, int.class),
|
||||||
|
intrinsic);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WasmGCIntrinsic get(MethodReference method) {
|
public WasmGCIntrinsic get(MethodReference method) {
|
||||||
return intrinsics.get(method);
|
return intrinsics.get(method);
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.backend.wasm.intrinsics.gc;
|
||||||
|
|
||||||
|
import org.teavm.ast.InvocationExpr;
|
||||||
|
import org.teavm.backend.wasm.generate.WasmGeneratorUtil;
|
||||||
|
import org.teavm.backend.wasm.model.WasmType;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmFloatBinary;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmFloatBinaryOperation;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmFloatType;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmIntBinary;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmIntBinaryOperation;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmIntType;
|
||||||
|
|
||||||
|
public class WasmRuntimeIntrinsic implements WasmGCIntrinsic {
|
||||||
|
@Override
|
||||||
|
public WasmExpression apply(InvocationExpr invocation, WasmGCIntrinsicContext context) {
|
||||||
|
switch (invocation.getMethod().getName()) {
|
||||||
|
case "lt":
|
||||||
|
return comparison(WasmIntBinaryOperation.LT_SIGNED, WasmFloatBinaryOperation.LT,
|
||||||
|
invocation, context);
|
||||||
|
case "gt":
|
||||||
|
return comparison(WasmIntBinaryOperation.GT_SIGNED, WasmFloatBinaryOperation.GT,
|
||||||
|
invocation, context);
|
||||||
|
case "ltu":
|
||||||
|
return comparison(WasmIntBinaryOperation.LT_UNSIGNED, WasmFloatBinaryOperation.LT,
|
||||||
|
invocation, context);
|
||||||
|
case "gtu":
|
||||||
|
return comparison(WasmIntBinaryOperation.GT_UNSIGNED, WasmFloatBinaryOperation.GT,
|
||||||
|
invocation, context);
|
||||||
|
case "min":
|
||||||
|
return comparison(WasmIntBinaryOperation.GT_SIGNED, WasmFloatBinaryOperation.MIN,
|
||||||
|
invocation, context);
|
||||||
|
case "max":
|
||||||
|
return comparison(WasmIntBinaryOperation.GT_SIGNED, WasmFloatBinaryOperation.MAX,
|
||||||
|
invocation, context);
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException(invocation.getMethod().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static WasmExpression comparison(WasmIntBinaryOperation intOp, WasmFloatBinaryOperation floatOp,
|
||||||
|
InvocationExpr invocation, WasmGCIntrinsicContext context) {
|
||||||
|
var type = (WasmType.Number) WasmGeneratorUtil.mapType(invocation.getMethod().parameterType(0));
|
||||||
|
|
||||||
|
WasmExpression first = context.generate(invocation.getArguments().get(0));
|
||||||
|
WasmExpression second = context.generate(invocation.getArguments().get(1));
|
||||||
|
|
||||||
|
switch (type.number) {
|
||||||
|
case INT32:
|
||||||
|
return new WasmIntBinary(WasmIntType.INT32, intOp, first, second);
|
||||||
|
case INT64:
|
||||||
|
return new WasmIntBinary(WasmIntType.INT64, intOp, first, second);
|
||||||
|
case FLOAT32:
|
||||||
|
return new WasmFloatBinary(WasmFloatType.FLOAT32, floatOp, first, second);
|
||||||
|
case FLOAT64:
|
||||||
|
return new WasmFloatBinary(WasmFloatType.FLOAT64, floatOp, first, second);
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException(type.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -74,21 +74,6 @@ public class VirtualTable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasValidEntries() {
|
public boolean hasValidEntries() {
|
||||||
if (!hasValidEntriesComputed) {
|
return !methods.isEmpty();
|
||||||
hasValidEntriesComputed = true;
|
|
||||||
hasValidEntries = false;
|
|
||||||
if (entryMap != null) {
|
|
||||||
for (var entry : entryMap.values()) {
|
|
||||||
if (entry.getImplementor() != null) {
|
|
||||||
hasValidEntries = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (parent != null && parent.hasValidEntries()) {
|
|
||||||
hasValidEntries = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hasValidEntries;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user