mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
wasm gc: fix with passing JS objects to non-JS methods
This commit is contained in:
parent
d29b436fa5
commit
dff3e2f328
|
@ -324,7 +324,7 @@ class JSClassProcessor {
|
||||||
processConstructArray((ConstructArrayInstruction) insn);
|
processConstructArray((ConstructArrayInstruction) insn);
|
||||||
} else if (insn instanceof ExitInstruction) {
|
} else if (insn instanceof ExitInstruction) {
|
||||||
var exit = (ExitInstruction) insn;
|
var exit = (ExitInstruction) insn;
|
||||||
exit.setValueToReturn(wrapJsAsJava(insn, exit.getValueToReturn(),
|
exit.setValueToReturn(convertValue(insn, exit.getValueToReturn(),
|
||||||
methodToProcess.getResultType()));
|
methodToProcess.getResultType()));
|
||||||
} else if (insn instanceof ClassConstantInstruction) {
|
} else if (insn instanceof ClassConstantInstruction) {
|
||||||
processClassConstant((ClassConstantInstruction) insn);
|
processClassConstant((ClassConstantInstruction) insn);
|
||||||
|
@ -399,7 +399,7 @@ class JSClassProcessor {
|
||||||
for (var i = 0; i < invoke.getArguments().size(); ++i) {
|
for (var i = 0; i < invoke.getArguments().size(); ++i) {
|
||||||
var type = invoke.getMethod().parameterType(i);
|
var type = invoke.getMethod().parameterType(i);
|
||||||
var arg = invoke.getArguments().get(i);
|
var arg = invoke.getArguments().get(i);
|
||||||
var newArg = wrapJsAsJava(invoke, arg, type);
|
var newArg = convertValue(invoke, arg, type);
|
||||||
if (newArg != arg) {
|
if (newArg != arg) {
|
||||||
if (newArgs == null) {
|
if (newArgs == null) {
|
||||||
newArgs = invoke.getArguments().toArray(new Variable[0]);
|
newArgs = invoke.getArguments().toArray(new Variable[0]);
|
||||||
|
@ -412,12 +412,12 @@ class JSClassProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (invoke.getInstance() != null) {
|
if (invoke.getInstance() != null) {
|
||||||
invoke.setInstance(wrapJsAsJava(invoke, invoke.getInstance(), ValueType.object(className)));
|
invoke.setInstance(convertValue(invoke, invoke.getInstance(), ValueType.object(className)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processPutField(PutFieldInstruction putField) {
|
private void processPutField(PutFieldInstruction putField) {
|
||||||
putField.setValue(wrapJsAsJava(putField, putField.getValue(), putField.getFieldType()));
|
putField.setValue(convertValue(putField, putField.getValue(), putField.getFieldType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processGetFromArray(GetElementInstruction insn) {
|
private void processGetFromArray(GetElementInstruction insn) {
|
||||||
|
@ -772,16 +772,20 @@ class JSClassProcessor {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Variable wrapJsAsJava(Instruction instruction, Variable var, ValueType type) {
|
private Variable convertValue(Instruction instruction, Variable var, ValueType type) {
|
||||||
if (!(type instanceof ValueType.Object)) {
|
if (!(type instanceof ValueType.Object)) {
|
||||||
return var;
|
return var;
|
||||||
}
|
}
|
||||||
|
|
||||||
var cls = ((ValueType.Object) type).getClassName();
|
var cls = ((ValueType.Object) type).getClassName();
|
||||||
if (typeHelper.isJavaScriptClass(cls)) {
|
if (typeHelper.isJavaScriptClass(cls)) {
|
||||||
return var;
|
return convertJavaValueToJs(instruction, var);
|
||||||
|
} else {
|
||||||
|
return convertJsValueToJava(instruction, var);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Variable convertJsValueToJava(Instruction instruction, Variable var) {
|
||||||
var varType = types.typeOf(var);
|
var varType = types.typeOf(var);
|
||||||
if (varType != JSType.JS && varType != JSType.MIXED) {
|
if (varType != JSType.JS && varType != JSType.MIXED) {
|
||||||
return var;
|
return var;
|
||||||
|
@ -796,6 +800,21 @@ class JSClassProcessor {
|
||||||
return wrap.getReceiver();
|
return wrap.getReceiver();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Variable convertJavaValueToJs(Instruction instruction, Variable var) {
|
||||||
|
var varType = types.typeOf(var);
|
||||||
|
if (varType == JSType.JS || varType == JSType.MIXED || varType == JSType.NULL) {
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
var wrap = new InvokeInstruction();
|
||||||
|
wrap.setType(InvocationType.SPECIAL);
|
||||||
|
wrap.setMethod(JSMethods.UNWRAP);
|
||||||
|
wrap.setArguments(var);
|
||||||
|
wrap.setReceiver(program.createVariable());
|
||||||
|
wrap.setLocation(instruction.getLocation());
|
||||||
|
instruction.insertPrevious(wrap);
|
||||||
|
return wrap.getReceiver();
|
||||||
|
}
|
||||||
|
|
||||||
private Variable unwrapJavaToJs(Instruction instruction, Variable var) {
|
private Variable unwrapJavaToJs(Instruction instruction, Variable var) {
|
||||||
var varType = types.typeOf(var);
|
var varType = types.typeOf(var);
|
||||||
if (varType != JSType.JAVA && varType != JSType.MIXED) {
|
if (varType != JSType.JAVA && varType != JSType.MIXED) {
|
||||||
|
|
|
@ -47,6 +47,16 @@ public class ExportClassTest {
|
||||||
assertEquals("w", o.fooValue);
|
assertEquals("w", o.fooValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void simpleClassExportedViaStaticHelper() {
|
||||||
|
assertEquals("(OK)", callNativeJSMethod(new SimpleClass()));
|
||||||
|
assertEquals("[OK]", callNativeJSMethod(new DerivedSimpleClass()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String callNativeJSMethod(I a) {
|
||||||
|
return callIFromJs(a);
|
||||||
|
}
|
||||||
|
|
||||||
@JSBody(params = "a", script = "return a.foo('OK');")
|
@JSBody(params = "a", script = "return a.foo('OK');")
|
||||||
private static native String callIFromJs(I a);
|
private static native String callIFromJs(I a);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user