Commit cae9aaeb authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[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: 's avatarClemens Backes [né Hammacher] <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63987}
parent 14d1e532
...@@ -131,6 +131,7 @@ class Undetectable; ...@@ -131,6 +131,7 @@ class Undetectable;
class UniqueName; class UniqueName;
class WasmCapiFunctionData; class WasmCapiFunctionData;
class WasmExceptionObject; class WasmExceptionObject;
class WasmExceptionPackage;
class WasmExceptionTag; class WasmExceptionTag;
class WasmExportedFunctionData; class WasmExportedFunctionData;
class WasmGlobalObject; class WasmGlobalObject;
......
...@@ -226,6 +226,7 @@ class ZoneForwardList; ...@@ -226,6 +226,7 @@ class ZoneForwardList;
V(Undetectable) \ V(Undetectable) \
V(UniqueName) \ V(UniqueName) \
V(WasmExceptionObject) \ V(WasmExceptionObject) \
V(WasmExceptionPackage) \
V(WasmGlobalObject) \ V(WasmGlobalObject) \
V(WasmInstanceObject) \ V(WasmInstanceObject) \
V(WasmMemoryObject) \ V(WasmMemoryObject) \
......
...@@ -411,6 +411,12 @@ DEF_GETTER(HeapObject, IsSmallOrderedHashTable, bool) { ...@@ -411,6 +411,12 @@ DEF_GETTER(HeapObject, IsSmallOrderedHashTable, bool) {
IsSmallOrderedNameDictionary(isolate); 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 { bool Object::IsPrimitive() const {
if (IsSmi()) return true; if (IsSmi()) return true;
HeapObject this_heap_object = HeapObject::cast(*this); HeapObject this_heap_object = HeapObject::cast(*this);
......
...@@ -1049,7 +1049,7 @@ RUNTIME_FUNCTION(Runtime_GetWasmRecoveredTrapCount) { ...@@ -1049,7 +1049,7 @@ RUNTIME_FUNCTION(Runtime_GetWasmRecoveredTrapCount) {
RUNTIME_FUNCTION(Runtime_GetWasmExceptionId) { RUNTIME_FUNCTION(Runtime_GetWasmExceptionId) {
HandleScope scope(isolate); HandleScope scope(isolate);
DCHECK_EQ(2, args.length()); 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); CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 1);
Handle<Object> tag = Handle<Object> tag =
WasmExceptionPackage::GetExceptionTag(isolate, exception); WasmExceptionPackage::GetExceptionTag(isolate, exception);
...@@ -1065,7 +1065,7 @@ RUNTIME_FUNCTION(Runtime_GetWasmExceptionId) { ...@@ -1065,7 +1065,7 @@ RUNTIME_FUNCTION(Runtime_GetWasmExceptionId) {
RUNTIME_FUNCTION(Runtime_GetWasmExceptionValues) { RUNTIME_FUNCTION(Runtime_GetWasmExceptionValues) {
HandleScope scope(isolate); HandleScope scope(isolate);
DCHECK_EQ(1, args.length()); DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, exception, 0); CONVERT_ARG_HANDLE_CHECKED(WasmExceptionPackage, exception, 0);
Handle<Object> values_obj = Handle<Object> values_obj =
WasmExceptionPackage::GetExceptionValues(isolate, exception); WasmExceptionPackage::GetExceptionValues(isolate, exception);
CHECK(values_obj->IsFixedArray()); // Only called with correct input. CHECK(values_obj->IsFixedArray()); // Only called with correct input.
......
...@@ -150,7 +150,12 @@ RUNTIME_FUNCTION(Runtime_WasmExceptionGetTag) { ...@@ -150,7 +150,12 @@ RUNTIME_FUNCTION(Runtime_WasmExceptionGetTag) {
CONVERT_ARG_CHECKED(Object, except_obj_raw, 0); CONVERT_ARG_CHECKED(Object, except_obj_raw, 0);
// TODO(mstarzinger): Manually box because parameters are not visited yet. // TODO(mstarzinger): Manually box because parameters are not visited yet.
Handle<Object> except_obj(except_obj_raw, isolate); 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) { RUNTIME_FUNCTION(Runtime_WasmExceptionGetValues) {
...@@ -162,7 +167,12 @@ RUNTIME_FUNCTION(Runtime_WasmExceptionGetValues) { ...@@ -162,7 +167,12 @@ RUNTIME_FUNCTION(Runtime_WasmExceptionGetValues) {
CONVERT_ARG_CHECKED(Object, except_obj_raw, 0); CONVERT_ARG_CHECKED(Object, except_obj_raw, 0);
// TODO(mstarzinger): Manually box because parameters are not visited yet. // TODO(mstarzinger): Manually box because parameters are not visited yet.
Handle<Object> except_obj(except_obj_raw, isolate); 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) { RUNTIME_FUNCTION(Runtime_WasmRunInterpreter) {
......
...@@ -2727,7 +2727,7 @@ class ThreadImpl { ...@@ -2727,7 +2727,7 @@ class ThreadImpl {
WasmExceptionTag::cast(instance_object_->exceptions_table().get(index)), WasmExceptionTag::cast(instance_object_->exceptions_table().get(index)),
isolate_); isolate_);
uint32_t encoded_size = WasmExceptionPackage::GetEncodedSize(exception); uint32_t encoded_size = WasmExceptionPackage::GetEncodedSize(exception);
Handle<Object> exception_object = Handle<WasmExceptionPackage> exception_object =
WasmExceptionPackage::New(isolate_, exception_tag, encoded_size); WasmExceptionPackage::New(isolate_, exception_tag, encoded_size);
Handle<FixedArray> encoded_values = Handle<FixedArray>::cast( Handle<FixedArray> encoded_values = Handle<FixedArray>::cast(
WasmExceptionPackage::GetExceptionValues(isolate_, exception_object)); WasmExceptionPackage::GetExceptionValues(isolate_, exception_object));
...@@ -2796,8 +2796,9 @@ class ThreadImpl { ...@@ -2796,8 +2796,9 @@ class ThreadImpl {
// Determines whether the given exception has a tag matching the expected tag // Determines whether the given exception has a tag matching the expected tag
// for the given index within the exception table of the current instance. // for the given index within the exception table of the current instance.
bool MatchingExceptionTag(Handle<Object> exception_object, uint32_t index) { bool MatchingExceptionTag(Handle<Object> exception_object, uint32_t index) {
Handle<Object> caught_tag = if (!exception_object->IsWasmExceptionPackage(isolate_)) return false;
WasmExceptionPackage::GetExceptionTag(isolate_, exception_object); Handle<Object> caught_tag = WasmExceptionPackage::GetExceptionTag(
isolate_, Handle<WasmExceptionPackage>::cast(exception_object));
Handle<Object> expected_tag = Handle<Object> expected_tag =
handle(instance_object_->exceptions_table().get(index), isolate_); handle(instance_object_->exceptions_table().get(index), isolate_);
DCHECK(expected_tag->IsWasmExceptionTag()); DCHECK(expected_tag->IsWasmExceptionTag());
...@@ -2824,8 +2825,9 @@ class ThreadImpl { ...@@ -2824,8 +2825,9 @@ class ThreadImpl {
// the encoded values match the expected signature of the exception. // the encoded values match the expected signature of the exception.
void DoUnpackException(const WasmException* exception, void DoUnpackException(const WasmException* exception,
Handle<Object> exception_object) { Handle<Object> exception_object) {
Handle<FixedArray> encoded_values = Handle<FixedArray>::cast( Handle<FixedArray> encoded_values =
WasmExceptionPackage::GetExceptionValues(isolate_, exception_object)); Handle<FixedArray>::cast(WasmExceptionPackage::GetExceptionValues(
isolate_, Handle<WasmExceptionPackage>::cast(exception_object)));
// Decode the exception values from the given exception package and push // 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 // them onto the operand stack. This encoding has to be in sync with other
// backends so that exceptions can be passed between them. // backends so that exceptions can be passed between them.
......
...@@ -309,6 +309,10 @@ ACCESSORS(WasmExceptionObject, serialized_signature, PodArray<wasm::ValueType>, ...@@ -309,6 +309,10 @@ ACCESSORS(WasmExceptionObject, serialized_signature, PodArray<wasm::ValueType>,
kSerializedSignatureOffset) kSerializedSignatureOffset)
ACCESSORS(WasmExceptionObject, exception_tag, HeapObject, kExceptionTagOffset) ACCESSORS(WasmExceptionObject, exception_tag, HeapObject, kExceptionTagOffset)
// WasmExceptionPackage
OBJECT_CONSTRUCTORS_IMPL(WasmExceptionPackage, JSReceiver)
CAST_ACCESSOR(WasmExceptionPackage)
// WasmExportedFunction // WasmExportedFunction
WasmExportedFunction::WasmExportedFunction(Address ptr) : JSFunction(ptr) { WasmExportedFunction::WasmExportedFunction(Address ptr) : JSFunction(ptr) {
SLOW_DCHECK(IsWasmExportedFunction(*this)); SLOW_DCHECK(IsWasmExportedFunction(*this));
......
...@@ -1930,7 +1930,7 @@ bool WasmCapiFunction::IsSignatureEqual(const wasm::FunctionSig* sig) const { ...@@ -1930,7 +1930,7 @@ bool WasmCapiFunction::IsSignatureEqual(const wasm::FunctionSig* sig) const {
} }
// static // static
Handle<JSReceiver> WasmExceptionPackage::New( Handle<WasmExceptionPackage> WasmExceptionPackage::New(
Isolate* isolate, Handle<WasmExceptionTag> exception_tag, int size) { Isolate* isolate, Handle<WasmExceptionTag> exception_tag, int size) {
Handle<Object> exception = isolate->factory()->NewWasmRuntimeError( Handle<Object> exception = isolate->factory()->NewWasmRuntimeError(
MessageTemplate::kWasmExceptionError); MessageTemplate::kWasmExceptionError);
...@@ -1945,37 +1945,31 @@ Handle<JSReceiver> WasmExceptionPackage::New( ...@@ -1945,37 +1945,31 @@ Handle<JSReceiver> WasmExceptionPackage::New(
values, StoreOrigin::kMaybeKeyed, values, StoreOrigin::kMaybeKeyed,
Just(ShouldThrow::kThrowOnError)) Just(ShouldThrow::kThrowOnError))
.is_null()); .is_null());
return Handle<JSReceiver>::cast(exception); return Handle<WasmExceptionPackage>::cast(exception);
} }
// static // static
Handle<Object> WasmExceptionPackage::GetExceptionTag( Handle<Object> WasmExceptionPackage::GetExceptionTag(
Isolate* isolate, Handle<Object> exception_object) { Isolate* isolate, Handle<WasmExceptionPackage> exception_package) {
if (exception_object->IsJSReceiver()) { Handle<Object> tag;
Handle<JSReceiver> exception = Handle<JSReceiver>::cast(exception_object); if (JSReceiver::GetProperty(isolate, exception_package,
Handle<Object> tag; isolate->factory()->wasm_exception_tag_symbol())
if (JSReceiver::GetProperty(isolate, exception, .ToHandle(&tag)) {
isolate->factory()->wasm_exception_tag_symbol()) return tag;
.ToHandle(&tag)) {
return tag;
}
} }
return ReadOnlyRoots(isolate).undefined_value_handle(); return ReadOnlyRoots(isolate).undefined_value_handle();
} }
// static // static
Handle<Object> WasmExceptionPackage::GetExceptionValues( Handle<Object> WasmExceptionPackage::GetExceptionValues(
Isolate* isolate, Handle<Object> exception_object) { Isolate* isolate, Handle<WasmExceptionPackage> exception_package) {
if (exception_object->IsJSReceiver()) { Handle<Object> values;
Handle<JSReceiver> exception = Handle<JSReceiver>::cast(exception_object); if (JSReceiver::GetProperty(
Handle<Object> values; isolate, exception_package,
if (JSReceiver::GetProperty( isolate->factory()->wasm_exception_values_symbol())
isolate, exception, .ToHandle(&values)) {
isolate->factory()->wasm_exception_values_symbol()) DCHECK(values->IsFixedArray());
.ToHandle(&values)) { return values;
DCHECK(values->IsFixedArray());
return values;
}
} }
return ReadOnlyRoots(isolate).undefined_value_handle(); return ReadOnlyRoots(isolate).undefined_value_handle();
} }
......
...@@ -626,20 +626,22 @@ class WasmExceptionObject : public JSObject { ...@@ -626,20 +626,22 @@ class WasmExceptionObject : public JSObject {
// A Wasm exception that has been thrown out of Wasm code. // A Wasm exception that has been thrown out of Wasm code.
class WasmExceptionPackage : public JSReceiver { class WasmExceptionPackage : public JSReceiver {
public: public:
// TODO(mstarzinger): Ideally this interface would use {WasmExceptionPackage} static Handle<WasmExceptionPackage> New(
// instead of {JSReceiver} throughout. For now a type-check implies doing a Isolate* isolate, Handle<WasmExceptionTag> exception_tag,
// property lookup however, which would result in casts being handlified. int encoded_size);
static Handle<JSReceiver> New(Isolate* isolate,
Handle<WasmExceptionTag> exception_tag,
int encoded_size);
// The below getters return {undefined} in case the given exception package // The below getters return {undefined} in case the given exception package
// does not carry the requested values (i.e. is of a different type). // does not carry the requested values (i.e. is of a different type).
static Handle<Object> GetExceptionTag(Isolate*, Handle<Object> exception); static Handle<Object> GetExceptionTag(
static Handle<Object> GetExceptionValues(Isolate*, Handle<Object> exception); 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. // Determines the size of the array holding all encoded exception values.
static uint32_t GetEncodedSize(const wasm::WasmException* exception); 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. // A Wasm function that is wrapped and exported to JavaScript.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment