summaryrefslogtreecommitdiff
path: root/deps/v8/src/builtins/builtins-object-gen.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/builtins/builtins-object-gen.cc')
-rw-r--r--deps/v8/src/builtins/builtins-object-gen.cc91
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);