[wasm] Refine installation of the WebAssembly.Exception constructor

Bug: chromium:1219630

Change-Id: Idf187bfb16157074b0affda1db3b8ac0b0870e7a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2964094
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75177}
diff --git a/src/wasm/wasm-js.cc b/src/wasm/wasm-js.cc
index 7d3b54e..598b5ef 100644
--- a/src/wasm/wasm-js.cc
+++ b/src/wasm/wasm-js.cc
@@ -2308,24 +2308,48 @@
     Handle<JSGlobalObject> global = handle(context->global_object(), isolate);
     MaybeHandle<Object> maybe_webassembly =
         JSObject::GetProperty(isolate, global, "WebAssembly");
-    Handle<JSObject> webassembly =
-        Handle<JSObject>::cast(maybe_webassembly.ToHandleChecked());
+    Handle<Object> webassembly_obj;
+    if (!maybe_webassembly.ToHandle(&webassembly_obj)) {
+      // There is not {WebAssembly} object. We just return without adding the
+      // {Exception} constructor.
+      return;
+    }
+    if (!webassembly_obj->IsJSObject()) {
+      // The {WebAssembly} object is invalid. As we cannot add the {Exception}
+      // constructor, we just return.
+      return;
+    }
+    Handle<JSObject> webassembly = Handle<JSObject>::cast(webassembly_obj);
     // Setup Exception
     Handle<String> exception_name = v8_str(isolate, "Exception");
-    if (!JSObject::HasProperty(webassembly, exception_name).FromMaybe(true)) {
-      Handle<JSFunction> exception_constructor = InstallConstructorFunc(
-          isolate, webassembly, "Exception", WebAssemblyException);
-      // Install the constructor on the context.
-      context->set_wasm_exception_constructor(*exception_constructor);
-      SetDummyInstanceTemplate(isolate, exception_constructor);
-      JSFunction::EnsureHasInitialMap(exception_constructor);
-      Handle<JSObject> exception_proto(
-          JSObject::cast(exception_constructor->instance_prototype()), isolate);
-      Handle<Map> exception_map = isolate->factory()->NewMap(
-          i::WASM_EXCEPTION_OBJECT_TYPE, WasmExceptionObject::kHeaderSize);
-      JSFunction::SetInitialMap(isolate, exception_constructor, exception_map,
-                                exception_proto);
+    if (JSObject::HasOwnProperty(webassembly, exception_name).FromMaybe(true)) {
+      // The {Exception} constructor already exists, there is nothing more to
+      // do.
+      return;
     }
+
+    bool has_prototype = true;
+    Handle<JSFunction> exception_constructor =
+        CreateFunc(isolate, exception_name, WebAssemblyException, has_prototype,
+                   SideEffectType::kHasNoSideEffect);
+    exception_constructor->shared().set_length(1);
+    auto result = Object::SetProperty(
+        isolate, webassembly, exception_name, exception_constructor,
+        StoreOrigin::kNamed, Just(ShouldThrow::kDontThrow));
+    if (result.is_null()) {
+      // Setting the {Exception} constructor failed. We just bail out.
+      return;
+    }
+    // Install the constructor on the context.
+    context->set_wasm_exception_constructor(*exception_constructor);
+    SetDummyInstanceTemplate(isolate, exception_constructor);
+    JSFunction::EnsureHasInitialMap(exception_constructor);
+    Handle<JSObject> exception_proto(
+        JSObject::cast(exception_constructor->instance_prototype()), isolate);
+    Handle<Map> exception_map = isolate->factory()->NewMap(
+        i::WASM_EXCEPTION_OBJECT_TYPE, WasmExceptionObject::kHeaderSize);
+    JSFunction::SetInitialMap(isolate, exception_constructor, exception_map,
+                              exception_proto);
   }
 }
 #undef ASSIGN