diff options
Diffstat (limited to 'deps/v8/src/builtins/builtins-object-gen.cc')
-rw-r--r-- | deps/v8/src/builtins/builtins-object-gen.cc | 91 |
1 files changed, 71 insertions, 20 deletions
diff --git a/deps/v8/src/builtins/builtins-object-gen.cc b/deps/v8/src/builtins/builtins-object-gen.cc index 6173bb79ab..6db05d9f1f 100644 --- a/deps/v8/src/builtins/builtins-object-gen.cc +++ b/deps/v8/src/builtins/builtins-object-gen.cc @@ -39,8 +39,8 @@ void ObjectBuiltinsAssembler::IsString(Node* object, Label* if_string, void ObjectBuiltinsAssembler::ReturnToStringFormat(Node* context, Node* string) { - Node* lhs = HeapConstant(factory()->NewStringFromStaticChars("[object ")); - Node* rhs = HeapConstant(factory()->NewStringFromStaticChars("]")); + Node* lhs = StringConstant("[object "); + Node* rhs = StringConstant("]"); Callable callable = CodeFactory::StringAdd(isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED); @@ -157,15 +157,15 @@ TF_BUILTIN(ObjectKeys, ObjectBuiltinsAssembler) { Node* array = nullptr; Node* elements = nullptr; Node* native_context = LoadNativeContext(context); - Node* array_map = LoadJSArrayElementsMap(FAST_ELEMENTS, native_context); + Node* array_map = LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context); Node* array_length = SmiTag(object_enum_length); std::tie(array, elements) = AllocateUninitializedJSArrayWithElements( - FAST_ELEMENTS, array_map, array_length, nullptr, object_enum_length, + PACKED_ELEMENTS, array_map, array_length, nullptr, object_enum_length, INTPTR_PARAMETERS); StoreMapNoWriteBarrier(elements, Heap::kFixedArrayMapRootIndex); StoreObjectFieldNoWriteBarrier(elements, FixedArray::kLengthOffset, array_length); - CopyFixedArrayElements(FAST_ELEMENTS, object_enum_cache, elements, + CopyFixedArrayElements(PACKED_ELEMENTS, object_enum_cache, elements, object_enum_length, SKIP_WRITE_BARRIER); Return(array); } @@ -191,15 +191,61 @@ TF_BUILTIN(ObjectKeys, ObjectBuiltinsAssembler) { { // Wrap the elements into a proper JSArray and return that. Node* native_context = LoadNativeContext(context); - Node* array_map = LoadJSArrayElementsMap(FAST_ELEMENTS, native_context); + Node* array_map = LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context); Node* array = AllocateUninitializedJSArrayWithoutElements( - FAST_ELEMENTS, array_map, var_length.value(), nullptr); + PACKED_ELEMENTS, array_map, var_length.value(), nullptr); StoreObjectFieldNoWriteBarrier(array, JSArray::kElementsOffset, var_elements.value()); Return(array); } } +// ES #sec-object.prototype.isprototypeof +TF_BUILTIN(ObjectPrototypeIsPrototypeOf, ObjectBuiltinsAssembler) { + Node* receiver = Parameter(Descriptor::kReceiver); + Node* value = Parameter(Descriptor::kValue); + Node* context = Parameter(Descriptor::kContext); + Label if_receiverisnullorundefined(this, Label::kDeferred), + if_valueisnotreceiver(this, Label::kDeferred); + + // We only check whether {value} is a Smi here, so that the + // prototype chain walk below can safely access the {value}s + // map. We don't rule out Primitive {value}s, since all of + // them have null as their prototype, so the chain walk below + // immediately aborts and returns false anyways. + GotoIf(TaggedIsSmi(value), &if_valueisnotreceiver); + + // Check if {receiver} is either null or undefined and in that case, + // invoke the ToObject builtin, which raises the appropriate error. + // Otherwise we don't need to invoke ToObject, since {receiver} is + // either already a JSReceiver, in which case ToObject is a no-op, + // or it's a Primitive and ToObject would allocate a fresh JSValue + // wrapper, which wouldn't be identical to any existing JSReceiver + // found in the prototype chain of {value}, hence it will return + // false no matter if we search for the Primitive {receiver} or + // a newly allocated JSValue wrapper for {receiver}. + GotoIf(IsNull(receiver), &if_receiverisnullorundefined); + GotoIf(IsUndefined(receiver), &if_receiverisnullorundefined); + + // Loop through the prototype chain looking for the {receiver}. + Return(HasInPrototypeChain(context, value, receiver)); + + BIND(&if_receiverisnullorundefined); + { + // If {value} is a primitive HeapObject, we need to return + // false instead of throwing an exception per order of the + // steps in the specification, so check that first here. + GotoIfNot(IsJSReceiver(value), &if_valueisnotreceiver); + + // Simulate the ToObject invocation on {receiver}. + CallBuiltin(Builtins::kToObject, context, receiver); + Unreachable(); + } + + BIND(&if_valueisnotreceiver); + Return(FalseConstant()); +} + // ES6 #sec-object.prototype.tostring TF_BUILTIN(ObjectProtoToString, ObjectBuiltinsAssembler) { Label return_undefined(this, Label::kDeferred), @@ -222,8 +268,7 @@ TF_BUILTIN(ObjectProtoToString, ObjectBuiltinsAssembler) { GotoIf(WordEqual(receiver, NullConstant()), &return_null); - Callable to_object = CodeFactory::ToObject(isolate()); - receiver = CallStub(to_object, context, receiver); + receiver = CallBuiltin(Builtins::kToObject, context, receiver); Node* receiver_instance_type = LoadInstanceType(receiver); @@ -368,17 +413,21 @@ TF_BUILTIN(ObjectPrototypeValueOf, CodeStubAssembler) { Node* receiver = Parameter(Descriptor::kReceiver); Node* context = Parameter(Descriptor::kContext); - Callable to_object = CodeFactory::ToObject(isolate()); - receiver = CallStub(to_object, context, receiver); - - Return(receiver); + Return(CallBuiltin(Builtins::kToObject, context, receiver)); } // ES #sec-object.create TF_BUILTIN(ObjectCreate, ObjectBuiltinsAssembler) { - Node* prototype = Parameter(Descriptor::kPrototype); - Node* properties = Parameter(Descriptor::kProperties); - Node* context = Parameter(Descriptor::kContext); + int const kPrototypeArg = 0; + int const kPropertiesArg = 1; + + Node* argc = + ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount)); + CodeStubArguments args(this, argc); + + Node* prototype = args.GetOptionalArgumentValue(kPrototypeArg); + Node* properties = args.GetOptionalArgumentValue(kPropertiesArg); + Node* context = Parameter(BuiltinDescriptor::kContext); Label call_runtime(this, Label::kDeferred), prototype_valid(this), no_properties(this); @@ -449,13 +498,15 @@ TF_BUILTIN(ObjectCreate, ObjectBuiltinsAssembler) { BIND(&instantiate_map); { Node* instance = AllocateJSObjectFromMap(map.value(), properties.value()); - Return(instance); + args.PopAndReturn(instance); } } BIND(&call_runtime); { - Return(CallRuntime(Runtime::kObjectCreate, context, prototype, properties)); + Node* result = + CallRuntime(Runtime::kObjectCreate, context, prototype, properties); + args.PopAndReturn(result); } } @@ -527,8 +578,8 @@ TF_BUILTIN(CreateGeneratorObject, ObjectBuiltinsAssembler) { Node* frame_size = ChangeInt32ToIntPtr(LoadObjectField( bytecode_array, BytecodeArray::kFrameSizeOffset, MachineType::Int32())); Node* size = WordSar(frame_size, IntPtrConstant(kPointerSizeLog2)); - Node* register_file = AllocateFixedArray(FAST_HOLEY_ELEMENTS, size); - FillFixedArrayWithValue(FAST_HOLEY_ELEMENTS, register_file, IntPtrConstant(0), + Node* register_file = AllocateFixedArray(HOLEY_ELEMENTS, size); + FillFixedArrayWithValue(HOLEY_ELEMENTS, register_file, IntPtrConstant(0), size, Heap::kUndefinedValueRootIndex); Node* const result = AllocateJSObjectFromMap(maybe_map); |