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(WordEqual(receiver, NullConstant()), &if_receiverisnullorundefined); | |
jgruber
2017/06/13 07:49:51
Nit: IsNull, IsUndefined (predicates are autogener
Benedikt Meurer
2017/06/13 18:22:44
Done.
| |
220 GotoIf(WordEqual(receiver, UndefinedConstant()), | |
221 &if_receiverisnullorundefined); | |
222 | |
223 // Loop through the prototype chain looking for the {receiver}. | |
224 Return(HasInPrototypeChain(context, value, receiver)); | |
225 | |
226 BIND(&if_receiverisnullorundefined); | |
227 { | |
228 // If {value} is a primitive HeapObject, we need to return | |
229 // false instead of throwing an exception per order of the | |
230 // steps in the specification, so check that first here. | |
231 GotoIfNot(IsJSReceiver(value), &if_valueisnotreceiver); | |
232 | |
233 // Simulate the ToObject invocation on {receiver}. | |
234 CallBuiltin(Builtins::kToObject, context, receiver); | |
235 Unreachable(); | |
236 } | |
237 | |
238 BIND(&if_valueisnotreceiver); | |
239 Return(BooleanConstant(false)); | |
240 } | |
241 | |
195 // ES6 #sec-object.prototype.tostring | 242 // ES6 #sec-object.prototype.tostring |
196 TF_BUILTIN(ObjectProtoToString, ObjectBuiltinsAssembler) { | 243 TF_BUILTIN(ObjectProtoToString, ObjectBuiltinsAssembler) { |
197 Label return_undefined(this, Label::kDeferred), | 244 Label return_undefined(this, Label::kDeferred), |
198 return_null(this, Label::kDeferred), | 245 return_null(this, Label::kDeferred), |
199 return_arguments(this, Label::kDeferred), return_array(this), | 246 return_arguments(this, Label::kDeferred), return_array(this), |
200 return_api(this, Label::kDeferred), return_object(this), | 247 return_api(this, Label::kDeferred), return_object(this), |
201 return_regexp(this), return_function(this), return_error(this), | 248 return_regexp(this), return_function(this), return_error(this), |
202 return_date(this), return_jsvalue(this), | 249 return_date(this), return_jsvalue(this), |
203 return_jsproxy(this, Label::kDeferred); | 250 return_jsproxy(this, Label::kDeferred); |
204 | 251 |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
537 | 584 |
538 BIND(&runtime); | 585 BIND(&runtime); |
539 { | 586 { |
540 Return(CallRuntime(Runtime::kCreateJSGeneratorObject, context, closure, | 587 Return(CallRuntime(Runtime::kCreateJSGeneratorObject, context, closure, |
541 receiver)); | 588 receiver)); |
542 } | 589 } |
543 } | 590 } |
544 | 591 |
545 } // namespace internal | 592 } // namespace internal |
546 } // namespace v8 | 593 } // namespace v8 |
OLD | NEW |