V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
runtime-object.cc
1 // Copyright 2014 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/arguments-inl.h"
6 #include "src/bootstrapper.h"
7 #include "src/counters.h"
8 #include "src/debug/debug.h"
9 #include "src/isolate-inl.h"
10 #include "src/message-template.h"
11 #include "src/objects/hash-table-inl.h"
12 #include "src/objects/js-array-inl.h"
13 #include "src/objects/property-descriptor-object.h"
14 #include "src/property-descriptor.h"
15 #include "src/runtime/runtime-utils.h"
16 #include "src/runtime/runtime.h"
17 
18 namespace v8 {
19 namespace internal {
20 
21 MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
22  Handle<Object> object,
23  Handle<Object> key,
24  bool* is_found_out) {
25  if (object->IsNullOrUndefined(isolate)) {
26  if (*key == ReadOnlyRoots(isolate).iterator_symbol()) {
27  return Runtime::ThrowIteratorError(isolate, object);
28  }
29  THROW_NEW_ERROR(
30  isolate,
31  NewTypeError(MessageTemplate::kNonObjectPropertyLoad, key, object),
32  Object);
33  }
34 
35  bool success = false;
36  LookupIterator it =
37  LookupIterator::PropertyOrElement(isolate, object, key, &success);
38  if (!success) return MaybeHandle<Object>();
39 
40  MaybeHandle<Object> result = Object::GetProperty(&it);
41  if (is_found_out) *is_found_out = it.IsFound();
42 
43  if (!it.IsFound() && key->IsSymbol() &&
44  Symbol::cast(*key)->is_private_name()) {
45  THROW_NEW_ERROR(
46  isolate,
47  NewTypeError(MessageTemplate::kInvalidPrivateFieldAccess, key, object),
48  Object);
49  }
50  return result;
51 }
52 
53 namespace {
54 
55 bool DeleteObjectPropertyFast(Isolate* isolate, Handle<JSReceiver> receiver,
56  Handle<Object> raw_key) {
57  DisallowHeapAllocation no_allocation;
58  // This implements a special case for fast property deletion: when the
59  // last property in an object is deleted, then instead of normalizing
60  // the properties, we can undo the last map transition, with a few
61  // prerequisites:
62  // (1) The receiver must be a regular object and the key a unique name.
63  Map map = receiver->map();
64  if (map->IsSpecialReceiverMap()) return false;
65  if (!raw_key->IsUniqueName()) return false;
66  Handle<Name> key = Handle<Name>::cast(raw_key);
67  // (2) The property to be deleted must be the last property.
68  int nof = map->NumberOfOwnDescriptors();
69  if (nof == 0) return false;
70  int descriptor = nof - 1;
71  DescriptorArray* descriptors = map->instance_descriptors();
72  if (descriptors->GetKey(descriptor) != *key) return false;
73  // (3) The property to be deleted must be deletable.
74  PropertyDetails details = descriptors->GetDetails(descriptor);
75  if (!details.IsConfigurable()) return false;
76  // (4) The map must have a back pointer.
77  Object* backpointer = map->GetBackPointer();
78  if (!backpointer->IsMap()) return false;
79  // (5) The last transition must have been caused by adding a property
80  // (and not any kind of special transition).
81  if (Map::cast(backpointer)->NumberOfOwnDescriptors() != nof - 1) return false;
82 
83  // Preconditions successful. No more bailouts after this point.
84 
85  // Zap the property to avoid keeping objects alive. Zapping is not necessary
86  // for properties stored in the descriptor array.
87  if (details.location() == kField) {
88  isolate->heap()->NotifyObjectLayoutChange(*receiver, map->instance_size(),
89  no_allocation);
90  FieldIndex index = FieldIndex::ForPropertyIndex(map, details.field_index());
91  // Special case deleting the last out-of object property.
92  if (!index.is_inobject() && index.outobject_array_index() == 0) {
93  DCHECK(!Map::cast(backpointer)->HasOutOfObjectProperties());
94  // Clear out the properties backing store.
95  receiver->SetProperties(ReadOnlyRoots(isolate).empty_fixed_array());
96  } else {
97  Object* filler = ReadOnlyRoots(isolate).one_pointer_filler_map();
98  JSObject::cast(*receiver)->RawFastPropertyAtPut(index, filler);
99  // We must clear any recorded slot for the deleted property, because
100  // subsequent object modifications might put a raw double there.
101  // Slot clearing is the reason why this entire function cannot currently
102  // be implemented in the DeleteProperty stub.
103  if (index.is_inobject() && !map->IsUnboxedDoubleField(index)) {
104  isolate->heap()->ClearRecordedSlot(
105  *receiver, HeapObject::RawField(*receiver, index.offset()));
106  }
107  }
108  }
109  // If the map was marked stable before, then there could be optimized code
110  // that depends on the assumption that no object that reached this map
111  // transitions away from it without triggering the "deoptimize dependent
112  // code" mechanism.
113  map->NotifyLeafMapLayoutChange(isolate);
114  // Finally, perform the map rollback.
115  receiver->synchronized_set_map(Map::cast(backpointer));
116 #if VERIFY_HEAP
117  receiver->HeapObjectVerify(isolate);
118  receiver->property_array()->PropertyArrayVerify(isolate);
119 #endif
120  return true;
121 }
122 
123 } // namespace
124 
125 Maybe<bool> Runtime::DeleteObjectProperty(Isolate* isolate,
126  Handle<JSReceiver> receiver,
127  Handle<Object> key,
128  LanguageMode language_mode) {
129  if (DeleteObjectPropertyFast(isolate, receiver, key)) return Just(true);
130 
131  bool success = false;
132  LookupIterator it = LookupIterator::PropertyOrElement(
133  isolate, receiver, key, &success, LookupIterator::OWN);
134  if (!success) return Nothing<bool>();
135 
136  return JSReceiver::DeleteProperty(&it, language_mode);
137 }
138 
139 // ES #sec-object.keys
140 RUNTIME_FUNCTION(Runtime_ObjectKeys) {
141  HandleScope scope(isolate);
142  Handle<Object> object = args.at(0);
143 
144  // Convert the {object} to a proper {receiver}.
145  Handle<JSReceiver> receiver;
146  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
147  Object::ToObject(isolate, object));
148 
149  // Collect the own keys for the {receiver}.
150  Handle<FixedArray> keys;
151  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
152  isolate, keys,
153  KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly,
154  ENUMERABLE_STRINGS,
155  GetKeysConversion::kConvertToString));
156  return *keys;
157 }
158 
159 // ES #sec-object.getOwnPropertyNames
160 RUNTIME_FUNCTION(Runtime_ObjectGetOwnPropertyNames) {
161  HandleScope scope(isolate);
162  Handle<Object> object = args.at(0);
163 
164  // Convert the {object} to a proper {receiver}.
165  Handle<JSReceiver> receiver;
166  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
167  Object::ToObject(isolate, object));
168 
169  // Collect the own keys for the {receiver}.
170  Handle<FixedArray> keys;
171  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
172  isolate, keys,
173  KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly,
174  SKIP_SYMBOLS,
175  GetKeysConversion::kConvertToString));
176  return *keys;
177 }
178 
179 RUNTIME_FUNCTION(Runtime_ObjectGetOwnPropertyNamesTryFast) {
180  HandleScope scope(isolate);
181  Handle<Object> object = args.at(0);
182 
183  // Convert the {object} to a proper {receiver}.
184  Handle<JSReceiver> receiver;
185  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
186  Object::ToObject(isolate, object));
187 
188  Handle<Map> map(receiver->map(), isolate);
189 
190  int nod = map->NumberOfOwnDescriptors();
191  Handle<FixedArray> keys;
192  if (nod != 0 && map->NumberOfEnumerableProperties() == nod) {
193  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
194  isolate, keys,
195  KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly,
196  ENUMERABLE_STRINGS,
197  GetKeysConversion::kConvertToString));
198  } else {
199  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
200  isolate, keys,
201  KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly,
202  SKIP_SYMBOLS,
203  GetKeysConversion::kConvertToString));
204  }
205 
206  return *keys;
207 }
208 
209 // ES6 19.1.3.2
210 RUNTIME_FUNCTION(Runtime_ObjectHasOwnProperty) {
211  HandleScope scope(isolate);
212  Handle<Object> property = args.at(1);
213 
214  Handle<Name> key;
215  uint32_t index;
216  bool key_is_array_index = property->ToArrayIndex(&index);
217 
218  if (!key_is_array_index) {
219  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key,
220  Object::ToName(isolate, property));
221  key_is_array_index = key->AsArrayIndex(&index);
222  }
223 
224  Handle<Object> object = args.at(0);
225 
226  if (object->IsJSModuleNamespace()) {
227  if (key.is_null()) {
228  DCHECK(key_is_array_index);
229  // Namespace objects can't have indexed properties.
230  return ReadOnlyRoots(isolate).false_value();
231  }
232 
233  Maybe<bool> result =
234  JSReceiver::HasOwnProperty(Handle<JSReceiver>::cast(object), key);
235  if (!result.IsJust()) return ReadOnlyRoots(isolate).exception();
236  return isolate->heap()->ToBoolean(result.FromJust());
237 
238  } else if (object->IsJSObject()) {
239  Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
240  // Fast case: either the key is a real named property or it is not
241  // an array index and there are no interceptors or hidden
242  // prototypes.
243  // TODO(jkummerow): Make JSReceiver::HasOwnProperty fast enough to
244  // handle all cases directly (without this custom fast path).
245  {
246  LookupIterator::Configuration c = LookupIterator::OWN_SKIP_INTERCEPTOR;
247  LookupIterator it =
248  key_is_array_index ? LookupIterator(isolate, js_obj, index, js_obj, c)
249  : LookupIterator(js_obj, key, js_obj, c);
250  Maybe<bool> maybe = JSReceiver::HasProperty(&it);
251  if (maybe.IsNothing()) return ReadOnlyRoots(isolate).exception();
252  DCHECK(!isolate->has_pending_exception());
253  if (maybe.FromJust()) return ReadOnlyRoots(isolate).true_value();
254  }
255 
256  Map map = js_obj->map();
257  if (!map->has_hidden_prototype() &&
258  (key_is_array_index ? !map->has_indexed_interceptor()
259  : !map->has_named_interceptor())) {
260  return ReadOnlyRoots(isolate).false_value();
261  }
262 
263  // Slow case.
264  LookupIterator::Configuration c = LookupIterator::OWN;
265  LookupIterator it = key_is_array_index
266  ? LookupIterator(isolate, js_obj, index, js_obj, c)
267  : LookupIterator(js_obj, key, js_obj, c);
268 
269  Maybe<bool> maybe = JSReceiver::HasProperty(&it);
270  if (maybe.IsNothing()) return ReadOnlyRoots(isolate).exception();
271  DCHECK(!isolate->has_pending_exception());
272  return isolate->heap()->ToBoolean(maybe.FromJust());
273 
274  } else if (object->IsJSProxy()) {
275  if (key.is_null()) {
276  DCHECK(key_is_array_index);
277  key = isolate->factory()->Uint32ToString(index);
278  }
279 
280  Maybe<bool> result =
281  JSReceiver::HasOwnProperty(Handle<JSProxy>::cast(object), key);
282  if (result.IsNothing()) return ReadOnlyRoots(isolate).exception();
283  return isolate->heap()->ToBoolean(result.FromJust());
284 
285  } else if (object->IsString()) {
286  return isolate->heap()->ToBoolean(
287  key_is_array_index
288  ? index < static_cast<uint32_t>(String::cast(*object)->length())
289  : key->Equals(ReadOnlyRoots(isolate).length_string()));
290  } else if (object->IsNullOrUndefined(isolate)) {
291  THROW_NEW_ERROR_RETURN_FAILURE(
292  isolate, NewTypeError(MessageTemplate::kUndefinedOrNullToObject));
293  }
294 
295  return ReadOnlyRoots(isolate).false_value();
296 }
297 
298 RUNTIME_FUNCTION(Runtime_AddDictionaryProperty) {
299  HandleScope scope(isolate);
300  Handle<JSObject> receiver = args.at<JSObject>(0);
301  Handle<Name> name = args.at<Name>(1);
302  Handle<Object> value = args.at(2);
303 
304  DCHECK(name->IsUniqueName());
305 
306  Handle<NameDictionary> dictionary(receiver->property_dictionary(), isolate);
307  PropertyDetails property_details(kData, NONE, PropertyCellType::kNoCell);
308  dictionary =
309  NameDictionary::Add(isolate, dictionary, name, value, property_details);
310  receiver->SetProperties(*dictionary);
311  return *value;
312 }
313 
314 // ES6 section 19.1.2.2 Object.create ( O [ , Properties ] )
315 // TODO(verwaest): Support the common cases with precached map directly in
316 // an Object.create stub.
317 RUNTIME_FUNCTION(Runtime_ObjectCreate) {
318  HandleScope scope(isolate);
319  Handle<Object> prototype = args.at(0);
320  Handle<Object> properties = args.at(1);
321  Handle<JSObject> obj;
322  // 1. If Type(O) is neither Object nor Null, throw a TypeError exception.
323  if (!prototype->IsNull(isolate) && !prototype->IsJSReceiver()) {
324  THROW_NEW_ERROR_RETURN_FAILURE(
325  isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, prototype));
326  }
327  // 2. Let obj be ObjectCreate(O).
328  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
329  isolate, obj, JSObject::ObjectCreate(isolate, prototype));
330 
331  // 3. If Properties is not undefined, then
332  if (!properties->IsUndefined(isolate)) {
333  // a. Return ? ObjectDefineProperties(obj, Properties).
334  // Define the properties if properties was specified and is not undefined.
335  RETURN_RESULT_OR_FAILURE(
336  isolate, JSReceiver::DefineProperties(isolate, obj, properties));
337  }
338  // 4. Return obj.
339  return *obj;
340 }
341 
342 MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
343  Handle<Object> object,
344  Handle<Object> key,
345  Handle<Object> value,
346  LanguageMode language_mode,
347  StoreOrigin store_origin) {
348  if (object->IsNullOrUndefined(isolate)) {
349  THROW_NEW_ERROR(
350  isolate,
351  NewTypeError(MessageTemplate::kNonObjectPropertyStore, key, object),
352  Object);
353  }
354 
355  // Check if the given key is an array index.
356  bool success = false;
357  LookupIterator it =
358  LookupIterator::PropertyOrElement(isolate, object, key, &success);
359  if (!success) return MaybeHandle<Object>();
360 
361  if (!it.IsFound() && key->IsSymbol() &&
362  Symbol::cast(*key)->is_private_name()) {
363  THROW_NEW_ERROR(
364  isolate,
365  NewTypeError(MessageTemplate::kInvalidPrivateFieldAccess, key, object),
366  Object);
367  }
368 
369  MAYBE_RETURN_NULL(
370  Object::SetProperty(&it, value, language_mode, store_origin));
371 
372  return value;
373 }
374 
375 
376 RUNTIME_FUNCTION(Runtime_InternalSetPrototype) {
377  HandleScope scope(isolate);
378  DCHECK_EQ(2, args.length());
379  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
380  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
381  if (prototype->IsJSFunction()) {
382  Handle<JSFunction> function = Handle<JSFunction>::cast(prototype);
383  if (!function->shared()->HasSharedName()) {
384  Handle<Map> function_map(function->map(), isolate);
385  if (!JSFunction::SetName(function, isolate->factory()->proto_string(),
386  isolate->factory()->empty_string())) {
387  return ReadOnlyRoots(isolate).exception();
388  }
389  CHECK_EQ(*function_map, function->map());
390  }
391  }
392  MAYBE_RETURN(JSReceiver::SetPrototype(obj, prototype, false, kThrowOnError),
393  ReadOnlyRoots(isolate).exception());
394  return *obj;
395 }
396 
397 RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
398  HandleScope scope(isolate);
399  DCHECK_EQ(2, args.length());
400  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
401  CONVERT_SMI_ARG_CHECKED(properties, 1);
402  // Conservative upper limit to prevent fuzz tests from going OOM.
403  if (properties > 100000) return isolate->ThrowIllegalOperation();
404  if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
405  JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties,
406  "OptimizeForAdding");
407  }
408  return *object;
409 }
410 
411 RUNTIME_FUNCTION(Runtime_ObjectValues) {
412  HandleScope scope(isolate);
413  DCHECK_EQ(1, args.length());
414 
415  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
416 
417  Handle<FixedArray> values;
418  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
419  isolate, values,
420  JSReceiver::GetOwnValues(receiver, PropertyFilter::ENUMERABLE_STRINGS,
421  true));
422  return *isolate->factory()->NewJSArrayWithElements(values);
423 }
424 
425 RUNTIME_FUNCTION(Runtime_ObjectValuesSkipFastPath) {
426  HandleScope scope(isolate);
427  DCHECK_EQ(1, args.length());
428 
429  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
430 
431  Handle<FixedArray> value;
432  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
433  isolate, value,
434  JSReceiver::GetOwnValues(receiver, PropertyFilter::ENUMERABLE_STRINGS,
435  false));
436  return *isolate->factory()->NewJSArrayWithElements(value);
437 }
438 
439 RUNTIME_FUNCTION(Runtime_ObjectEntries) {
440  HandleScope scope(isolate);
441  DCHECK_EQ(1, args.length());
442 
443  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
444 
445  Handle<FixedArray> entries;
446  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
447  isolate, entries,
448  JSReceiver::GetOwnEntries(receiver, PropertyFilter::ENUMERABLE_STRINGS,
449  true));
450  return *isolate->factory()->NewJSArrayWithElements(entries);
451 }
452 
453 RUNTIME_FUNCTION(Runtime_ObjectEntriesSkipFastPath) {
454  HandleScope scope(isolate);
455  DCHECK_EQ(1, args.length());
456 
457  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
458 
459  Handle<FixedArray> entries;
460  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
461  isolate, entries,
462  JSReceiver::GetOwnEntries(receiver, PropertyFilter::ENUMERABLE_STRINGS,
463  false));
464  return *isolate->factory()->NewJSArrayWithElements(entries);
465 }
466 
467 RUNTIME_FUNCTION(Runtime_GetProperty) {
468  HandleScope scope(isolate);
469  DCHECK_EQ(2, args.length());
470  CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
471  CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
472 
473  // Fast cases for getting named properties of the receiver JSObject
474  // itself.
475  //
476  // The global proxy objects has to be excluded since LookupOwn on
477  // the global proxy object can return a valid result even though the
478  // global proxy object never has properties. This is the case
479  // because the global proxy object forwards everything to its hidden
480  // prototype including own lookups.
481  //
482  // Additionally, we need to make sure that we do not cache results
483  // for objects that require access checks.
484 
485  // Convert string-index keys to their number variant to avoid internalization
486  // below; and speed up subsequent conversion to index.
487  uint32_t index;
488  if (key_obj->IsString() && String::cast(*key_obj)->AsArrayIndex(&index)) {
489  key_obj = isolate->factory()->NewNumberFromUint(index);
490  }
491  if (receiver_obj->IsJSObject()) {
492  if (!receiver_obj->IsJSGlobalProxy() &&
493  !receiver_obj->IsAccessCheckNeeded() && key_obj->IsName()) {
494  Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
495  Handle<Name> key = Handle<Name>::cast(key_obj);
496  key_obj = key = isolate->factory()->InternalizeName(key);
497 
498  DisallowHeapAllocation no_allocation;
499  if (receiver->IsJSGlobalObject()) {
500  // Attempt dictionary lookup.
501  GlobalDictionary dictionary =
502  JSGlobalObject::cast(*receiver)->global_dictionary();
503  int entry = dictionary->FindEntry(isolate, key);
504  if (entry != GlobalDictionary::kNotFound) {
505  PropertyCell* cell = dictionary->CellAt(entry);
506  if (cell->property_details().kind() == kData) {
507  Object* value = cell->value();
508  if (!value->IsTheHole(isolate)) return value;
509  // If value is the hole (meaning, absent) do the general lookup.
510  }
511  }
512  } else if (!receiver->HasFastProperties()) {
513  // Attempt dictionary lookup.
514  NameDictionary dictionary = receiver->property_dictionary();
515  int entry = dictionary->FindEntry(isolate, key);
516  if ((entry != NameDictionary::kNotFound) &&
517  (dictionary->DetailsAt(entry).kind() == kData)) {
518  return dictionary->ValueAt(entry);
519  }
520  }
521  } else if (key_obj->IsSmi()) {
522  // JSObject without a name key. If the key is a Smi, check for a
523  // definite out-of-bounds access to elements, which is a strong indicator
524  // that subsequent accesses will also call the runtime. Proactively
525  // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
526  // doubles for those future calls in the case that the elements would
527  // become PACKED_DOUBLE_ELEMENTS.
528  Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
529  ElementsKind elements_kind = js_object->GetElementsKind();
530  if (IsDoubleElementsKind(elements_kind)) {
531  if (Smi::ToInt(*key_obj) >= js_object->elements()->length()) {
532  elements_kind = IsHoleyElementsKind(elements_kind) ? HOLEY_ELEMENTS
533  : PACKED_ELEMENTS;
534  JSObject::TransitionElementsKind(js_object, elements_kind);
535  }
536  } else {
537  DCHECK(IsSmiOrObjectElementsKind(elements_kind) ||
538  !IsFastElementsKind(elements_kind));
539  }
540  }
541  } else if (receiver_obj->IsString() && key_obj->IsSmi()) {
542  // Fast case for string indexing using [] with a smi index.
543  Handle<String> str = Handle<String>::cast(receiver_obj);
544  int index = Handle<Smi>::cast(key_obj)->value();
545  if (index >= 0 && index < str->length()) {
546  Factory* factory = isolate->factory();
547  return *factory->LookupSingleCharacterStringFromCode(
548  String::Flatten(isolate, str)->Get(index));
549  }
550  }
551 
552  // Fall back to GetObjectProperty.
553  RETURN_RESULT_OR_FAILURE(
554  isolate, Runtime::GetObjectProperty(isolate, receiver_obj, key_obj));
555 }
556 
557 RUNTIME_FUNCTION(Runtime_AddNamedProperty) {
558  HandleScope scope(isolate);
559  DCHECK_EQ(4, args.length());
560 
561  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
562  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
563  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
564  CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
565 
566 #ifdef DEBUG
567  uint32_t index = 0;
568  DCHECK(!name->ToArrayIndex(&index));
569  LookupIterator it(object, name, object, LookupIterator::OWN_SKIP_INTERCEPTOR);
570  Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
571  if (maybe.IsNothing()) return ReadOnlyRoots(isolate).exception();
572  DCHECK(!it.IsFound());
573 #endif
574 
575  RETURN_RESULT_OR_FAILURE(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
576  object, name, value, attrs));
577 }
578 
579 
580 // Adds an element to an array.
581 // This is used to create an indexed data property into an array.
582 RUNTIME_FUNCTION(Runtime_AddElement) {
583  HandleScope scope(isolate);
584  DCHECK_EQ(3, args.length());
585 
586  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
587  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
588  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
589 
590  uint32_t index = 0;
591  CHECK(key->ToArrayIndex(&index));
592 
593 #ifdef DEBUG
594  LookupIterator it(isolate, object, index, object,
595  LookupIterator::OWN_SKIP_INTERCEPTOR);
596  Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
597  if (maybe.IsNothing()) return ReadOnlyRoots(isolate).exception();
598  DCHECK(!it.IsFound());
599 
600  if (object->IsJSArray()) {
601  Handle<JSArray> array = Handle<JSArray>::cast(object);
602  DCHECK(!JSArray::WouldChangeReadOnlyLength(array, index));
603  }
604 #endif
605 
606  RETURN_RESULT_OR_FAILURE(isolate, JSObject::SetOwnElementIgnoreAttributes(
607  object, index, value, NONE));
608 }
609 
610 RUNTIME_FUNCTION(Runtime_SetKeyedProperty) {
611  HandleScope scope(isolate);
612  DCHECK_EQ(4, args.length());
613 
614  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
615  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
616  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
617  CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 3);
618 
619  RETURN_RESULT_OR_FAILURE(
620  isolate,
621  Runtime::SetObjectProperty(isolate, object, key, value, language_mode,
622  StoreOrigin::kMaybeKeyed));
623 }
624 
625 RUNTIME_FUNCTION(Runtime_SetNamedProperty) {
626  HandleScope scope(isolate);
627  DCHECK_EQ(4, args.length());
628 
629  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
630  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
631  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
632  CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 3);
633 
634  RETURN_RESULT_OR_FAILURE(
635  isolate, Runtime::SetObjectProperty(isolate, object, key, value,
636  language_mode, StoreOrigin::kNamed));
637 }
638 
639 // Similar to DefineDataPropertyInLiteral, but does not update feedback, and
640 // and does not have a flags parameter for performing SetFunctionName().
641 //
642 // Currently, this is used for ObjectLiteral spread properties.
643 RUNTIME_FUNCTION(Runtime_StoreDataPropertyInLiteral) {
644  HandleScope scope(isolate);
645  DCHECK_EQ(3, args.length());
646 
647  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
648  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
649  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
650 
651  bool success;
652  LookupIterator it = LookupIterator::PropertyOrElement(
653  isolate, object, key, &success, LookupIterator::OWN);
654 
655  Maybe<bool> result =
656  JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, NONE, kDontThrow);
657  RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
658  DCHECK(result.IsJust());
659  USE(result);
660 
661  return *value;
662 }
663 
664 namespace {
665 
666 // ES6 section 12.5.4.
667 Object* DeleteProperty(Isolate* isolate, Handle<Object> object,
668  Handle<Object> key, LanguageMode language_mode) {
669  Handle<JSReceiver> receiver;
670  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
671  Object::ToObject(isolate, object));
672  Maybe<bool> result =
673  Runtime::DeleteObjectProperty(isolate, receiver, key, language_mode);
674  MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
675  return isolate->heap()->ToBoolean(result.FromJust());
676 }
677 
678 } // namespace
679 
680 RUNTIME_FUNCTION(Runtime_DeleteProperty) {
681  HandleScope scope(isolate);
682  DCHECK_EQ(3, args.length());
683  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
684  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
685  CONVERT_SMI_ARG_CHECKED(language_mode, 2);
686  return DeleteProperty(isolate, object, key,
687  static_cast<LanguageMode>(language_mode));
688 }
689 
690 RUNTIME_FUNCTION(Runtime_ShrinkPropertyDictionary) {
691  HandleScope scope(isolate);
692  DCHECK_EQ(1, args.length());
693  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
694  Handle<NameDictionary> dictionary(receiver->property_dictionary(), isolate);
695  Handle<NameDictionary> new_properties =
696  NameDictionary::Shrink(isolate, dictionary);
697  receiver->SetProperties(*new_properties);
698  return Smi::kZero;
699 }
700 
701 // ES6 section 12.9.3, operator in.
702 RUNTIME_FUNCTION(Runtime_HasProperty) {
703  HandleScope scope(isolate);
704  DCHECK_EQ(2, args.length());
705  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
706  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
707 
708  // Check that {object} is actually a receiver.
709  if (!object->IsJSReceiver()) {
710  THROW_NEW_ERROR_RETURN_FAILURE(
711  isolate,
712  NewTypeError(MessageTemplate::kInvalidInOperatorUse, key, object));
713  }
714  Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
715 
716  // Convert the {key} to a name.
717  Handle<Name> name;
718  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
719  Object::ToName(isolate, key));
720 
721  // Lookup the {name} on {receiver}.
722  Maybe<bool> maybe = JSReceiver::HasProperty(receiver, name);
723  if (maybe.IsNothing()) return ReadOnlyRoots(isolate).exception();
724  return isolate->heap()->ToBoolean(maybe.FromJust());
725 }
726 
727 
728 RUNTIME_FUNCTION(Runtime_GetOwnPropertyKeys) {
729  HandleScope scope(isolate);
730  DCHECK_EQ(2, args.length());
731  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
732  CONVERT_SMI_ARG_CHECKED(filter_value, 1);
733  PropertyFilter filter = static_cast<PropertyFilter>(filter_value);
734 
735  Handle<FixedArray> keys;
736  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
737  isolate, keys,
738  KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly, filter,
739  GetKeysConversion::kConvertToString));
740 
741  return *isolate->factory()->NewJSArrayWithElements(keys);
742 }
743 
744 
745 RUNTIME_FUNCTION(Runtime_ToFastProperties) {
746  HandleScope scope(isolate);
747  DCHECK_EQ(1, args.length());
748  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
749  if (object->IsJSObject() && !object->IsJSGlobalObject()) {
750  JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0,
751  "RuntimeToFastProperties");
752  }
753  return *object;
754 }
755 
756 
757 RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) {
758  HandleScope scope(isolate);
759  DCHECK_EQ(0, args.length());
760  return *isolate->factory()->NewHeapNumber(0);
761 }
762 
763 
764 RUNTIME_FUNCTION(Runtime_NewObject) {
765  HandleScope scope(isolate);
766  DCHECK_EQ(2, args.length());
767  CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
768  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, new_target, 1);
769  RETURN_RESULT_OR_FAILURE(
770  isolate,
771  JSObject::New(target, new_target, Handle<AllocationSite>::null()));
772 }
773 
774 RUNTIME_FUNCTION(Runtime_CompleteInobjectSlackTrackingForMap) {
775  DisallowHeapAllocation no_gc;
776  HandleScope scope(isolate);
777  DCHECK_EQ(1, args.length());
778 
779  CONVERT_ARG_HANDLE_CHECKED(Map, initial_map, 0);
780  initial_map->CompleteInobjectSlackTracking(isolate);
781 
782  return ReadOnlyRoots(isolate).undefined_value();
783 }
784 
785 
786 RUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
787  HandleScope scope(isolate);
788  DCHECK_EQ(1, args.length());
789  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
790  if (!object->IsJSObject()) return Smi::kZero;
791  Handle<JSObject> js_object = Handle<JSObject>::cast(object);
792  // It could have been a DCHECK but we call this function directly from tests.
793  if (!js_object->map()->is_deprecated()) return Smi::kZero;
794  // This call must not cause lazy deopts, because it's called from deferred
795  // code where we can't handle lazy deopts for lack of a suitable bailout
796  // ID. So we just try migration and signal failure if necessary,
797  // which will also trigger a deopt.
798  if (!JSObject::TryMigrateInstance(js_object)) return Smi::kZero;
799  return *object;
800 }
801 
802 
803 static bool IsValidAccessor(Isolate* isolate, Handle<Object> obj) {
804  return obj->IsNullOrUndefined(isolate) || obj->IsCallable();
805 }
806 
807 
808 // Implements part of 8.12.9 DefineOwnProperty.
809 // There are 3 cases that lead here:
810 // Step 4b - define a new accessor property.
811 // Steps 9c & 12 - replace an existing data property with an accessor property.
812 // Step 12 - update an existing accessor property with an accessor or generic
813 // descriptor.
814 RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
815  HandleScope scope(isolate);
816  DCHECK_EQ(5, args.length());
817  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
818  CHECK(!obj->IsNull(isolate));
819  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
820  CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
821  CHECK(IsValidAccessor(isolate, getter));
822  CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
823  CHECK(IsValidAccessor(isolate, setter));
824  CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 4);
825 
826  RETURN_FAILURE_ON_EXCEPTION(
827  isolate, JSObject::DefineAccessor(obj, name, getter, setter, attrs));
828  return ReadOnlyRoots(isolate).undefined_value();
829 }
830 
831 
832 RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) {
833  HandleScope scope(isolate);
834  DCHECK_EQ(6, args.length());
835  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
836  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
837  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
838  CONVERT_SMI_ARG_CHECKED(flag, 3);
839  CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 4);
840  CONVERT_SMI_ARG_CHECKED(index, 5);
841 
842  FeedbackNexus nexus(vector, FeedbackVector::ToSlot(index));
843  if (nexus.ic_state() == UNINITIALIZED) {
844  if (name->IsUniqueName()) {
845  nexus.ConfigureMonomorphic(name, handle(object->map(), isolate),
846  MaybeObjectHandle());
847  } else {
848  nexus.ConfigureMegamorphic(PROPERTY);
849  }
850  } else if (nexus.ic_state() == MONOMORPHIC) {
851  if (nexus.FindFirstMap() != object->map() ||
852  nexus.GetFeedbackExtra() != MaybeObject::FromObject(*name)) {
853  nexus.ConfigureMegamorphic(PROPERTY);
854  }
855  }
856 
857  DataPropertyInLiteralFlags flags =
858  static_cast<DataPropertyInLiteralFlag>(flag);
859 
860  PropertyAttributes attrs = (flags & DataPropertyInLiteralFlag::kDontEnum)
861  ? PropertyAttributes::DONT_ENUM
862  : PropertyAttributes::NONE;
863 
864  if (flags & DataPropertyInLiteralFlag::kSetFunctionName) {
865  DCHECK(value->IsJSFunction());
866  Handle<JSFunction> function = Handle<JSFunction>::cast(value);
867  DCHECK(!function->shared()->HasSharedName());
868  Handle<Map> function_map(function->map(), isolate);
869  if (!JSFunction::SetName(function, name,
870  isolate->factory()->empty_string())) {
871  return ReadOnlyRoots(isolate).exception();
872  }
873  // Class constructors do not reserve in-object space for name field.
874  CHECK_IMPLIES(!IsClassConstructor(function->shared()->kind()),
875  *function_map == function->map());
876  }
877 
878  LookupIterator it = LookupIterator::PropertyOrElement(
879  isolate, object, name, object, LookupIterator::OWN);
880  // Cannot fail since this should only be called when
881  // creating an object literal.
882  CHECK(
883  JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attrs, kDontThrow)
884  .IsJust());
885  return *object;
886 }
887 
888 RUNTIME_FUNCTION(Runtime_CollectTypeProfile) {
889  HandleScope scope(isolate);
890  DCHECK_EQ(3, args.length());
891  CONVERT_ARG_HANDLE_CHECKED(Smi, position, 0);
892  CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
893  CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 2);
894 
895  Handle<String> type = Object::TypeOf(isolate, value);
896  if (value->IsJSReceiver()) {
897  Handle<JSReceiver> object = Handle<JSReceiver>::cast(value);
898  type = JSReceiver::GetConstructorName(object);
899  } else if (value->IsNull(isolate)) {
900  // typeof(null) is object. But it's more user-friendly to annotate
901  // null as type "null".
902  type = Handle<String>(ReadOnlyRoots(isolate).null_string(), isolate);
903  }
904 
905  DCHECK(vector->metadata()->HasTypeProfileSlot());
906  FeedbackNexus nexus(vector, vector->GetTypeProfileSlot());
907  nexus.Collect(type, position->value());
908 
909  return ReadOnlyRoots(isolate).undefined_value();
910 }
911 
912 RUNTIME_FUNCTION(Runtime_HasFastPackedElements) {
913  SealHandleScope shs(isolate);
914  DCHECK_EQ(1, args.length());
915  CONVERT_ARG_CHECKED(HeapObject, obj, 0);
916  return isolate->heap()->ToBoolean(
917  IsFastPackedElementsKind(obj->map()->elements_kind()));
918 }
919 
920 
921 RUNTIME_FUNCTION(Runtime_IsJSReceiver) {
922  SealHandleScope shs(isolate);
923  DCHECK_EQ(1, args.length());
924  CONVERT_ARG_CHECKED(Object, obj, 0);
925  return isolate->heap()->ToBoolean(obj->IsJSReceiver());
926 }
927 
928 
929 RUNTIME_FUNCTION(Runtime_ClassOf) {
930  SealHandleScope shs(isolate);
931  DCHECK_EQ(1, args.length());
932  CONVERT_ARG_CHECKED(Object, obj, 0);
933  if (!obj->IsJSReceiver()) return ReadOnlyRoots(isolate).null_value();
934  return JSReceiver::cast(obj)->class_name();
935 }
936 
937 RUNTIME_FUNCTION(Runtime_GetFunctionName) {
938  HandleScope scope(isolate);
939  DCHECK_EQ(1, args.length());
940  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
941  return *JSFunction::GetName(isolate, function);
942 }
943 
944 RUNTIME_FUNCTION(Runtime_DefineGetterPropertyUnchecked) {
945  HandleScope scope(isolate);
946  DCHECK_EQ(4, args.length());
947  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
948  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
949  CONVERT_ARG_HANDLE_CHECKED(JSFunction, getter, 2);
950  CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
951 
952  if (String::cast(getter->shared()->Name())->length() == 0) {
953  Handle<Map> getter_map(getter->map(), isolate);
954  if (!JSFunction::SetName(getter, name, isolate->factory()->get_string())) {
955  return ReadOnlyRoots(isolate).exception();
956  }
957  CHECK_EQ(*getter_map, getter->map());
958  }
959 
960  RETURN_FAILURE_ON_EXCEPTION(
961  isolate,
962  JSObject::DefineAccessor(object, name, getter,
963  isolate->factory()->null_value(), attrs));
964  return ReadOnlyRoots(isolate).undefined_value();
965 }
966 
967 RUNTIME_FUNCTION(Runtime_SetDataProperties) {
968  HandleScope scope(isolate);
969  DCHECK_EQ(2, args.length());
970  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, target, 0);
971  CONVERT_ARG_HANDLE_CHECKED(Object, source, 1);
972 
973  // 2. If source is undefined or null, let keys be an empty List.
974  if (source->IsUndefined(isolate) || source->IsNull(isolate)) {
975  return ReadOnlyRoots(isolate).undefined_value();
976  }
977 
978  MAYBE_RETURN(JSReceiver::SetOrCopyDataProperties(isolate, target, source),
979  ReadOnlyRoots(isolate).exception());
980  return ReadOnlyRoots(isolate).undefined_value();
981 }
982 
983 RUNTIME_FUNCTION(Runtime_CopyDataProperties) {
984  HandleScope scope(isolate);
985  DCHECK_EQ(2, args.length());
986  CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
987  CONVERT_ARG_HANDLE_CHECKED(Object, source, 1);
988 
989  // 2. If source is undefined or null, let keys be an empty List.
990  if (source->IsUndefined(isolate) || source->IsNull(isolate)) {
991  return ReadOnlyRoots(isolate).undefined_value();
992  }
993 
994  MAYBE_RETURN(JSReceiver::SetOrCopyDataProperties(isolate, target, source,
995  nullptr, false),
996  ReadOnlyRoots(isolate).exception());
997  return ReadOnlyRoots(isolate).undefined_value();
998 }
999 
1000 RUNTIME_FUNCTION(Runtime_CopyDataPropertiesWithExcludedProperties) {
1001  HandleScope scope(isolate);
1002  DCHECK_LE(1, args.length());
1003  CONVERT_ARG_HANDLE_CHECKED(Object, source, 0);
1004 
1005  // 2. If source is undefined or null, let keys be an empty List.
1006  if (source->IsUndefined(isolate) || source->IsNull(isolate)) {
1007  return ReadOnlyRoots(isolate).undefined_value();
1008  }
1009 
1010  ScopedVector<Handle<Object>> excluded_properties(args.length() - 1);
1011  for (int i = 1; i < args.length(); i++) {
1012  Handle<Object> property = args.at(i);
1013  uint32_t property_num;
1014  // We convert string to number if possible, in cases of computed
1015  // properties resolving to numbers, which would've been strings
1016  // instead because of our call to %ToName() in the desugaring for
1017  // computed properties.
1018  if (property->IsString() &&
1019  String::cast(*property)->AsArrayIndex(&property_num)) {
1020  property = isolate->factory()->NewNumberFromUint(property_num);
1021  }
1022 
1023  excluded_properties[i - 1] = property;
1024  }
1025 
1026  Handle<JSObject> target =
1027  isolate->factory()->NewJSObject(isolate->object_function());
1028  MAYBE_RETURN(JSReceiver::SetOrCopyDataProperties(isolate, target, source,
1029  &excluded_properties, false),
1030  ReadOnlyRoots(isolate).exception());
1031  return *target;
1032 }
1033 
1034 namespace {
1035 
1036 inline void TrySetNative(Handle<Object> maybe_func) {
1037  if (!maybe_func->IsJSFunction()) return;
1038  JSFunction::cast(*maybe_func)->shared()->set_native(true);
1039 }
1040 
1041 inline void TrySetNativeAndLength(Handle<Object> maybe_func, int length) {
1042  if (!maybe_func->IsJSFunction()) return;
1043  SharedFunctionInfo* shared = JSFunction::cast(*maybe_func)->shared();
1044  shared->set_native(true);
1045  if (length >= 0) {
1046  shared->set_length(length);
1047  }
1048 }
1049 
1050 } // namespace
1051 
1052 RUNTIME_FUNCTION(Runtime_DefineMethodsInternal) {
1053  HandleScope scope(isolate);
1054  DCHECK_EQ(3, args.length());
1055  CHECK(isolate->bootstrapper()->IsActive());
1056  CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
1057  CONVERT_ARG_HANDLE_CHECKED(JSFunction, source_class, 1);
1058  CONVERT_SMI_ARG_CHECKED(length, 2);
1059 
1060  DCHECK(source_class->prototype()->IsJSObject());
1061  Handle<JSObject> source(JSObject::cast(source_class->prototype()), isolate);
1062 
1063  Handle<FixedArray> keys;
1064  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1065  isolate, keys,
1066  KeyAccumulator::GetKeys(source, KeyCollectionMode::kOwnOnly,
1067  ALL_PROPERTIES,
1068  GetKeysConversion::kConvertToString));
1069 
1070  for (int i = 0; i < keys->length(); ++i) {
1071  Handle<Name> key = Handle<Name>::cast(FixedArray::get(*keys, i, isolate));
1072  if (*key == ReadOnlyRoots(isolate).constructor_string()) continue;
1073 
1074  PropertyDescriptor descriptor;
1075  Maybe<bool> did_get_descriptor =
1076  JSReceiver::GetOwnPropertyDescriptor(isolate, source, key, &descriptor);
1077  CHECK(did_get_descriptor.FromJust());
1078  if (descriptor.has_value()) {
1079  TrySetNativeAndLength(descriptor.value(), length);
1080  } else {
1081  if (descriptor.has_get()) TrySetNative(descriptor.get());
1082  if (descriptor.has_set()) TrySetNative(descriptor.set());
1083  }
1084 
1085  Maybe<bool> success = JSReceiver::DefineOwnProperty(
1086  isolate, target, key, &descriptor, kDontThrow);
1087  CHECK(success.FromJust());
1088  }
1089  return ReadOnlyRoots(isolate).undefined_value();
1090 }
1091 
1092 RUNTIME_FUNCTION(Runtime_DefineSetterPropertyUnchecked) {
1093  HandleScope scope(isolate);
1094  DCHECK_EQ(4, args.length());
1095  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
1096  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
1097  CONVERT_ARG_HANDLE_CHECKED(JSFunction, setter, 2);
1098  CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
1099 
1100  if (String::cast(setter->shared()->Name())->length() == 0) {
1101  Handle<Map> setter_map(setter->map(), isolate);
1102  if (!JSFunction::SetName(setter, name, isolate->factory()->set_string())) {
1103  return ReadOnlyRoots(isolate).exception();
1104  }
1105  CHECK_EQ(*setter_map, setter->map());
1106  }
1107 
1108  RETURN_FAILURE_ON_EXCEPTION(
1109  isolate,
1110  JSObject::DefineAccessor(object, name, isolate->factory()->null_value(),
1111  setter, attrs));
1112  return ReadOnlyRoots(isolate).undefined_value();
1113 }
1114 
1115 RUNTIME_FUNCTION(Runtime_ToObject) {
1116  // Runtime call is implemented in InterpreterIntrinsics and lowered in
1117  // JSIntrinsicLowering.
1118  UNREACHABLE();
1119 }
1120 
1121 RUNTIME_FUNCTION(Runtime_ToNumber) {
1122  HandleScope scope(isolate);
1123  DCHECK_EQ(1, args.length());
1124  CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
1125  RETURN_RESULT_OR_FAILURE(isolate, Object::ToNumber(isolate, input));
1126 }
1127 
1128 RUNTIME_FUNCTION(Runtime_ToNumeric) {
1129  HandleScope scope(isolate);
1130  DCHECK_EQ(1, args.length());
1131  CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
1132  RETURN_RESULT_OR_FAILURE(isolate, Object::ToNumeric(isolate, input));
1133 }
1134 
1135 
1136 RUNTIME_FUNCTION(Runtime_ToLength) {
1137  HandleScope scope(isolate);
1138  DCHECK_EQ(1, args.length());
1139  CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
1140  RETURN_RESULT_OR_FAILURE(isolate, Object::ToLength(isolate, input));
1141 }
1142 
1143 
1144 RUNTIME_FUNCTION(Runtime_ToString) {
1145  HandleScope scope(isolate);
1146  DCHECK_EQ(1, args.length());
1147  CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
1148  RETURN_RESULT_OR_FAILURE(isolate, Object::ToString(isolate, input));
1149 }
1150 
1151 
1152 RUNTIME_FUNCTION(Runtime_ToName) {
1153  HandleScope scope(isolate);
1154  DCHECK_EQ(1, args.length());
1155  CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
1156  RETURN_RESULT_OR_FAILURE(isolate, Object::ToName(isolate, input));
1157 }
1158 
1159 RUNTIME_FUNCTION(Runtime_HasInPrototypeChain) {
1160  HandleScope scope(isolate);
1161  DCHECK_EQ(2, args.length());
1162  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
1163  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
1164  if (!object->IsJSReceiver()) return ReadOnlyRoots(isolate).false_value();
1165  Maybe<bool> result = JSReceiver::HasInPrototypeChain(
1166  isolate, Handle<JSReceiver>::cast(object), prototype);
1167  MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
1168  return isolate->heap()->ToBoolean(result.FromJust());
1169 }
1170 
1171 
1172 // ES6 section 7.4.7 CreateIterResultObject ( value, done )
1173 RUNTIME_FUNCTION(Runtime_CreateIterResultObject) {
1174  HandleScope scope(isolate);
1175  DCHECK_EQ(2, args.length());
1176  CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
1177  CONVERT_ARG_HANDLE_CHECKED(Object, done, 1);
1178  return *isolate->factory()->NewJSIteratorResult(value,
1179  done->BooleanValue(isolate));
1180 }
1181 
1182 RUNTIME_FUNCTION(Runtime_CreateDataProperty) {
1183  HandleScope scope(isolate);
1184  DCHECK_EQ(3, args.length());
1185  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, o, 0);
1186  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1187  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
1188  bool success;
1189  LookupIterator it = LookupIterator::PropertyOrElement(
1190  isolate, o, key, &success, LookupIterator::OWN);
1191  if (!success) return ReadOnlyRoots(isolate).exception();
1192  MAYBE_RETURN(JSReceiver::CreateDataProperty(&it, value, kThrowOnError),
1193  ReadOnlyRoots(isolate).exception());
1194  return *value;
1195 }
1196 
1197 RUNTIME_FUNCTION(Runtime_GetOwnPropertyDescriptor) {
1198  HandleScope scope(isolate);
1199 
1200  DCHECK_EQ(2, args.length());
1201  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
1202  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
1203 
1204  PropertyDescriptor desc;
1205  Maybe<bool> found =
1206  JSReceiver::GetOwnPropertyDescriptor(isolate, object, name, &desc);
1207  MAYBE_RETURN(found, ReadOnlyRoots(isolate).exception());
1208 
1209  if (!found.FromJust()) return ReadOnlyRoots(isolate).undefined_value();
1210  return *desc.ToPropertyDescriptorObject(isolate);
1211 }
1212 
1213 RUNTIME_FUNCTION(Runtime_AddPrivateField) {
1214  HandleScope scope(isolate);
1215  DCHECK_EQ(3, args.length());
1216  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, o, 0);
1217  CONVERT_ARG_HANDLE_CHECKED(Symbol, key, 1);
1218  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
1219  DCHECK(key->is_private_name());
1220 
1221  LookupIterator it =
1222  LookupIterator::PropertyOrElement(isolate, o, key, LookupIterator::OWN);
1223 
1224  if (it.IsFound()) {
1225  THROW_NEW_ERROR_RETURN_FAILURE(
1226  isolate, NewTypeError(MessageTemplate::kVarRedeclaration, key));
1227  }
1228 
1229  CHECK(Object::AddDataProperty(&it, value, NONE, kDontThrow,
1230  StoreOrigin::kMaybeKeyed)
1231  .FromJust());
1232  return ReadOnlyRoots(isolate).undefined_value();
1233 }
1234 
1235 } // namespace internal
1236 } // namespace v8
Definition: libplatform.h:13
PropertyFilter
Definition: v8.h:3185