Skip to content

Commit

Permalink
wasm gc: add strict mode, fix some bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
konsoletyper committed Sep 10, 2024
1 parent 2d8556d commit a7f3b89
Show file tree
Hide file tree
Showing 17 changed files with 71 additions and 22 deletions.
19 changes: 17 additions & 2 deletions classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.Set;
import org.teavm.backend.javascript.spi.GeneratedBy;
import org.teavm.backend.javascript.spi.InjectedBy;
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassFlags;
import org.teavm.classlib.PlatformDetector;
import org.teavm.classlib.impl.reflection.ClassSupport;
import org.teavm.classlib.impl.reflection.Flags;
Expand Down Expand Up @@ -292,6 +293,9 @@ private void setCanonicalNameCacheLowLevel(RuntimeObject object) {
}

public boolean isPrimitive() {
if (PlatformDetector.isWebAssemblyGC()) {
return (getWasmGCFlags() & WasmGCClassFlags.PRIMITIVE) != 0;
}
return Platform.isPrimitive(platformClass);
}

Expand All @@ -303,22 +307,33 @@ public boolean isArray() {
}

public boolean isEnum() {
if (PlatformDetector.isWebAssemblyGC()) {
return (getWasmGCFlags() & WasmGCClassFlags.ENUM) != 0;
}
return Platform.isEnum(platformClass);
}

public boolean isInterface() {
if (PlatformDetector.isWebAssemblyGC()) {
return (getWasmGCFlags() & WasmGCClassFlags.INTERFACE) != 0;
}
return (platformClass.getMetadata().getFlags() & Flags.INTERFACE) != 0;

}

public boolean isLocalClass() {
return (platformClass.getMetadata().getFlags() & Flags.SYNTHETIC) != 0
&& getEnclosingClass() != null;
if (PlatformDetector.isWebAssemblyGC()) {
return (getWasmGCFlags() & WasmGCClassFlags.SYNTHETIC) != 0 && getEnclosingClass() != null;
}
return (platformClass.getMetadata().getFlags() & Flags.SYNTHETIC) != 0 && getEnclosingClass() != null;
}

public boolean isMemberClass() {
return getDeclaringClass() != null;
}

private native int getWasmGCFlags();

