mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
wasm gc: implement some Class intrinsics, fix issues with type inference
This commit is contained in:
parent
fea62af09a
commit
d0226aab88
|
@ -164,12 +164,16 @@ public final class TClass<T> extends TObject implements TAnnotatedElement, TType
|
||||||
if (isArray()) {
|
if (isArray()) {
|
||||||
simpleName = getComponentType().getSimpleName() + "[]";
|
simpleName = getComponentType().getSimpleName() + "[]";
|
||||||
} else if (getEnclosingClass() != null) {
|
} else if (getEnclosingClass() != null) {
|
||||||
simpleName = Platform.getSimpleName(platformClass);
|
simpleName = PlatformDetector.isWebAssemblyGC()
|
||||||
|
? getSimpleNameCache(this)
|
||||||
|
: Platform.getSimpleName(platformClass);
|
||||||
if (simpleName == null) {
|
if (simpleName == null) {
|
||||||
simpleName = "";
|
simpleName = "";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
String name = Platform.getName(platformClass);
|
var name = PlatformDetector.isWebAssemblyGC()
|
||||||
|
? getName()
|
||||||
|
: Platform.getName(platformClass);
|
||||||
int lastDollar = name.lastIndexOf('$');
|
int lastDollar = name.lastIndexOf('$');
|
||||||
if (lastDollar != -1) {
|
if (lastDollar != -1) {
|
||||||
name = name.substring(lastDollar + 1);
|
name = name.substring(lastDollar + 1);
|
||||||
|
|
|
@ -1097,7 +1097,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
||||||
conditionalExpr.setConsequent(firstAssignment.getRightValue());
|
conditionalExpr.setConsequent(firstAssignment.getRightValue());
|
||||||
conditionalExpr.setAlternative(secondAssignment.getRightValue());
|
conditionalExpr.setAlternative(secondAssignment.getRightValue());
|
||||||
conditionalExpr.setLocation(statement.getCondition().getLocation());
|
conditionalExpr.setLocation(statement.getCondition().getLocation());
|
||||||
conditionalExpr.setVariableIndex(firstAssignment.getRightValue().getVariableIndex());
|
conditionalExpr.setVariableIndex(firstAssignment.getLeftValue().getVariableIndex());
|
||||||
AssignmentStatement assignment = new AssignmentStatement();
|
AssignmentStatement assignment = new AssignmentStatement();
|
||||||
assignment.setLocation(conditionalExpr.getLocation());
|
assignment.setLocation(conditionalExpr.getLocation());
|
||||||
VariableExpr lhs = new VariableExpr();
|
VariableExpr lhs = new VariableExpr();
|
||||||
|
|
|
@ -34,9 +34,9 @@ public final class WasmGCUtil {
|
||||||
if (firstPath.get(0) != secondPath.get(0)) {
|
if (firstPath.get(0) != secondPath.get(0)) {
|
||||||
return "java.lang.Object";
|
return "java.lang.Object";
|
||||||
}
|
}
|
||||||
var min = Math.min(firstPath.size(), secondPath.size());
|
var min = Math.min(firstPath.size(), secondPath.size()) - 1;
|
||||||
var index = 1;
|
var index = 0;
|
||||||
while (index < min && firstPath.get(index) == secondPath.get(index)) {
|
while (index < min && firstPath.get(index + 1) == secondPath.get(index + 1)) {
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
return index < firstPath.size() ? firstPath.get(index).getName() : secondPath.get(index).getName();
|
return index < firstPath.size() ? firstPath.get(index).getName() : secondPath.get(index).getName();
|
||||||
|
|
|
@ -119,11 +119,13 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
private int classTagOffset;
|
private int classTagOffset;
|
||||||
private int classFlagsOffset;
|
private int classFlagsOffset;
|
||||||
private int classNameOffset;
|
private int classNameOffset;
|
||||||
|
private int classSimpleNameOffset;
|
||||||
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 virtualTableFieldOffset;
|
private int virtualTableFieldOffset;
|
||||||
private int arrayLengthOffset = -1;
|
private int arrayLengthOffset = -1;
|
||||||
private int arrayGetOffset = -1;
|
private int arrayGetOffset = -1;
|
||||||
|
@ -351,12 +353,24 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
return classSupertypeFunctionOffset;
|
return classSupertypeFunctionOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getClassEnclosingClassOffset() {
|
||||||
|
standardClasses.classClass().getStructure().init();
|
||||||
|
return classEnclosingClassOffset;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getClassNameOffset() {
|
public int getClassNameOffset() {
|
||||||
standardClasses.classClass().getStructure().init();
|
standardClasses.classClass().getStructure().init();
|
||||||
return classNameOffset;
|
return classNameOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getClassSimpleNameOffset() {
|
||||||
|
standardClasses.classClass().getStructure().init();
|
||||||
|
return classSimpleNameOffset;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNewArrayFunctionOffset() {
|
public int getNewArrayFunctionOffset() {
|
||||||
standardClasses.classClass().getStructure().init();
|
standardClasses.classClass().getStructure().init();
|
||||||
|
@ -445,12 +459,16 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
if (cls != null) {
|
if (cls != null) {
|
||||||
if (metadataReq.simpleName() && cls.getSimpleName() != null) {
|
if (metadataReq.simpleName() && cls.getSimpleName() != null) {
|
||||||
var namePtr = strings.getStringConstant(cls.getSimpleName()).global;
|
var namePtr = strings.getStringConstant(cls.getSimpleName()).global;
|
||||||
target.add(setClassField(classInfo, classNameOffset, new WasmGetGlobal(namePtr)));
|
target.add(setClassField(classInfo, classSimpleNameOffset, new WasmGetGlobal(namePtr)));
|
||||||
}
|
}
|
||||||
if (cls.getParent() != null && metadataReq.superclass()) {
|
if (cls.getParent() != null && metadataReq.superclass()) {
|
||||||
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()) {
|
||||||
|
var owner = getClassInfo(cls.getOwnerName());
|
||||||
|
target.add(setClassField(classInfo, classEnclosingClassOffset, new WasmGetGlobal(owner.pointer)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (virtualTable != null && virtualTable.isConcrete()) {
|
if (virtualTable != null && virtualTable.isConcrete()) {
|
||||||
fillVirtualTableMethods(target, classStructure, classInfo.pointer, virtualTable);
|
fillVirtualTableMethods(target, classStructure, classInfo.pointer, virtualTable);
|
||||||
|
@ -960,8 +978,12 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
classNewArrayOffset = fields.size();
|
classNewArrayOffset = fields.size();
|
||||||
fields.add(createClassField(newArrayGenerator.getNewArrayFunctionType().getReference().asStorage(),
|
fields.add(createClassField(newArrayGenerator.getNewArrayFunctionType().getReference().asStorage(),
|
||||||
"createArrayInstance"));
|
"createArrayInstance"));
|
||||||
|
classEnclosingClassOffset = fields.size();
|
||||||
|
fields.add(createClassField(standardClasses.stringClass().getType().asStorage(), "enclosingClass"));
|
||||||
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();
|
||||||
|
fields.add(createClassField(standardClasses.stringClass().getType().asStorage(), "simpleNAme"));
|
||||||
virtualTableFieldOffset = fields.size();
|
virtualTableFieldOffset = fields.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,10 +40,14 @@ public interface WasmGCClassInfoProvider {
|
||||||
|
|
||||||
int getClassSupertypeFunctionOffset();
|
int getClassSupertypeFunctionOffset();
|
||||||
|
|
||||||
|
int getClassEnclosingClassOffset();
|
||||||
|
|
||||||
int getNewArrayFunctionOffset();
|
int getNewArrayFunctionOffset();
|
||||||
|
|
||||||
int getClassNameOffset();
|
int getClassNameOffset();
|
||||||
|
|
||||||
|
int getClassSimpleNameOffset();
|
||||||
|
|
||||||
int getArrayGetOffset();
|
int getArrayGetOffset();
|
||||||
|
|
||||||
int getArrayLengthOffset();
|
int getArrayLengthOffset();
|
||||||
|
|
|
@ -20,21 +20,34 @@ 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;
|
import org.teavm.backend.wasm.model.expression.WasmStructSet;
|
||||||
|
|
||||||
public class ClassIntrinsics implements WasmGCIntrinsic {
|
public class ClassIntrinsic implements WasmGCIntrinsic {
|
||||||
@Override
|
@Override
|
||||||
public WasmExpression apply(InvocationExpr invocation, WasmGCIntrinsicContext context) {
|
public WasmExpression apply(InvocationExpr invocation, WasmGCIntrinsicContext context) {
|
||||||
switch (invocation.getMethod().getName()) {
|
switch (invocation.getMethod().getName()) {
|
||||||
case "getComponentType":
|
case "getComponentType": {
|
||||||
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().getClassArrayItemOffset());
|
context.classInfoProvider().getClassArrayItemOffset());
|
||||||
result.setLocation(invocation.getLocation());
|
result.setLocation(invocation.getLocation());
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
case "getEnclosingClass": {
|
||||||
|
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().getClassEnclosingClassOffset());
|
||||||
|
result.setLocation(invocation.getLocation());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
case "getNameImpl":
|
case "getNameImpl":
|
||||||
return generateGetName(invocation, context);
|
return generateGetName(invocation, context);
|
||||||
case "setNameImpl":
|
case "setNameImpl":
|
||||||
return generateSetName(invocation, context);
|
return generateSetName(invocation, context);
|
||||||
|
case "getSimpleNameCache":
|
||||||
|
return generateGetSimpleName(invocation, context);
|
||||||
|
case "setSimpleNameCache":
|
||||||
|
return generateSetSimpleName(invocation, context);
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unsupported invocation method: " + invocation.getMethod());
|
throw new IllegalArgumentException("Unsupported invocation method: " + invocation.getMethod());
|
||||||
}
|
}
|
||||||
|
@ -53,4 +66,18 @@ public class ClassIntrinsics implements WasmGCIntrinsic {
|
||||||
return new WasmStructSet(classCls.getStructure(), arg, context.classInfoProvider().getClassNameOffset(),
|
return new WasmStructSet(classCls.getStructure(), arg, context.classInfoProvider().getClassNameOffset(),
|
||||||
value);
|
value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private WasmExpression generateGetSimpleName(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().getClassSimpleNameOffset());
|
||||||
|
}
|
||||||
|
|
||||||
|
private WasmExpression generateSetSimpleName(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().getClassSimpleNameOffset(), value);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -78,10 +78,13 @@ public class WasmGCIntrinsics implements WasmGCIntrinsicProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillClass() {
|
private void fillClass() {
|
||||||
var intrinsic = new ClassIntrinsics();
|
var intrinsic = new ClassIntrinsic();
|
||||||
add(new MethodReference(Class.class, "getComponentType", Class.class), intrinsic);
|
add(new MethodReference(Class.class, "getComponentType", Class.class), intrinsic);
|
||||||
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, "getSimpleNameCache", Class.class, String.class), intrinsic);
|
||||||
|
add(new MethodReference(Class.class, "setSimpleNameCache", Class.class, String.class, void.class), intrinsic);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillSystem() {
|
private void fillSystem() {
|
||||||
|
|
|
@ -77,6 +77,9 @@ public class BaseClassesTransformation implements ClassHolderTransformer {
|
||||||
switch (method.getName()) {
|
switch (method.getName()) {
|
||||||
case "getComponentType":
|
case "getComponentType":
|
||||||
case "isInstance":
|
case "isInstance":
|
||||||
|
case "getEnclosingClass":
|
||||||
|
case "getSimpleNameCache":
|
||||||
|
case "setSimpleNameCache":
|
||||||
method.setProgram(null);
|
method.setProgram(null);
|
||||||
method.getModifiers().add(ElementModifier.NATIVE);
|
method.getModifiers().add(ElementModifier.NATIVE);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user