mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
wasm gc: fix bugs with Class
This commit is contained in:
parent
d12637f959
commit
eccfaff889
|
@ -46,9 +46,7 @@ import org.teavm.dependency.PluggableDependency;
|
||||||
import org.teavm.interop.Address;
|
import org.teavm.interop.Address;
|
||||||
import org.teavm.interop.DelegateTo;
|
import org.teavm.interop.DelegateTo;
|
||||||
import org.teavm.interop.NoSideEffects;
|
import org.teavm.interop.NoSideEffects;
|
||||||
import org.teavm.interop.Platforms;
|
|
||||||
import org.teavm.interop.Unmanaged;
|
import org.teavm.interop.Unmanaged;
|
||||||
import org.teavm.interop.UnsupportedOn;
|
|
||||||
import org.teavm.jso.core.JSArray;
|
import org.teavm.jso.core.JSArray;
|
||||||
import org.teavm.platform.Platform;
|
import org.teavm.platform.Platform;
|
||||||
import org.teavm.platform.PlatformClass;
|
import org.teavm.platform.PlatformClass;
|
||||||
|
@ -101,8 +99,10 @@ public final class TClass<T> extends TObject implements TAnnotatedElement, TType
|
||||||
}
|
}
|
||||||
|
|
||||||
@DelegateTo("isInstanceLowLevel")
|
@DelegateTo("isInstanceLowLevel")
|
||||||
@UnsupportedOn(Platforms.WEBASSEMBLY_GC)
|
|
||||||
public boolean isInstance(TObject obj) {
|
public boolean isInstance(TObject obj) {
|
||||||
|
if (PlatformDetector.isWebAssemblyGC()) {
|
||||||
|
return obj != null && isAssignableFrom((TClass<?>) (Object) obj.getClass());
|
||||||
|
}
|
||||||
return Platform.isInstance(Platform.getPlatformObject(obj), platformClass);
|
return Platform.isInstance(Platform.getPlatformObject(obj), platformClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,6 @@ public final class TClass<T> extends TObject implements TAnnotatedElement, TType
|
||||||
}
|
}
|
||||||
|
|
||||||
@DelegateTo("isAssignableFromLowLevel")
|
@DelegateTo("isAssignableFromLowLevel")
|
||||||
@UnsupportedOn(Platforms.WEBASSEMBLY_GC)
|
|
||||||
public boolean isAssignableFrom(TClass<?> obj) {
|
public boolean isAssignableFrom(TClass<?> obj) {
|
||||||
return Platform.isAssignable(obj.getPlatformClass(), platformClass);
|
return Platform.isAssignable(obj.getPlatformClass(), platformClass);
|
||||||
}
|
}
|
||||||
|
@ -268,7 +267,9 @@ public final class TClass<T> extends TObject implements TAnnotatedElement, TType
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSynthetic() {
|
private boolean isSynthetic() {
|
||||||
if (PlatformDetector.isJavaScript()) {
|
if (PlatformDetector.isWebAssemblyGC()) {
|
||||||
|
return (getWasmGCFlags() & WasmGCClassFlags.SYNTHETIC) != 0;
|
||||||
|
} else if (PlatformDetector.isJavaScript()) {
|
||||||
return (platformClass.getMetadata().getAccessLevel() & Flags.SYNTHETIC) != 0;
|
return (platformClass.getMetadata().getAccessLevel() & Flags.SYNTHETIC) != 0;
|
||||||
} else {
|
} else {
|
||||||
return (RuntimeClass.getClass(Address.ofObject(this).toStructure()).flags & RuntimeClass.SYNTHETIC) != 0;
|
return (RuntimeClass.getClass(Address.ofObject(this).toStructure()).flags & RuntimeClass.SYNTHETIC) != 0;
|
||||||
|
|
|
@ -92,6 +92,8 @@ import org.teavm.backend.wasm.model.expression.WasmInt64Constant;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmIntBinary;
|
import org.teavm.backend.wasm.model.expression.WasmIntBinary;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmIntBinaryOperation;
|
import org.teavm.backend.wasm.model.expression.WasmIntBinaryOperation;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmIntType;
|
import org.teavm.backend.wasm.model.expression.WasmIntType;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmIntUnary;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmIntUnaryOperation;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmReturn;
|
import org.teavm.backend.wasm.model.expression.WasmReturn;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmSetLocal;
|
import org.teavm.backend.wasm.model.expression.WasmSetLocal;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmSwitch;
|
import org.teavm.backend.wasm.model.expression.WasmSwitch;
|
||||||
|
@ -1446,7 +1448,7 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.EQ, expr, new WasmInt32Constant(0));
|
var result = new WasmIntUnary(WasmIntType.INT32, WasmIntUnaryOperation.EQZ, expr);
|
||||||
result.setLocation(expr.getLocation());
|
result.setLocation(expr.getLocation());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,12 +129,14 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
private int classFlagsOffset;
|
private int classFlagsOffset;
|
||||||
private int classNameOffset;
|
private int classNameOffset;
|
||||||
private int classSimpleNameOffset;
|
private int classSimpleNameOffset;
|
||||||
|
private int classCanonicalNameOffset;
|
||||||
private int classParentOffset;
|
private int classParentOffset;
|
||||||
private int classArrayOffset;
|
private int classArrayOffset;
|
||||||
private int classArrayItemOffset;
|
private int classArrayItemOffset;
|
||||||
private int classNewArrayOffset;
|
private int classNewArrayOffset;
|
||||||
private int classSupertypeFunctionOffset;
|
private int classSupertypeFunctionOffset;
|
||||||
private int classEnclosingClassOffset;
|
private int classEnclosingClassOffset;
|
||||||
|
private int classDeclaringClassOffset;
|
||||||
private int virtualTableFieldOffset;
|
private int virtualTableFieldOffset;
|
||||||
private int enumConstantsFunctionOffset;
|
private int enumConstantsFunctionOffset;
|
||||||
private int arrayLengthOffset = -1;
|
private int arrayLengthOffset = -1;
|
||||||
|
@ -380,6 +382,12 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
return classEnclosingClassOffset;
|
return classEnclosingClassOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getClassDeclaringClassOffset() {
|
||||||
|
standardClasses.classClass().getStructure().init();
|
||||||
|
return classDeclaringClassOffset;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getClassParentOffset() {
|
public int getClassParentOffset() {
|
||||||
standardClasses.classClass().getStructure().init();
|
standardClasses.classClass().getStructure().init();
|
||||||
|
@ -398,6 +406,12 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
return classSimpleNameOffset;
|
return classSimpleNameOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getClassCanonicalNameOffset() {
|
||||||
|
standardClasses.classClass().getStructure().init();
|
||||||
|
return classCanonicalNameOffset;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNewArrayFunctionOffset() {
|
public int getNewArrayFunctionOffset() {
|
||||||
standardClasses.classClass().getStructure().init();
|
standardClasses.classClass().getStructure().init();
|
||||||
|
@ -498,10 +512,14 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
var parent = getClassInfo(cls.getParent());
|
var parent = getClassInfo(cls.getParent());
|
||||||
target.add(setClassField(classInfo, classParentOffset, new WasmGetGlobal(parent.pointer)));
|
target.add(setClassField(classInfo, classParentOffset, new WasmGetGlobal(parent.pointer)));
|
||||||
}
|
}
|
||||||
if (cls.getOwnerName() != null && metadataReq.superclass()) {
|
if (cls.getOwnerName() != null && metadataReq.enclosingClass()) {
|
||||||
var owner = getClassInfo(cls.getOwnerName());
|
var owner = getClassInfo(cls.getOwnerName());
|
||||||
target.add(setClassField(classInfo, classEnclosingClassOffset, new WasmGetGlobal(owner.pointer)));
|
target.add(setClassField(classInfo, classEnclosingClassOffset, new WasmGetGlobal(owner.pointer)));
|
||||||
}
|
}
|
||||||
|
if (cls.getDeclaringClassName() != null && metadataReq.declaringClass()) {
|
||||||
|
var owner = getClassInfo(cls.getDeclaringClassName());
|
||||||
|
target.add(setClassField(classInfo, classDeclaringClassOffset, new WasmGetGlobal(owner.pointer)));
|
||||||
|
}
|
||||||
if (metadataReq.cloneMethod()) {
|
if (metadataReq.cloneMethod()) {
|
||||||
WasmFunction cloneFunction;
|
WasmFunction cloneFunction;
|
||||||
if (hierarchy.isSuperType("java.lang.Cloneable", name, false)) {
|
if (hierarchy.isSuperType("java.lang.Cloneable", name, false)) {
|
||||||
|
@ -1067,10 +1085,14 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
"createArrayInstance"));
|
"createArrayInstance"));
|
||||||
classEnclosingClassOffset = fields.size();
|
classEnclosingClassOffset = fields.size();
|
||||||
fields.add(createClassField(standardClasses.classClass().getType().asStorage(), "enclosingClass"));
|
fields.add(createClassField(standardClasses.classClass().getType().asStorage(), "enclosingClass"));
|
||||||
|
classDeclaringClassOffset = fields.size();
|
||||||
|
fields.add(createClassField(standardClasses.classClass().getType().asStorage(), "declaringClass"));
|
||||||
classNameOffset = fields.size();
|
classNameOffset = fields.size();
|
||||||
fields.add(createClassField(standardClasses.stringClass().getType().asStorage(), "name"));
|
fields.add(createClassField(standardClasses.stringClass().getType().asStorage(), "name"));
|
||||||
classSimpleNameOffset = fields.size();
|
classSimpleNameOffset = fields.size();
|
||||||
fields.add(createClassField(standardClasses.stringClass().getType().asStorage(), "simpleName"));
|
fields.add(createClassField(standardClasses.stringClass().getType().asStorage(), "simpleName"));
|
||||||
|
classCanonicalNameOffset = fields.size();
|
||||||
|
fields.add(createClassField(standardClasses.stringClass().getType().asStorage(), "canonicalName"));
|
||||||
cloneOffset = fields.size();
|
cloneOffset = fields.size();
|
||||||
fields.add(createClassField(functionTypes.of(standardClasses.objectClass().getType(),
|
fields.add(createClassField(functionTypes.of(standardClasses.objectClass().getType(),
|
||||||
standardClasses.objectClass().getType()).getReference().asStorage(), "clone"));
|
standardClasses.objectClass().getType()).getReference().asStorage(), "clone"));
|
||||||
|
|
|
@ -44,6 +44,8 @@ public interface WasmGCClassInfoProvider {
|
||||||
|
|
||||||
int getClassEnclosingClassOffset();
|
int getClassEnclosingClassOffset();
|
||||||
|
|
||||||
|
int getClassDeclaringClassOffset();
|
||||||
|
|
||||||
int getClassParentOffset();
|
int getClassParentOffset();
|
||||||
|
|
||||||
int getNewArrayFunctionOffset();
|
int getNewArrayFunctionOffset();
|
||||||
|
@ -52,6 +54,8 @@ public interface WasmGCClassInfoProvider {
|
||||||
|
|
||||||
int getClassSimpleNameOffset();
|
int getClassSimpleNameOffset();
|
||||||
|
|
||||||
|
int getClassCanonicalNameOffset();
|
||||||
|
|
||||||
int getArrayGetOffset();
|
int getArrayGetOffset();
|
||||||
|
|
||||||
int getArrayLengthOffset();
|
int getArrayLengthOffset();
|
||||||
|
|
|
@ -37,8 +37,10 @@ import org.teavm.backend.wasm.generate.gc.strings.WasmGCStringProvider;
|
||||||
import org.teavm.backend.wasm.generators.gc.WasmGCCustomGenerator;
|
import org.teavm.backend.wasm.generators.gc.WasmGCCustomGenerator;
|
||||||
import org.teavm.backend.wasm.generators.gc.WasmGCCustomGeneratorContext;
|
import org.teavm.backend.wasm.generators.gc.WasmGCCustomGeneratorContext;
|
||||||
import org.teavm.backend.wasm.model.WasmFunction;
|
import org.teavm.backend.wasm.model.WasmFunction;
|
||||||
|
import org.teavm.backend.wasm.model.WasmGlobal;
|
||||||
import org.teavm.backend.wasm.model.WasmLocal;
|
import org.teavm.backend.wasm.model.WasmLocal;
|
||||||
import org.teavm.backend.wasm.model.WasmModule;
|
import org.teavm.backend.wasm.model.WasmModule;
|
||||||
|
import org.teavm.backend.wasm.model.WasmTag;
|
||||||
import org.teavm.backend.wasm.model.WasmType;
|
import org.teavm.backend.wasm.model.WasmType;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmFunctionReference;
|
import org.teavm.backend.wasm.model.expression.WasmFunctionReference;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmReturn;
|
import org.teavm.backend.wasm.model.expression.WasmReturn;
|
||||||
|
@ -364,5 +366,20 @@ public class WasmGCMethodGenerator implements BaseWasmFunctionRepository {
|
||||||
public WasmGCNameProvider names() {
|
public WasmGCNameProvider names() {
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WasmGlobal exceptionGlobal() {
|
||||||
|
return context.exceptionGlobal();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WasmTag exceptionTag() {
|
||||||
|
return context.getExceptionTag();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseWasmFunctionRepository functions() {
|
||||||
|
return WasmGCMethodGenerator.this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,55 +15,55 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.backend.wasm.generators.gc;
|
package org.teavm.backend.wasm.generators.gc;
|
||||||
|
|
||||||
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider;
|
|
||||||
import org.teavm.backend.wasm.model.WasmFunction;
|
import org.teavm.backend.wasm.model.WasmFunction;
|
||||||
import org.teavm.backend.wasm.model.WasmLocal;
|
import org.teavm.backend.wasm.model.WasmLocal;
|
||||||
import org.teavm.backend.wasm.model.WasmType;
|
import org.teavm.backend.wasm.model.WasmType;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmCall;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmCallReference;
|
import org.teavm.backend.wasm.model.expression.WasmCallReference;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmConditional;
|
import org.teavm.backend.wasm.model.expression.WasmConditional;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmGetLocal;
|
import org.teavm.backend.wasm.model.expression.WasmGetLocal;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmInt32Constant;
|
|
||||||
import org.teavm.backend.wasm.model.expression.WasmNullConstant;
|
import org.teavm.backend.wasm.model.expression.WasmNullConstant;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmReferencesEqual;
|
import org.teavm.backend.wasm.model.expression.WasmReferencesEqual;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmReturn;
|
import org.teavm.backend.wasm.model.expression.WasmReturn;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmSetGlobal;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmStructGet;
|
import org.teavm.backend.wasm.model.expression.WasmStructGet;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmThrow;
|
||||||
|
import org.teavm.backend.wasm.runtime.WasmGCSupport;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
public class ClassGenerators implements WasmGCCustomGenerator {
|
public class ClassGenerators implements WasmGCCustomGenerator {
|
||||||
@Override
|
@Override
|
||||||
public void apply(MethodReference method, WasmFunction function, WasmGCCustomGeneratorContext context) {
|
public void apply(MethodReference method, WasmFunction function, WasmGCCustomGeneratorContext context) {
|
||||||
switch (method.getName()) {
|
switch (method.getName()) {
|
||||||
case "isInstance":
|
case "isAssignableFrom":
|
||||||
generateIsInstance(function, context);
|
generateIsAssignable(function, context);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unsupported method: " + method);
|
throw new IllegalArgumentException("Unsupported method: " + method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateIsInstance(WasmFunction function, WasmGCCustomGeneratorContext context) {
|
private void generateIsAssignable(WasmFunction function, WasmGCCustomGeneratorContext context) {
|
||||||
var classCls = context.classInfoProvider().getClassInfo("java.lang.Class");
|
var classCls = context.classInfoProvider().getClassInfo("java.lang.Class");
|
||||||
var objectCls = context.classInfoProvider().getClassInfo("java.lang.Object");
|
|
||||||
var thisVar = new WasmLocal(classCls.getType());
|
var thisVar = new WasmLocal(classCls.getType());
|
||||||
var objectVar = new WasmLocal(objectCls.getType());
|
var otherClassVar = new WasmLocal(classCls.getType());
|
||||||
function.add(thisVar);
|
function.add(thisVar);
|
||||||
function.add(objectVar);
|
function.add(otherClassVar);
|
||||||
|
|
||||||
var conditional = new WasmConditional(new WasmReferencesEqual(new WasmGetLocal(objectVar),
|
var conditional = new WasmConditional(new WasmReferencesEqual(new WasmGetLocal(otherClassVar),
|
||||||
new WasmNullConstant(WasmType.Reference.STRUCT)));
|
new WasmNullConstant(WasmType.Reference.STRUCT)));
|
||||||
conditional.setType(WasmType.INT32);
|
function.getBody().add(conditional);
|
||||||
conditional.getThenBlock().getBody().add(new WasmInt32Constant(0));
|
var npe = new WasmCall(context.functions().forStaticMethod(new MethodReference(WasmGCSupport.class, "npe",
|
||||||
|
NullPointerException.class)));
|
||||||
|
conditional.getThenBlock().getBody().add(new WasmSetGlobal(context.exceptionGlobal(), npe));
|
||||||
|
conditional.getThenBlock().getBody().add(new WasmThrow(context.exceptionTag()));
|
||||||
|
|
||||||
var objectClass = new WasmStructGet(objectCls.getStructure(), new WasmGetLocal(objectVar),
|
|
||||||
WasmGCClassInfoProvider.CLASS_FIELD_OFFSET);
|
|
||||||
var functionRef = new WasmStructGet(classCls.getStructure(), new WasmGetLocal(thisVar),
|
var functionRef = new WasmStructGet(classCls.getStructure(), new WasmGetLocal(thisVar),
|
||||||
context.classInfoProvider().getClassSupertypeFunctionOffset());
|
context.classInfoProvider().getClassSupertypeFunctionOffset());
|
||||||
var call = new WasmCallReference(functionRef,
|
var call = new WasmCallReference(functionRef,
|
||||||
context.functionTypes().of(WasmType.INT32, classCls.getType()));
|
context.functionTypes().of(WasmType.INT32, classCls.getType()));
|
||||||
call.getArguments().add(objectClass);
|
call.getArguments().add(new WasmGetLocal(otherClassVar));
|
||||||
conditional.getElseBlock().getBody().add(call);
|
|
||||||
|
|
||||||
function.getBody().add(new WasmReturn(conditional));
|
function.getBody().add(new WasmReturn(call));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,11 +15,14 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.backend.wasm.generators.gc;
|
package org.teavm.backend.wasm.generators.gc;
|
||||||
|
|
||||||
|
import org.teavm.backend.wasm.BaseWasmFunctionRepository;
|
||||||
import org.teavm.backend.wasm.WasmFunctionTypes;
|
import org.teavm.backend.wasm.WasmFunctionTypes;
|
||||||
import org.teavm.backend.wasm.generate.gc.WasmGCNameProvider;
|
import org.teavm.backend.wasm.generate.gc.WasmGCNameProvider;
|
||||||
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider;
|
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider;
|
||||||
import org.teavm.backend.wasm.generate.gc.classes.WasmGCTypeMapper;
|
import org.teavm.backend.wasm.generate.gc.classes.WasmGCTypeMapper;
|
||||||
|
import org.teavm.backend.wasm.model.WasmGlobal;
|
||||||
import org.teavm.backend.wasm.model.WasmModule;
|
import org.teavm.backend.wasm.model.WasmModule;
|
||||||
|
import org.teavm.backend.wasm.model.WasmTag;
|
||||||
|
|
||||||
public interface WasmGCCustomGeneratorContext {
|
public interface WasmGCCustomGeneratorContext {
|
||||||
WasmModule module();
|
WasmModule module();
|
||||||
|
@ -31,4 +34,10 @@ public interface WasmGCCustomGeneratorContext {
|
||||||
WasmGCClassInfoProvider classInfoProvider();
|
WasmGCClassInfoProvider classInfoProvider();
|
||||||
|
|
||||||
WasmGCNameProvider names();
|
WasmGCNameProvider names();
|
||||||
|
|
||||||
|
WasmGlobal exceptionGlobal();
|
||||||
|
|
||||||
|
BaseWasmFunctionRepository functions();
|
||||||
|
|
||||||
|
WasmTag exceptionTag();
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,8 @@ 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, "isAssignableFrom", Class.class, boolean.class),
|
||||||
|
classGenerators);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillStringPool() {
|
private void fillStringPool() {
|
||||||
|
|
|
@ -47,11 +47,18 @@ public class ClassIntrinsic implements WasmGCIntrinsic {
|
||||||
result.setLocation(invocation.getLocation());
|
result.setLocation(invocation.getLocation());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
case "getSuperclass": {
|
case "getDeclaringClass": {
|
||||||
var cls = context.generate(invocation.getArguments().get(0));
|
var cls = context.generate(invocation.getArguments().get(0));
|
||||||
var clsStruct = context.classInfoProvider().getClassInfo("java.lang.Class").getStructure();
|
var clsStruct = context.classInfoProvider().getClassInfo("java.lang.Class").getStructure();
|
||||||
var result = new WasmStructGet(clsStruct, cls,
|
var result = new WasmStructGet(clsStruct, cls,
|
||||||
context.classInfoProvider().getClassParentOffset());
|
context.classInfoProvider().getClassDeclaringClassOffset());
|
||||||
|
result.setLocation(invocation.getLocation());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
case "getSuperclass": {
|
||||||
|
var cls = context.generate(invocation.getArguments().get(0));
|
||||||
|
var clsStruct = context.classInfoProvider().getClassInfo("java.lang.Class").getStructure();
|
||||||
|
var result = new WasmStructGet(clsStruct, cls, context.classInfoProvider().getClassParentOffset());
|
||||||
result.setLocation(invocation.getLocation());
|
result.setLocation(invocation.getLocation());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -63,6 +70,10 @@ public class ClassIntrinsic implements WasmGCIntrinsic {
|
||||||
return generateGetSimpleName(invocation, context);
|
return generateGetSimpleName(invocation, context);
|
||||||
case "setSimpleNameCache":
|
case "setSimpleNameCache":
|
||||||
return generateSetSimpleName(invocation, context);
|
return generateSetSimpleName(invocation, context);
|
||||||
|
case "getCanonicalNameCache":
|
||||||
|
return generateGetCanonicalName(invocation, context);
|
||||||
|
case "setCanonicalNameCache":
|
||||||
|
return generateSetCanonicalName(invocation, context);
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unsupported invocation method: " + invocation.getMethod());
|
throw new IllegalArgumentException("Unsupported invocation method: " + invocation.getMethod());
|
||||||
}
|
}
|
||||||
|
@ -95,4 +106,19 @@ public class ClassIntrinsic implements WasmGCIntrinsic {
|
||||||
return new WasmStructSet(classCls.getStructure(), arg,
|
return new WasmStructSet(classCls.getStructure(), arg,
|
||||||
context.classInfoProvider().getClassSimpleNameOffset(), value);
|
context.classInfoProvider().getClassSimpleNameOffset(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private WasmExpression generateGetCanonicalName(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().getClassCanonicalNameOffset());
|
||||||
|
}
|
||||||
|
|
||||||
|
private WasmExpression generateSetCanonicalName(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().getClassCanonicalNameOffset(), value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,9 +86,12 @@ public class WasmGCIntrinsics implements WasmGCIntrinsicProvider {
|
||||||
add(new MethodReference(Class.class, "getNameImpl", String.class), intrinsic);
|
add(new MethodReference(Class.class, "getNameImpl", String.class), intrinsic);
|
||||||
add(new MethodReference(Class.class, "setNameImpl", String.class, void.class), intrinsic);
|
add(new MethodReference(Class.class, "setNameImpl", String.class, void.class), intrinsic);
|
||||||
add(new MethodReference(Class.class, "getEnclosingClass", Class.class), intrinsic);
|
add(new MethodReference(Class.class, "getEnclosingClass", Class.class), intrinsic);
|
||||||
|
add(new MethodReference(Class.class, "getDeclaringClass", Class.class), intrinsic);
|
||||||
add(new MethodReference(Class.class, "getSuperclass", Class.class), intrinsic);
|
add(new MethodReference(Class.class, "getSuperclass", Class.class), intrinsic);
|
||||||
add(new MethodReference(Class.class, "getSimpleNameCache", Class.class, String.class), intrinsic);
|
add(new MethodReference(Class.class, "getSimpleNameCache", Class.class, String.class), intrinsic);
|
||||||
add(new MethodReference(Class.class, "setSimpleNameCache", Class.class, String.class, void.class), intrinsic);
|
add(new MethodReference(Class.class, "setSimpleNameCache", Class.class, String.class, void.class), intrinsic);
|
||||||
|
add(new MethodReference(Class.class, "getCanonicalNameCache", String.class), intrinsic);
|
||||||
|
add(new MethodReference(Class.class, "setCanonicalNameCache", String.class, void.class), intrinsic);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillClassSupport() {
|
private void fillClassSupport() {
|
||||||
|
|
|
@ -69,8 +69,9 @@ public class BaseClassesTransformation implements ClassHolderTransformer {
|
||||||
for (var method : cls.getMethods()) {
|
for (var method : cls.getMethods()) {
|
||||||
switch (method.getName()) {
|
switch (method.getName()) {
|
||||||
case "getComponentType":
|
case "getComponentType":
|
||||||
case "isInstance":
|
case "isAssignableFrom":
|
||||||
case "getEnclosingClass":
|
case "getEnclosingClass":
|
||||||
|
case "getDeclaringClass":
|
||||||
case "getSimpleNameCache":
|
case "getSimpleNameCache":
|
||||||
case "setSimpleNameCache":
|
case "setSimpleNameCache":
|
||||||
case "getSuperclass":
|
case "getSuperclass":
|
||||||
|
|
|
@ -103,14 +103,12 @@ public class ClassTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SkipPlatform(TestPlatform.WEBASSEMBLY_GC)
|
|
||||||
public void castingAppropriateObject() {
|
public void castingAppropriateObject() {
|
||||||
Object obj = 23;
|
Object obj = 23;
|
||||||
assertEquals(Integer.valueOf(23), Integer.class.cast(obj));
|
assertEquals(Integer.valueOf(23), Integer.class.cast(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = ClassCastException.class)
|
@Test(expected = ClassCastException.class)
|
||||||
@SkipPlatform(TestPlatform.WEBASSEMBLY_GC)
|
|
||||||
public void inappropriateObjectCastingFails() {
|
public void inappropriateObjectCastingFails() {
|
||||||
Object obj = 23;
|
Object obj = 23;
|
||||||
Float.class.cast(obj);
|
Float.class.cast(obj);
|
||||||
|
@ -150,7 +148,6 @@ public class ClassTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SkipPlatform(TestPlatform.WEBASSEMBLY_GC)
|
|
||||||
public void classProperties() {
|
public void classProperties() {
|
||||||
class B {
|
class B {
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user