@PluggableDependency(ClassGenerator.class)
public TClass<?> getComponentType() {
return getClass(Platform.getArrayItem(platformClass));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ public int hashCode() {
}

@Override
@UnsupportedOn(Platforms.WEBASSEMBLY_GC)
public String toString() {
if (PlatformDetector.isC()) {
return toStringC(value);
Expand Down
16 changes: 10 additions & 6 deletions core/src/main/java/org/teavm/backend/wasm/WasmGCTarget.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@

public class WasmGCTarget implements TeaVMTarget, TeaVMWasmGCHost {
private TeaVMTargetController controller;
private NullCheckInsertion nullCheckInsertion;
private NullCheckInsertion nullCheckInsertion = new NullCheckInsertion(NullCheckFilter.EMPTY);
private BoundCheckInsertion boundCheckInsertion = new BoundCheckInsertion();
private boolean strict;
private boolean obfuscated;
private List<WasmGCIntrinsicFactory> intrinsicFactories = new ArrayList<>();
private Map<MethodReference, WasmGCIntrinsic> customIntrinsics = new HashMap<>();
Expand All @@ -64,6 +65,10 @@ public void setObfuscated(boolean obfuscated) {
this.obfuscated = obfuscated;
}

public void setStrict(boolean strict) {
this.strict = strict;
}

@Override
public void addIntrinsicFactory(WasmGCIntrinsicFactory intrinsicFactory) {
intrinsicFactories.add(intrinsicFactory);
Expand All @@ -82,7 +87,6 @@ public void addCustomTypeMapperFactory(WasmGCCustomTypeMapperFactory customTypeM
@Override
public void setController(TeaVMTargetController controller) {
this.controller = controller;
nullCheckInsertion = new NullCheckInsertion(NullCheckFilter.EMPTY);
}

@Override
Expand Down Expand Up @@ -116,10 +120,10 @@ public List<TeaVMHostExtension> getHostExtensions() {

@Override
public void beforeOptimizations(Program program, MethodReader method) {
/*
nullCheckInsertion.transformProgram(program, method.getReference());
boundCheckInsertion.transformProgram(program, method.getReference());
*/
if (strict) {
nullCheckInsertion.transformProgram(program, method.getReference());
boundCheckInsertion.transformProgram(program, method.getReference());
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ private void contributeExceptionUtils() {
analyzer.linkMethod(new MethodReference(WasmGCSupport.class, "aiiobe", ArrayIndexOutOfBoundsException.class))
.use();
analyzer.linkMethod(new MethodReference(WasmGCSupport.class, "cce", ClassCastException.class)).use();
analyzer.linkMethod(new MethodReference(WasmGCSupport.class, "defaultClone", Object.class,
Object.class)).use();
analyzer.linkMethod(new MethodReference(WasmGCSupport.class, "throwCloneNotSupportedException",
void.class)).use();
}

private void contributeInitializerUtils() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -594,10 +594,6 @@ private WasmBlock throwJumpTarget() {
return lastTryBlock != null ? lastTryBlock : rethrowBlock();
}

private boolean needsCallSiteId() {
return managed;
}

private void generateAllocStack(Expr sizeExpr) {
if (stackVariable != null) {
throw new IllegalStateException("Call to ShadowStack.allocStack must be done only once");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
import org.teavm.backend.wasm.model.expression.WasmSwitch;
import org.teavm.backend.wasm.model.expression.WasmThrow;
import org.teavm.backend.wasm.model.expression.WasmTry;
import org.teavm.backend.wasm.model.expression.WasmUnreachable;
import org.teavm.backend.wasm.render.WasmTypeInference;
import org.teavm.model.FieldReference;
import org.teavm.model.MethodReference;
Expand Down Expand Up @@ -450,11 +451,14 @@ private WasmExpression nullCheck(Expr value, TextLocation location) {
block.setLocation(location);

accept(value);
if (result instanceof WasmUnreachable) {
return result;
}
result.acceptVisitor(typeInference);
block.setType(typeInference.getResult());
var cachedValue = exprCache.create(result, typeInference.getResult(), location, block.getBody());

var check = new WasmBranch(cachedValue.expr(), block);
var check = new WasmBranch(negate(genIsNull(cachedValue.expr())), block);
check.setResult(cachedValue.expr());
block.getBody().add(new WasmDrop(check));

Expand Down Expand Up @@ -945,7 +949,7 @@ protected abstract WasmExpression generateVirtualCall(
List<WasmExpression> arguments
);

private boolean needsCallSiteId() {
protected boolean needsCallSiteId() {
return isManaged();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,12 @@ public int getClassArrayItemOffset() {
return classArrayItemOffset;
}

@Override
public int getClassFlagsOffset() {
standardClasses.classClass().getStructure().init();
return classFlagsOffset;
}

@Override
public int getClassSupertypeFunctionOffset() {
standardClasses.classClass().getStructure().init();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public interface WasmGCClassInfoProvider {

int getClassArrayItemOffset();

int getClassFlagsOffset();

int getClassSupertypeFunctionOffset();

int getClassEnclosingClassOffset();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ public WasmFunction npeMethod() {

public WasmFunction aaiobeMethod() {
if (aaiobeMethod == null) {
aaiobeMethod = functions().forStaticMethod(new MethodReference(WasmGCSupport.class, "aaiobe",
aaiobeMethod = functions().forStaticMethod(new MethodReference(WasmGCSupport.class, "aiiobe",
ArrayIndexOutOfBoundsException.class));
}
return aaiobeMethod;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ protected void acceptWithType(Expr expr, ValueType type) {

@Override
protected boolean isManaged() {
return true;
}

@Override
protected boolean needsCallSiteId() {
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ public class ClassIntrinsic implements WasmGCIntrinsic {
@Override
public WasmExpression apply(InvocationExpr invocation, WasmGCIntrinsicContext context) {
switch (invocation.getMethod().getName()) {
case "getWasmGCFlags": {
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().getClassFlagsOffset());
result.setLocation(invocation.getLocation());
return result;
}
case "getComponentType": {
var cls = context.generate(invocation.getArguments().get(0));
var clsStruct = context.classInfoProvider().getClassInfo("java.lang.Class").getStructure();
Expand All @@ -43,7 +50,8 @@ public WasmExpression apply(InvocationExpr invocation, WasmGCIntrinsicContext co
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());
var result = new WasmStructGet(clsStruct, cls,
context.classInfoProvider().getClassParentOffset());
result.setLocation(invocation.getLocation());
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ private void fillObject() {
private void fillClass() {
var intrinsic = new ClassIntrinsic();
add(new MethodReference(Class.class, "getComponentType", Class.class), intrinsic);
add(new MethodReference(Class.class, "getWasmGCFlags", int.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, "getEnclosingClass", Class.class), intrinsic);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public static ClassCastException cce() {
return new ClassCastException();
}

public static Object defaultClone(Object value) throws CloneNotSupportedException {
public static void throwCloneNotSupportedException() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}

Expand Down
3 changes: 3 additions & 0 deletions core/src/main/java/org/teavm/runtime/Fiber.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@

import java.util.Arrays;
import org.teavm.interop.AsyncCallback;
import org.teavm.interop.Platforms;
import org.teavm.interop.StaticInit;
import org.teavm.interop.Unmanaged;
import org.teavm.interop.UnsupportedOn;

@StaticInit
@UnsupportedOn(Platforms.WEBASSEMBLY_GC)
public class Fiber {
public static final int STATE_RUNNING = 0;
public static final int STATE_SUSPENDING = 1;
Expand Down
2 changes: 2 additions & 0 deletions platform/src/main/java/org/teavm/platform/Platform.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.teavm.interop.PlatformMarker;
import org.teavm.interop.Platforms;
import org.teavm.interop.Unmanaged;
import org.teavm.interop.UnsupportedOn;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
import org.teavm.jso.browser.Window;
Expand All @@ -35,6 +36,7 @@
import org.teavm.runtime.RuntimeClass;
import org.teavm.runtime.RuntimeObject;

@UnsupportedOn(Platforms.WEBASSEMBLY_GC)
public final class Platform {
private Platform() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,16 @@
@EachTestCompiledSeparately
public class WeakReferenceTest {
@Test
@SkipPlatform({ TestPlatform.JAVASCRIPT, TestPlatform.WEBASSEMBLY, TestPlatform.WASI })
@SkipPlatform({ TestPlatform.JAVASCRIPT, TestPlatform.WEBASSEMBLY, TestPlatform.WASI,
TestPlatform.WEBASSEMBLY_GC })
public void deref() {
var ref = createAndTestRef(null);
GCSupport.tryToTriggerGC(ref);
assertNull(ref.get());
}

@Test
@SkipPlatform({ TestPlatform.JAVASCRIPT, TestPlatform.WEBASSEMBLY, TestPlatform.WASI })
@SkipPlatform({ TestPlatform.JAVASCRIPT, TestPlatform.WEBASSEMBLY, TestPlatform.WASI, TestPlatform.WEBASSEMBLY_GC })
public void refQueue() {
var queue = new ReferenceQueue<>();
var ref = createAndTestRef(queue);
Expand Down Expand Up @@ -70,7 +71,7 @@ private static void waitInJVM() {
}

@Test
@SkipPlatform({ TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI })
@SkipPlatform({ TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI, TestPlatform.WEBASSEMBLY_GC })
public void queueRemove() throws InterruptedException {
var queue = new ReferenceQueue<>();
var ref = createAndTestRef(queue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ CompileResult compile(Consumer<TeaVM> additionalProcessing, String baseName,
Supplier<WasmGCTarget> targetSupplier = () -> {
var target = new WasmGCTarget();
target.setObfuscated(false);
target.setStrict(true);
var sourceDirs = System.getProperty(SOURCE_DIRS);
if (sourceDirs != null) {
var dirs = new ArrayList<File>();
Expand Down

0 comments on commit a7f3b89

Please sign in to comment.