[wasm][eh] Add WebAssembly.Exception.getArg()
Also introduce a separate error type for WebAssembly.Exception, since the properties should not be added to RuntimeError. R=jkummerow@chromium.org Bug: v8:11992 Change-Id: I8f4ae0da9a95184366e07dc43e58a5a9ff4382ae Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3055304 Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Commit-Queue: Thibaud Michaud <thibaudm@chromium.org> Cr-Commit-Position: refs/heads/master@{#76061}
This commit is contained in:
parent
11a15e7feb
commit
27a517b892
@ -2133,6 +2133,7 @@ DEFINE_ERROR(TypeError, type_error)
|
||||
DEFINE_ERROR(WasmCompileError, wasm_compile_error)
|
||||
DEFINE_ERROR(WasmLinkError, wasm_link_error)
|
||||
DEFINE_ERROR(WasmRuntimeError, wasm_runtime_error)
|
||||
DEFINE_ERROR(WasmExceptionError, wasm_exception_error)
|
||||
#undef DEFINE_ERROR
|
||||
|
||||
Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) {
|
||||
|
@ -693,6 +693,7 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
|
||||
DECLARE_ERROR(WasmCompileError)
|
||||
DECLARE_ERROR(WasmLinkError)
|
||||
DECLARE_ERROR(WasmRuntimeError)
|
||||
DECLARE_ERROR(WasmExceptionError)
|
||||
#undef DECLARE_ERROR
|
||||
|
||||
Handle<String> NumberToString(Handle<Object> number,
|
||||
|
@ -2690,6 +2690,10 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
// -- R u n t i m e E r r o r
|
||||
InstallError(isolate_, dummy, factory->RuntimeError_string(),
|
||||
Context::WASM_RUNTIME_ERROR_FUNCTION_INDEX);
|
||||
|
||||
// -- W e b A s s e m b l y . E x c e p t i o n
|
||||
InstallError(isolate_, dummy, factory->WebAssemblyException_string(),
|
||||
Context::WASM_EXCEPTION_ERROR_FUNCTION_INDEX);
|
||||
}
|
||||
|
||||
// Initialize the embedder data slot.
|
||||
|
@ -304,6 +304,7 @@
|
||||
V(_, return_string, "return") \
|
||||
V(_, revoke_string, "revoke") \
|
||||
V(_, RuntimeError_string, "RuntimeError") \
|
||||
V(_, WebAssemblyException_string, "WebAssembly.Exception") \
|
||||
V(_, Script_string, "Script") \
|
||||
V(_, script_string, "script") \
|
||||
V(_, short_string, "short") \
|
||||
|
@ -292,6 +292,7 @@ enum ContextLookupFlags {
|
||||
V(SYMBOL_FUNCTION_INDEX, JSFunction, symbol_function) \
|
||||
V(WASM_EXPORTED_FUNCTION_MAP_INDEX, Map, wasm_exported_function_map) \
|
||||
V(WASM_TAG_CONSTRUCTOR_INDEX, JSFunction, wasm_tag_constructor) \
|
||||
V(WASM_EXCEPTION_CONSTRUCTOR_INDEX, JSFunction, wasm_exception_constructor) \
|
||||
V(WASM_GLOBAL_CONSTRUCTOR_INDEX, JSFunction, wasm_global_constructor) \
|
||||
V(WASM_INSTANCE_CONSTRUCTOR_INDEX, JSFunction, wasm_instance_constructor) \
|
||||
V(WASM_MEMORY_CONSTRUCTOR_INDEX, JSFunction, wasm_memory_constructor) \
|
||||
@ -336,6 +337,8 @@ enum ContextLookupFlags {
|
||||
V(WASM_LINK_ERROR_FUNCTION_INDEX, JSFunction, wasm_link_error_function) \
|
||||
V(WASM_RUNTIME_ERROR_FUNCTION_INDEX, JSFunction, \
|
||||
wasm_runtime_error_function) \
|
||||
V(WASM_EXCEPTION_ERROR_FUNCTION_INDEX, JSFunction, \
|
||||
wasm_exception_error_function) \
|
||||
V(WEAKMAP_SET_INDEX, JSFunction, weakmap_set) \
|
||||
V(WEAKMAP_GET_INDEX, JSFunction, weakmap_get) \
|
||||
V(WEAKMAP_DELETE_INDEX, JSFunction, weakmap_delete) \
|
||||
|
@ -168,18 +168,8 @@ RUNTIME_FUNCTION(Runtime_WasmThrow) {
|
||||
// TODO(wasm): Manually box because parameters are not visited yet.
|
||||
Handle<WasmExceptionTag> tag(tag_raw, isolate);
|
||||
Handle<FixedArray> values(values_raw, isolate);
|
||||
|
||||
Handle<Object> exception = isolate->factory()->NewWasmRuntimeError(
|
||||
MessageTemplate::kWasmExceptionError);
|
||||
Object::SetProperty(
|
||||
isolate, exception, isolate->factory()->wasm_exception_tag_symbol(), tag,
|
||||
StoreOrigin::kMaybeKeyed, Just(ShouldThrow::kThrowOnError))
|
||||
.Check();
|
||||
Object::SetProperty(
|
||||
isolate, exception, isolate->factory()->wasm_exception_values_symbol(),
|
||||
values, StoreOrigin::kMaybeKeyed, Just(ShouldThrow::kThrowOnError))
|
||||
.Check();
|
||||
|
||||
Handle<WasmExceptionPackage> exception =
|
||||
WasmExceptionPackage::New(isolate, tag, values);
|
||||
wasm::GetWasmEngine()->SampleThrowEvent(isolate);
|
||||
return isolate->Throw(*exception);
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "src/heap/factory.h"
|
||||
#include "src/init/v8.h"
|
||||
#include "src/objects/fixed-array.h"
|
||||
#include "src/objects/instance-type.h"
|
||||
#include "src/objects/js-promise-inl.h"
|
||||
#include "src/objects/objects-inl.h"
|
||||
#include "src/objects/templates.h"
|
||||
@ -184,6 +185,7 @@ GET_FIRST_ARGUMENT_AS(Module)
|
||||
GET_FIRST_ARGUMENT_AS(Memory)
|
||||
GET_FIRST_ARGUMENT_AS(Table)
|
||||
GET_FIRST_ARGUMENT_AS(Global)
|
||||
GET_FIRST_ARGUMENT_AS(Tag)
|
||||
|
||||
#undef GET_FIRST_ARGUMENT_AS
|
||||
|
||||
@ -1770,6 +1772,7 @@ constexpr const char* kName_WasmMemoryObject = "WebAssembly.Memory";
|
||||
constexpr const char* kName_WasmInstanceObject = "WebAssembly.Instance";
|
||||
constexpr const char* kName_WasmTableObject = "WebAssembly.Table";
|
||||
constexpr const char* kName_WasmTagObject = "WebAssembly.Tag";
|
||||
constexpr const char* kName_WasmExceptionPackage = "WebAssembly.Exception";
|
||||
|
||||
#define EXTRACT_THIS(var, WasmType) \
|
||||
i::Handle<i::WasmType> var; \
|
||||
@ -2022,6 +2025,141 @@ void WebAssemblyTagType(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
args.GetReturnValue().Set(Utils::ToLocal(type));
|
||||
}
|
||||
|
||||
void WebAssemblyExceptionGetArg(
|
||||
const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
v8::Isolate* isolate = args.GetIsolate();
|
||||
HandleScope scope(isolate);
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Exception.getArg()");
|
||||
|
||||
EXTRACT_THIS(exception, WasmExceptionPackage);
|
||||
if (thrower.error()) return;
|
||||
|
||||
i::MaybeHandle<i::WasmTagObject> maybe_tag =
|
||||
GetFirstArgumentAsTag(args, &thrower);
|
||||
if (thrower.error()) return;
|
||||
auto tag = maybe_tag.ToHandleChecked();
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
uint32_t index;
|
||||
if (!EnforceUint32("Index", args[1], context, &thrower, &index)) {
|
||||
return;
|
||||
}
|
||||
auto maybe_values =
|
||||
i::WasmExceptionPackage::GetExceptionValues(i_isolate, exception);
|
||||
if (maybe_values->IsUndefined()) {
|
||||
thrower.TypeError("Expected a WebAssembly.Exception object");
|
||||
return;
|
||||
}
|
||||
auto values = i::Handle<i::FixedArray>::cast(maybe_values);
|
||||
auto signature = tag->serialized_signature();
|
||||
if (index >= static_cast<uint32_t>(signature.length())) {
|
||||
thrower.RangeError("Index out of range");
|
||||
return;
|
||||
}
|
||||
// First, find the index in the values array.
|
||||
uint32_t decode_index = 0;
|
||||
// Since the bounds check above passed, the cast to int is safe.
|
||||
for (int i = 0; i < static_cast<int>(index); ++i) {
|
||||
switch (signature.get(i).kind()) {
|
||||
case i::wasm::kI32:
|
||||
case i::wasm::kF32:
|
||||
decode_index += 2;
|
||||
break;
|
||||
case i::wasm::kI64:
|
||||
case i::wasm::kF64:
|
||||
decode_index += 4;
|
||||
break;
|
||||
case i::wasm::kRef:
|
||||
case i::wasm::kOptRef:
|
||||
switch (signature.get(i).heap_representation()) {
|
||||
case i::wasm::HeapType::kExtern:
|
||||
case i::wasm::HeapType::kFunc:
|
||||
case i::wasm::HeapType::kAny:
|
||||
case i::wasm::HeapType::kEq:
|
||||
case i::wasm::HeapType::kI31:
|
||||
case i::wasm::HeapType::kData:
|
||||
decode_index++;
|
||||
break;
|
||||
case i::wasm::HeapType::kBottom:
|
||||
UNREACHABLE();
|
||||
default:
|
||||
// TODO(7748): Add support for custom struct/array types.
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
break;
|
||||
case i::wasm::kRtt:
|
||||
case i::wasm::kRttWithDepth:
|
||||
case i::wasm::kI8:
|
||||
case i::wasm::kI16:
|
||||
case i::wasm::kVoid:
|
||||
case i::wasm::kBottom:
|
||||
case i::wasm::kS128:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
// Decode the value at {decode_index}.
|
||||
Local<Value> result;
|
||||
switch (signature.get(index).kind()) {
|
||||
case i::wasm::kI32: {
|
||||
uint32_t u32_bits = 0;
|
||||
i::DecodeI32ExceptionValue(values, &decode_index, &u32_bits);
|
||||
int32_t i32 = static_cast<int32_t>(u32_bits);
|
||||
result = v8::Integer::New(isolate, i32);
|
||||
break;
|
||||
}
|
||||
case i::wasm::kI64: {
|
||||
uint64_t u64_bits = 0;
|
||||
i::DecodeI64ExceptionValue(values, &decode_index, &u64_bits);
|
||||
int64_t i64 = static_cast<int64_t>(u64_bits);
|
||||
result = v8::BigInt::New(isolate, i64);
|
||||
break;
|
||||
}
|
||||
case i::wasm::kF32: {
|
||||
uint32_t f32_bits = 0;
|
||||
DecodeI32ExceptionValue(values, &decode_index, &f32_bits);
|
||||
float f32 = bit_cast<float>(f32_bits);
|
||||
result = v8::Number::New(isolate, f32);
|
||||
break;
|
||||
}
|
||||
case i::wasm::kF64: {
|
||||
uint64_t f64_bits = 0;
|
||||
DecodeI64ExceptionValue(values, &decode_index, &f64_bits);
|
||||
double f64 = bit_cast<double>(f64_bits);
|
||||
result = v8::Number::New(isolate, f64);
|
||||
break;
|
||||
}
|
||||
case i::wasm::kRef:
|
||||
case i::wasm::kOptRef:
|
||||
switch (signature.get(index).heap_representation()) {
|
||||
case i::wasm::HeapType::kExtern:
|
||||
case i::wasm::HeapType::kFunc:
|
||||
case i::wasm::HeapType::kAny:
|
||||
case i::wasm::HeapType::kEq:
|
||||
case i::wasm::HeapType::kI31:
|
||||
case i::wasm::HeapType::kData: {
|
||||
auto obj = values->get(decode_index);
|
||||
result = Utils::ToLocal(i::Handle<i::Object>(obj, i_isolate));
|
||||
break;
|
||||
}
|
||||
case i::wasm::HeapType::kBottom:
|
||||
UNREACHABLE();
|
||||
default:
|
||||
// TODO(7748): Add support for custom struct/array types.
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
break;
|
||||
case i::wasm::kRtt:
|
||||
case i::wasm::kRttWithDepth:
|
||||
case i::wasm::kI8:
|
||||
case i::wasm::kI16:
|
||||
case i::wasm::kVoid:
|
||||
case i::wasm::kBottom:
|
||||
case i::wasm::kS128:
|
||||
UNREACHABLE();
|
||||
}
|
||||
args.GetReturnValue().Set(result);
|
||||
}
|
||||
|
||||
void WebAssemblyGlobalGetValueCommon(
|
||||
const v8::FunctionCallbackInfo<v8::Value>& args, const char* name) {
|
||||
v8::Isolate* isolate = args.GetIsolate();
|
||||
@ -2476,15 +2614,18 @@ void WasmJs::Install(Isolate* isolate, bool exposed_on_global_object) {
|
||||
Handle<JSFunction> exception_constructor = InstallConstructorFunc(
|
||||
isolate, webassembly, "Exception", WebAssemblyException);
|
||||
SetDummyInstanceTemplate(isolate, exception_constructor);
|
||||
Handle<Map> initial_map(
|
||||
isolate->native_context()->wasm_runtime_error_function().initial_map(),
|
||||
Handle<Map> exception_map = isolate->factory()->NewMap(
|
||||
i::JS_ERROR_TYPE, WasmExceptionPackage::kHeaderSize);
|
||||
Handle<JSObject> exception_proto(
|
||||
JSObject::cast(isolate->native_context()
|
||||
->wasm_exception_error_function()
|
||||
.instance_prototype()),
|
||||
isolate);
|
||||
Handle<HeapObject> instance_prototype(isolate->native_context()
|
||||
->wasm_runtime_error_function()
|
||||
.instance_prototype(),
|
||||
isolate);
|
||||
JSFunction::SetInitialMap(isolate, exception_constructor, initial_map,
|
||||
instance_prototype);
|
||||
InstallFunc(isolate, exception_proto, "getArg", WebAssemblyExceptionGetArg,
|
||||
2);
|
||||
context->set_wasm_exception_constructor(*exception_constructor);
|
||||
JSFunction::SetInitialMap(isolate, exception_constructor, exception_map,
|
||||
exception_proto);
|
||||
}
|
||||
|
||||
// Setup Function
|
||||
|
@ -1769,14 +1769,20 @@ bool WasmCapiFunction::MatchesSignature(const wasm::FunctionSig* sig) const {
|
||||
// static
|
||||
Handle<WasmExceptionPackage> WasmExceptionPackage::New(
|
||||
Isolate* isolate, Handle<WasmExceptionTag> exception_tag, int size) {
|
||||
Handle<Object> exception = isolate->factory()->NewWasmRuntimeError(
|
||||
Handle<FixedArray> values = isolate->factory()->NewFixedArray(size);
|
||||
return New(isolate, exception_tag, values);
|
||||
}
|
||||
|
||||
Handle<WasmExceptionPackage> WasmExceptionPackage::New(
|
||||
Isolate* isolate, Handle<WasmExceptionTag> exception_tag,
|
||||
Handle<FixedArray> values) {
|
||||
Handle<JSObject> exception = isolate->factory()->NewWasmExceptionError(
|
||||
MessageTemplate::kWasmExceptionError);
|
||||
CHECK(!Object::SetProperty(isolate, exception,
|
||||
isolate->factory()->wasm_exception_tag_symbol(),
|
||||
exception_tag, StoreOrigin::kMaybeKeyed,
|
||||
Just(ShouldThrow::kThrowOnError))
|
||||
.is_null());
|
||||
Handle<FixedArray> values = isolate->factory()->NewFixedArray(size);
|
||||
CHECK(!Object::SetProperty(isolate, exception,
|
||||
isolate->factory()->wasm_exception_values_symbol(),
|
||||
values, StoreOrigin::kMaybeKeyed,
|
||||
@ -1825,6 +1831,21 @@ void EncodeI64ExceptionValue(Handle<FixedArray> encoded_values,
|
||||
static_cast<uint32_t>(value));
|
||||
}
|
||||
|
||||
void DecodeI32ExceptionValue(Handle<FixedArray> encoded_values,
|
||||
uint32_t* encoded_index, uint32_t* value) {
|
||||
uint32_t msb = Smi::cast(encoded_values->get((*encoded_index)++)).value();
|
||||
uint32_t lsb = Smi::cast(encoded_values->get((*encoded_index)++)).value();
|
||||
*value = (msb << 16) | (lsb & 0xffff);
|
||||
}
|
||||
|
||||
void DecodeI64ExceptionValue(Handle<FixedArray> encoded_values,
|
||||
uint32_t* encoded_index, uint64_t* value) {
|
||||
uint32_t lsb = 0, msb = 0;
|
||||
DecodeI32ExceptionValue(encoded_values, encoded_index, &msb);
|
||||
DecodeI32ExceptionValue(encoded_values, encoded_index, &lsb);
|
||||
*value = (static_cast<uint64_t>(msb) << 32) | static_cast<uint64_t>(lsb);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
namespace {
|
||||
|
@ -576,6 +576,10 @@ class V8_EXPORT_PRIVATE WasmExceptionPackage : public JSObject {
|
||||
Isolate* isolate, Handle<WasmExceptionTag> exception_tag,
|
||||
int encoded_size);
|
||||
|
||||
static Handle<WasmExceptionPackage> New(
|
||||
Isolate* isolate, Handle<WasmExceptionTag> exception_tag,
|
||||
Handle<FixedArray> values);
|
||||
|
||||
// The below getters return {undefined} in case the given exception package
|
||||
// does not carry the requested values (i.e. is of a different type).
|
||||
static Handle<Object> GetExceptionTag(
|
||||
@ -596,6 +600,14 @@ void V8_EXPORT_PRIVATE EncodeI32ExceptionValue(
|
||||
void V8_EXPORT_PRIVATE EncodeI64ExceptionValue(
|
||||
Handle<FixedArray> encoded_values, uint32_t* encoded_index, uint64_t value);
|
||||
|
||||
void V8_EXPORT_PRIVATE
|
||||
DecodeI32ExceptionValue(Handle<FixedArray> encoded_values,
|
||||
uint32_t* encoded_index, uint32_t* value);
|
||||
|
||||
void V8_EXPORT_PRIVATE
|
||||
DecodeI64ExceptionValue(Handle<FixedArray> encoded_values,
|
||||
uint32_t* encoded_index, uint64_t* value);
|
||||
|
||||
// A Wasm function that is wrapped and exported to JavaScript.
|
||||
// Representation of WebAssembly.Function JavaScript-level object.
|
||||
class WasmExportedFunction : public JSFunction {
|
||||
|
@ -3186,21 +3186,6 @@ class WasmInterpreterInternals {
|
||||
return expected_tag.is_identical_to(caught_tag);
|
||||
}
|
||||
|
||||
void DecodeI32ExceptionValue(Handle<FixedArray> encoded_values,
|
||||
uint32_t* encoded_index, uint32_t* value) {
|
||||
uint32_t msb = Smi::cast(encoded_values->get((*encoded_index)++)).value();
|
||||
uint32_t lsb = Smi::cast(encoded_values->get((*encoded_index)++)).value();
|
||||
*value = (msb << 16) | (lsb & 0xffff);
|
||||
}
|
||||
|
||||
void DecodeI64ExceptionValue(Handle<FixedArray> encoded_values,
|
||||
uint32_t* encoded_index, uint64_t* value) {
|
||||
uint32_t lsb = 0, msb = 0;
|
||||
DecodeI32ExceptionValue(encoded_values, encoded_index, &msb);
|
||||
DecodeI32ExceptionValue(encoded_values, encoded_index, &lsb);
|
||||
*value = (static_cast<uint64_t>(msb) << 32) | static_cast<uint64_t>(lsb);
|
||||
}
|
||||
|
||||
// Unpack the values encoded in the given exception. The exception values are
|
||||
// pushed onto the operand stack. Callers must perform a tag check to ensure
|
||||
// the encoded values match the expected signature of the exception.
|
||||
|
@ -1,4 +1,4 @@
|
||||
wasm-function[0]:0x32: RuntimeError: wasm exception
|
||||
RuntimeError: wasm exception
|
||||
wasm-function[0]:0x32: WebAssembly.Exception: wasm exception
|
||||
WebAssembly.Exception: wasm exception
|
||||
at rethrow0 (<anonymous>:wasm-function[0]:0x32)
|
||||
at *%(basename)s:21:18
|
||||
|
@ -1,4 +1,4 @@
|
||||
wasm-function[0]:0x2e: RuntimeError: wasm exception
|
||||
RuntimeError: wasm exception
|
||||
wasm-function[0]:0x2e: WebAssembly.Exception: wasm exception
|
||||
WebAssembly.Exception: wasm exception
|
||||
at throw0 (<anonymous>:wasm-function[0]:0x2e)
|
||||
at *%(basename)s:17:18
|
||||
|
@ -22,8 +22,8 @@ try {
|
||||
exception = e;
|
||||
}
|
||||
|
||||
// Check that the exception is an instance of the correct error function and
|
||||
// Check that the exception is an instance of WebAssembly.Exception and
|
||||
// that no extraneous properties exist. Setting such properties could be
|
||||
// observable by JavaScript and could break compatibility.
|
||||
assertInstanceof(exception, WebAssembly.RuntimeError);
|
||||
assertInstanceof(exception, WebAssembly.Exception);
|
||||
assertArrayEquals(["stack", "message"], Object.getOwnPropertyNames(exception));
|
||||
|
@ -21,7 +21,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
assertPromiseResult(WebAssembly.instantiate(module), inst => step3(inst));
|
||||
}
|
||||
function step3(instance) {
|
||||
assertThrows(() => instance.exports.thrw(), WebAssembly.RuntimeError);
|
||||
assertThrows(() => instance.exports.thrw(), WebAssembly.Exception);
|
||||
}
|
||||
step1(builder.toBuffer());
|
||||
})();
|
||||
|
@ -21,5 +21,5 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
var serialized = %SerializeWasmModule(module);
|
||||
module = %DeserializeWasmModule(serialized, wire_bytes);
|
||||
var instance2 = new WebAssembly.Instance(module);
|
||||
assertThrows(() => instance2.exports.f(), WebAssembly.RuntimeError);
|
||||
assertThrows(() => instance2.exports.f(), WebAssembly.Exception);
|
||||
})();
|
||||
|
@ -170,3 +170,52 @@ function TestCatchJS(types_str, types, values) {
|
||||
[kWasmI32, kWasmI64, kWasmF32, kWasmF64, kWasmExternRef],
|
||||
[6, 7n, 8, 9, {value: 10}]);
|
||||
})();
|
||||
|
||||
function TestGetArgHelper(types_str, types, values) {
|
||||
let tag = new WebAssembly.Tag({parameters: types_str});
|
||||
let exception = new WebAssembly.Exception(tag, values);
|
||||
for (i = 0; i < types.length; ++i) {
|
||||
assertEquals(exception.getArg(tag, i), values[i]);
|
||||
}
|
||||
|
||||
let builder = new WasmModuleBuilder();
|
||||
let sig = makeSig(types, []);
|
||||
let tag_index = builder.addImportedTag("m", "t", sig);
|
||||
let body = [];
|
||||
for (i = 0; i < types.length; ++i) {
|
||||
body.push(kExprLocalGet, i);
|
||||
}
|
||||
body.push(kExprThrow, tag_index);
|
||||
builder.addFunction("throw", sig)
|
||||
.addBody(body).exportFunc();
|
||||
let instance = builder.instantiate({'m': {'t': tag}});
|
||||
try {
|
||||
instance.exports.throw(...values);
|
||||
} catch (e) {
|
||||
for (i = 0; i < types.length; ++i) {
|
||||
assertEquals(e.getArg(tag, i), values[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(function TestGetArg() {
|
||||
// Check errors.
|
||||
let tag = new WebAssembly.Tag({parameters: ['i32']});
|
||||
let exception = new WebAssembly.Exception(tag, [0]);
|
||||
assertThrows(() => exception.getArg(0, 0), TypeError,
|
||||
/Argument 0 must be a WebAssembly.Tag/);
|
||||
assertThrows(() => exception.getArg({}, 0), TypeError,
|
||||
/Argument 0 must be a WebAssembly.Tag/);
|
||||
assertThrows(() => exception.getArg(tag, undefined), TypeError,
|
||||
/Index must be convertible to a valid number/);
|
||||
assertThrows(() => exception.getArg(tag, 0xFFFFFFFF), RangeError,
|
||||
/Index out of range/);
|
||||
|
||||
// Check decoding.
|
||||
TestGetArgHelper(['i32'], [kWasmI32], [1]);
|
||||
TestGetArgHelper(['i64'], [kWasmI64], [2n]);
|
||||
TestGetArgHelper(['f32'], [kWasmF32], [3]);
|
||||
TestGetArgHelper(['f64'], [kWasmF64], [4]);
|
||||
TestGetArgHelper(['externref'], [kWasmExternRef], [{val: 5}]);
|
||||
TestGetArgHelper(['i32', 'i64', 'f32', 'f64', 'externref'], [kWasmI32, kWasmI64, kWasmF32, kWasmF64, kWasmExternRef], [5, 6n, 7, 8, {val: 9}]);
|
||||
})();
|
||||
|
@ -38,7 +38,7 @@ function NewExportedException() {
|
||||
let ex_obj = new Error("my exception");
|
||||
let instance = builder.instantiate({ m: { f: function() { throw ex_obj }}});
|
||||
|
||||
assertThrows(() => instance.exports.throw(), WebAssembly.RuntimeError);
|
||||
assertThrows(() => instance.exports.throw(), WebAssembly.Exception);
|
||||
assertThrowsEquals(() => instance.exports.catch(), ex_obj);
|
||||
try {
|
||||
instance.exports.throw();
|
||||
@ -71,7 +71,7 @@ function NewExportedException() {
|
||||
let instance1 = builder.instantiate({ m: { f: assertUnreachable }});
|
||||
let instance2 = builder.instantiate({ m: { f: function() { throw ex_obj }}});
|
||||
|
||||
assertThrows(() => instance1.exports.throw(), WebAssembly.RuntimeError);
|
||||
assertThrows(() => instance1.exports.throw(), WebAssembly.Exception);
|
||||
assertThrowsEquals(() => instance2.exports.catch(), ex_obj);
|
||||
try {
|
||||
instance1.exports.throw();
|
||||
@ -108,7 +108,7 @@ function NewExportedException() {
|
||||
let instance2 = builder.instantiate({ m: { f: function() { throw ex_obj },
|
||||
ex1: instance1.exports.ex2 }});
|
||||
|
||||
assertThrows(() => instance1.exports.throw(), WebAssembly.RuntimeError);
|
||||
assertThrows(() => instance1.exports.throw(), WebAssembly.Exception);
|
||||
assertThrowsEquals(() => instance2.exports.catch(), ex_obj);
|
||||
try {
|
||||
instance1.exports.throw();
|
||||
@ -146,7 +146,7 @@ function NewExportedException() {
|
||||
let instance2 = builder2.instantiate({ m: { f: function() { throw ex_obj },
|
||||
ex: instance1.exports.ex }});
|
||||
|
||||
assertThrows(() => instance1.exports.throw(), WebAssembly.RuntimeError);
|
||||
assertThrows(() => instance1.exports.throw(), WebAssembly.Exception);
|
||||
assertThrowsEquals(() => instance2.exports.catch(), ex_obj);
|
||||
try {
|
||||
instance1.exports.throw();
|
||||
|
@ -15,7 +15,7 @@ function assertWasmThrows(instance, runtime_id, values, code) {
|
||||
eval(code);
|
||||
}
|
||||
} catch (e) {
|
||||
assertInstanceof(e, WebAssembly.RuntimeError);
|
||||
assertInstanceof(e, WebAssembly.Exception);
|
||||
var e_runtime_id = %GetWasmExceptionTagId(e, instance);
|
||||
assertTrue(Number.isInteger(e_runtime_id));
|
||||
assertEquals(e_runtime_id, runtime_id);
|
||||
|
@ -212,7 +212,7 @@ d8.file.execute("test/mjsunit/wasm/exceptions-utils.js");
|
||||
}
|
||||
assertTrue(!!caught, 'should have trapped');
|
||||
assertEquals(caught, wrapped_exn);
|
||||
assertInstanceof(caught.__proto__, WebAssembly.RuntimeError);
|
||||
assertInstanceof(caught.__proto__, WebAssembly.Exception);
|
||||
})();
|
||||
|
||||
(function TestStackOverflowNotCaught() {
|
||||
@ -883,7 +883,7 @@ d8.file.execute("test/mjsunit/wasm/exceptions-utils.js");
|
||||
kExprEnd,
|
||||
]).exportFunc();
|
||||
instance = builder.instantiate();
|
||||
assertTraps(WebAssembly.RuntimeError, instance.exports.test);
|
||||
assertThrows(instance.exports.test, WebAssembly.Exception);
|
||||
})();
|
||||
|
||||
// Check that the exception is merged properly when both scopes can throw.
|
||||
@ -925,9 +925,9 @@ d8.file.execute("test/mjsunit/wasm/exceptions-utils.js");
|
||||
]).exportFunc();
|
||||
instance = builder.instantiate();
|
||||
assertEquals(2, instance.exports.test(1, 0));
|
||||
assertTraps(WebAssembly.RuntimeError, () => instance.exports.test(2, 0));
|
||||
assertThrows(() => instance.exports.test(2, 0), WebAssembly.Exception);
|
||||
assertEquals(2, instance.exports.test(0, 1));
|
||||
assertTraps(WebAssembly.RuntimeError, () => instance.exports.test(0, 2));
|
||||
assertThrows(() => instance.exports.test(0, 2), WebAssembly.Exception);
|
||||
assertEquals(1, instance.exports.test(0, 0));
|
||||
})();
|
||||
|
||||
@ -994,7 +994,7 @@ d8.file.execute("test/mjsunit/wasm/exceptions-utils.js");
|
||||
kExprEnd
|
||||
]).exportFunc();
|
||||
instance = builder.instantiate();
|
||||
assertTraps(WebAssembly.RuntimeError, () => instance.exports.test());
|
||||
assertThrows(() => instance.exports.test(), WebAssembly.Exception);
|
||||
})();
|
||||
|
||||
(function TestThrowBeforeUnreachable() {
|
||||
|
@ -329,66 +329,66 @@ KNOWN_MAPS = {
|
||||
("read_only_space", 0x03215): (67, "BasicBlockCountersMarkerMap"),
|
||||
("read_only_space", 0x03259): (91, "ArrayBoilerplateDescriptionMap"),
|
||||
("read_only_space", 0x03359): (104, "InterceptorInfoMap"),
|
||||
("read_only_space", 0x05675): (76, "PromiseFulfillReactionJobTaskMap"),
|
||||
("read_only_space", 0x0569d): (77, "PromiseRejectReactionJobTaskMap"),
|
||||
("read_only_space", 0x056c5): (78, "CallableTaskMap"),
|
||||
("read_only_space", 0x056ed): (79, "CallbackTaskMap"),
|
||||
("read_only_space", 0x05715): (80, "PromiseResolveThenableJobTaskMap"),
|
||||
("read_only_space", 0x0573d): (83, "FunctionTemplateInfoMap"),
|
||||
("read_only_space", 0x05765): (84, "ObjectTemplateInfoMap"),
|
||||
("read_only_space", 0x0578d): (85, "AccessCheckInfoMap"),
|
||||
("read_only_space", 0x057b5): (86, "AccessorInfoMap"),
|
||||
("read_only_space", 0x057dd): (87, "AccessorPairMap"),
|
||||
("read_only_space", 0x05805): (88, "AliasedArgumentsEntryMap"),
|
||||
("read_only_space", 0x0582d): (89, "AllocationMementoMap"),
|
||||
("read_only_space", 0x05855): (92, "AsmWasmDataMap"),
|
||||
("read_only_space", 0x0587d): (93, "AsyncGeneratorRequestMap"),
|
||||
("read_only_space", 0x058a5): (94, "BaselineDataMap"),
|
||||
("read_only_space", 0x058cd): (95, "BreakPointMap"),
|
||||
("read_only_space", 0x058f5): (96, "BreakPointInfoMap"),
|
||||
("read_only_space", 0x0591d): (97, "CachedTemplateObjectMap"),
|
||||
("read_only_space", 0x05945): (99, "ClassPositionsMap"),
|
||||
("read_only_space", 0x0596d): (100, "DebugInfoMap"),
|
||||
("read_only_space", 0x05995): (103, "FunctionTemplateRareDataMap"),
|
||||
("read_only_space", 0x059bd): (105, "InterpreterDataMap"),
|
||||
("read_only_space", 0x059e5): (106, "ModuleRequestMap"),
|
||||
("read_only_space", 0x05a0d): (107, "PromiseCapabilityMap"),
|
||||
("read_only_space", 0x05a35): (108, "PromiseReactionMap"),
|
||||
("read_only_space", 0x05a5d): (109, "PropertyDescriptorObjectMap"),
|
||||
("read_only_space", 0x05a85): (110, "PrototypeInfoMap"),
|
||||
("read_only_space", 0x05aad): (111, "RegExpBoilerplateDescriptionMap"),
|
||||
("read_only_space", 0x05ad5): (112, "ScriptMap"),
|
||||
("read_only_space", 0x05afd): (113, "SourceTextModuleInfoEntryMap"),
|
||||
("read_only_space", 0x05b25): (114, "StackFrameInfoMap"),
|
||||
("read_only_space", 0x05b4d): (115, "TemplateObjectDescriptionMap"),
|
||||
("read_only_space", 0x05b75): (116, "Tuple2Map"),
|
||||
("read_only_space", 0x05b9d): (117, "WasmExceptionTagMap"),
|
||||
("read_only_space", 0x05bc5): (118, "WasmIndirectFunctionTableMap"),
|
||||
("read_only_space", 0x05bed): (136, "SloppyArgumentsElementsMap"),
|
||||
("read_only_space", 0x05c15): (153, "DescriptorArrayMap"),
|
||||
("read_only_space", 0x05c3d): (158, "UncompiledDataWithoutPreparseDataMap"),
|
||||
("read_only_space", 0x05c65): (157, "UncompiledDataWithPreparseDataMap"),
|
||||
("read_only_space", 0x05c8d): (174, "OnHeapBasicBlockProfilerDataMap"),
|
||||
("read_only_space", 0x05cb5): (170, "InternalClassMap"),
|
||||
("read_only_space", 0x05cdd): (181, "SmiPairMap"),
|
||||
("read_only_space", 0x05d05): (180, "SmiBoxMap"),
|
||||
("read_only_space", 0x05d2d): (147, "ExportedSubClassBaseMap"),
|
||||
("read_only_space", 0x05d55): (148, "ExportedSubClassMap"),
|
||||
("read_only_space", 0x05d7d): (68, "AbstractInternalClassSubclass1Map"),
|
||||
("read_only_space", 0x05da5): (69, "AbstractInternalClassSubclass2Map"),
|
||||
("read_only_space", 0x05dcd): (135, "InternalClassWithSmiElementsMap"),
|
||||
("read_only_space", 0x05df5): (171, "InternalClassWithStructElementsMap"),
|
||||
("read_only_space", 0x05e1d): (149, "ExportedSubClass2Map"),
|
||||
("read_only_space", 0x05e45): (182, "SortStateMap"),
|
||||
("read_only_space", 0x05e6d): (90, "AllocationSiteWithWeakNextMap"),
|
||||
("read_only_space", 0x05e95): (90, "AllocationSiteWithoutWeakNextMap"),
|
||||
("read_only_space", 0x05ebd): (81, "LoadHandler1Map"),
|
||||
("read_only_space", 0x05ee5): (81, "LoadHandler2Map"),
|
||||
("read_only_space", 0x05f0d): (81, "LoadHandler3Map"),
|
||||
("read_only_space", 0x05f35): (82, "StoreHandler0Map"),
|
||||
("read_only_space", 0x05f5d): (82, "StoreHandler1Map"),
|
||||
("read_only_space", 0x05f85): (82, "StoreHandler2Map"),
|
||||
("read_only_space", 0x05fad): (82, "StoreHandler3Map"),
|
||||
("read_only_space", 0x05699): (76, "PromiseFulfillReactionJobTaskMap"),
|
||||
("read_only_space", 0x056c1): (77, "PromiseRejectReactionJobTaskMap"),
|
||||
("read_only_space", 0x056e9): (78, "CallableTaskMap"),
|
||||
("read_only_space", 0x05711): (79, "CallbackTaskMap"),
|
||||
("read_only_space", 0x05739): (80, "PromiseResolveThenableJobTaskMap"),
|
||||
("read_only_space", 0x05761): (83, "FunctionTemplateInfoMap"),
|
||||
("read_only_space", 0x05789): (84, "ObjectTemplateInfoMap"),
|
||||
("read_only_space", 0x057b1): (85, "AccessCheckInfoMap"),
|
||||
("read_only_space", 0x057d9): (86, "AccessorInfoMap"),
|
||||
("read_only_space", 0x05801): (87, "AccessorPairMap"),
|
||||
("read_only_space", 0x05829): (88, "AliasedArgumentsEntryMap"),
|
||||
("read_only_space", 0x05851): (89, "AllocationMementoMap"),
|
||||
("read_only_space", 0x05879): (92, "AsmWasmDataMap"),
|
||||
("read_only_space", 0x058a1): (93, "AsyncGeneratorRequestMap"),
|
||||
("read_only_space", 0x058c9): (94, "BaselineDataMap"),
|
||||
("read_only_space", 0x058f1): (95, "BreakPointMap"),
|
||||
("read_only_space", 0x05919): (96, "BreakPointInfoMap"),
|
||||
("read_only_space", 0x05941): (97, "CachedTemplateObjectMap"),
|
||||
("read_only_space", 0x05969): (99, "ClassPositionsMap"),
|
||||
("read_only_space", 0x05991): (100, "DebugInfoMap"),
|
||||
("read_only_space", 0x059b9): (103, "FunctionTemplateRareDataMap"),
|
||||
("read_only_space", 0x059e1): (105, "InterpreterDataMap"),
|
||||
("read_only_space", 0x05a09): (106, "ModuleRequestMap"),
|
||||
("read_only_space", 0x05a31): (107, "PromiseCapabilityMap"),
|
||||
("read_only_space", 0x05a59): (108, "PromiseReactionMap"),
|
||||
("read_only_space", 0x05a81): (109, "PropertyDescriptorObjectMap"),
|
||||
("read_only_space", 0x05aa9): (110, "PrototypeInfoMap"),
|
||||
("read_only_space", 0x05ad1): (111, "RegExpBoilerplateDescriptionMap"),
|
||||
("read_only_space", 0x05af9): (112, "ScriptMap"),
|
||||
("read_only_space", 0x05b21): (113, "SourceTextModuleInfoEntryMap"),
|
||||
("read_only_space", 0x05b49): (114, "StackFrameInfoMap"),
|
||||
("read_only_space", 0x05b71): (115, "TemplateObjectDescriptionMap"),
|
||||
("read_only_space", 0x05b99): (116, "Tuple2Map"),
|
||||
("read_only_space", 0x05bc1): (117, "WasmExceptionTagMap"),
|
||||
("read_only_space", 0x05be9): (118, "WasmIndirectFunctionTableMap"),
|
||||
("read_only_space", 0x05c11): (136, "SloppyArgumentsElementsMap"),
|
||||
("read_only_space", 0x05c39): (153, "DescriptorArrayMap"),
|
||||
("read_only_space", 0x05c61): (158, "UncompiledDataWithoutPreparseDataMap"),
|
||||
("read_only_space", 0x05c89): (157, "UncompiledDataWithPreparseDataMap"),
|
||||
("read_only_space", 0x05cb1): (174, "OnHeapBasicBlockProfilerDataMap"),
|
||||
("read_only_space", 0x05cd9): (170, "InternalClassMap"),
|
||||
("read_only_space", 0x05d01): (181, "SmiPairMap"),
|
||||
("read_only_space", 0x05d29): (180, "SmiBoxMap"),
|
||||
("read_only_space", 0x05d51): (147, "ExportedSubClassBaseMap"),
|
||||
("read_only_space", 0x05d79): (148, "ExportedSubClassMap"),
|
||||
("read_only_space", 0x05da1): (68, "AbstractInternalClassSubclass1Map"),
|
||||
("read_only_space", 0x05dc9): (69, "AbstractInternalClassSubclass2Map"),
|
||||
("read_only_space", 0x05df1): (135, "InternalClassWithSmiElementsMap"),
|
||||
("read_only_space", 0x05e19): (171, "InternalClassWithStructElementsMap"),
|
||||
("read_only_space", 0x05e41): (149, "ExportedSubClass2Map"),
|
||||
("read_only_space", 0x05e69): (182, "SortStateMap"),
|
||||
("read_only_space", 0x05e91): (90, "AllocationSiteWithWeakNextMap"),
|
||||
("read_only_space", 0x05eb9): (90, "AllocationSiteWithoutWeakNextMap"),
|
||||
("read_only_space", 0x05ee1): (81, "LoadHandler1Map"),
|
||||
("read_only_space", 0x05f09): (81, "LoadHandler2Map"),
|
||||
("read_only_space", 0x05f31): (81, "LoadHandler3Map"),
|
||||
("read_only_space", 0x05f59): (82, "StoreHandler0Map"),
|
||||
("read_only_space", 0x05f81): (82, "StoreHandler1Map"),
|
||||
("read_only_space", 0x05fa9): (82, "StoreHandler2Map"),
|
||||
("read_only_space", 0x05fd1): (82, "StoreHandler3Map"),
|
||||
("map_space", 0x02119): (1057, "ExternalMap"),
|
||||
("map_space", 0x02141): (1098, "JSMessageObjectMap"),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user