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