Skip to content

Commit

Permalink
Introduce WebAssemblyValueType enum.
Browse files Browse the repository at this point in the history
  • Loading branch information
woess committed Oct 2, 2024
1 parent 96e9010 commit 6942dea
Show file tree
Hide file tree
Showing 13 changed files with 176 additions and 186 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@
import com.oracle.truffle.js.runtime.builtins.wasm.JSWebAssemblyModule;
import com.oracle.truffle.js.runtime.builtins.wasm.JSWebAssemblyModuleObject;
import com.oracle.truffle.js.runtime.builtins.wasm.JSWebAssemblyTable;
import com.oracle.truffle.js.runtime.builtins.wasm.JSWebAssemblyValueTypes;
import com.oracle.truffle.js.runtime.builtins.wasm.WebAssemblyValueType;
import com.oracle.truffle.js.runtime.java.JavaImporter;
import com.oracle.truffle.js.runtime.java.JavaPackage;
import com.oracle.truffle.js.runtime.objects.IteratorRecord;
Expand Down Expand Up @@ -3345,12 +3345,14 @@ public ConstructWebAssemblyTableNode(JSContext context, JSBuiltin builtin, boole
@Specialization
protected JSObject constructTable(JSDynamicObject newTarget, Object descriptor, Object[] args,
@Cached JSToStringNode toStringNode,
@Cached TruffleString.ToJavaStringNode toJavaString,
@Cached ToWebAssemblyValueNode toWebAssemblyValueNode) {
if (!isObjectNode.executeBoolean(descriptor)) {
throw Errors.createTypeError("WebAssembly.Table(): Argument 0 must be a table descriptor", this);
}
TruffleString elementKind = toStringNode.executeString(getElementNode.getValue(descriptor));
if (!JSWebAssemblyValueTypes.isReferenceType(elementKind)) {
String elementKindStr = toJavaString.execute(toStringNode.executeString(getElementNode.getValue(descriptor)));
WebAssemblyValueType elementKind = WebAssemblyValueType.lookupType(elementKindStr);
if (elementKind == null || !elementKind.isReference()) {
throw Errors.createTypeError("WebAssembly.Table(): Descriptor property 'element' must be 'anyfunc' or 'externref'", this);
}
Object initial = getInitialNode.getValue(descriptor);
Expand All @@ -3377,14 +3379,14 @@ protected JSObject constructTable(JSDynamicObject newTarget, Object descriptor,
final JSRealm realm = getRealm();
Object wasmValue;
if (args.length == 0) {
wasmValue = JSWebAssemblyValueTypes.getDefaultValue(realm, elementKind);
wasmValue = elementKind.getDefaultValue(realm);
} else {
wasmValue = toWebAssemblyValueNode.execute(args[0], elementKind);
}
Object wasmTable;
try {
Object createTable = realm.getWASMTableAlloc();
wasmTable = tableAllocLib.execute(createTable, initialInt, maximumInt, elementKind, wasmValue);
wasmTable = tableAllocLib.execute(createTable, initialInt, maximumInt, elementKindStr, wasmValue);
} catch (InteropException ex) {
throw Errors.shouldNotReachHere(ex);
}
Expand Down Expand Up @@ -3416,34 +3418,36 @@ protected JSObject constructGlobal(JSDynamicObject newTarget, Object descriptor,
@Cached IsObjectNode isObjectNode,
@Cached(inline = true) JSToBooleanNode toBooleanNode,
@Cached JSToStringNode toStringNode,
@Cached TruffleString.ToJavaStringNode toJavaString,
@Cached ToWebAssemblyValueNode toWebAssemblyValueNode) {
if (!isObjectNode.executeBoolean(descriptor)) {
throw Errors.createTypeError("WebAssembly.Global(): Argument 0 must be a global descriptor", this);
}
boolean mutable = toBooleanNode.executeBoolean(this, getMutableNode.getValue(descriptor));
TruffleString valueType = toStringNode.executeString(getValueNode.getValue(descriptor));
if (!JSWebAssemblyValueTypes.isValueType(valueType)) {
String valueTypeStr = toJavaString.execute(toStringNode.executeString(getValueNode.getValue(descriptor)));
WebAssemblyValueType valueType = WebAssemblyValueType.lookupType(valueTypeStr);
if (valueType == null) {
throw Errors.createTypeError("WebAssembly.Global(): Descriptor property 'value' must be a WebAssembly type (i32, i64, f32, f64, anyfunc, externref)", this);
}
if (JSWebAssemblyValueTypes.isV128(valueType)) {
if (valueType == WebAssemblyValueType.v128) {
throw Errors.createTypeError("WebAssembly.Global(): Descriptor property 'value' must not be v128", this);
}
final JSRealm realm = getRealm();
Object webAssemblyValue;
// According to the spec only missing values should produce a default value.
// According to the tests also undefined should use the default value.
if (args.length == 0 || args[0] == Undefined.instance) {
webAssemblyValue = JSWebAssemblyValueTypes.getDefaultValue(realm, valueType);
webAssemblyValue = valueType.getDefaultValue(realm);
} else {
if (!getContext().getLanguageOptions().wasmBigInt() && JSWebAssemblyValueTypes.isI64(valueType)) {
if (!getContext().getLanguageOptions().wasmBigInt() && valueType == WebAssemblyValueType.i64) {
throw Errors.createTypeError("WebAssembly.Global(): Can't set the value of i64 WebAssembly.Global", this);
}
webAssemblyValue = toWebAssemblyValueNode.execute(args[0], valueType);
}
Object wasmGlobal;
try {
Object createGlobal = realm.getWASMGlobalAlloc();
wasmGlobal = globalAllocLib.execute(createGlobal, valueType, mutable, webAssemblyValue);
wasmGlobal = globalAllocLib.execute(createGlobal, valueTypeStr, mutable, webAssemblyValue);
} catch (InteropException ex) {
throw Errors.shouldNotReachHere(ex);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -63,7 +63,7 @@
import com.oracle.truffle.js.runtime.builtins.BuiltinEnum;
import com.oracle.truffle.js.runtime.builtins.wasm.JSWebAssemblyGlobal;
import com.oracle.truffle.js.runtime.builtins.wasm.JSWebAssemblyGlobalObject;
import com.oracle.truffle.js.runtime.builtins.wasm.JSWebAssemblyValueTypes;
import com.oracle.truffle.js.runtime.builtins.wasm.WebAssemblyValueType;
import com.oracle.truffle.js.runtime.objects.Undefined;

public class WebAssemblyGlobalPrototypeBuiltins extends JSBuiltinsContainer.SwitchEnum<WebAssemblyGlobalPrototypeBuiltins.WebAssemblyGlobalPrototype> {
Expand Down Expand Up @@ -136,7 +136,7 @@ protected Object getValue(JSWebAssemblyGlobalObject object,
@Cached InlinedBranchProfile errorBranch,
@Cached ToJSValueNode toJSValueNode,
@CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary globalReadLib) {
if (JSWebAssemblyValueTypes.isV128(object.getValueType())) {
if (object.getValueType() == WebAssemblyValueType.v128) {
errorBranch.enter(this);
v128TypeError();
}
Expand Down Expand Up @@ -177,7 +177,7 @@ protected Object setValue(JSWebAssemblyGlobalObject global, Object[] args,
errorBranch.enter(this);
throw Errors.createTypeError("set WebAssembly.Global.value: Can't set the value of an immutable global");
}
if (JSWebAssemblyValueTypes.isV128(global.getValueType())) {
if (global.getValueType() == WebAssemblyValueType.v128) {
errorBranch.enter(this);
throw Errors.createTypeError("set WebAssembly.Global.value: cannot write value type v128", this);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -50,7 +50,6 @@
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.profiles.InlinedBranchProfile;
import com.oracle.truffle.api.strings.TruffleString;
import com.oracle.truffle.js.builtins.JSBuiltinsContainer;
import com.oracle.truffle.js.builtins.wasm.WebAssemblyTablePrototypeBuiltinsFactory.WebAssemblyTableGetLengthNodeGen;
import com.oracle.truffle.js.builtins.wasm.WebAssemblyTablePrototypeBuiltinsFactory.WebAssemblyTableGetNodeGen;
Expand All @@ -68,7 +67,7 @@
import com.oracle.truffle.js.runtime.builtins.BuiltinEnum;
import com.oracle.truffle.js.runtime.builtins.wasm.JSWebAssemblyTable;
import com.oracle.truffle.js.runtime.builtins.wasm.JSWebAssemblyTableObject;
import com.oracle.truffle.js.runtime.builtins.wasm.JSWebAssemblyValueTypes;
import com.oracle.truffle.js.runtime.builtins.wasm.WebAssemblyValueType;
import com.oracle.truffle.js.runtime.objects.Undefined;

public class WebAssemblyTablePrototypeBuiltins extends JSBuiltinsContainer.SwitchEnum<WebAssemblyTablePrototypeBuiltins.WebAssemblyTablePrototype> {
Expand Down Expand Up @@ -143,12 +142,12 @@ protected Object grow(Object thiz, Object delta, Object[] args,
JSWebAssemblyTableObject table = (JSWebAssemblyTableObject) thiz;
int deltaInt = toDeltaNode.executeInt(delta);
Object wasmTable = table.getWASMTable();
TruffleString elementKind = table.getElementKind();
WebAssemblyValueType elementKind = table.getElementKind();

final JSRealm realm = getRealm();
final Object wasmValue;
if (args.length == 0) {
wasmValue = JSWebAssemblyValueTypes.getDefaultValue(realm, elementKind);
wasmValue = elementKind.getDefaultValue(realm);
} else {
wasmValue = toWebAssemblyValueNode.execute(args[0], elementKind);
}
Expand Down Expand Up @@ -220,12 +219,12 @@ protected Object set(Object thiz, Object index, Object[] args,
JSWebAssemblyTableObject table = (JSWebAssemblyTableObject) thiz;
int indexInt = toIndexNode.executeInt(index);
Object wasmTable = table.getWASMTable();
TruffleString elementKind = table.getElementKind();
WebAssemblyValueType elementKind = table.getElementKind();
final JSRealm realm = getRealm();

final Object wasmValue;
if (args.length == 0) {
wasmValue = JSWebAssemblyValueTypes.getDefaultValue(realm, elementKind);
wasmValue = elementKind.getDefaultValue(realm);
} else {
wasmValue = toWebAssemblyValueNode.execute(args[0], elementKind);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.profiles.InlinedBranchProfile;
import com.oracle.truffle.api.strings.TruffleString;
import com.oracle.truffle.js.nodes.JavaScriptBaseNode;
import com.oracle.truffle.js.nodes.cast.JSToBigIntNode;
import com.oracle.truffle.js.nodes.cast.JSToInt32Node;
Expand All @@ -57,52 +56,52 @@
import com.oracle.truffle.js.runtime.JSException;
import com.oracle.truffle.js.runtime.JSRuntime;
import com.oracle.truffle.js.runtime.builtins.wasm.JSWebAssembly;
import com.oracle.truffle.js.runtime.builtins.wasm.JSWebAssemblyValueTypes;
import com.oracle.truffle.js.runtime.builtins.wasm.WebAssemblyValueType;
import com.oracle.truffle.js.runtime.objects.JSDynamicObject;
import com.oracle.truffle.js.runtime.objects.Null;

/**
* Implementation of ToWebAssemblyValue() operation. See
* <a href="https://www.w3.org/TR/wasm-js-api/#towebassemblyvalue">Wasm JS-API Spec</a>
*/
@ImportStatic(JSWebAssemblyValueTypes.class)
@ImportStatic(WebAssemblyValueType.class)
@GenerateUncached
public abstract class ToWebAssemblyValueNode extends JavaScriptBaseNode {

protected ToWebAssemblyValueNode() {
}

public abstract Object execute(Object value, TruffleString type);
public abstract Object execute(Object value, WebAssemblyValueType type);

@Specialization(guards = "isI32(type)")
static int i32(Object value, @SuppressWarnings("unused") TruffleString type,
@Specialization(guards = "type == i32")
static int i32(Object value, @SuppressWarnings("unused") WebAssemblyValueType type,
@Cached JSToInt32Node toInt32Node) {
return toInt32Node.executeInt(value);
}

@Specialization(guards = "isI64(type)")
static long i64(Object value, @SuppressWarnings("unused") TruffleString type,
@Specialization(guards = "type == i64")
static long i64(Object value, @SuppressWarnings("unused") WebAssemblyValueType type,
@Cached JSToBigIntNode toBigIntNode) {
return toBigIntNode.executeBigInteger(value).longValue();
}

@Specialization(guards = "isF32(type)")
static float f32(Object value, @SuppressWarnings("unused") TruffleString type,
@Specialization(guards = "type == f32")
static float f32(Object value, @SuppressWarnings("unused") WebAssemblyValueType type,
@Cached @Shared JSToNumberNode toNumberNode) {
Number numberValue = toNumberNode.executeNumber(value);
double doubleValue = JSRuntime.toDouble(numberValue);
return (float) doubleValue;
}

@Specialization(guards = "isF64(type)")
static double f64(Object value, @SuppressWarnings("unused") TruffleString type,
@Specialization(guards = "type == f64")
static double f64(Object value, @SuppressWarnings("unused") WebAssemblyValueType type,
@Cached @Shared JSToNumberNode toNumberNode) {
Number numberValue = toNumberNode.executeNumber(value);
return JSRuntime.toDouble(numberValue);
}

@Specialization(guards = "isAnyfunc(type)")
final Object anyfunc(Object value, @SuppressWarnings("unused") TruffleString type,
@Specialization(guards = "type == anyfunc")
final Object anyfunc(Object value, @SuppressWarnings("unused") WebAssemblyValueType type,
@Cached InlinedBranchProfile errorBranch) {
if (value == Null.instance) {
return getRealm().getWasmRefNull();
Expand All @@ -120,8 +119,8 @@ private static JSException notAnExportedFunctionError() {
throw Errors.createTypeError("value is not an exported function");
}

@Specialization(guards = "isExternref(type)")
final Object externref(Object value, @SuppressWarnings("unused") TruffleString type) {
@Specialization(guards = "type == externref")
final Object externref(Object value, @SuppressWarnings("unused") WebAssemblyValueType type) {
if (value == Null.instance) {
return getRealm().getWasmRefNull();
} else {
Expand All @@ -131,7 +130,7 @@ final Object externref(Object value, @SuppressWarnings("unused") TruffleString t

@Fallback
@TruffleBoundary
final Object fallback(@SuppressWarnings("unused") Object value, TruffleString type) {
final Object fallback(@SuppressWarnings("unused") Object value, WebAssemblyValueType type) {
throw Errors.createTypeError("Unknown type: " + type, this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,11 @@ public static JSConstructor createConstructor(JSRealm realm) {
return INSTANCE.createConstructorAndPrototype(realm);
}

public static JSWebAssemblyGlobalObject create(JSContext context, JSRealm realm, Object wasmGlobal, TruffleString valueType, boolean mutable) {
public static JSWebAssemblyGlobalObject create(JSContext context, JSRealm realm, Object wasmGlobal, WebAssemblyValueType valueType, boolean mutable) {
return create(context, realm, INSTANCE.getIntrinsicDefaultProto(realm), wasmGlobal, valueType, mutable);
}

public static JSWebAssemblyGlobalObject create(JSContext context, JSRealm realm, JSDynamicObject proto, Object wasmGlobal, TruffleString valueType, boolean mutable) {
public static JSWebAssemblyGlobalObject create(JSContext context, JSRealm realm, JSDynamicObject proto, Object wasmGlobal, WebAssemblyValueType valueType, boolean mutable) {
Object embedderData = JSWebAssembly.getEmbedderData(realm, wasmGlobal);
if (embedderData instanceof JSWebAssemblyGlobalObject) {
return (JSWebAssemblyGlobalObject) embedderData;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@

public final class JSWebAssemblyGlobalObject extends JSNonProxyObject {
private final Object wasmGlobal;
private final TruffleString valueType;
private final WebAssemblyValueType valueType;
private final boolean mutable;

protected JSWebAssemblyGlobalObject(Shape shape, JSDynamicObject proto, Object wasmGlobal, TruffleString valueType, boolean mutable) {
protected JSWebAssemblyGlobalObject(Shape shape, JSDynamicObject proto, Object wasmGlobal, WebAssemblyValueType valueType, boolean mutable) {
super(shape, proto);
this.wasmGlobal = wasmGlobal;
this.valueType = valueType;
Expand All @@ -61,7 +61,7 @@ public Object getWASMGlobal() {
return wasmGlobal;
}

public TruffleString getValueType() {
public WebAssemblyValueType getValueType() {
return valueType;
}

Expand Down
Loading

0 comments on commit 6942dea

Please sign in to comment.