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