OLD | NEW |
1 // Copyright 2017 the V8 project authors. All rights reserved. | 1 // Copyright 2017 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/builtins/builtins-utils-gen.h" | 5 #include "src/builtins/builtins-utils-gen.h" |
6 #include "src/builtins/builtins.h" | 6 #include "src/builtins/builtins.h" |
7 #include "src/code-stub-assembler.h" | 7 #include "src/code-stub-assembler.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 Node* native_context = LoadNativeContext(context); | 185 Node* native_context = LoadNativeContext(context); |
186 Node* array_map = LoadJSArrayElementsMap(FAST_ELEMENTS, native_context); | 186 Node* array_map = LoadJSArrayElementsMap(FAST_ELEMENTS, native_context); |
187 Node* array = AllocateUninitializedJSArrayWithoutElements( | 187 Node* array = AllocateUninitializedJSArrayWithoutElements( |
188 FAST_ELEMENTS, array_map, var_length.value(), nullptr); | 188 FAST_ELEMENTS, array_map, var_length.value(), nullptr); |
189 StoreObjectFieldNoWriteBarrier(array, JSArray::kElementsOffset, | 189 StoreObjectFieldNoWriteBarrier(array, JSArray::kElementsOffset, |
190 var_elements.value()); | 190 var_elements.value()); |
191 Return(array); | 191 Return(array); |
192 } | 192 } |
193 } | 193 } |
194 | 194 |
| 195 // ES #sec-object.prototype.isprototypeof |
| 196 TF_BUILTIN(ObjectPrototypeIsPrototypeOf, ObjectBuiltinsAssembler) { |
| 197 Node* receiver = Parameter(Descriptor::kReceiver); |
| 198 Node* value = Parameter(Descriptor::kValue); |
| 199 Node* context = Parameter(Descriptor::kContext); |
| 200 Label if_receiverisnullorundefined(this, Label::kDeferred), |
| 201 if_valueisnotreceiver(this, Label::kDeferred); |
| 202 |
| 203 // We only check whether {value} is a Smi here, so that the |
| 204 // prototype chain walk below can safely access the {value}s |
| 205 // map. We don't rule out Primitive {value}s, since all of |
| 206 // them have null as their prototype, so the chain walk below |
| 207 // immediately aborts and returns false anyways. |
| 208 GotoIf(TaggedIsSmi(value), &if_valueisnotreceiver); |
| 209 |
| 210 // Check if {receiver} is either null or undefined and in that case, |
| 211 // invoke the ToObject builtin, which raises the appropriate error. |
| 212 // Otherwise we don't need to invoke ToObject, since {receiver} is |
| 213 // either already a JSReceiver, in which case ToObject is a no-op, |
| 214 // or it's a Primitive and ToObject would allocate a fresh JSValue |
| 215 // wrapper, which wouldn't be identical to any existing JSReceiver |
| 216 // found in the prototype chain of {value}, hence it will return |
| 217 // false no matter if we search for the Primitive {receiver} or |
| 218 // a newly allocated JSValue wrapper for {receiver}. |
| 219 GotoIf(IsNull(receiver), &if_receiverisnullorundefined); |
| 220 GotoIf(IsUndefined(receiver), &if_receiverisnullorundefined); |
| 221 |
| 222 // Loop through the prototype chain looking for the {receiver}. |
| 223 Return(HasInPrototypeChain(context, value, receiver)); |
| 224 |
| 225 BIND(&if_receiverisnullorundefined); |
| 226 { |
| 227 // If {value} is a primitive HeapObject, we need to return |
| 228 // false instead of throwing an exception per order of the |
| 229 // steps in the specification, so check that first here. |
| 230 GotoIfNot(IsJSReceiver(value), &if_valueisnotreceiver); |
| 231 |
| 232 // Simulate the ToObject invocation on {receiver}. |
| 233 CallBuiltin(Builtins::kToObject, context, receiver); |
| 234 Unreachable(); |
| 235 } |
| 236 |
| 237 BIND(&if_valueisnotreceiver); |
| 238 Return(FalseConstant()); |
| 239 } |
| 240 |
195 // ES6 #sec-object.prototype.tostring | 241 // ES6 #sec-object.prototype.tostring |
196 TF_BUILTIN(ObjectProtoToString, ObjectBuiltinsAssembler) { | 242 TF_BUILTIN(ObjectProtoToString, ObjectBuiltinsAssembler) { |
197 Label return_undefined(this, Label::kDeferred), | 243 Label return_undefined(this, Label::kDeferred), |
198 return_null(this, Label::kDeferred), | 244 return_null(this, Label::kDeferred), |
199 return_arguments(this, Label::kDeferred), return_array(this), | 245 return_arguments(this, Label::kDeferred), return_array(this), |
200 return_api(this, Label::kDeferred), return_object(this), | 246 return_api(this, Label::kDeferred), return_object(this), |
201 return_regexp(this), return_function(this), return_error(this), | 247 return_regexp(this), return_function(this), return_error(this), |
202 return_date(this), return_jsvalue(this), | 248 return_date(this), return_jsvalue(this), |
203 return_jsproxy(this, Label::kDeferred); | 249 return_jsproxy(this, Label::kDeferred); |
204 | 250 |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
537 | 583 |
538 BIND(&runtime); | 584 BIND(&runtime); |
539 { | 585 { |
540 Return(CallRuntime(Runtime::kCreateJSGeneratorObject, context, closure, | 586 Return(CallRuntime(Runtime::kCreateJSGeneratorObject, context, closure, |
541 receiver)); | 587 receiver)); |
542 } | 588 } |
543 } | 589 } |
544 | 590 |
545 } // namespace internal | 591 } // namespace internal |
546 } // namespace v8 | 592 } // namespace v8 |
OLD | NEW |