Diff
Modified: trunk/JSTests/ChangeLog (210125 => 210126)
--- trunk/JSTests/ChangeLog 2016-12-23 01:23:15 UTC (rev 210125)
+++ trunk/JSTests/ChangeLog 2016-12-23 01:32:30 UTC (rev 210126)
@@ -1,3 +1,16 @@
+2016-12-22 Saam Barati <[email protected]>
+
+ WebAssembly: Make calling Wasm functions that returns or takes an i64 as a parameter an early exception
+ https://bugs.webkit.org/show_bug.cgi?id=166437
+ <rdar://problem/29793949>
+
+ Reviewed by Keith Miller.
+
+ * wasm.yaml:
+ * wasm/function-tests/i64-from-js-exceptions.js: Added.
+ (const.imp.import.sideEffects):
+ (assert.throws.instance.exports.foo.valueOf):
+
2016-12-22 Mark Lam <[email protected]>
De-duplicate finally blocks.
Added: trunk/JSTests/wasm/function-tests/i64-from-js-exceptions.js (0 => 210126)
--- trunk/JSTests/wasm/function-tests/i64-from-js-exceptions.js (rev 0)
+++ trunk/JSTests/wasm/function-tests/i64-from-js-exceptions.js 2016-12-23 01:32:30 UTC (rev 210126)
@@ -0,0 +1,40 @@
+import Builder from '../Builder.js'
+import * as assert from '../assert.js'
+
+const builder = (new Builder())
+ .Type().End()
+ .Import()
+ .Function("import", "sideEffects", {params: [], ret: "void"})
+ .End()
+ .Function().End()
+ .Export()
+ .Function("foo")
+ .Function("bar")
+ .End()
+ .Code()
+ .Function("foo", {params: ["i64"], ret: "void"})
+ .Call(0)
+ .Return()
+ .End()
+ .Function("bar", {params: [], ret: "i64"})
+ .Call(0)
+ .I32Const(25)
+ .I64ExtendUI32()
+ .Return()
+ .End()
+ .End();
+
+const bin = builder.WebAssembly().get();
+const module = new WebAssembly.Module(bin);
+let called = false;
+const imp = {
+ import: {
+ sideEffects() { called = true; }
+ }
+};
+
+const instance = new WebAssembly.Instance(module, imp);
+assert.throws(() => instance.exports.foo(20), WebAssembly.RuntimeError, "WebAssembly function with an i64 argument can't be called from _javascript_");
+assert.throws(() => instance.exports.foo({valueOf() { throw new Error("Should not be called!"); }}), WebAssembly.RuntimeError, "WebAssembly function with an i64 argument can't be called from _javascript_");
+assert.throws(() => instance.exports.bar(), WebAssembly.RuntimeError, "WebAssembly function that returns i64 can't be called from _javascript_");
+assert.eq(called, false);
Modified: trunk/JSTests/wasm.yaml (210125 => 210126)
--- trunk/JSTests/wasm.yaml 2016-12-23 01:23:15 UTC (rev 210125)
+++ trunk/JSTests/wasm.yaml 2016-12-23 01:32:30 UTC (rev 210126)
@@ -188,7 +188,7 @@
cmd: runWebAssemblySpecTest :normal
- path: wasm/spec-tests/unreachable.wast.js
- cmd: runWebAssemblySpecTest :skip
+ cmd: runWebAssemblySpecTest :normal
- path: wasm/spec-tests/unwind.wast.js
cmd: runWebAssemblySpecTest :skip
Modified: trunk/Source/_javascript_Core/ChangeLog (210125 => 210126)
--- trunk/Source/_javascript_Core/ChangeLog 2016-12-23 01:23:15 UTC (rev 210125)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-12-23 01:32:30 UTC (rev 210126)
@@ -1,3 +1,23 @@
+2016-12-22 Saam Barati <[email protected]>
+
+ WebAssembly: Make calling Wasm functions that returns or takes an i64 as a parameter an early exception
+ https://bugs.webkit.org/show_bug.cgi?id=166437
+ <rdar://problem/29793949>
+
+ Reviewed by Keith Miller.
+
+ This patch makes it so that we throw an exception before we do
+ anything else if we call a wasm function that either takes an
+ i64 as an argument or returns an i64.
+
+ * wasm/js/WebAssemblyFunction.cpp:
+ (JSC::callWebAssemblyFunction):
+ (JSC::WebAssemblyFunction::WebAssemblyFunction):
+ (JSC::WebAssemblyFunction::call): Deleted.
+ * wasm/js/WebAssemblyFunction.h:
+ (JSC::WebAssemblyFunction::signatureIndex):
+ (JSC::WebAssemblyFunction::jsEntrypoint):
+
2016-12-22 Keith Miller <[email protected]>
Add BitOr for floating points to B3
Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.cpp (210125 => 210126)
--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.cpp 2016-12-23 01:23:15 UTC (rev 210125)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.cpp 2016-12-23 01:32:30 UTC (rev 210126)
@@ -35,6 +35,7 @@
#include "JSWebAssemblyCallee.h"
#include "JSWebAssemblyInstance.h"
#include "JSWebAssemblyMemory.h"
+#include "JSWebAssemblyRuntimeError.h"
#include "LLIntThunks.h"
#include "ProtoCallFrame.h"
#include "VM.h"
@@ -59,9 +60,27 @@
if (exec->argumentCount() != signature->argumentCount())
return JSValue::encode(throwException(exec, scope, createNotEnoughArgumentsError(exec, defaultSourceAppender)));
+ {
+ // Check if we have a disallowed I64 use.
+
+ for (unsigned argIndex = 0; argIndex < signature->argumentCount(); ++argIndex) {
+ if (signature->argument(argIndex) == Wasm::I64) {
+ JSWebAssemblyRuntimeError* error = JSWebAssemblyRuntimeError::create(exec, vm, exec->lexicalGlobalObject()->WebAssemblyRuntimeErrorStructure(),
+ "WebAssembly function with an i64 argument can't be called from _javascript_");
+ return JSValue::encode(throwException(exec, scope, error));
+ }
+ }
+
+ if (signature->returnType() == Wasm::I64) {
+ JSWebAssemblyRuntimeError* error = JSWebAssemblyRuntimeError::create(exec, vm, exec->lexicalGlobalObject()->WebAssemblyRuntimeErrorStructure(),
+ "WebAssembly function that returns i64 can't be called from _javascript_");
+ return JSValue::encode(throwException(exec, scope, error));
+ }
+ }
+
// FIXME is this boxing correct? https://bugs.webkit.org/show_bug.cgi?id=164876
Vector<JSValue> boxedArgs;
- for (unsigned argIndex = 0; argIndex < exec->argumentCount(); ++argIndex) {
+ for (unsigned argIndex = 0; argIndex < signature->argumentCount(); ++argIndex) {
JSValue arg = exec->uncheckedArgument(argIndex);
switch (signature->argument(argIndex)) {
case Wasm::I32:
@@ -100,13 +119,7 @@
ProtoCallFrame protoCallFrame;
protoCallFrame.init(nullptr, wasmFunction, firstArgument, argCount, remainingArgs);
- return wasmFunction->call(vm, &protoCallFrame);
-}
-
-EncodedJSValue WebAssemblyFunction::call(VM& vm, ProtoCallFrame* protoCallFrame)
-{
- // Setup the memory that the entrance loads.
- if (JSWebAssemblyMemory* memory = instance()->memory()) {
+ if (JSWebAssemblyMemory* memory = wasmFunction->instance()->memory()) {
Wasm::Memory* wasmMemory = memory->memory();
vm.topWasmMemoryPointer = wasmMemory->memory();
vm.topWasmMemorySize = wasmMemory->size();
@@ -116,28 +129,28 @@
}
JSWebAssemblyInstance* prevJSWebAssemblyInstance = vm.topJSWebAssemblyInstance;
- vm.topJSWebAssemblyInstance = instance();
- ASSERT(instance());
- EncodedJSValue rawResult = vmEntryToWasm(m_jsEntrypoint->entrypoint(), &vm, protoCallFrame);
+ vm.topJSWebAssemblyInstance = wasmFunction->instance();
+ ASSERT(wasmFunction->instance());
+ EncodedJSValue rawResult = vmEntryToWasm(wasmFunction->jsEntrypoint(), &vm, &protoCallFrame);
vm.topJSWebAssemblyInstance = prevJSWebAssemblyInstance;
+ RETURN_IF_EXCEPTION(scope, { });
// FIXME is this correct? https://bugs.webkit.org/show_bug.cgi?id=164876
- switch (m_returnType) {
+ switch (signature->returnType()) {
case Wasm::Void:
return JSValue::encode(jsUndefined());
case Wasm::I32:
- return JSValue::encode(JSValue(static_cast<int32_t>(rawResult)));
+ return JSValue::encode(jsNumber(static_cast<int32_t>(rawResult)));
case Wasm::F32:
- return JSValue::encode(JSValue(bitwise_cast<float>(static_cast<int32_t>(rawResult))));
+ return JSValue::encode(jsNumber(purifyNaN(static_cast<double>(bitwise_cast<float>(static_cast<int32_t>(rawResult))))));
case Wasm::F64:
- return JSValue::encode(JSValue(bitwise_cast<double>(rawResult)));
+ return JSValue::encode(jsNumber(purifyNaN(bitwise_cast<double>(rawResult))));
case Wasm::I64:
case Wasm::Func:
case Wasm::Anyfunc:
- break;
+ RELEASE_ASSERT_NOT_REACHED();
}
- RELEASE_ASSERT_NOT_REACHED();
return EncodedJSValue();
}
@@ -159,11 +172,7 @@
WebAssemblyFunction::WebAssemblyFunction(VM& vm, JSGlobalObject* globalObject, Structure* structure, Wasm::SignatureIndex signatureIndex)
: Base(vm, globalObject, structure)
, m_signatureIndex(signatureIndex)
-{
- // Don't cache the signature pointer: it's a global on VM and can change as new WebAssembly.Module are created.
- const Wasm::Signature* signature = Wasm::SignatureInformation::get(&vm, m_signatureIndex);
- m_returnType = signature->returnType();
-}
+{ }
void WebAssemblyFunction::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.h (210125 => 210126)
--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.h 2016-12-23 01:23:15 UTC (rev 210125)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.h 2016-12-23 01:32:30 UTC (rev 210126)
@@ -54,8 +54,8 @@
JSWebAssemblyInstance* instance() const { return m_instance.get(); }
Wasm::SignatureIndex signatureIndex() const { return m_signatureIndex; }
- EncodedJSValue call(VM&, ProtoCallFrame*);
void* wasmEntrypoint() { return m_wasmEntrypoint->entrypoint(); }
+ void* jsEntrypoint() { return m_jsEntrypoint->entrypoint(); }
protected:
static void visitChildren(JSCell*, SlotVisitor&);
@@ -69,7 +69,6 @@
WriteBarrier<JSWebAssemblyCallee> m_jsEntrypoint;
WriteBarrier<JSWebAssemblyCallee> m_wasmEntrypoint;
Wasm::SignatureIndex m_signatureIndex;
- Wasm::Type m_returnType;
};
} // namespace JSC