[wasm] Improve {WasmExceptionPackage} type safety.
This uses Handle<WasmExceptionPackage> where applicable to increase type safety. Note that {WasmExceptionPackage} is not a full-fledged instance type though. The {HeapObject::IsWasmExceptionPackage} predicate is an approximation because a precise version could only be implemented using handlified code performing a property lookup. R=clemensb@chromium.org Change-Id: I061e3eea201a0e9909ba67ae33db81d14aaefe4b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1477673 Commit-Queue: Michael Starzinger <mstarzinger@chromium.org> Reviewed-by: Clemens Backes [né Hammacher] <clemensb@chromium.org> Cr-Commit-Position: refs/heads/master@{#63987}
This commit is contained in:
parent
14d1e5320c
commit
cae9aaeb32
@ -131,6 +131,7 @@ class Undetectable;
|
||||
class UniqueName;
|
||||
class WasmCapiFunctionData;
|
||||
class WasmExceptionObject;
|
||||
class WasmExceptionPackage;
|
||||
class WasmExceptionTag;
|
||||
class WasmExportedFunctionData;
|
||||
class WasmGlobalObject;
|
||||
|
@ -226,6 +226,7 @@ class ZoneForwardList;
|
||||
V(Undetectable) \
|
||||
V(UniqueName) \
|
||||
V(WasmExceptionObject) \
|
||||
V(WasmExceptionPackage) \
|
||||
V(WasmGlobalObject) \
|
||||
V(WasmInstanceObject) \
|
||||
V(WasmMemoryObject) \
|
||||
|
@ -411,6 +411,12 @@ DEF_GETTER(HeapObject, IsSmallOrderedHashTable, bool) {
|
||||
IsSmallOrderedNameDictionary(isolate);
|
||||
}
|
||||
|
||||
DEF_GETTER(HeapObject, IsWasmExceptionPackage, bool) {
|
||||
// It is not possible to check for the existence of certain properties on the
|
||||
// underlying {JSReceiver} here because that requires calling handlified code.
|
||||
return IsJSReceiver(isolate);
|
||||
}
|
||||
|
||||
bool Object::IsPrimitive() const {
|
||||
if (IsSmi()) return true;
|
||||
HeapObject this_heap_object = HeapObject::cast(*this);
|
||||
|
@ -1049,7 +1049,7 @@ RUNTIME_FUNCTION(Runtime_GetWasmRecoveredTrapCount) {
|
||||
RUNTIME_FUNCTION(Runtime_GetWasmExceptionId) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(2, args.length());
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, exception, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(WasmExceptionPackage, exception, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 1);
|
||||
Handle<Object> tag =
|
||||
WasmExceptionPackage::GetExceptionTag(isolate, exception);
|
||||
@ -1065,7 +1065,7 @@ RUNTIME_FUNCTION(Runtime_GetWasmExceptionId) {
|
||||
RUNTIME_FUNCTION(Runtime_GetWasmExceptionValues) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, exception, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(WasmExceptionPackage, exception, 0);
|
||||
Handle<Object> values_obj =
|
||||
WasmExceptionPackage::GetExceptionValues(isolate, exception);
|
||||
CHECK(values_obj->IsFixedArray()); // Only called with correct input.
|
||||
|
@ -150,7 +150,12 @@ RUNTIME_FUNCTION(Runtime_WasmExceptionGetTag) {
|
||||
CONVERT_ARG_CHECKED(Object, except_obj_raw, 0);
|
||||
// TODO(mstarzinger): Manually box because parameters are not visited yet.
|
||||
Handle<Object> except_obj(except_obj_raw, isolate);
|
||||
return *WasmExceptionPackage::GetExceptionTag(isolate, except_obj);
|
||||
if (!except_obj->IsWasmExceptionPackage(isolate)) {
|
||||
return ReadOnlyRoots(isolate).undefined_value();
|
||||
}
|
||||
Handle<WasmExceptionPackage> exception =
|
||||
Handle<WasmExceptionPackage>::cast(except_obj);
|
||||
return *WasmExceptionPackage::GetExceptionTag(isolate, exception);
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_WasmExceptionGetValues) {
|
||||
@ -162,7 +167,12 @@ RUNTIME_FUNCTION(Runtime_WasmExceptionGetValues) {
|
||||
CONVERT_ARG_CHECKED(Object, except_obj_raw, 0);
|
||||
// TODO(mstarzinger): Manually box because parameters are not visited yet.
|
||||
Handle<Object> except_obj(except_obj_raw, isolate);
|
||||
return *WasmExceptionPackage::GetExceptionValues(isolate, except_obj);
|
||||
if (!except_obj->IsWasmExceptionPackage(isolate)) {
|
||||
return ReadOnlyRoots(isolate).undefined_value();
|
||||
}
|
||||
Handle<WasmExceptionPackage> exception =
|
||||
Handle<WasmExceptionPackage>::cast(except_obj);
|
||||
return *WasmExceptionPackage::GetExceptionValues(isolate, exception);
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_WasmRunInterpreter) {
|
||||
|
@ -2727,7 +2727,7 @@ class ThreadImpl {
|
||||
WasmExceptionTag::cast(instance_object_->exceptions_table().get(index)),
|
||||
isolate_);
|
||||
uint32_t encoded_size = WasmExceptionPackage::GetEncodedSize(exception);
|
||||
Handle<Object> exception_object =
|
||||
Handle<WasmExceptionPackage> exception_object =
|
||||
WasmExceptionPackage::New(isolate_, exception_tag, encoded_size);
|
||||
Handle<FixedArray> encoded_values = Handle<FixedArray>::cast(
|
||||
WasmExceptionPackage::GetExceptionValues(isolate_, exception_object));
|
||||
@ -2796,8 +2796,9 @@ class ThreadImpl {
|
||||
// Determines whether the given exception has a tag matching the expected tag
|
||||
// for the given index within the exception table of the current instance.
|
||||
bool MatchingExceptionTag(Handle<Object> exception_object, uint32_t index) {
|
||||
Handle<Object> caught_tag =
|
||||
WasmExceptionPackage::GetExceptionTag(isolate_, exception_object);
|
||||
if (!exception_object->IsWasmExceptionPackage(isolate_)) return false;
|
||||
Handle<Object> caught_tag = WasmExceptionPackage::GetExceptionTag(
|
||||
isolate_, Handle<WasmExceptionPackage>::cast(exception_object));
|
||||
Handle<Object> expected_tag =
|
||||
handle(instance_object_->exceptions_table().get(index), isolate_);
|
||||
DCHECK(expected_tag->IsWasmExceptionTag());
|
||||
@ -2824,8 +2825,9 @@ class ThreadImpl {
|
||||
// the encoded values match the expected signature of the exception.
|
||||
void DoUnpackException(const WasmException* exception,
|
||||
Handle<Object> exception_object) {
|
||||
Handle<FixedArray> encoded_values = Handle<FixedArray>::cast(
|
||||
WasmExceptionPackage::GetExceptionValues(isolate_, exception_object));
|
||||
Handle<FixedArray> encoded_values =
|
||||
Handle<FixedArray>::cast(WasmExceptionPackage::GetExceptionValues(
|
||||
isolate_, Handle<WasmExceptionPackage>::cast(exception_object)));
|
||||
// Decode the exception values from the given exception package and push
|
||||
// them onto the operand stack. This encoding has to be in sync with other
|
||||
// backends so that exceptions can be passed between them.
|
||||
|
@ -309,6 +309,10 @@ ACCESSORS(WasmExceptionObject, serialized_signature, PodArray<wasm::ValueType>,
|
||||
kSerializedSignatureOffset)
|
||||
ACCESSORS(WasmExceptionObject, exception_tag, HeapObject, kExceptionTagOffset)
|
||||
|
||||
// WasmExceptionPackage
|
||||
OBJECT_CONSTRUCTORS_IMPL(WasmExceptionPackage, JSReceiver)
|
||||
CAST_ACCESSOR(WasmExceptionPackage)
|
||||
|
||||
// WasmExportedFunction
|
||||
WasmExportedFunction::WasmExportedFunction(Address ptr) : JSFunction(ptr) {
|
||||
SLOW_DCHECK(IsWasmExportedFunction(*this));
|
||||
|
@ -1930,7 +1930,7 @@ bool WasmCapiFunction::IsSignatureEqual(const wasm::FunctionSig* sig) const {
|
||||
}
|
||||
|
||||
// static
|
||||
Handle<JSReceiver> WasmExceptionPackage::New(
|
||||
Handle<WasmExceptionPackage> WasmExceptionPackage::New(
|
||||
Isolate* isolate, Handle<WasmExceptionTag> exception_tag, int size) {
|
||||
Handle<Object> exception = isolate->factory()->NewWasmRuntimeError(
|
||||
MessageTemplate::kWasmExceptionError);
|
||||
@ -1945,37 +1945,31 @@ Handle<JSReceiver> WasmExceptionPackage::New(
|
||||
values, StoreOrigin::kMaybeKeyed,
|
||||
Just(ShouldThrow::kThrowOnError))
|
||||
.is_null());
|
||||
return Handle<JSReceiver>::cast(exception);
|
||||
return Handle<WasmExceptionPackage>::cast(exception);
|
||||
}
|
||||
|
||||
// static
|
||||
Handle<Object> WasmExceptionPackage::GetExceptionTag(
|
||||
Isolate* isolate, Handle<Object> exception_object) {
|
||||
if (exception_object->IsJSReceiver()) {
|
||||
Handle<JSReceiver> exception = Handle<JSReceiver>::cast(exception_object);
|
||||
Handle<Object> tag;
|
||||
if (JSReceiver::GetProperty(isolate, exception,
|
||||
isolate->factory()->wasm_exception_tag_symbol())
|
||||
.ToHandle(&tag)) {
|
||||
return tag;
|
||||
}
|
||||
Isolate* isolate, Handle<WasmExceptionPackage> exception_package) {
|
||||
Handle<Object> tag;
|
||||
if (JSReceiver::GetProperty(isolate, exception_package,
|
||||
isolate->factory()->wasm_exception_tag_symbol())
|
||||
.ToHandle(&tag)) {
|
||||
return tag;
|
||||
}
|
||||
return ReadOnlyRoots(isolate).undefined_value_handle();
|
||||
}
|
||||
|
||||
// static
|
||||
Handle<Object> WasmExceptionPackage::GetExceptionValues(
|
||||
Isolate* isolate, Handle<Object> exception_object) {
|
||||
if (exception_object->IsJSReceiver()) {
|
||||
Handle<JSReceiver> exception = Handle<JSReceiver>::cast(exception_object);
|
||||
Handle<Object> values;
|
||||
if (JSReceiver::GetProperty(
|
||||
isolate, exception,
|
||||
isolate->factory()->wasm_exception_values_symbol())
|
||||
.ToHandle(&values)) {
|
||||
DCHECK(values->IsFixedArray());
|
||||
return values;
|
||||
}
|
||||
Isolate* isolate, Handle<WasmExceptionPackage> exception_package) {
|
||||
Handle<Object> values;
|
||||
if (JSReceiver::GetProperty(
|
||||
isolate, exception_package,
|
||||
isolate->factory()->wasm_exception_values_symbol())
|
||||
.ToHandle(&values)) {
|
||||
DCHECK(values->IsFixedArray());
|
||||
return values;
|
||||
}
|
||||
return ReadOnlyRoots(isolate).undefined_value_handle();
|
||||
}
|
||||
|
@ -626,20 +626,22 @@ class WasmExceptionObject : public JSObject {
|
||||
// A Wasm exception that has been thrown out of Wasm code.
|
||||
class WasmExceptionPackage : public JSReceiver {
|
||||
public:
|
||||
// TODO(mstarzinger): Ideally this interface would use {WasmExceptionPackage}
|
||||
// instead of {JSReceiver} throughout. For now a type-check implies doing a
|
||||
// property lookup however, which would result in casts being handlified.
|
||||
static Handle<JSReceiver> New(Isolate* isolate,
|
||||
Handle<WasmExceptionTag> exception_tag,
|
||||
int encoded_size);
|
||||
static Handle<WasmExceptionPackage> New(
|
||||
Isolate* isolate, Handle<WasmExceptionTag> exception_tag,
|
||||
int encoded_size);
|
||||
|
||||
// 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(Isolate*, Handle<Object> exception);
|
||||
static Handle<Object> GetExceptionValues(Isolate*, Handle<Object> exception);
|
||||
static Handle<Object> GetExceptionTag(
|
||||
Isolate* isolate, Handle<WasmExceptionPackage> exception_package);
|
||||
static Handle<Object> GetExceptionValues(
|
||||
Isolate* isolate, Handle<WasmExceptionPackage> exception_package);
|
||||
|
||||
// Determines the size of the array holding all encoded exception values.
|
||||
static uint32_t GetEncodedSize(const wasm::WasmException* exception);
|
||||
|
||||
DECL_CAST(WasmExceptionPackage)
|
||||
OBJECT_CONSTRUCTORS(WasmExceptionPackage, JSReceiver);
|
||||
};
|
||||
|
||||
// A Wasm function that is wrapped and exported to JavaScript.
|
||||
|
Loading…
Reference in New Issue
Block a user