1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/builtins/builtins.h"
6 #include "src/builtins/builtins-utils.h"
7 
8 #include "src/code-factory.h"
9 #include "src/property-descriptor.h"
10 
11 namespace v8 {
12 namespace internal {
13 
14 // -----------------------------------------------------------------------------
15 // ES6 section 19.1 Object Objects
16 
Generate_ObjectHasOwnProperty(CodeStubAssembler * assembler)17 void Builtins::Generate_ObjectHasOwnProperty(CodeStubAssembler* assembler) {
18   typedef compiler::Node Node;
19   typedef CodeStubAssembler::Label Label;
20   typedef CodeStubAssembler::Variable Variable;
21 
22   Node* object = assembler->Parameter(0);
23   Node* key = assembler->Parameter(1);
24   Node* context = assembler->Parameter(4);
25 
26   Label call_runtime(assembler), return_true(assembler),
27       return_false(assembler);
28 
29   // Smi receivers do not have own properties.
30   Label if_objectisnotsmi(assembler);
31   assembler->Branch(assembler->TaggedIsSmi(object), &return_false,
32                     &if_objectisnotsmi);
33   assembler->Bind(&if_objectisnotsmi);
34 
35   Node* map = assembler->LoadMap(object);
36   Node* instance_type = assembler->LoadMapInstanceType(map);
37 
38   Variable var_index(assembler, MachineType::PointerRepresentation());
39 
40   Label keyisindex(assembler), if_iskeyunique(assembler);
41   assembler->TryToName(key, &keyisindex, &var_index, &if_iskeyunique,
42                        &call_runtime);
43 
44   assembler->Bind(&if_iskeyunique);
45   assembler->TryHasOwnProperty(object, map, instance_type, key, &return_true,
46                                &return_false, &call_runtime);
47 
48   assembler->Bind(&keyisindex);
49   // Handle negative keys in the runtime.
50   assembler->GotoIf(assembler->IntPtrLessThan(var_index.value(),
51                                               assembler->IntPtrConstant(0)),
52                     &call_runtime);
53   assembler->TryLookupElement(object, map, instance_type, var_index.value(),
54                               &return_true, &return_false, &call_runtime);
55 
56   assembler->Bind(&return_true);
57   assembler->Return(assembler->BooleanConstant(true));
58 
59   assembler->Bind(&return_false);
60   assembler->Return(assembler->BooleanConstant(false));
61 
62   assembler->Bind(&call_runtime);
63   assembler->Return(assembler->CallRuntime(Runtime::kObjectHasOwnProperty,
64                                            context, object, key));
65 }
66 
67 namespace {
68 
FastAssign(Handle<JSReceiver> to,Handle<Object> next_source)69 MUST_USE_RESULT Maybe<bool> FastAssign(Handle<JSReceiver> to,
70                                        Handle<Object> next_source) {
71   // Non-empty strings are the only non-JSReceivers that need to be handled
72   // explicitly by Object.assign.
73   if (!next_source->IsJSReceiver()) {
74     return Just(!next_source->IsString() ||
75                 String::cast(*next_source)->length() == 0);
76   }
77 
78   // If the target is deprecated, the object will be updated on first store. If
79   // the source for that store equals the target, this will invalidate the
80   // cached representation of the source. Preventively upgrade the target.
81   // Do this on each iteration since any property load could cause deprecation.
82   if (to->map()->is_deprecated()) {
83     JSObject::MigrateInstance(Handle<JSObject>::cast(to));
84   }
85 
86   Isolate* isolate = to->GetIsolate();
87   Handle<Map> map(JSReceiver::cast(*next_source)->map(), isolate);
88 
89   if (!map->IsJSObjectMap()) return Just(false);
90   if (!map->OnlyHasSimpleProperties()) return Just(false);
91 
92   Handle<JSObject> from = Handle<JSObject>::cast(next_source);
93   if (from->elements() != isolate->heap()->empty_fixed_array()) {
94     return Just(false);
95   }
96 
97   Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate);
98   int length = map->NumberOfOwnDescriptors();
99 
100   bool stable = true;
101 
102   for (int i = 0; i < length; i++) {
103     Handle<Name> next_key(descriptors->GetKey(i), isolate);
104     Handle<Object> prop_value;
105     // Directly decode from the descriptor array if |from| did not change shape.
106     if (stable) {
107       PropertyDetails details = descriptors->GetDetails(i);
108       if (!details.IsEnumerable()) continue;
109       if (details.kind() == kData) {
110         if (details.location() == kDescriptor) {
111           prop_value = handle(descriptors->GetValue(i), isolate);
112         } else {
113           Representation representation = details.representation();
114           FieldIndex index = FieldIndex::ForDescriptor(*map, i);
115           prop_value = JSObject::FastPropertyAt(from, representation, index);
116         }
117       } else {
118         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
119             isolate, prop_value, JSReceiver::GetProperty(from, next_key),
120             Nothing<bool>());
121         stable = from->map() == *map;
122       }
123     } else {
124       // If the map did change, do a slower lookup. We are still guaranteed that
125       // the object has a simple shape, and that the key is a name.
126       LookupIterator it(from, next_key, from,
127                         LookupIterator::OWN_SKIP_INTERCEPTOR);
128       if (!it.IsFound()) continue;
129       DCHECK(it.state() == LookupIterator::DATA ||
130              it.state() == LookupIterator::ACCESSOR);
131       if (!it.IsEnumerable()) continue;
132       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
133           isolate, prop_value, Object::GetProperty(&it), Nothing<bool>());
134     }
135     LookupIterator it(to, next_key, to);
136     bool call_to_js = it.IsFound() && it.state() != LookupIterator::DATA;
137     Maybe<bool> result = Object::SetProperty(
138         &it, prop_value, STRICT, Object::CERTAINLY_NOT_STORE_FROM_KEYED);
139     if (result.IsNothing()) return result;
140     if (stable && call_to_js) stable = from->map() == *map;
141   }
142 
143   return Just(true);
144 }
145 
146 }  // namespace
147 
148 // ES6 19.1.2.1 Object.assign
BUILTIN(ObjectAssign)149 BUILTIN(ObjectAssign) {
150   HandleScope scope(isolate);
151   Handle<Object> target = args.atOrUndefined(isolate, 1);
152 
153   // 1. Let to be ? ToObject(target).
154   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, target,
155                                      Object::ToObject(isolate, target));
156   Handle<JSReceiver> to = Handle<JSReceiver>::cast(target);
157   // 2. If only one argument was passed, return to.
158   if (args.length() == 2) return *to;
159   // 3. Let sources be the List of argument values starting with the
160   //    second argument.
161   // 4. For each element nextSource of sources, in ascending index order,
162   for (int i = 2; i < args.length(); ++i) {
163     Handle<Object> next_source = args.at<Object>(i);
164     Maybe<bool> fast_assign = FastAssign(to, next_source);
165     if (fast_assign.IsNothing()) return isolate->heap()->exception();
166     if (fast_assign.FromJust()) continue;
167     // 4a. If nextSource is undefined or null, let keys be an empty List.
168     // 4b. Else,
169     // 4b i. Let from be ToObject(nextSource).
170     // Only non-empty strings and JSReceivers have enumerable properties.
171     Handle<JSReceiver> from =
172         Object::ToObject(isolate, next_source).ToHandleChecked();
173     // 4b ii. Let keys be ? from.[[OwnPropertyKeys]]().
174     Handle<FixedArray> keys;
175     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
176         isolate, keys, KeyAccumulator::GetKeys(
177                            from, KeyCollectionMode::kOwnOnly, ALL_PROPERTIES,
178                            GetKeysConversion::kKeepNumbers));
179     // 4c. Repeat for each element nextKey of keys in List order,
180     for (int j = 0; j < keys->length(); ++j) {
181       Handle<Object> next_key(keys->get(j), isolate);
182       // 4c i. Let desc be ? from.[[GetOwnProperty]](nextKey).
183       PropertyDescriptor desc;
184       Maybe<bool> found =
185           JSReceiver::GetOwnPropertyDescriptor(isolate, from, next_key, &desc);
186       if (found.IsNothing()) return isolate->heap()->exception();
187       // 4c ii. If desc is not undefined and desc.[[Enumerable]] is true, then
188       if (found.FromJust() && desc.enumerable()) {
189         // 4c ii 1. Let propValue be ? Get(from, nextKey).
190         Handle<Object> prop_value;
191         ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
192             isolate, prop_value,
193             Runtime::GetObjectProperty(isolate, from, next_key));
194         // 4c ii 2. Let status be ? Set(to, nextKey, propValue, true).
195         Handle<Object> status;
196         ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
197             isolate, status, Runtime::SetObjectProperty(isolate, to, next_key,
198                                                         prop_value, STRICT));
199       }
200     }
201   }
202   // 5. Return to.
203   return *to;
204 }
205 
206 // ES6 section 19.1.3.4 Object.prototype.propertyIsEnumerable ( V )
BUILTIN(ObjectPrototypePropertyIsEnumerable)207 BUILTIN(ObjectPrototypePropertyIsEnumerable) {
208   HandleScope scope(isolate);
209   Handle<JSReceiver> object;
210   Handle<Name> name;
211   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
212       isolate, name, Object::ToName(isolate, args.atOrUndefined(isolate, 1)));
213   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
214       isolate, object, JSReceiver::ToObject(isolate, args.receiver()));
215   Maybe<PropertyAttributes> maybe =
216       JSReceiver::GetOwnPropertyAttributes(object, name);
217   if (!maybe.IsJust()) return isolate->heap()->exception();
218   if (maybe.FromJust() == ABSENT) return isolate->heap()->false_value();
219   return isolate->heap()->ToBoolean((maybe.FromJust() & DONT_ENUM) == 0);
220 }
221 
222 namespace {  // anonymous namespace for ObjectProtoToString()
223 
IsString(CodeStubAssembler * assembler,compiler::Node * object,CodeStubAssembler::Label * if_string,CodeStubAssembler::Label * if_notstring)224 void IsString(CodeStubAssembler* assembler, compiler::Node* object,
225               CodeStubAssembler::Label* if_string,
226               CodeStubAssembler::Label* if_notstring) {
227   typedef compiler::Node Node;
228   typedef CodeStubAssembler::Label Label;
229 
230   Label if_notsmi(assembler);
231   assembler->Branch(assembler->TaggedIsSmi(object), if_notstring, &if_notsmi);
232 
233   assembler->Bind(&if_notsmi);
234   {
235     Node* instance_type = assembler->LoadInstanceType(object);
236 
237     assembler->Branch(assembler->IsStringInstanceType(instance_type), if_string,
238                       if_notstring);
239   }
240 }
241 
ReturnToStringFormat(CodeStubAssembler * assembler,compiler::Node * context,compiler::Node * string)242 void ReturnToStringFormat(CodeStubAssembler* assembler, compiler::Node* context,
243                           compiler::Node* string) {
244   typedef compiler::Node Node;
245 
246   Node* lhs = assembler->HeapConstant(
247       assembler->factory()->NewStringFromStaticChars("[object "));
248   Node* rhs = assembler->HeapConstant(
249       assembler->factory()->NewStringFromStaticChars("]"));
250 
251   Callable callable = CodeFactory::StringAdd(
252       assembler->isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED);
253 
254   assembler->Return(assembler->CallStub(
255       callable, context, assembler->CallStub(callable, context, lhs, string),
256       rhs));
257 }
258 
ReturnIfPrimitive(CodeStubAssembler * assembler,compiler::Node * instance_type,CodeStubAssembler::Label * return_string,CodeStubAssembler::Label * return_boolean,CodeStubAssembler::Label * return_number)259 void ReturnIfPrimitive(CodeStubAssembler* assembler,
260                        compiler::Node* instance_type,
261                        CodeStubAssembler::Label* return_string,
262                        CodeStubAssembler::Label* return_boolean,
263                        CodeStubAssembler::Label* return_number) {
264   assembler->GotoIf(assembler->IsStringInstanceType(instance_type),
265                     return_string);
266 
267   assembler->GotoIf(assembler->Word32Equal(
268                         instance_type, assembler->Int32Constant(ODDBALL_TYPE)),
269                     return_boolean);
270 
271   assembler->GotoIf(
272       assembler->Word32Equal(instance_type,
273                              assembler->Int32Constant(HEAP_NUMBER_TYPE)),
274       return_number);
275 }
276 
277 }  // namespace
278 
279 // ES6 section 19.1.3.6 Object.prototype.toString
Generate_ObjectProtoToString(CodeStubAssembler * assembler)280 void Builtins::Generate_ObjectProtoToString(CodeStubAssembler* assembler) {
281   typedef compiler::Node Node;
282   typedef CodeStubAssembler::Label Label;
283   typedef CodeStubAssembler::Variable Variable;
284 
285   Label return_undefined(assembler, Label::kDeferred),
286       return_null(assembler, Label::kDeferred),
287       return_arguments(assembler, Label::kDeferred), return_array(assembler),
288       return_api(assembler, Label::kDeferred), return_object(assembler),
289       return_regexp(assembler), return_function(assembler),
290       return_error(assembler), return_date(assembler), return_string(assembler),
291       return_boolean(assembler), return_jsvalue(assembler),
292       return_jsproxy(assembler, Label::kDeferred), return_number(assembler);
293 
294   Label if_isproxy(assembler, Label::kDeferred);
295 
296   Label checkstringtag(assembler);
297   Label if_tostringtag(assembler), if_notostringtag(assembler);
298 
299   Node* receiver = assembler->Parameter(0);
300   Node* context = assembler->Parameter(3);
301 
302   assembler->GotoIf(
303       assembler->WordEqual(receiver, assembler->UndefinedConstant()),
304       &return_undefined);
305 
306   assembler->GotoIf(assembler->WordEqual(receiver, assembler->NullConstant()),
307                     &return_null);
308 
309   assembler->GotoIf(assembler->TaggedIsSmi(receiver), &return_number);
310 
311   Node* receiver_instance_type = assembler->LoadInstanceType(receiver);
312   ReturnIfPrimitive(assembler, receiver_instance_type, &return_string,
313                     &return_boolean, &return_number);
314 
315   // for proxies, check IsArray before getting @@toStringTag
316   Variable var_proxy_is_array(assembler, MachineRepresentation::kTagged);
317   var_proxy_is_array.Bind(assembler->BooleanConstant(false));
318 
319   assembler->Branch(
320       assembler->Word32Equal(receiver_instance_type,
321                              assembler->Int32Constant(JS_PROXY_TYPE)),
322       &if_isproxy, &checkstringtag);
323 
324   assembler->Bind(&if_isproxy);
325   {
326     // This can throw
327     var_proxy_is_array.Bind(
328         assembler->CallRuntime(Runtime::kArrayIsArray, context, receiver));
329     assembler->Goto(&checkstringtag);
330   }
331 
332   assembler->Bind(&checkstringtag);
333   {
334     Node* to_string_tag_symbol = assembler->HeapConstant(
335         assembler->isolate()->factory()->to_string_tag_symbol());
336 
337     GetPropertyStub stub(assembler->isolate());
338     Callable get_property =
339         Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
340     Node* to_string_tag_value = assembler->CallStub(
341         get_property, context, receiver, to_string_tag_symbol);
342 
343     IsString(assembler, to_string_tag_value, &if_tostringtag,
344              &if_notostringtag);
345 
346     assembler->Bind(&if_tostringtag);
347     ReturnToStringFormat(assembler, context, to_string_tag_value);
348   }
349   assembler->Bind(&if_notostringtag);
350   {
351     size_t const kNumCases = 11;
352     Label* case_labels[kNumCases];
353     int32_t case_values[kNumCases];
354     case_labels[0] = &return_api;
355     case_values[0] = JS_API_OBJECT_TYPE;
356     case_labels[1] = &return_api;
357     case_values[1] = JS_SPECIAL_API_OBJECT_TYPE;
358     case_labels[2] = &return_arguments;
359     case_values[2] = JS_ARGUMENTS_TYPE;
360     case_labels[3] = &return_array;
361     case_values[3] = JS_ARRAY_TYPE;
362     case_labels[4] = &return_function;
363     case_values[4] = JS_BOUND_FUNCTION_TYPE;
364     case_labels[5] = &return_function;
365     case_values[5] = JS_FUNCTION_TYPE;
366     case_labels[6] = &return_error;
367     case_values[6] = JS_ERROR_TYPE;
368     case_labels[7] = &return_date;
369     case_values[7] = JS_DATE_TYPE;
370     case_labels[8] = &return_regexp;
371     case_values[8] = JS_REGEXP_TYPE;
372     case_labels[9] = &return_jsvalue;
373     case_values[9] = JS_VALUE_TYPE;
374     case_labels[10] = &return_jsproxy;
375     case_values[10] = JS_PROXY_TYPE;
376 
377     assembler->Switch(receiver_instance_type, &return_object, case_values,
378                       case_labels, arraysize(case_values));
379 
380     assembler->Bind(&return_undefined);
381     assembler->Return(assembler->HeapConstant(
382         assembler->isolate()->factory()->undefined_to_string()));
383 
384     assembler->Bind(&return_null);
385     assembler->Return(assembler->HeapConstant(
386         assembler->isolate()->factory()->null_to_string()));
387 
388     assembler->Bind(&return_number);
389     assembler->Return(assembler->HeapConstant(
390         assembler->isolate()->factory()->number_to_string()));
391 
392     assembler->Bind(&return_string);
393     assembler->Return(assembler->HeapConstant(
394         assembler->isolate()->factory()->string_to_string()));
395 
396     assembler->Bind(&return_boolean);
397     assembler->Return(assembler->HeapConstant(
398         assembler->isolate()->factory()->boolean_to_string()));
399 
400     assembler->Bind(&return_arguments);
401     assembler->Return(assembler->HeapConstant(
402         assembler->isolate()->factory()->arguments_to_string()));
403 
404     assembler->Bind(&return_array);
405     assembler->Return(assembler->HeapConstant(
406         assembler->isolate()->factory()->array_to_string()));
407 
408     assembler->Bind(&return_function);
409     assembler->Return(assembler->HeapConstant(
410         assembler->isolate()->factory()->function_to_string()));
411 
412     assembler->Bind(&return_error);
413     assembler->Return(assembler->HeapConstant(
414         assembler->isolate()->factory()->error_to_string()));
415 
416     assembler->Bind(&return_date);
417     assembler->Return(assembler->HeapConstant(
418         assembler->isolate()->factory()->date_to_string()));
419 
420     assembler->Bind(&return_regexp);
421     assembler->Return(assembler->HeapConstant(
422         assembler->isolate()->factory()->regexp_to_string()));
423 
424     assembler->Bind(&return_api);
425     {
426       Node* class_name =
427           assembler->CallRuntime(Runtime::kClassOf, context, receiver);
428       ReturnToStringFormat(assembler, context, class_name);
429     }
430 
431     assembler->Bind(&return_jsvalue);
432     {
433       Node* value = assembler->LoadJSValueValue(receiver);
434       assembler->GotoIf(assembler->TaggedIsSmi(value), &return_number);
435 
436       ReturnIfPrimitive(assembler, assembler->LoadInstanceType(value),
437                         &return_string, &return_boolean, &return_number);
438       assembler->Goto(&return_object);
439     }
440 
441     assembler->Bind(&return_jsproxy);
442     {
443       assembler->GotoIf(assembler->WordEqual(var_proxy_is_array.value(),
444                                              assembler->BooleanConstant(true)),
445                         &return_array);
446 
447       Node* map = assembler->LoadMap(receiver);
448 
449       // Return object if the proxy {receiver} is not callable.
450       assembler->Branch(assembler->IsCallableMap(map), &return_function,
451                         &return_object);
452     }
453 
454     // Default
455     assembler->Bind(&return_object);
456     assembler->Return(assembler->HeapConstant(
457         assembler->isolate()->factory()->object_to_string()));
458   }
459 }
460 
Generate_ObjectCreate(CodeStubAssembler * a)461 void Builtins::Generate_ObjectCreate(CodeStubAssembler* a) {
462   typedef compiler::Node Node;
463   typedef CodeStubAssembler::Label Label;
464   typedef CodeStubAssembler::Variable Variable;
465 
466   Node* prototype = a->Parameter(1);
467   Node* properties = a->Parameter(2);
468   Node* context = a->Parameter(3 + 2);
469 
470   Label call_runtime(a, Label::kDeferred), prototype_valid(a), no_properties(a);
471   {
472     a->Comment("Argument 1 check: prototype");
473     a->GotoIf(a->WordEqual(prototype, a->NullConstant()), &prototype_valid);
474     a->BranchIfJSReceiver(prototype, &prototype_valid, &call_runtime);
475   }
476 
477   a->Bind(&prototype_valid);
478   {
479     a->Comment("Argument 2 check: properties");
480     // Check that we have a simple object
481     a->GotoIf(a->TaggedIsSmi(properties), &call_runtime);
482     // Undefined implies no properties.
483     a->GotoIf(a->WordEqual(properties, a->UndefinedConstant()), &no_properties);
484     Node* properties_map = a->LoadMap(properties);
485     a->GotoIf(a->IsSpecialReceiverMap(properties_map), &call_runtime);
486     // Stay on the fast path only if there are no elements.
487     a->GotoUnless(a->WordEqual(a->LoadElements(properties),
488                                a->LoadRoot(Heap::kEmptyFixedArrayRootIndex)),
489                   &call_runtime);
490     // Handle dictionary objects or fast objects with properties in runtime.
491     Node* bit_field3 = a->LoadMapBitField3(properties_map);
492     a->GotoIf(a->IsSetWord32<Map::DictionaryMap>(bit_field3), &call_runtime);
493     a->Branch(a->IsSetWord32<Map::NumberOfOwnDescriptorsBits>(bit_field3),
494               &call_runtime, &no_properties);
495   }
496 
497   // Create a new object with the given prototype.
498   a->Bind(&no_properties);
499   {
500     Variable map(a, MachineRepresentation::kTagged);
501     Variable properties(a, MachineRepresentation::kTagged);
502     Label non_null_proto(a), instantiate_map(a), good(a);
503 
504     a->Branch(a->WordEqual(prototype, a->NullConstant()), &good,
505               &non_null_proto);
506 
507     a->Bind(&good);
508     {
509       map.Bind(a->LoadContextElement(
510           context, Context::SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP));
511       properties.Bind(
512           a->AllocateNameDictionary(NameDictionary::kInitialCapacity));
513       a->Goto(&instantiate_map);
514     }
515 
516     a->Bind(&non_null_proto);
517     {
518       properties.Bind(a->EmptyFixedArrayConstant());
519       Node* object_function =
520           a->LoadContextElement(context, Context::OBJECT_FUNCTION_INDEX);
521       Node* object_function_map = a->LoadObjectField(
522           object_function, JSFunction::kPrototypeOrInitialMapOffset);
523       map.Bind(object_function_map);
524       a->GotoIf(a->WordEqual(prototype, a->LoadMapPrototype(map.value())),
525                 &instantiate_map);
526       // Try loading the prototype info.
527       Node* prototype_info =
528           a->LoadMapPrototypeInfo(a->LoadMap(prototype), &call_runtime);
529       a->Comment("Load ObjectCreateMap from PrototypeInfo");
530       Node* weak_cell =
531           a->LoadObjectField(prototype_info, PrototypeInfo::kObjectCreateMap);
532       a->GotoIf(a->WordEqual(weak_cell, a->UndefinedConstant()), &call_runtime);
533       map.Bind(a->LoadWeakCellValue(weak_cell, &call_runtime));
534       a->Goto(&instantiate_map);
535     }
536 
537     a->Bind(&instantiate_map);
538     {
539       Node* instance =
540           a->AllocateJSObjectFromMap(map.value(), properties.value());
541       a->Return(instance);
542     }
543   }
544 
545   a->Bind(&call_runtime);
546   {
547     a->Return(
548         a->CallRuntime(Runtime::kObjectCreate, context, prototype, properties));
549   }
550 }
551 
552 // ES6 section 19.1.2.3 Object.defineProperties
BUILTIN(ObjectDefineProperties)553 BUILTIN(ObjectDefineProperties) {
554   HandleScope scope(isolate);
555   DCHECK_EQ(3, args.length());
556   Handle<Object> target = args.at<Object>(1);
557   Handle<Object> properties = args.at<Object>(2);
558 
559   RETURN_RESULT_OR_FAILURE(
560       isolate, JSReceiver::DefineProperties(isolate, target, properties));
561 }
562 
563 // ES6 section 19.1.2.4 Object.defineProperty
BUILTIN(ObjectDefineProperty)564 BUILTIN(ObjectDefineProperty) {
565   HandleScope scope(isolate);
566   DCHECK_EQ(4, args.length());
567   Handle<Object> target = args.at<Object>(1);
568   Handle<Object> key = args.at<Object>(2);
569   Handle<Object> attributes = args.at<Object>(3);
570 
571   return JSReceiver::DefineProperty(isolate, target, key, attributes);
572 }
573 
574 namespace {
575 
576 template <AccessorComponent which_accessor>
ObjectDefineAccessor(Isolate * isolate,Handle<Object> object,Handle<Object> name,Handle<Object> accessor)577 Object* ObjectDefineAccessor(Isolate* isolate, Handle<Object> object,
578                              Handle<Object> name, Handle<Object> accessor) {
579   // 1. Let O be ? ToObject(this value).
580   Handle<JSReceiver> receiver;
581   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
582                                      Object::ConvertReceiver(isolate, object));
583   // 2. If IsCallable(getter) is false, throw a TypeError exception.
584   if (!accessor->IsCallable()) {
585     MessageTemplate::Template message =
586         which_accessor == ACCESSOR_GETTER
587             ? MessageTemplate::kObjectGetterExpectingFunction
588             : MessageTemplate::kObjectSetterExpectingFunction;
589     THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewTypeError(message));
590   }
591   // 3. Let desc be PropertyDescriptor{[[Get]]: getter, [[Enumerable]]: true,
592   //                                   [[Configurable]]: true}.
593   PropertyDescriptor desc;
594   if (which_accessor == ACCESSOR_GETTER) {
595     desc.set_get(accessor);
596   } else {
597     DCHECK(which_accessor == ACCESSOR_SETTER);
598     desc.set_set(accessor);
599   }
600   desc.set_enumerable(true);
601   desc.set_configurable(true);
602   // 4. Let key be ? ToPropertyKey(P).
603   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
604                                      Object::ToPropertyKey(isolate, name));
605   // 5. Perform ? DefinePropertyOrThrow(O, key, desc).
606   // To preserve legacy behavior, we ignore errors silently rather than
607   // throwing an exception.
608   Maybe<bool> success = JSReceiver::DefineOwnProperty(
609       isolate, receiver, name, &desc, Object::DONT_THROW);
610   MAYBE_RETURN(success, isolate->heap()->exception());
611   if (!success.FromJust()) {
612     isolate->CountUsage(v8::Isolate::kDefineGetterOrSetterWouldThrow);
613   }
614   // 6. Return undefined.
615   return isolate->heap()->undefined_value();
616 }
617 
ObjectLookupAccessor(Isolate * isolate,Handle<Object> object,Handle<Object> key,AccessorComponent component)618 Object* ObjectLookupAccessor(Isolate* isolate, Handle<Object> object,
619                              Handle<Object> key, AccessorComponent component) {
620   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, object,
621                                      Object::ConvertReceiver(isolate, object));
622   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key,
623                                      Object::ToPropertyKey(isolate, key));
624   bool success = false;
625   LookupIterator it = LookupIterator::PropertyOrElement(
626       isolate, object, key, &success,
627       LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
628   DCHECK(success);
629 
630   for (; it.IsFound(); it.Next()) {
631     switch (it.state()) {
632       case LookupIterator::INTERCEPTOR:
633       case LookupIterator::NOT_FOUND:
634       case LookupIterator::TRANSITION:
635         UNREACHABLE();
636 
637       case LookupIterator::ACCESS_CHECK:
638         if (it.HasAccess()) continue;
639         isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>());
640         RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
641         return isolate->heap()->undefined_value();
642 
643       case LookupIterator::JSPROXY:
644         return isolate->heap()->undefined_value();
645 
646       case LookupIterator::INTEGER_INDEXED_EXOTIC:
647         return isolate->heap()->undefined_value();
648       case LookupIterator::DATA:
649         continue;
650       case LookupIterator::ACCESSOR: {
651         Handle<Object> maybe_pair = it.GetAccessors();
652         if (maybe_pair->IsAccessorPair()) {
653           return *AccessorPair::GetComponent(
654               Handle<AccessorPair>::cast(maybe_pair), component);
655         }
656       }
657     }
658   }
659 
660   return isolate->heap()->undefined_value();
661 }
662 
663 }  // namespace
664 
665 // ES6 B.2.2.2 a.k.a.
666 // https://tc39.github.io/ecma262/#sec-object.prototype.__defineGetter__
BUILTIN(ObjectDefineGetter)667 BUILTIN(ObjectDefineGetter) {
668   HandleScope scope(isolate);
669   Handle<Object> object = args.at<Object>(0);  // Receiver.
670   Handle<Object> name = args.at<Object>(1);
671   Handle<Object> getter = args.at<Object>(2);
672   return ObjectDefineAccessor<ACCESSOR_GETTER>(isolate, object, name, getter);
673 }
674 
675 // ES6 B.2.2.3 a.k.a.
676 // https://tc39.github.io/ecma262/#sec-object.prototype.__defineSetter__
BUILTIN(ObjectDefineSetter)677 BUILTIN(ObjectDefineSetter) {
678   HandleScope scope(isolate);
679   Handle<Object> object = args.at<Object>(0);  // Receiver.
680   Handle<Object> name = args.at<Object>(1);
681   Handle<Object> setter = args.at<Object>(2);
682   return ObjectDefineAccessor<ACCESSOR_SETTER>(isolate, object, name, setter);
683 }
684 
685 // ES6 B.2.2.4 a.k.a.
686 // https://tc39.github.io/ecma262/#sec-object.prototype.__lookupGetter__
BUILTIN(ObjectLookupGetter)687 BUILTIN(ObjectLookupGetter) {
688   HandleScope scope(isolate);
689   Handle<Object> object = args.at<Object>(0);
690   Handle<Object> name = args.at<Object>(1);
691   return ObjectLookupAccessor(isolate, object, name, ACCESSOR_GETTER);
692 }
693 
694 // ES6 B.2.2.5 a.k.a.
695 // https://tc39.github.io/ecma262/#sec-object.prototype.__lookupSetter__
BUILTIN(ObjectLookupSetter)696 BUILTIN(ObjectLookupSetter) {
697   HandleScope scope(isolate);
698   Handle<Object> object = args.at<Object>(0);
699   Handle<Object> name = args.at<Object>(1);
700   return ObjectLookupAccessor(isolate, object, name, ACCESSOR_SETTER);
701 }
702 
703 // ES6 section 19.1.2.5 Object.freeze ( O )
BUILTIN(ObjectFreeze)704 BUILTIN(ObjectFreeze) {
705   HandleScope scope(isolate);
706   Handle<Object> object = args.atOrUndefined(isolate, 1);
707   if (object->IsJSReceiver()) {
708     MAYBE_RETURN(JSReceiver::SetIntegrityLevel(Handle<JSReceiver>::cast(object),
709                                                FROZEN, Object::THROW_ON_ERROR),
710                  isolate->heap()->exception());
711   }
712   return *object;
713 }
714 
715 // ES section 19.1.2.9 Object.getPrototypeOf ( O )
BUILTIN(ObjectGetPrototypeOf)716 BUILTIN(ObjectGetPrototypeOf) {
717   HandleScope scope(isolate);
718   Handle<Object> object = args.atOrUndefined(isolate, 1);
719 
720   Handle<JSReceiver> receiver;
721   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
722                                      Object::ToObject(isolate, object));
723 
724   RETURN_RESULT_OR_FAILURE(isolate,
725                            JSReceiver::GetPrototype(isolate, receiver));
726 }
727 
728 // ES6 section 19.1.2.21 Object.setPrototypeOf ( O, proto )
BUILTIN(ObjectSetPrototypeOf)729 BUILTIN(ObjectSetPrototypeOf) {
730   HandleScope scope(isolate);
731 
732   // 1. Let O be ? RequireObjectCoercible(O).
733   Handle<Object> object = args.atOrUndefined(isolate, 1);
734   if (object->IsNull(isolate) || object->IsUndefined(isolate)) {
735     THROW_NEW_ERROR_RETURN_FAILURE(
736         isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined,
737                               isolate->factory()->NewStringFromAsciiChecked(
738                                   "Object.setPrototypeOf")));
739   }
740 
741   // 2. If Type(proto) is neither Object nor Null, throw a TypeError exception.
742   Handle<Object> proto = args.atOrUndefined(isolate, 2);
743   if (!proto->IsNull(isolate) && !proto->IsJSReceiver()) {
744     THROW_NEW_ERROR_RETURN_FAILURE(
745         isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, proto));
746   }
747 
748   // 3. If Type(O) is not Object, return O.
749   if (!object->IsJSReceiver()) return *object;
750   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
751 
752   // 4. Let status be ? O.[[SetPrototypeOf]](proto).
753   // 5. If status is false, throw a TypeError exception.
754   MAYBE_RETURN(
755       JSReceiver::SetPrototype(receiver, proto, true, Object::THROW_ON_ERROR),
756       isolate->heap()->exception());
757 
758   // 6. Return O.
759   return *receiver;
760 }
761 
762 // ES6 section B.2.2.1.1 get Object.prototype.__proto__
BUILTIN(ObjectPrototypeGetProto)763 BUILTIN(ObjectPrototypeGetProto) {
764   HandleScope scope(isolate);
765   // 1. Let O be ? ToObject(this value).
766   Handle<JSReceiver> receiver;
767   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
768       isolate, receiver, Object::ToObject(isolate, args.receiver()));
769 
770   // 2. Return ? O.[[GetPrototypeOf]]().
771   RETURN_RESULT_OR_FAILURE(isolate,
772                            JSReceiver::GetPrototype(isolate, receiver));
773 }
774 
775 // ES6 section B.2.2.1.2 set Object.prototype.__proto__
BUILTIN(ObjectPrototypeSetProto)776 BUILTIN(ObjectPrototypeSetProto) {
777   HandleScope scope(isolate);
778   // 1. Let O be ? RequireObjectCoercible(this value).
779   Handle<Object> object = args.receiver();
780   if (object->IsNull(isolate) || object->IsUndefined(isolate)) {
781     THROW_NEW_ERROR_RETURN_FAILURE(
782         isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined,
783                               isolate->factory()->NewStringFromAsciiChecked(
784                                   "set Object.prototype.__proto__")));
785   }
786 
787   // 2. If Type(proto) is neither Object nor Null, return undefined.
788   Handle<Object> proto = args.at<Object>(1);
789   if (!proto->IsNull(isolate) && !proto->IsJSReceiver()) {
790     return isolate->heap()->undefined_value();
791   }
792 
793   // 3. If Type(O) is not Object, return undefined.
794   if (!object->IsJSReceiver()) return isolate->heap()->undefined_value();
795   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
796 
797   // 4. Let status be ? O.[[SetPrototypeOf]](proto).
798   // 5. If status is false, throw a TypeError exception.
799   MAYBE_RETURN(
800       JSReceiver::SetPrototype(receiver, proto, true, Object::THROW_ON_ERROR),
801       isolate->heap()->exception());
802 
803   // Return undefined.
804   return isolate->heap()->undefined_value();
805 }
806 
807 // ES6 section 19.1.2.6 Object.getOwnPropertyDescriptor ( O, P )
BUILTIN(ObjectGetOwnPropertyDescriptor)808 BUILTIN(ObjectGetOwnPropertyDescriptor) {
809   HandleScope scope(isolate);
810   // 1. Let obj be ? ToObject(O).
811   Handle<Object> object = args.atOrUndefined(isolate, 1);
812   Handle<JSReceiver> receiver;
813   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
814                                      Object::ToObject(isolate, object));
815   // 2. Let key be ? ToPropertyKey(P).
816   Handle<Object> property = args.atOrUndefined(isolate, 2);
817   Handle<Name> key;
818   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key,
819                                      Object::ToName(isolate, property));
820   // 3. Let desc be ? obj.[[GetOwnProperty]](key).
821   PropertyDescriptor desc;
822   Maybe<bool> found =
823       JSReceiver::GetOwnPropertyDescriptor(isolate, receiver, key, &desc);
824   MAYBE_RETURN(found, isolate->heap()->exception());
825   // 4. Return FromPropertyDescriptor(desc).
826   if (!found.FromJust()) return isolate->heap()->undefined_value();
827   return *desc.ToObject(isolate);
828 }
829 
830 namespace {
831 
GetOwnPropertyKeys(Isolate * isolate,BuiltinArguments args,PropertyFilter filter)832 Object* GetOwnPropertyKeys(Isolate* isolate, BuiltinArguments args,
833                            PropertyFilter filter) {
834   HandleScope scope(isolate);
835   Handle<Object> object = args.atOrUndefined(isolate, 1);
836   Handle<JSReceiver> receiver;
837   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
838                                      Object::ToObject(isolate, object));
839   Handle<FixedArray> keys;
840   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
841       isolate, keys,
842       KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly, filter,
843                               GetKeysConversion::kConvertToString));
844   return *isolate->factory()->NewJSArrayWithElements(keys);
845 }
846 
847 }  // namespace
848 
849 // ES6 section 19.1.2.7 Object.getOwnPropertyNames ( O )
BUILTIN(ObjectGetOwnPropertyNames)850 BUILTIN(ObjectGetOwnPropertyNames) {
851   return GetOwnPropertyKeys(isolate, args, SKIP_SYMBOLS);
852 }
853 
854 // ES6 section 19.1.2.8 Object.getOwnPropertySymbols ( O )
BUILTIN(ObjectGetOwnPropertySymbols)855 BUILTIN(ObjectGetOwnPropertySymbols) {
856   return GetOwnPropertyKeys(isolate, args, SKIP_STRINGS);
857 }
858 
859 // ES#sec-object.is Object.is ( value1, value2 )
BUILTIN(ObjectIs)860 BUILTIN(ObjectIs) {
861   SealHandleScope shs(isolate);
862   DCHECK_EQ(3, args.length());
863   Handle<Object> value1 = args.at<Object>(1);
864   Handle<Object> value2 = args.at<Object>(2);
865   return isolate->heap()->ToBoolean(value1->SameValue(*value2));
866 }
867 
868 // ES6 section 19.1.2.11 Object.isExtensible ( O )
BUILTIN(ObjectIsExtensible)869 BUILTIN(ObjectIsExtensible) {
870   HandleScope scope(isolate);
871   Handle<Object> object = args.atOrUndefined(isolate, 1);
872   Maybe<bool> result =
873       object->IsJSReceiver()
874           ? JSReceiver::IsExtensible(Handle<JSReceiver>::cast(object))
875           : Just(false);
876   MAYBE_RETURN(result, isolate->heap()->exception());
877   return isolate->heap()->ToBoolean(result.FromJust());
878 }
879 
880 // ES6 section 19.1.2.12 Object.isFrozen ( O )
BUILTIN(ObjectIsFrozen)881 BUILTIN(ObjectIsFrozen) {
882   HandleScope scope(isolate);
883   Handle<Object> object = args.atOrUndefined(isolate, 1);
884   Maybe<bool> result = object->IsJSReceiver()
885                            ? JSReceiver::TestIntegrityLevel(
886                                  Handle<JSReceiver>::cast(object), FROZEN)
887                            : Just(true);
888   MAYBE_RETURN(result, isolate->heap()->exception());
889   return isolate->heap()->ToBoolean(result.FromJust());
890 }
891 
892 // ES6 section 19.1.2.13 Object.isSealed ( O )
BUILTIN(ObjectIsSealed)893 BUILTIN(ObjectIsSealed) {
894   HandleScope scope(isolate);
895   Handle<Object> object = args.atOrUndefined(isolate, 1);
896   Maybe<bool> result = object->IsJSReceiver()
897                            ? JSReceiver::TestIntegrityLevel(
898                                  Handle<JSReceiver>::cast(object), SEALED)
899                            : Just(true);
900   MAYBE_RETURN(result, isolate->heap()->exception());
901   return isolate->heap()->ToBoolean(result.FromJust());
902 }
903 
904 // ES6 section 19.1.2.14 Object.keys ( O )
BUILTIN(ObjectKeys)905 BUILTIN(ObjectKeys) {
906   HandleScope scope(isolate);
907   Handle<Object> object = args.atOrUndefined(isolate, 1);
908   Handle<JSReceiver> receiver;
909   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
910                                      Object::ToObject(isolate, object));
911 
912   Handle<FixedArray> keys;
913   int enum_length = receiver->map()->EnumLength();
914   if (enum_length != kInvalidEnumCacheSentinel &&
915       JSObject::cast(*receiver)->elements() ==
916           isolate->heap()->empty_fixed_array()) {
917     DCHECK(receiver->IsJSObject());
918     DCHECK(!JSObject::cast(*receiver)->HasNamedInterceptor());
919     DCHECK(!JSObject::cast(*receiver)->IsAccessCheckNeeded());
920     DCHECK(!receiver->map()->has_hidden_prototype());
921     DCHECK(JSObject::cast(*receiver)->HasFastProperties());
922     if (enum_length == 0) {
923       keys = isolate->factory()->empty_fixed_array();
924     } else {
925       Handle<FixedArray> cache(
926           receiver->map()->instance_descriptors()->GetEnumCache());
927       keys = isolate->factory()->CopyFixedArrayUpTo(cache, enum_length);
928     }
929   } else {
930     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
931         isolate, keys,
932         KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly,
933                                 ENUMERABLE_STRINGS,
934                                 GetKeysConversion::kConvertToString));
935   }
936   return *isolate->factory()->NewJSArrayWithElements(keys, FAST_ELEMENTS);
937 }
938 
BUILTIN(ObjectValues)939 BUILTIN(ObjectValues) {
940   HandleScope scope(isolate);
941   Handle<Object> object = args.atOrUndefined(isolate, 1);
942   Handle<JSReceiver> receiver;
943   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
944                                      Object::ToObject(isolate, object));
945   Handle<FixedArray> values;
946   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
947       isolate, values, JSReceiver::GetOwnValues(receiver, ENUMERABLE_STRINGS));
948   return *isolate->factory()->NewJSArrayWithElements(values);
949 }
950 
BUILTIN(ObjectEntries)951 BUILTIN(ObjectEntries) {
952   HandleScope scope(isolate);
953   Handle<Object> object = args.atOrUndefined(isolate, 1);
954   Handle<JSReceiver> receiver;
955   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
956                                      Object::ToObject(isolate, object));
957   Handle<FixedArray> entries;
958   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
959       isolate, entries,
960       JSReceiver::GetOwnEntries(receiver, ENUMERABLE_STRINGS));
961   return *isolate->factory()->NewJSArrayWithElements(entries);
962 }
963 
BUILTIN(ObjectGetOwnPropertyDescriptors)964 BUILTIN(ObjectGetOwnPropertyDescriptors) {
965   HandleScope scope(isolate);
966   Handle<Object> object = args.atOrUndefined(isolate, 1);
967 
968   Handle<JSReceiver> receiver;
969   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
970                                      Object::ToObject(isolate, object));
971 
972   Handle<FixedArray> keys;
973   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
974       isolate, keys, KeyAccumulator::GetKeys(
975                          receiver, KeyCollectionMode::kOwnOnly, ALL_PROPERTIES,
976                          GetKeysConversion::kConvertToString));
977 
978   Handle<JSObject> descriptors =
979       isolate->factory()->NewJSObject(isolate->object_function());
980 
981   for (int i = 0; i < keys->length(); ++i) {
982     Handle<Name> key = Handle<Name>::cast(FixedArray::get(*keys, i, isolate));
983     PropertyDescriptor descriptor;
984     Maybe<bool> did_get_descriptor = JSReceiver::GetOwnPropertyDescriptor(
985         isolate, receiver, key, &descriptor);
986     MAYBE_RETURN(did_get_descriptor, isolate->heap()->exception());
987 
988     if (!did_get_descriptor.FromJust()) continue;
989     Handle<Object> from_descriptor = descriptor.ToObject(isolate);
990 
991     LookupIterator it = LookupIterator::PropertyOrElement(
992         isolate, descriptors, key, descriptors, LookupIterator::OWN);
993     Maybe<bool> success = JSReceiver::CreateDataProperty(&it, from_descriptor,
994                                                          Object::DONT_THROW);
995     CHECK(success.FromJust());
996   }
997 
998   return *descriptors;
999 }
1000 
1001 // ES6 section 19.1.2.15 Object.preventExtensions ( O )
BUILTIN(ObjectPreventExtensions)1002 BUILTIN(ObjectPreventExtensions) {
1003   HandleScope scope(isolate);
1004   Handle<Object> object = args.atOrUndefined(isolate, 1);
1005   if (object->IsJSReceiver()) {
1006     MAYBE_RETURN(JSReceiver::PreventExtensions(Handle<JSReceiver>::cast(object),
1007                                                Object::THROW_ON_ERROR),
1008                  isolate->heap()->exception());
1009   }
1010   return *object;
1011 }
1012 
1013 // ES6 section 19.1.2.17 Object.seal ( O )
BUILTIN(ObjectSeal)1014 BUILTIN(ObjectSeal) {
1015   HandleScope scope(isolate);
1016   Handle<Object> object = args.atOrUndefined(isolate, 1);
1017   if (object->IsJSReceiver()) {
1018     MAYBE_RETURN(JSReceiver::SetIntegrityLevel(Handle<JSReceiver>::cast(object),
1019                                                SEALED, Object::THROW_ON_ERROR),
1020                  isolate->heap()->exception());
1021   }
1022   return *object;
1023 }
1024 
Generate_HasProperty(CodeStubAssembler * assembler)1025 void Builtins::Generate_HasProperty(CodeStubAssembler* assembler) {
1026   typedef HasPropertyDescriptor Descriptor;
1027   typedef compiler::Node Node;
1028 
1029   Node* key = assembler->Parameter(Descriptor::kKey);
1030   Node* object = assembler->Parameter(Descriptor::kObject);
1031   Node* context = assembler->Parameter(Descriptor::kContext);
1032 
1033   assembler->Return(
1034       assembler->HasProperty(object, key, context, Runtime::kHasProperty));
1035 }
1036 
Generate_ForInFilter(CodeStubAssembler * assembler)1037 void Builtins::Generate_ForInFilter(CodeStubAssembler* assembler) {
1038   typedef compiler::Node Node;
1039   typedef ForInFilterDescriptor Descriptor;
1040 
1041   Node* key = assembler->Parameter(Descriptor::kKey);
1042   Node* object = assembler->Parameter(Descriptor::kObject);
1043   Node* context = assembler->Parameter(Descriptor::kContext);
1044 
1045   assembler->Return(assembler->ForInFilter(key, object, context));
1046 }
1047 
Generate_InstanceOf(CodeStubAssembler * assembler)1048 void Builtins::Generate_InstanceOf(CodeStubAssembler* assembler) {
1049   typedef compiler::Node Node;
1050   typedef CompareDescriptor Descriptor;
1051   Node* object = assembler->Parameter(Descriptor::kLeft);
1052   Node* callable = assembler->Parameter(Descriptor::kRight);
1053   Node* context = assembler->Parameter(Descriptor::kContext);
1054 
1055   assembler->Return(assembler->InstanceOf(object, callable, context));
1056 }
1057 
1058 // ES6 section 7.3.19 OrdinaryHasInstance ( C, O )
Generate_OrdinaryHasInstance(CodeStubAssembler * assembler)1059 void Builtins::Generate_OrdinaryHasInstance(CodeStubAssembler* assembler) {
1060   typedef compiler::Node Node;
1061   typedef CompareDescriptor Descriptor;
1062 
1063   Node* constructor = assembler->Parameter(Descriptor::kLeft);
1064   Node* object = assembler->Parameter(Descriptor::kRight);
1065   Node* context = assembler->Parameter(Descriptor::kContext);
1066 
1067   assembler->Return(
1068       assembler->OrdinaryHasInstance(context, constructor, object));
1069 }
1070 
1071 }  // namespace internal
1072 }  // namespace v8
1073