mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
wasm gc: support Array.newInstance
This commit is contained in:
parent
40fbce0ddd
commit
199032d48a
|
@ -16,6 +16,7 @@
|
||||||
package org.teavm.classlib.java.lang.reflect;
|
package org.teavm.classlib.java.lang.reflect;
|
||||||
|
|
||||||
import org.teavm.backend.javascript.spi.GeneratedBy;
|
import org.teavm.backend.javascript.spi.GeneratedBy;
|
||||||
|
import org.teavm.classlib.PlatformDetector;
|
||||||
import org.teavm.classlib.java.lang.TArrayIndexOutOfBoundsException;
|
import org.teavm.classlib.java.lang.TArrayIndexOutOfBoundsException;
|
||||||
import org.teavm.classlib.java.lang.TClass;
|
import org.teavm.classlib.java.lang.TClass;
|
||||||
import org.teavm.classlib.java.lang.TIllegalArgumentException;
|
import org.teavm.classlib.java.lang.TIllegalArgumentException;
|
||||||
|
@ -59,8 +60,14 @@ public final class TArray extends TObject {
|
||||||
if (length < 0) {
|
if (length < 0) {
|
||||||
throw new TNegativeArraySizeException();
|
throw new TNegativeArraySizeException();
|
||||||
}
|
}
|
||||||
|
if (PlatformDetector.isWebAssemblyGC()) {
|
||||||
|
return newInstanceImpl(componentType, length);
|
||||||
|
} else {
|
||||||
return newInstanceImpl(((TClass<?>) (Object) componentType).getPlatformClass(), length);
|
return newInstanceImpl(((TClass<?>) (Object) componentType).getPlatformClass(), length);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native TObject newInstanceImpl(Class<?> componentType, int length);
|
||||||
|
|
||||||
@GeneratedBy(ArrayNativeGenerator.class)
|
@GeneratedBy(ArrayNativeGenerator.class)
|
||||||
@DelegateTo("newInstanceLowLevel")
|
@DelegateTo("newInstanceLowLevel")
|
||||||
|
|
|
@ -304,6 +304,11 @@ public class WasmGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
return new WasmInt32Constant(0);
|
return new WasmInt32Constant(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected WasmExpression nullLiteral(WasmType type) {
|
||||||
|
return new WasmInt32Constant(0);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected WasmExpression genIsNull(WasmExpression value) {
|
protected WasmExpression genIsNull(WasmExpression value) {
|
||||||
return new WasmIntUnary(WasmIntType.INT32, WasmIntUnaryOperation.EQZ, value);
|
return new WasmIntUnary(WasmIntType.INT32, WasmIntUnaryOperation.EQZ, value);
|
||||||
|
|
|
@ -575,6 +575,8 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
|
|
||||||
protected abstract WasmExpression nullLiteral(Expr expr);
|
protected abstract WasmExpression nullLiteral(Expr expr);
|
||||||
|
|
||||||
|
protected abstract WasmExpression nullLiteral(WasmType type);
|
||||||
|
|
||||||
protected abstract WasmExpression stringLiteral(String s);
|
protected abstract WasmExpression stringLiteral(String s);
|
||||||
|
|
||||||
protected abstract WasmExpression classLiteral(ValueType type);
|
protected abstract WasmExpression classLiteral(ValueType type);
|
||||||
|
@ -1179,13 +1181,13 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
var valueToCast = exprCache.create(result, wasmSourceType, expr.getLocation(), block.getBody());
|
var valueToCast = exprCache.create(result, wasmSourceType, expr.getLocation(), block.getBody());
|
||||||
|
|
||||||
var nullCheck = new WasmBranch(genIsNull(valueToCast.expr()), block);
|
var nullCheck = new WasmBranch(genIsNull(valueToCast.expr()), block);
|
||||||
nullCheck.setResult(valueToCast.expr());
|
nullCheck.setResult(nullLiteral(wasmTargetType));
|
||||||
block.getBody().add(new WasmDrop(nullCheck));
|
block.getBody().add(new WasmDrop(nullCheck));
|
||||||
|
|
||||||
var supertypeCall = generateInstanceOf(valueToCast.expr(), expr.getTarget());
|
var supertypeCall = generateInstanceOf(valueToCast.expr(), expr.getTarget());
|
||||||
|
|
||||||
var breakIfPassed = new WasmBranch(supertypeCall, block);
|
var breakIfPassed = new WasmBranch(supertypeCall, block);
|
||||||
breakIfPassed.setResult(valueToCast.expr());
|
breakIfPassed.setResult(generateCast(valueToCast.expr(), wasmTargetType));
|
||||||
block.getBody().add(new WasmDrop(breakIfPassed));
|
block.getBody().add(new WasmDrop(breakIfPassed));
|
||||||
|
|
||||||
var callSiteId = generateCallSiteId(expr.getLocation());
|
var callSiteId = generateCallSiteId(expr.getLocation());
|
||||||
|
@ -1194,7 +1196,7 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
callSiteId.generateThrow(block.getBody(), expr.getLocation());
|
callSiteId.generateThrow(block.getBody(), expr.getLocation());
|
||||||
|
|
||||||
valueToCast.release();
|
valueToCast.release();
|
||||||
result = generateCast(block, wasmTargetType);
|
result = block;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract WasmExpression generateCast(WasmExpression value, WasmType targetType);
|
protected abstract WasmExpression generateCast(WasmExpression value, WasmType targetType);
|
||||||
|
|
|
@ -96,6 +96,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
private WasmFunction createPrimitiveClassFunction;
|
private WasmFunction createPrimitiveClassFunction;
|
||||||
private WasmFunction createArrayClassFunction;
|
private WasmFunction createArrayClassFunction;
|
||||||
private final WasmGCSupertypeFunctionGenerator supertypeGenerator;
|
private final WasmGCSupertypeFunctionGenerator supertypeGenerator;
|
||||||
|
private final WasmGCNewArrayFunctionGenerator newArrayGenerator;
|
||||||
|
|
||||||
private int classTagOffset;
|
private int classTagOffset;
|
||||||
private int classFlagsOffset;
|
private int classFlagsOffset;
|
||||||
|
@ -103,6 +104,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
private int classParentOffset;
|
private int classParentOffset;
|
||||||
private int classArrayOffset;
|
private int classArrayOffset;
|
||||||
private int classArrayItemOffset;
|
private int classArrayItemOffset;
|
||||||
|
private int classNewArrayOffset;
|
||||||
private int classSupertypeFunctionOffset;
|
private int classSupertypeFunctionOffset;
|
||||||
private int virtualTableFieldOffset;
|
private int virtualTableFieldOffset;
|
||||||
|
|
||||||
|
@ -123,6 +125,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
standardClasses = new WasmGCStandardClasses(this);
|
standardClasses = new WasmGCStandardClasses(this);
|
||||||
strings = new WasmGCStringPool(standardClasses, module, functionProvider);
|
strings = new WasmGCStringPool(standardClasses, module, functionProvider);
|
||||||
supertypeGenerator = new WasmGCSupertypeFunctionGenerator(module, this, names, tagRegistry, functionTypes);
|
supertypeGenerator = new WasmGCSupertypeFunctionGenerator(module, this, names, tagRegistry, functionTypes);
|
||||||
|
newArrayGenerator = new WasmGCNewArrayFunctionGenerator(module, functionTypes, this);
|
||||||
typeMapper = new WasmGCTypeMapper(this, functionTypes, module);
|
typeMapper = new WasmGCTypeMapper(this, functionTypes, module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,12 +193,20 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
initializerFunctionStatements.clear();
|
initializerFunctionStatements.clear();
|
||||||
for (var classInfo : classInfoMap.values()) {
|
for (var classInfo : classInfoMap.values()) {
|
||||||
var req = metadataRequirements.getInfo(classInfo.getValueType());
|
var req = metadataRequirements.getInfo(classInfo.getValueType());
|
||||||
if (req != null && req.isAssignable()) {
|
if (req != null) {
|
||||||
|
if (req.isAssignable()) {
|
||||||
var supertypeFunction = supertypeGenerator.getIsSupertypeFunction(classInfo.getValueType());
|
var supertypeFunction = supertypeGenerator.getIsSupertypeFunction(classInfo.getValueType());
|
||||||
supertypeFunction.setReferenced(true);
|
supertypeFunction.setReferenced(true);
|
||||||
function.getBody().add(setClassField(classInfo, classSupertypeFunctionOffset,
|
function.getBody().add(setClassField(classInfo, classSupertypeFunctionOffset,
|
||||||
new WasmFunctionReference(supertypeFunction)));
|
new WasmFunctionReference(supertypeFunction)));
|
||||||
}
|
}
|
||||||
|
if (req.newArray()) {
|
||||||
|
var newArrayFunction = newArrayGenerator.generateNewArrayFunction(classInfo.getValueType());
|
||||||
|
newArrayFunction.setReferenced(true);
|
||||||
|
function.getBody().add(setClassField(classInfo, classNewArrayOffset,
|
||||||
|
new WasmFunctionReference(newArrayFunction)));
|
||||||
|
}
|
||||||
|
}
|
||||||
function.getBody().add(setClassField(classInfo, CLASS_FIELD_OFFSET,
|
function.getBody().add(setClassField(classInfo, CLASS_FIELD_OFFSET,
|
||||||
new WasmGetGlobal(classClass.pointer)));
|
new WasmGetGlobal(classClass.pointer)));
|
||||||
if (classInfo.initializerPointer != null) {
|
if (classInfo.initializerPointer != null) {
|
||||||
|
@ -275,6 +286,16 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
return classSupertypeFunctionOffset;
|
return classSupertypeFunctionOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getClassNameOffset() {
|
||||||
|
return classNameOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNewArrayFunctionOffset() {
|
||||||
|
return classNewArrayOffset;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getVirtualMethodsOffset() {
|
public int getVirtualMethodsOffset() {
|
||||||
return virtualTableFieldOffset;
|
return virtualTableFieldOffset;
|
||||||
|
@ -546,6 +567,8 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
fields.add(standardClasses.classClass().getType().asStorage());
|
fields.add(standardClasses.classClass().getType().asStorage());
|
||||||
classSupertypeFunctionOffset = fields.size();
|
classSupertypeFunctionOffset = fields.size();
|
||||||
fields.add(supertypeGenerator.getFunctionType().getReference().asStorage());
|
fields.add(supertypeGenerator.getFunctionType().getReference().asStorage());
|
||||||
|
classNewArrayOffset = fields.size();
|
||||||
|
fields.add(newArrayGenerator.getNewArrayFunctionType().getReference().asStorage());
|
||||||
virtualTableFieldOffset = fields.size();
|
virtualTableFieldOffset = fields.size();
|
||||||
classNameOffset = fieldIndexes.getOrDefault(new FieldReference(className, "name"), -1);
|
classNameOffset = fieldIndexes.getOrDefault(new FieldReference(className, "name"), -1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,10 @@ public interface WasmGCClassInfoProvider {
|
||||||
|
|
||||||
int getClassSupertypeFunctionOffset();
|
int getClassSupertypeFunctionOffset();
|
||||||
|
|
||||||
|
int getNewArrayFunctionOffset();
|
||||||
|
|
||||||
|
int getClassNameOffset();
|
||||||
|
|
||||||
default WasmGCClassInfo getClassInfo(String name) {
|
default WasmGCClassInfo getClassInfo(String name) {
|
||||||
return getClassInfo(ValueType.object(name));
|
return getClassInfo(ValueType.object(name));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* 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.generate.gc.classes;
|
||||||
|
|
||||||
|
import org.teavm.backend.wasm.WasmFunctionTypes;
|
||||||
|
import org.teavm.backend.wasm.generate.TemporaryVariablePool;
|
||||||
|
import org.teavm.backend.wasm.generate.gc.methods.WasmGCGenerationUtil;
|
||||||
|
import org.teavm.backend.wasm.model.WasmFunction;
|
||||||
|
import org.teavm.backend.wasm.model.WasmFunctionType;
|
||||||
|
import org.teavm.backend.wasm.model.WasmLocal;
|
||||||
|
import org.teavm.backend.wasm.model.WasmModule;
|
||||||
|
import org.teavm.backend.wasm.model.WasmType;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmGetLocal;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmReturn;
|
||||||
|
import org.teavm.model.ValueType;
|
||||||
|
|
||||||
|
class WasmGCNewArrayFunctionGenerator {
|
||||||
|
private WasmModule module;
|
||||||
|
private WasmFunctionTypes functionTypes;
|
||||||
|
private WasmGCClassInfoProvider classInfoProvider;
|
||||||
|
private WasmFunctionType newArrayFunctionType;
|
||||||
|
|
||||||
|
WasmGCNewArrayFunctionGenerator(WasmModule module, WasmFunctionTypes functionTypes,
|
||||||
|
WasmGCClassInfoProvider classInfoProvider) {
|
||||||
|
this.module = module;
|
||||||
|
this.functionTypes = functionTypes;
|
||||||
|
this.classInfoProvider = classInfoProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
WasmFunction generateNewArrayFunction(ValueType itemType) {
|
||||||
|
var function = new WasmFunction(getNewArrayFunctionType());
|
||||||
|
module.functions.add(function);
|
||||||
|
var sizeLocal = new WasmLocal(WasmType.INT32);
|
||||||
|
function.add(sizeLocal);
|
||||||
|
var tempVars = new TemporaryVariablePool(function);
|
||||||
|
var genUtil = new WasmGCGenerationUtil(classInfoProvider, tempVars);
|
||||||
|
var targetVar = new WasmLocal(classInfoProvider.getClassInfo(ValueType.arrayOf(itemType)).getType());
|
||||||
|
function.add(targetVar);
|
||||||
|
genUtil.allocateArray(itemType, new WasmGetLocal(sizeLocal), null, targetVar, function.getBody());
|
||||||
|
function.getBody().add(new WasmReturn(new WasmGetLocal(targetVar)));
|
||||||
|
return function;
|
||||||
|
}
|
||||||
|
|
||||||
|
WasmFunctionType getNewArrayFunctionType() {
|
||||||
|
if (newArrayFunctionType == null) {
|
||||||
|
newArrayFunctionType = functionTypes.of(classInfoProvider.getClassInfo("java.lang.Object").getType(),
|
||||||
|
WasmType.INT32);
|
||||||
|
}
|
||||||
|
return newArrayFunctionType;
|
||||||
|
}
|
||||||
|
}
|
|
@ -211,6 +211,11 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
: WasmType.Reference.STRUCT);
|
: WasmType.Reference.STRUCT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected WasmExpression nullLiteral(WasmType type) {
|
||||||
|
return new WasmNullConstant((WasmType.Reference) type);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected WasmExpression genIsNull(WasmExpression value) {
|
protected WasmExpression genIsNull(WasmExpression value) {
|
||||||
return new WasmReferencesEqual(value, new WasmNullConstant(WasmType.Reference.STRUCT));
|
return new WasmReferencesEqual(value, new WasmNullConstant(WasmType.Reference.STRUCT));
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* 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.generators.gc;
|
||||||
|
|
||||||
|
import org.teavm.backend.wasm.model.WasmFunction;
|
||||||
|
import org.teavm.backend.wasm.model.WasmLocal;
|
||||||
|
import org.teavm.backend.wasm.model.WasmType;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmCallReference;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmGetLocal;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmReturn;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmStructGet;
|
||||||
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
|
public class ArrayGenerator implements WasmGCCustomGenerator {
|
||||||
|
@Override
|
||||||
|
public void apply(MethodReference method, WasmFunction function, WasmGCCustomGeneratorContext context) {
|
||||||
|
var clsStruct = context.classInfoProvider().getClassInfo("java.lang.Class").getStructure();
|
||||||
|
var classLocal = new WasmLocal(clsStruct.getReference());
|
||||||
|
var sizeLocal = new WasmLocal(WasmType.INT32);
|
||||||
|
function.add(classLocal);
|
||||||
|
function.add(sizeLocal);
|
||||||
|
var constructorRef = new WasmStructGet(clsStruct, new WasmGetLocal(classLocal),
|
||||||
|
context.classInfoProvider().getNewArrayFunctionOffset());
|
||||||
|
var functionType = context.functionTypes().of(
|
||||||
|
context.classInfoProvider().getClassInfo("java.lang.Object").getType(),
|
||||||
|
WasmType.INT32
|
||||||
|
);
|
||||||
|
var result = new WasmCallReference(constructorRef, functionType);
|
||||||
|
result.getArguments().add(new WasmGetLocal(sizeLocal));
|
||||||
|
function.getBody().add(new WasmReturn(result));
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,6 +36,9 @@ 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);
|
||||||
}
|
}
|
||||||
|
@ -65,4 +68,14 @@ 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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.backend.wasm.generators.gc;
|
package org.teavm.backend.wasm.generators.gc;
|
||||||
|
|
||||||
|
import java.lang.reflect.Array;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.teavm.backend.wasm.generate.gc.methods.WasmGCCustomGeneratorProvider;
|
import org.teavm.backend.wasm.generate.gc.methods.WasmGCCustomGeneratorProvider;
|
||||||
|
@ -28,11 +29,13 @@ public class WasmGCCustomGenerators implements WasmGCCustomGeneratorProvider {
|
||||||
fillClass();
|
fillClass();
|
||||||
fillStringPool();
|
fillStringPool();
|
||||||
fillSystem();
|
fillSystem();
|
||||||
|
fillArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
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() {
|
||||||
|
@ -50,6 +53,12 @@ public class WasmGCCustomGenerators implements WasmGCCustomGeneratorProvider {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void fillArray() {
|
||||||
|
var arrayGenerator = new ArrayGenerator();
|
||||||
|
generators.put(new MethodReference(Array.class, "newInstanceImpl", Class.class, int.class, Object.class),
|
||||||
|
arrayGenerator);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WasmGCCustomGenerator get(MethodReference method) {
|
public WasmGCCustomGenerator get(MethodReference method) {
|
||||||
return generators.get(method);
|
return generators.get(method);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.model.analysis;
|
package org.teavm.model.analysis;
|
||||||
|
|
||||||
|
import java.lang.reflect.Array;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.teavm.dependency.DependencyInfo;
|
import org.teavm.dependency.DependencyInfo;
|
||||||
|
@ -34,6 +35,8 @@ public class ClassMetadataRequirements {
|
||||||
"getDeclaringClass", Class.class);
|
"getDeclaringClass", Class.class);
|
||||||
private static final MethodReference GET_ENCLOSING_CLASS_METHOD = new MethodReference(Class.class,
|
private static final MethodReference GET_ENCLOSING_CLASS_METHOD = new MethodReference(Class.class,
|
||||||
"getEnclosingClass", Class.class);
|
"getEnclosingClass", Class.class);
|
||||||
|
private static final MethodReference NEW_ARRAY = new MethodReference(Array.class,
|
||||||
|
"newInstance", Class.class, int.class, Object.class);
|
||||||
private static final ClassInfo EMPTY_INFO = new ClassInfo();
|
private static final ClassInfo EMPTY_INFO = new ClassInfo();
|
||||||
private Map<ValueType, ClassInfo> requirements = new HashMap<>();
|
private Map<ValueType, ClassInfo> requirements = new HashMap<>();
|
||||||
|
|
||||||
|
@ -85,6 +88,14 @@ public class ClassMetadataRequirements {
|
||||||
requirements.computeIfAbsent(decodeType(className), k -> new ClassInfo()).enclosingClass = true;
|
requirements.computeIfAbsent(decodeType(className), k -> new ClassInfo()).enclosingClass = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var newArrayMethod = dependencyInfo.getMethod(NEW_ARRAY);
|
||||||
|
if (newArrayMethod != null) {
|
||||||
|
var classNames = newArrayMethod.getVariable(1).getClassValueNode().getTypes();
|
||||||
|
for (var className : classNames) {
|
||||||
|
requirements.computeIfAbsent(decodeType(className), k -> new ClassInfo()).newArray = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Info getInfo(String className) {
|
public Info getInfo(String className) {
|
||||||
|
@ -122,6 +133,7 @@ public class ClassMetadataRequirements {
|
||||||
boolean enclosingClass;
|
boolean enclosingClass;
|
||||||
boolean superclass;
|
boolean superclass;
|
||||||
boolean isAssignable;
|
boolean isAssignable;
|
||||||
|
boolean newArray;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean name() {
|
public boolean name() {
|
||||||
|
@ -152,6 +164,11 @@ public class ClassMetadataRequirements {
|
||||||
public boolean isAssignable() {
|
public boolean isAssignable() {
|
||||||
return isAssignable;
|
return isAssignable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean newArray() {
|
||||||
|
return newArray;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface Info {
|
public interface Info {
|
||||||
|
@ -166,5 +183,7 @@ public class ClassMetadataRequirements {
|
||||||
boolean superclass();
|
boolean superclass();
|
||||||
|
|
||||||
boolean isAssignable();
|
boolean isAssignable();
|
||||||
|
|
||||||
|
boolean newArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user