summaryrefslogtreecommitdiff
path: root/deps/v8/src/runtime/runtime-object.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/runtime/runtime-object.cc')
-rw-r--r--deps/v8/src/runtime/runtime-object.cc334
1 files changed, 287 insertions, 47 deletions
diff --git a/deps/v8/src/runtime/runtime-object.cc b/deps/v8/src/runtime/runtime-object.cc
index 56e58bea3e..ff1f1d0c9a 100644
--- a/deps/v8/src/runtime/runtime-object.cc
+++ b/deps/v8/src/runtime/runtime-object.cc
@@ -219,8 +219,10 @@ bool DeleteObjectPropertyFast(Isolate* isolate, Handle<JSReceiver> receiver,
// Finally, perform the map rollback.
receiver->set_map(*parent_map, kReleaseStore);
#if VERIFY_HEAP
- receiver->HeapObjectVerify(isolate);
- receiver->property_array().PropertyArrayVerify(isolate);
+ if (v8_flags.verify_heap) {
+ receiver->HeapObjectVerify(isolate);
+ receiver->property_array().PropertyArrayVerify(isolate);
+ }
#endif
// If the {descriptor} was "const" so far, we need to update the
@@ -700,7 +702,7 @@ RUNTIME_FUNCTION(Runtime_ObjectIsExtensible) {
Maybe<bool> result =
object->IsJSReceiver()
- ? JSReceiver::IsExtensible(Handle<JSReceiver>::cast(object))
+ ? JSReceiver::IsExtensible(isolate, Handle<JSReceiver>::cast(object))
: Just(false);
MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
return isolate->heap()->ToBoolean(result.FromJust());
@@ -711,8 +713,8 @@ RUNTIME_FUNCTION(Runtime_JSReceiverPreventExtensionsThrow) {
DCHECK_EQ(1, args.length());
Handle<JSReceiver> object = args.at<JSReceiver>(0);
- MAYBE_RETURN(JSReceiver::PreventExtensions(Handle<JSReceiver>::cast(object),
- kThrowOnError),
+ MAYBE_RETURN(JSReceiver::PreventExtensions(
+ isolate, Handle<JSReceiver>::cast(object), kThrowOnError),
ReadOnlyRoots(isolate).exception());
return *object;
}
@@ -723,7 +725,7 @@ RUNTIME_FUNCTION(Runtime_JSReceiverPreventExtensionsDontThrow) {
Handle<JSReceiver> object = args.at<JSReceiver>(0);
Maybe<bool> result = JSReceiver::PreventExtensions(
- Handle<JSReceiver>::cast(object), kDontThrow);
+ isolate, Handle<JSReceiver>::cast(object), kDontThrow);
MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
return *isolate->factory()->ToBoolean(result.FromJust());
}
@@ -909,32 +911,6 @@ RUNTIME_FUNCTION(Runtime_SetNamedProperty) {
StoreOrigin::kNamed));
}
-// Similar to DefineKeyedOwnPropertyInLiteral, but does not update feedback, and
-// and does not have a flags parameter for performing SetFunctionName().
-//
-// Currently, this is used for ObjectLiteral spread properties in CloneObjectIC
-// and for array literal creations in StoreInArrayLiteralIC.
-// TODO(v8:12548): merge this into DefineKeyedOwnPropertyInLiteral.
-RUNTIME_FUNCTION(Runtime_DefineKeyedOwnPropertyInLiteral_Simple) {
- HandleScope scope(isolate);
- DCHECK_EQ(3, args.length());
-
- Handle<JSReceiver> object = args.at<JSReceiver>(0);
- Handle<Object> key = args.at(1);
- Handle<Object> value = args.at(2);
-
- PropertyKey lookup_key(isolate, key);
- LookupIterator it(isolate, object, lookup_key, LookupIterator::OWN);
-
- Maybe<bool> result = JSObject::DefineOwnPropertyIgnoreAttributes(
- &it, value, NONE, Just(kDontThrow));
- RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
- DCHECK(result.IsJust());
- USE(result);
-
- return *value;
-}
-
namespace {
// ES6 section 12.5.4.
@@ -1054,7 +1030,8 @@ RUNTIME_FUNCTION(Runtime_GetDerivedMap) {
Handle<Object> rab_gsab = args.at(2);
if (rab_gsab->IsTrue()) {
RETURN_RESULT_OR_FAILURE(
- isolate, JSFunction::GetDerivedRabGsabMap(isolate, target, new_target));
+ isolate, JSFunction::GetDerivedRabGsabTypedArrayMap(isolate, target,
+ new_target));
} else {
RETURN_RESULT_OR_FAILURE(
isolate, JSFunction::GetDerivedMap(isolate, target, new_target));
@@ -1113,23 +1090,44 @@ RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
return ReadOnlyRoots(isolate).undefined_value();
}
+RUNTIME_FUNCTION(Runtime_SetFunctionName) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(2, args.length());
+ Handle<Object> value = args.at(0);
+ Handle<Name> name = args.at<Name>(1);
+ DCHECK(value->IsJSFunction());
+ Handle<JSFunction> function = Handle<JSFunction>::cast(value);
+ DCHECK(!function->shared().HasSharedName());
+ Handle<Map> function_map(function->map(), isolate);
+ if (!JSFunction::SetName(function, name,
+ isolate->factory()->empty_string())) {
+ return ReadOnlyRoots(isolate).exception();
+ }
+ // Class constructors do not reserve in-object space for name field.
+ DCHECK_IMPLIES(!IsClassConstructor(function->shared().kind()),
+ *function_map == function->map());
+ return *value;
+}
+
RUNTIME_FUNCTION(Runtime_DefineKeyedOwnPropertyInLiteral) {
HandleScope scope(isolate);
DCHECK_EQ(6, args.length());
- Handle<JSObject> object = args.at<JSObject>(0);
- Handle<Name> name = args.at<Name>(1);
+ Handle<JSReceiver> object = args.at<JSReceiver>(0);
+ Handle<Object> name = args.at(1);
Handle<Object> value = args.at(2);
int flag = args.smi_value_at(3);
Handle<HeapObject> maybe_vector = args.at<HeapObject>(4);
- int index = args.tagged_index_value_at(5);
if (!maybe_vector->IsUndefined()) {
+ int index = args.tagged_index_value_at(5);
+ DCHECK(name->IsName());
DCHECK(maybe_vector->IsFeedbackVector());
Handle<FeedbackVector> vector = Handle<FeedbackVector>::cast(maybe_vector);
FeedbackNexus nexus(vector, FeedbackVector::ToSlot(index));
if (nexus.ic_state() == InlineCacheState::UNINITIALIZED) {
if (name->IsUniqueName()) {
- nexus.ConfigureMonomorphic(name, handle(object->map(), isolate),
+ nexus.ConfigureMonomorphic(Handle<Name>::cast(name),
+ handle(object->map(), isolate),
MaybeObjectHandle());
} else {
nexus.ConfigureMegamorphic(IcCheckType::kProperty);
@@ -1142,32 +1140,32 @@ RUNTIME_FUNCTION(Runtime_DefineKeyedOwnPropertyInLiteral) {
}
DefineKeyedOwnPropertyInLiteralFlags flags(flag);
- PropertyAttributes attrs =
- (flags & DefineKeyedOwnPropertyInLiteralFlag::kDontEnum)
- ? PropertyAttributes::DONT_ENUM
- : PropertyAttributes::NONE;
if (flags & DefineKeyedOwnPropertyInLiteralFlag::kSetFunctionName) {
+ DCHECK(name->IsName());
DCHECK(value->IsJSFunction());
Handle<JSFunction> function = Handle<JSFunction>::cast(value);
DCHECK(!function->shared().HasSharedName());
Handle<Map> function_map(function->map(), isolate);
- if (!JSFunction::SetName(function, name,
+ if (!JSFunction::SetName(function, Handle<Name>::cast(name),
isolate->factory()->empty_string())) {
return ReadOnlyRoots(isolate).exception();
}
// Class constructors do not reserve in-object space for name field.
- CHECK_IMPLIES(!IsClassConstructor(function->shared().kind()),
- *function_map == function->map());
+ DCHECK_IMPLIES(!IsClassConstructor(function->shared().kind()),
+ *function_map == function->map());
}
PropertyKey key(isolate, name);
LookupIterator it(isolate, object, key, object, LookupIterator::OWN);
+
+ Maybe<bool> result = JSObject::DefineOwnPropertyIgnoreAttributes(
+ &it, value, PropertyAttributes::NONE, Just(kDontThrow));
// Cannot fail since this should only be called when
// creating an object literal.
- CHECK(JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attrs,
- Just(kDontThrow))
- .IsJust());
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
+ DCHECK(result.IsJust());
+ USE(result);
// Return the value so that
// BaselineCompiler::VisitDefineKeyedOwnPropertyInLiteral doesn't have to
@@ -1469,9 +1467,251 @@ RUNTIME_FUNCTION(Runtime_GetOwnPropertyDescriptor) {
MAYBE_RETURN(found, ReadOnlyRoots(isolate).exception());
if (!found.FromJust()) return ReadOnlyRoots(isolate).undefined_value();
+ return *desc.ToObject(isolate);
+}
+
+// Returns a PropertyDescriptorObject (property-descriptor-object.h)
+RUNTIME_FUNCTION(Runtime_GetOwnPropertyDescriptorObject) {
+ HandleScope scope(isolate);
+
+ DCHECK_EQ(2, args.length());
+ Handle<JSReceiver> object = args.at<JSReceiver>(0);
+ Handle<Name> name = args.at<Name>(1);
+
+ PropertyDescriptor desc;
+ Maybe<bool> found =
+ JSReceiver::GetOwnPropertyDescriptor(isolate, object, name, &desc);
+ MAYBE_RETURN(found, ReadOnlyRoots(isolate).exception());
+
+ if (!found.FromJust()) return ReadOnlyRoots(isolate).undefined_value();
return *desc.ToPropertyDescriptorObject(isolate);
}
+enum class PrivateMemberType {
+ kPrivateField,
+ kPrivateAccessor,
+ kPrivateMethod,
+};
+
+struct PrivateMember {
+ PrivateMemberType type;
+ // It's the class constructor for static methods/accessors,
+ // the brand symbol for instance methods/accessors,
+ // and the private name symbol for fields.
+ Handle<Object> brand_or_field_symbol;
+ Handle<Object> value;
+};
+
+namespace {
+void CollectPrivateMethodsAndAccessorsFromContext(
+ Isolate* isolate, Handle<Context> context, Handle<String> desc,
+ Handle<Object> brand, IsStaticFlag is_static_flag,
+ std::vector<PrivateMember>* results) {
+ Handle<ScopeInfo> scope_info(context->scope_info(), isolate);
+ VariableLookupResult lookup_result;
+ int context_index = scope_info->ContextSlotIndex(desc, &lookup_result);
+ if (context_index == -1 ||
+ !IsPrivateMethodOrAccessorVariableMode(lookup_result.mode) ||
+ lookup_result.is_static_flag != is_static_flag) {
+ return;
+ }
+
+ Handle<Object> slot_value(context->get(context_index), isolate);
+ DCHECK_IMPLIES(lookup_result.mode == VariableMode::kPrivateMethod,
+ slot_value->IsJSFunction());
+ DCHECK_IMPLIES(lookup_result.mode != VariableMode::kPrivateMethod,
+ slot_value->IsAccessorPair());
+ results->push_back({
+ lookup_result.mode == VariableMode::kPrivateMethod
+ ? PrivateMemberType::kPrivateMethod
+ : PrivateMemberType::kPrivateAccessor,
+ brand,
+ slot_value,
+ });
+}
+
+Maybe<bool> CollectPrivateMembersFromReceiver(
+ Isolate* isolate, Handle<JSReceiver> receiver, Handle<String> desc,
+ std::vector<PrivateMember>* results) {
+ PropertyFilter key_filter =
+ static_cast<PropertyFilter>(PropertyFilter::PRIVATE_NAMES_ONLY);
+ Handle<FixedArray> keys;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, keys,
+ KeyAccumulator::GetKeys(isolate, receiver, KeyCollectionMode::kOwnOnly,
+ key_filter, GetKeysConversion::kConvertToString),
+ Nothing<bool>());
+
+ if (receiver->IsJSFunction()) {
+ Handle<JSFunction> func(JSFunction::cast(*receiver), isolate);
+ Handle<SharedFunctionInfo> shared(func->shared(), isolate);
+ if (shared->is_class_constructor() &&
+ shared->has_static_private_methods_or_accessors()) {
+ Handle<Context> recevier_context(JSFunction::cast(*receiver).context(),
+ isolate);
+ CollectPrivateMethodsAndAccessorsFromContext(
+ isolate, recevier_context, desc, func, IsStaticFlag::kStatic,
+ results);
+ }
+ }
+
+ for (int i = 0; i < keys->length(); ++i) {
+ Handle<Object> obj_key(keys->get(i), isolate);
+ Handle<Symbol> symbol(Symbol::cast(*obj_key), isolate);
+ CHECK(symbol->is_private_name());
+ Handle<Object> value;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, value, Object::GetProperty(isolate, receiver, symbol),
+ Nothing<bool>());
+
+ if (symbol->is_private_brand()) {
+ Handle<Context> value_context(Context::cast(*value), isolate);
+ CollectPrivateMethodsAndAccessorsFromContext(
+ isolate, value_context, desc, symbol, IsStaticFlag::kNotStatic,
+ results);
+ } else {
+ Handle<String> symbol_desc(String::cast(symbol->description()), isolate);
+ if (symbol_desc->Equals(*desc)) {
+ results->push_back({
+ PrivateMemberType::kPrivateField,
+ symbol,
+ value,
+ });
+ }
+ }
+ }
+
+ return Just(true);
+}
+
+Maybe<bool> FindPrivateMembersFromReceiver(Isolate* isolate,
+ Handle<JSReceiver> receiver,
+ Handle<String> desc,
+ MessageTemplate not_found_message,
+ PrivateMember* result) {
+ std::vector<PrivateMember> results;
+ MAYBE_RETURN(
+ CollectPrivateMembersFromReceiver(isolate, receiver, desc, &results),
+ Nothing<bool>());
+
+ if (results.size() == 0) {
+ THROW_NEW_ERROR_RETURN_VALUE(isolate, NewError(not_found_message, desc),
+ Nothing<bool>());
+ } else if (results.size() > 1) {
+ THROW_NEW_ERROR_RETURN_VALUE(
+ isolate, NewError(MessageTemplate::kConflictingPrivateName, desc),
+ Nothing<bool>());
+ }
+
+ *result = results[0];
+ return Just(true);
+}
+} // namespace
+
+MaybeHandle<Object> Runtime::GetPrivateMember(Isolate* isolate,
+ Handle<JSReceiver> receiver,
+ Handle<String> desc) {
+ PrivateMember result;
+ MAYBE_RETURN_NULL(FindPrivateMembersFromReceiver(
+ isolate, receiver, desc, MessageTemplate::kInvalidPrivateMemberRead,
+ &result));
+
+ switch (result.type) {
+ case PrivateMemberType::kPrivateField:
+ case PrivateMemberType::kPrivateMethod: {
+ return result.value;
+ }
+ case PrivateMemberType::kPrivateAccessor: {
+ // The accessors are collected from the contexts, so there is no need to
+ // perform brand checks.
+ Handle<AccessorPair> pair = Handle<AccessorPair>::cast(result.value);
+ if (pair->getter().IsNull()) {
+ THROW_NEW_ERROR(
+ isolate,
+ NewError(MessageTemplate::kInvalidPrivateGetterAccess, desc),
+ Object);
+ }
+ DCHECK(pair->getter().IsJSFunction());
+ Handle<JSFunction> getter(JSFunction::cast(pair->getter()), isolate);
+ return Execution::Call(isolate, getter, receiver, 0, nullptr);
+ }
+ }
+}
+
+MaybeHandle<Object> Runtime::SetPrivateMember(Isolate* isolate,
+ Handle<JSReceiver> receiver,
+ Handle<String> desc,
+ Handle<Object> value) {
+ PrivateMember result;
+ MAYBE_RETURN_NULL(FindPrivateMembersFromReceiver(
+ isolate, receiver, desc, MessageTemplate::kInvalidPrivateMemberRead,
+ &result));
+
+ switch (result.type) {
+ case PrivateMemberType::kPrivateField: {
+ Handle<Symbol> symbol =
+ Handle<Symbol>::cast(result.brand_or_field_symbol);
+ return Object::SetProperty(isolate, receiver, symbol, value,
+ StoreOrigin::kMaybeKeyed);
+ }
+ case PrivateMemberType::kPrivateMethod: {
+ THROW_NEW_ERROR(
+ isolate, NewError(MessageTemplate::kInvalidPrivateMethodWrite, desc),
+ Object);
+ }
+ case PrivateMemberType::kPrivateAccessor: {
+ // The accessors are collected from the contexts, so there is no need to
+ // perform brand checks.
+ Handle<AccessorPair> pair = Handle<AccessorPair>::cast(result.value);
+ if (pair->setter().IsNull()) {
+ THROW_NEW_ERROR(
+ isolate,
+ NewError(MessageTemplate::kInvalidPrivateSetterAccess, desc),
+ Object);
+ }
+ DCHECK(pair->setter().IsJSFunction());
+ Handle<Object> argv[] = {value};
+ Handle<JSFunction> setter(JSFunction::cast(pair->setter()), isolate);
+ return Execution::Call(isolate, setter, receiver, arraysize(argv), argv);
+ }
+ }
+}
+
+RUNTIME_FUNCTION(Runtime_GetPrivateMember) {
+ HandleScope scope(isolate);
+ // TODO(chromium:1381806) support specifying scopes, or selecting the right
+ // one from the conflicting names.
+ DCHECK_EQ(args.length(), 2);
+ Handle<Object> receiver = args.at<Object>(0);
+ Handle<String> desc = args.at<String>(1);
+ if (receiver->IsNullOrUndefined(isolate)) {
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewTypeError(MessageTemplate::kNonObjectPrivateNameAccess,
+ desc, receiver));
+ }
+ RETURN_RESULT_OR_FAILURE(
+ isolate, Runtime::GetPrivateMember(
+ isolate, Handle<JSReceiver>::cast(receiver), desc));
+}
+
+RUNTIME_FUNCTION(Runtime_SetPrivateMember) {
+ HandleScope scope(isolate);
+ // TODO(chromium:1381806) support specifying scopes, or selecting the right
+ // one from the conflicting names.
+ DCHECK_EQ(args.length(), 3);
+ Handle<Object> receiver = args.at<Object>(0);
+ Handle<String> desc = args.at<String>(1);
+ if (receiver->IsNullOrUndefined(isolate)) {
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewTypeError(MessageTemplate::kNonObjectPrivateNameAccess,
+ desc, receiver));
+ }
+ Handle<Object> value = args.at<Object>(2);
+ RETURN_RESULT_OR_FAILURE(
+ isolate, Runtime::SetPrivateMember(
+ isolate, Handle<JSReceiver>::cast(receiver), desc, value));
+}
+
RUNTIME_FUNCTION(Runtime_LoadPrivateSetter) {
HandleScope scope(isolate);
DCHECK_EQ(args.length(), 1);