Commit d4baeee6 authored by Shu-yu Guo's avatar Shu-yu Guo Committed by V8 LUCI CQ

Plumb Isolate through SetPrototype

Currently the Isolate is gotten off of the object that the operation is
being performed on. Shared objects return the shared Isolate, which is
incorrect as it shouldn't be used to run JS, nor does it have
HandleScopes open. Plumb the executing Isolate through.

Bug: v8:12547
Change-Id: I4d2c9f5d4d7bc50b3aeb515eb78c08eb1b2a6824
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3440902Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78960}
parent 78bc7852
...@@ -4591,14 +4591,16 @@ Maybe<bool> v8::Object::SetPrototype(Local<Context> context, ...@@ -4591,14 +4591,16 @@ Maybe<bool> v8::Object::SetPrototype(Local<Context> context,
// We do not allow exceptions thrown while setting the prototype // We do not allow exceptions thrown while setting the prototype
// to propagate outside. // to propagate outside.
TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate)); TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
auto result = i::JSProxy::SetPrototype(i::Handle<i::JSProxy>::cast(self), auto result =
value_obj, false, i::kThrowOnError); i::JSProxy::SetPrototype(isolate, i::Handle<i::JSProxy>::cast(self),
value_obj, false, i::kThrowOnError);
has_pending_exception = result.IsNothing(); has_pending_exception = result.IsNothing();
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
} else { } else {
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
auto result = i::JSObject::SetPrototype(i::Handle<i::JSObject>::cast(self), auto result =
value_obj, false, i::kThrowOnError); i::JSObject::SetPrototype(isolate, i::Handle<i::JSObject>::cast(self),
value_obj, false, i::kThrowOnError);
if (result.IsNothing()) { if (result.IsNothing()) {
isolate->clear_pending_exception(); isolate->clear_pending_exception();
return Nothing<bool>(); return Nothing<bool>();
......
...@@ -260,8 +260,9 @@ BUILTIN(ObjectPrototypeSetProto) { ...@@ -260,8 +260,9 @@ BUILTIN(ObjectPrototypeSetProto) {
// 4. Let status be ? O.[[SetPrototypeOf]](proto). // 4. Let status be ? O.[[SetPrototypeOf]](proto).
// 5. If status is false, throw a TypeError exception. // 5. If status is false, throw a TypeError exception.
MAYBE_RETURN(JSReceiver::SetPrototype(receiver, proto, true, kThrowOnError), MAYBE_RETURN(
ReadOnlyRoots(isolate).exception()); JSReceiver::SetPrototype(isolate, receiver, proto, true, kThrowOnError),
ReadOnlyRoots(isolate).exception());
// Return undefined. // Return undefined.
return ReadOnlyRoots(isolate).undefined_value(); return ReadOnlyRoots(isolate).undefined_value();
......
...@@ -649,7 +649,8 @@ class ContextProxy { ...@@ -649,7 +649,8 @@ class ContextProxy {
GetOrCreateInstanceProxy<FunctionsProxy>(isolate, instance); GetOrCreateInstanceProxy<FunctionsProxy>(isolate, instance);
JSObject::AddProperty(isolate, object, "functions", functions, FROZEN); JSObject::AddProperty(isolate, object, "functions", functions, FROZEN);
Handle<JSObject> prototype = ContextProxyPrototype::Create(isolate); Handle<JSObject> prototype = ContextProxyPrototype::Create(isolate);
JSObject::SetPrototype(object, prototype, false, kDontThrow).Check(); JSObject::SetPrototype(isolate, object, prototype, false, kDontThrow)
.Check();
return object; return object;
} }
}; };
...@@ -1151,8 +1152,8 @@ Handle<ArrayList> AddWasmTableObjectInternalProperties( ...@@ -1151,8 +1152,8 @@ Handle<ArrayList> AddWasmTableObjectInternalProperties(
} }
Handle<JSArray> final_entries = isolate->factory()->NewJSArrayWithElements( Handle<JSArray> final_entries = isolate->factory()->NewJSArrayWithElements(
entries, i::PACKED_ELEMENTS, length); entries, i::PACKED_ELEMENTS, length);
JSObject::SetPrototype(final_entries, isolate->factory()->null_value(), false, JSObject::SetPrototype(isolate, final_entries,
kDontThrow) isolate->factory()->null_value(), false, kDontThrow)
.Check(); .Check();
Handle<String> entries_string = Handle<String> entries_string =
isolate->factory()->NewStringFromStaticChars("[[Entries]]"); isolate->factory()->NewStringFromStaticChars("[[Entries]]");
......
...@@ -1438,10 +1438,10 @@ static void InstallError(Isolate* isolate, Handle<JSObject> global, ...@@ -1438,10 +1438,10 @@ static void InstallError(Isolate* isolate, Handle<JSObject> global,
isolate->native_context()->set_initial_error_prototype(*prototype); isolate->native_context()->set_initial_error_prototype(*prototype);
} else { } else {
Handle<JSFunction> global_error = isolate->error_function(); Handle<JSFunction> global_error = isolate->error_function();
CHECK(JSReceiver::SetPrototype(error_fun, global_error, false, CHECK(JSReceiver::SetPrototype(isolate, error_fun, global_error, false,
kThrowOnError) kThrowOnError)
.FromMaybe(false)); .FromMaybe(false));
CHECK(JSReceiver::SetPrototype(prototype, CHECK(JSReceiver::SetPrototype(isolate, prototype,
handle(global_error->prototype(), isolate), handle(global_error->prototype(), isolate),
false, kThrowOnError) false, kThrowOnError)
.FromMaybe(false)); .FromMaybe(false));
...@@ -4057,7 +4057,8 @@ Handle<JSFunction> Genesis::InstallTypedArray(const char* name, ...@@ -4057,7 +4057,8 @@ Handle<JSFunction> Genesis::InstallTypedArray(const char* name,
result->shared().DontAdaptArguments(); result->shared().DontAdaptArguments();
result->shared().set_length(3); result->shared().set_length(3);
CHECK(JSObject::SetPrototype(result, typed_array_function, false, kDontThrow) CHECK(JSObject::SetPrototype(isolate(), result, typed_array_function, false,
kDontThrow)
.FromJust()); .FromJust());
Handle<Smi> bytes_per_element( Handle<Smi> bytes_per_element(
...@@ -4074,8 +4075,8 @@ Handle<JSFunction> Genesis::InstallTypedArray(const char* name, ...@@ -4074,8 +4075,8 @@ Handle<JSFunction> Genesis::InstallTypedArray(const char* name,
DCHECK(result->prototype().IsJSObject()); DCHECK(result->prototype().IsJSObject());
Handle<JSObject> prototype(JSObject::cast(result->prototype()), isolate()); Handle<JSObject> prototype(JSObject::cast(result->prototype()), isolate());
CHECK(JSObject::SetPrototype(prototype, typed_array_prototype, false, CHECK(JSObject::SetPrototype(isolate(), prototype, typed_array_prototype,
kDontThrow) false, kDontThrow)
.FromJust()); .FromJust());
CHECK_NE(prototype->map().ptr(), CHECK_NE(prototype->map().ptr(),
......
...@@ -2153,14 +2153,15 @@ MaybeHandle<FixedArray> JSReceiver::GetOwnEntries(Handle<JSReceiver> object, ...@@ -2153,14 +2153,15 @@ MaybeHandle<FixedArray> JSReceiver::GetOwnEntries(Handle<JSReceiver> object,
try_fast_path, true); try_fast_path, true);
} }
Maybe<bool> JSReceiver::SetPrototype(Handle<JSReceiver> object, Maybe<bool> JSReceiver::SetPrototype(Isolate* isolate,
Handle<JSReceiver> object,
Handle<Object> value, bool from_javascript, Handle<Object> value, bool from_javascript,
ShouldThrow should_throw) { ShouldThrow should_throw) {
if (object->IsJSProxy()) { if (object->IsJSProxy()) {
return JSProxy::SetPrototype(Handle<JSProxy>::cast(object), value, return JSProxy::SetPrototype(isolate, Handle<JSProxy>::cast(object), value,
from_javascript, should_throw); from_javascript, should_throw);
} }
return JSObject::SetPrototype(Handle<JSObject>::cast(object), value, return JSObject::SetPrototype(isolate, Handle<JSObject>::cast(object), value,
from_javascript, should_throw); from_javascript, should_throw);
} }
...@@ -4846,11 +4847,9 @@ void JSObject::InvalidatePrototypeValidityCell(JSGlobalObject global) { ...@@ -4846,11 +4847,9 @@ void JSObject::InvalidatePrototypeValidityCell(JSGlobalObject global) {
InvalidateOnePrototypeValidityCellInternal(global.map()); InvalidateOnePrototypeValidityCellInternal(global.map());
} }
Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object, Maybe<bool> JSObject::SetPrototype(Isolate* isolate, Handle<JSObject> object,
Handle<Object> value, bool from_javascript, Handle<Object> value, bool from_javascript,
ShouldThrow should_throw) { ShouldThrow should_throw) {
Isolate* isolate = object->GetIsolate();
#ifdef DEBUG #ifdef DEBUG
int size = object->Size(); int size = object->Size();
#endif #endif
......
...@@ -254,8 +254,8 @@ class JSReceiver : public TorqueGeneratedJSReceiver<JSReceiver, HeapObject> { ...@@ -254,8 +254,8 @@ class JSReceiver : public TorqueGeneratedJSReceiver<JSReceiver, HeapObject> {
// Set the object's prototype (only JSReceiver and null are allowed values). // Set the object's prototype (only JSReceiver and null are allowed values).
V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> SetPrototype( V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> SetPrototype(
Handle<JSReceiver> object, Handle<Object> value, bool from_javascript, Isolate* isolate, Handle<JSReceiver> object, Handle<Object> value,
ShouldThrow should_throw); bool from_javascript, ShouldThrow should_throw);
inline static Handle<Object> GetDataProperty(Handle<JSReceiver> object, inline static Handle<Object> GetDataProperty(Handle<JSReceiver> object,
Handle<Name> name); Handle<Name> name);
...@@ -702,8 +702,8 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> { ...@@ -702,8 +702,8 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> {
// Set the object's prototype (only JSReceiver and null are allowed values). // Set the object's prototype (only JSReceiver and null are allowed values).
V8_WARN_UNUSED_RESULT static Maybe<bool> SetPrototype( V8_WARN_UNUSED_RESULT static Maybe<bool> SetPrototype(
Handle<JSObject> object, Handle<Object> value, bool from_javascript, Isolate* isolate, Handle<JSObject> object, Handle<Object> value,
ShouldThrow should_throw); bool from_javascript, ShouldThrow should_throw);
// Makes the object prototype immutable // Makes the object prototype immutable
// Never called from JavaScript // Never called from JavaScript
......
...@@ -31,8 +31,8 @@ class JSProxy : public TorqueGeneratedJSProxy<JSProxy, JSReceiver> { ...@@ -31,8 +31,8 @@ class JSProxy : public TorqueGeneratedJSProxy<JSProxy, JSReceiver> {
// ES6 9.5.2 // ES6 9.5.2
V8_WARN_UNUSED_RESULT static Maybe<bool> SetPrototype( V8_WARN_UNUSED_RESULT static Maybe<bool> SetPrototype(
Handle<JSProxy> proxy, Handle<Object> value, bool from_javascript, Isolate* isolate, Handle<JSProxy> proxy, Handle<Object> value,
ShouldThrow should_throw); bool from_javascript, ShouldThrow should_throw);
// ES6 9.5.3 // ES6 9.5.3
V8_WARN_UNUSED_RESULT static Maybe<bool> IsExtensible(Handle<JSProxy> proxy); V8_WARN_UNUSED_RESULT static Maybe<bool> IsExtensible(Handle<JSProxy> proxy);
......
...@@ -5123,10 +5123,9 @@ Maybe<bool> JSArray::SetLength(Handle<JSArray> array, uint32_t new_length) { ...@@ -5123,10 +5123,9 @@ Maybe<bool> JSArray::SetLength(Handle<JSArray> array, uint32_t new_length) {
// ES6: 9.5.2 [[SetPrototypeOf]] (V) // ES6: 9.5.2 [[SetPrototypeOf]] (V)
// static // static
Maybe<bool> JSProxy::SetPrototype(Handle<JSProxy> proxy, Handle<Object> value, Maybe<bool> JSProxy::SetPrototype(Isolate* isolate, Handle<JSProxy> proxy,
bool from_javascript, Handle<Object> value, bool from_javascript,
ShouldThrow should_throw) { ShouldThrow should_throw) {
Isolate* isolate = proxy->GetIsolate();
STACK_CHECK(isolate, Nothing<bool>()); STACK_CHECK(isolate, Nothing<bool>());
Handle<Name> trap_name = isolate->factory()->setPrototypeOf_string(); Handle<Name> trap_name = isolate->factory()->setPrototypeOf_string();
// 1. Assert: Either Type(V) is Object or Type(V) is Null. // 1. Assert: Either Type(V) is Object or Type(V) is Null.
...@@ -5150,7 +5149,7 @@ Maybe<bool> JSProxy::SetPrototype(Handle<JSProxy> proxy, Handle<Object> value, ...@@ -5150,7 +5149,7 @@ Maybe<bool> JSProxy::SetPrototype(Handle<JSProxy> proxy, Handle<Object> value,
Nothing<bool>()); Nothing<bool>());
// 7. If trap is undefined, then return target.[[SetPrototypeOf]](). // 7. If trap is undefined, then return target.[[SetPrototypeOf]]().
if (trap->IsUndefined(isolate)) { if (trap->IsUndefined(isolate)) {
return JSReceiver::SetPrototype(target, value, from_javascript, return JSReceiver::SetPrototype(isolate, target, value, from_javascript,
should_throw); should_throw);
} }
// 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, «target, V»)). // 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, «target, V»)).
......
...@@ -589,8 +589,9 @@ RUNTIME_FUNCTION(Runtime_InternalSetPrototype) { ...@@ -589,8 +589,9 @@ RUNTIME_FUNCTION(Runtime_InternalSetPrototype) {
DCHECK_EQ(2, args.length()); DCHECK_EQ(2, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0); CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
MAYBE_RETURN(JSReceiver::SetPrototype(obj, prototype, false, kThrowOnError), MAYBE_RETURN(
ReadOnlyRoots(isolate).exception()); JSReceiver::SetPrototype(isolate, obj, prototype, false, kThrowOnError),
ReadOnlyRoots(isolate).exception());
return *obj; return *obj;
} }
...@@ -715,8 +716,9 @@ RUNTIME_FUNCTION(Runtime_JSReceiverSetPrototypeOfThrow) { ...@@ -715,8 +716,9 @@ RUNTIME_FUNCTION(Runtime_JSReceiverSetPrototypeOfThrow) {
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, proto, 1); CONVERT_ARG_HANDLE_CHECKED(Object, proto, 1);
MAYBE_RETURN(JSReceiver::SetPrototype(object, proto, true, kThrowOnError), MAYBE_RETURN(
ReadOnlyRoots(isolate).exception()); JSReceiver::SetPrototype(isolate, object, proto, true, kThrowOnError),
ReadOnlyRoots(isolate).exception());
return *object; return *object;
} }
...@@ -729,7 +731,7 @@ RUNTIME_FUNCTION(Runtime_JSReceiverSetPrototypeOfDontThrow) { ...@@ -729,7 +731,7 @@ RUNTIME_FUNCTION(Runtime_JSReceiverSetPrototypeOfDontThrow) {
CONVERT_ARG_HANDLE_CHECKED(Object, proto, 1); CONVERT_ARG_HANDLE_CHECKED(Object, proto, 1);
Maybe<bool> result = Maybe<bool> result =
JSReceiver::SetPrototype(object, proto, true, kDontThrow); JSReceiver::SetPrototype(isolate, object, proto, true, kDontThrow);
MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception()); MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
return *isolate->factory()->ToBoolean(result.FromJust()); return *isolate->factory()->ToBoolean(result.FromJust());
} }
......
...@@ -673,9 +673,9 @@ bool TransferPrototype(i::Isolate* isolate, i::Handle<i::JSObject> destination, ...@@ -673,9 +673,9 @@ bool TransferPrototype(i::Isolate* isolate, i::Handle<i::JSObject> destination,
i::JSObject::GetPrototype(isolate, source); i::JSObject::GetPrototype(isolate, source);
i::Handle<i::HeapObject> prototype; i::Handle<i::HeapObject> prototype;
if (maybe_prototype.ToHandle(&prototype)) { if (maybe_prototype.ToHandle(&prototype)) {
Maybe<bool> result = i::JSObject::SetPrototype(destination, prototype, Maybe<bool> result = i::JSObject::SetPrototype(
/*from_javascript=*/false, isolate, destination, prototype,
internal::kThrowOnError); /*from_javascript=*/false, internal::kThrowOnError);
if (!result.FromJust()) { if (!result.FromJust()) {
DCHECK(isolate->has_pending_exception()); DCHECK(isolate->has_pending_exception());
return false; return false;
...@@ -2931,7 +2931,7 @@ void WasmJs::Install(Isolate* isolate, bool exposed_on_global_object) { ...@@ -2931,7 +2931,7 @@ void WasmJs::Install(Isolate* isolate, bool exposed_on_global_object) {
Handle<Map> function_map = isolate->factory()->CreateSloppyFunctionMap( Handle<Map> function_map = isolate->factory()->CreateSloppyFunctionMap(
FUNCTION_WITHOUT_PROTOTYPE, MaybeHandle<JSFunction>()); FUNCTION_WITHOUT_PROTOTYPE, MaybeHandle<JSFunction>());
CHECK(JSObject::SetPrototype( CHECK(JSObject::SetPrototype(
function_proto, isolate, function_proto,
handle(context->function_function().prototype(), isolate), false, handle(context->function_function().prototype(), isolate), false,
kDontThrow) kDontThrow)
.FromJust()); .FromJust());
......
...@@ -188,8 +188,9 @@ TEST(ProtoWalkBackground_PrototypeChainWrite) { ...@@ -188,8 +188,9 @@ TEST(ProtoWalkBackground_PrototypeChainWrite) {
sema_started.Wait(); sema_started.Wait();
for (int i = 0; i < 20; ++i) { for (int i = 0; i < 20; ++i) {
CHECK(JSReceiver::SetPrototype( CHECK(JSReceiver::SetPrototype(isolate, js_object,
js_object, i % 2 == 0 ? new_proto : old_proto, false, kDontThrow) i % 2 == 0 ? new_proto : old_proto, false,
kDontThrow)
.FromJust()); .FromJust());
} }
......
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