Skip to content

Commit

Permalink
wasm gc: fix issue with extracting elements from arrays of JS objects
Browse files Browse the repository at this point in the history
  • Loading branch information
konsoletyper committed Oct 4, 2024
1 parent eba0e2b commit 0057bbd
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 3 deletions.
3 changes: 3 additions & 0 deletions jso/impl/src/main/java/org/teavm/jso/impl/JS.java
Original file line number Diff line number Diff line change
Expand Up @@ -785,4 +785,7 @@ public static native JSObject construct(JSObject cls, JSObject a, JSObject b, JS
@InjectedBy(JSNativeInjector.class)
@NoSideEffects
public static native boolean isNull(JSObject o);

@NoSideEffects
public static native Object jsArrayItem(Object array, int index);
}
10 changes: 10 additions & 0 deletions jso/impl/src/main/java/org/teavm/jso/impl/JSClassProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,16 @@ private void processGetFromArray(GetElementInstruction insn) {
unwrap.setLocation(insn.getLocation());
insn.setReceiver(unwrap.getArguments().get(0));
insn.insertNext(unwrap);

if (wasmGC) {
var invoke = new InvokeInstruction();
invoke.setType(InvocationType.SPECIAL);
invoke.setMethod(new MethodReference(JS.class, "jsArrayItem", Object.class, int.class, Object.class));
invoke.setReceiver(insn.getReceiver());
invoke.setArguments(insn.getArray(), insn.getIndex());
invoke.setLocation(insn.getLocation());
insn.replace(invoke);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
import static org.teavm.jso.impl.wasmgc.WasmGCJSConstants.STRING_TO_JS;
import org.teavm.dependency.AbstractDependencyListener;
import org.teavm.dependency.DependencyAgent;
import org.teavm.dependency.MethodDependency;
import org.teavm.jso.JSObject;
import org.teavm.jso.impl.JS;
import org.teavm.jso.impl.JSWrapper;
import org.teavm.model.MethodReference;

Expand All @@ -37,4 +39,13 @@ public void started(DependencyAgent agent) {
agent.linkMethod(new MethodReference(JSWrapper.class, "createWrapper", JSObject.class, Object.class))
.use();
}

@Override
public void methodReached(DependencyAgent agent, MethodDependency method) {
if (method.getMethod().getOwnerName().equals(JS.class.getName())) {
if (method.getMethod().getName().equals("jsArrayItem")) {
method.getVariable(1).getArrayItem().connect(method.getResult());
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.teavm.backend.wasm.intrinsics.gc.WasmGCIntrinsicContext;
import org.teavm.backend.wasm.model.WasmFunction;
import org.teavm.backend.wasm.model.WasmType;
import org.teavm.backend.wasm.model.expression.WasmArrayGet;
import org.teavm.backend.wasm.model.expression.WasmBlock;
import org.teavm.backend.wasm.model.expression.WasmBranch;
import org.teavm.backend.wasm.model.expression.WasmCall;
Expand All @@ -32,6 +33,7 @@
import org.teavm.jso.JSObject;
import org.teavm.jso.impl.JS;
import org.teavm.model.MethodReference;
import org.teavm.model.ValueType;

class WasmGCJSIntrinsic implements WasmGCIntrinsic {
private WasmFunction globalFunction;
Expand All @@ -53,9 +55,11 @@ public WasmExpression apply(InvocationExpr invocation, WasmGCIntrinsicContext co
return new WasmCall(getGlobalFunction(context), name);
}
case "throwCCEIfFalse":
return throwCCEIfFalse(context, invocation);
return throwCCEIfFalse(invocation, context);
case "isNull":
return new WasmIsNull(context.generate(invocation.getArguments().get(0)));
case "jsArrayItem":
return arrayItem(invocation, context);
default:
throw new IllegalArgumentException();
}
Expand All @@ -74,7 +78,7 @@ private WasmFunction getGlobalFunction(WasmGCIntrinsicContext context) {
return globalFunction;
}

private WasmExpression throwCCEIfFalse(WasmGCIntrinsicContext context, InvocationExpr invocation) {
private WasmExpression throwCCEIfFalse(InvocationExpr invocation, WasmGCIntrinsicContext context) {
var block = new WasmBlock(false);
block.setType(WasmType.Reference.EXTERN);

Expand All @@ -93,4 +97,10 @@ private WasmExpression throwCCEIfFalse(WasmGCIntrinsicContext context, Invocatio
block.getBody().add(context.generate(invocation.getArguments().get(1)));
return block;
}

private WasmExpression arrayItem(InvocationExpr invocation, WasmGCIntrinsicContext context) {
var array = context.generate(invocation.getArguments().get(0));
var arrayType = context.classInfoProvider().getClassInfo(ValueType.parse(Object[].class)).getArray();
return new WasmArrayGet(arrayType, array, context.generate(invocation.getArguments().get(1)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public static void install(TeaVMHost host, TeaVMWasmGCHost wasmGCHost, JSBodyRep
wasmGCHost.addIntrinsic(new MethodReference(JS.class, "throwCCEIfFalse", boolean.class, JSObject.class,
JSObject.class), jsIntrinsic);
wasmGCHost.addIntrinsic(new MethodReference(JS.class, "isNull", JSObject.class, boolean.class), jsIntrinsic);
wasmGCHost.addIntrinsic(new MethodReference(JS.class, "jsArrayItem", Object.class, int.class, Object.class),
jsIntrinsic);

var wrapperIntrinsic = new WasmGCJSWrapperIntrinsic();
wasmGCHost.addIntrinsic(new MethodReference(JSWrapper.class, "wrap", JSObject.class, Object.class),
Expand Down
1 change: 0 additions & 1 deletion tests/src/test/java/org/teavm/jso/test/ConversionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ public void passesJSObject() {
}

@Test
@SkipPlatform(TestPlatform.WEBASSEMBLY_GC)
public void convertsArrayOfJSObject() {
assertEquals("(foo)", surround(new JSString[] { JSString.valueOf("foo") })[0].stringValue());
assertEquals("(foo)", surround(new JSString[][] {{ JSString.valueOf("foo") }})[0][0].stringValue());
Expand Down

0 comments on commit 0057bbd

Please sign in to comment.