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/runtime/runtime-utils.h"
6 :
7 : #include "src/arguments.h"
8 : #include "src/bootstrapper.h"
9 : #include "src/debug/debug.h"
10 : #include "src/isolate-inl.h"
11 : #include "src/messages.h"
12 : #include "src/property-descriptor.h"
13 : #include "src/runtime/runtime.h"
14 :
15 : namespace v8 {
16 : namespace internal {
17 :
18 81705440 : MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
19 : Handle<Object> object,
20 : Handle<Object> key,
21 : bool* is_found_out) {
22 81705440 : if (object->IsNullOrUndefined(isolate)) {
23 43812 : THROW_NEW_ERROR(
24 : isolate,
25 : NewTypeError(MessageTemplate::kNonObjectPropertyLoad, key, object),
26 : Object);
27 : }
28 :
29 81683534 : bool success = false;
30 : LookupIterator it =
31 81683534 : LookupIterator::PropertyOrElement(isolate, object, key, &success);
32 81683533 : if (!success) return MaybeHandle<Object>();
33 :
34 81683512 : MaybeHandle<Object> result = Object::GetProperty(&it);
35 81684380 : if (is_found_out) *is_found_out = it.IsFound();
36 81683512 : return result;
37 : }
38 :
39 36185164 : static MaybeHandle<Object> KeyedGetObjectProperty(Isolate* isolate,
40 : Handle<Object> receiver_obj,
41 : Handle<Object> key_obj) {
42 : // Fast cases for getting named properties of the receiver JSObject
43 : // itself.
44 : //
45 : // The global proxy objects has to be excluded since LookupOwn on
46 : // the global proxy object can return a valid result even though the
47 : // global proxy object never has properties. This is the case
48 : // because the global proxy object forwards everything to its hidden
49 : // prototype including own lookups.
50 : //
51 : // Additionally, we need to make sure that we do not cache results
52 : // for objects that require access checks.
53 :
54 : // Convert string-index keys to their number variant to avoid internalization
55 : // below; and speed up subsequent conversion to index.
56 : uint32_t index;
57 41853359 : if (key_obj->IsString() && String::cast(*key_obj)->AsArrayIndex(&index)) {
58 29190 : key_obj = isolate->factory()->NewNumberFromUint(index);
59 : }
60 36185164 : if (receiver_obj->IsJSObject()) {
61 72208520 : if (!receiver_obj->IsJSGlobalProxy() &&
62 72207639 : !receiver_obj->IsAccessCheckNeeded() && key_obj->IsName()) {
63 : Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
64 : Handle<Name> key = Handle<Name>::cast(key_obj);
65 5581533 : key_obj = key = isolate->factory()->InternalizeName(key);
66 :
67 : DisallowHeapAllocation no_allocation;
68 5581533 : if (receiver->IsJSGlobalObject()) {
69 : // Attempt dictionary lookup.
70 : GlobalDictionary* dictionary = receiver->global_dictionary();
71 0 : int entry = dictionary->FindEntry(key);
72 0 : if (entry != GlobalDictionary::kNotFound) {
73 : DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
74 0 : PropertyCell* cell = PropertyCell::cast(dictionary->ValueAt(entry));
75 0 : if (cell->property_details().kind() == kData) {
76 : Object* value = cell->value();
77 0 : if (!value->IsTheHole(isolate)) {
78 : return Handle<Object>(value, isolate);
79 : }
80 : // If value is the hole (meaning, absent) do the general lookup.
81 : }
82 : }
83 5581533 : } else if (!receiver->HasFastProperties()) {
84 : // Attempt dictionary lookup.
85 : NameDictionary* dictionary = receiver->property_dictionary();
86 5208610 : int entry = dictionary->FindEntry(key);
87 10358923 : if ((entry != NameDictionary::kNotFound) &&
88 : (dictionary->DetailsAt(entry).kind() == kData)) {
89 5150033 : Object* value = dictionary->ValueAt(entry);
90 : return Handle<Object>(value, isolate);
91 : }
92 : }
93 30544917 : } else if (key_obj->IsSmi()) {
94 : // JSObject without a name key. If the key is a Smi, check for a
95 : // definite out-of-bounds access to elements, which is a strong indicator
96 : // that subsequent accesses will also call the runtime. Proactively
97 : // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
98 : // doubles for those future calls in the case that the elements would
99 : // become FAST_DOUBLE_ELEMENTS.
100 : Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
101 : ElementsKind elements_kind = js_object->GetElementsKind();
102 30495579 : if (IsFastDoubleElementsKind(elements_kind)) {
103 30 : if (Smi::cast(*key_obj)->value() >= js_object->elements()->length()) {
104 : elements_kind = IsFastHoleyElementsKind(elements_kind)
105 : ? FAST_HOLEY_ELEMENTS
106 0 : : FAST_ELEMENTS;
107 0 : JSObject::TransitionElementsKind(js_object, elements_kind);
108 : }
109 : } else {
110 : DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
111 : !IsFastElementsKind(elements_kind));
112 : }
113 : }
114 90820 : } else if (receiver_obj->IsString() && key_obj->IsSmi()) {
115 : // Fast case for string indexing using [] with a smi index.
116 : Handle<String> str = Handle<String>::cast(receiver_obj);
117 : int index = Handle<Smi>::cast(key_obj)->value();
118 48705 : if (index >= 0 && index < str->length()) {
119 : Factory* factory = isolate->factory();
120 : return factory->LookupSingleCharacterStringFromCode(
121 59967 : String::Flatten(str)->Get(index));
122 : }
123 : }
124 :
125 : // Fall back to GetObjectProperty.
126 31015142 : return Runtime::GetObjectProperty(isolate, receiver_obj, key_obj);
127 : }
128 :
129 :
130 9039562 : Maybe<bool> Runtime::DeleteObjectProperty(Isolate* isolate,
131 : Handle<JSReceiver> receiver,
132 : Handle<Object> key,
133 : LanguageMode language_mode) {
134 9039562 : bool success = false;
135 : LookupIterator it = LookupIterator::PropertyOrElement(
136 9039562 : isolate, receiver, key, &success, LookupIterator::OWN);
137 9039562 : if (!success) return Nothing<bool>();
138 :
139 9039548 : return JSReceiver::DeleteProperty(&it, language_mode);
140 : }
141 :
142 : // ES6 19.1.3.2
143 5156 : RUNTIME_FUNCTION(Runtime_ObjectHasOwnProperty) {
144 2578 : HandleScope scope(isolate);
145 2578 : Handle<Object> property = args.at(1);
146 :
147 : Handle<Name> key;
148 : uint32_t index;
149 2578 : bool key_is_array_index = property->ToArrayIndex(&index);
150 :
151 2578 : if (!key_is_array_index) {
152 4012 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key,
153 : Object::ToName(isolate, property));
154 1976 : key_is_array_index = key->AsArrayIndex(&index);
155 : }
156 :
157 2548 : Handle<Object> object = args.at(0);
158 :
159 2548 : if (object->IsJSObject()) {
160 1536 : Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
161 : // Fast case: either the key is a real named property or it is not
162 : // an array index and there are no interceptors or hidden
163 : // prototypes.
164 : // TODO(jkummerow): Make JSReceiver::HasOwnProperty fast enough to
165 : // handle all cases directly (without this custom fast path).
166 : {
167 : LookupIterator::Configuration c = LookupIterator::OWN_SKIP_INTERCEPTOR;
168 : LookupIterator it =
169 : key_is_array_index ? LookupIterator(isolate, js_obj, index, js_obj, c)
170 3453 : : LookupIterator(js_obj, key, js_obj, c);
171 1536 : Maybe<bool> maybe = JSReceiver::HasProperty(&it);
172 2282 : if (maybe.IsNothing()) return isolate->heap()->exception();
173 : DCHECK(!isolate->has_pending_exception());
174 1524 : if (maybe.FromJust()) return isolate->heap()->true_value();
175 : }
176 :
177 790 : Map* map = js_obj->map();
178 1954 : if (!map->has_hidden_prototype() &&
179 240 : (key_is_array_index ? !map->has_indexed_interceptor()
180 342 : : !map->has_named_interceptor())) {
181 519 : return isolate->heap()->false_value();
182 : }
183 :
184 : // Slow case.
185 : LookupIterator::Configuration c = LookupIterator::OWN;
186 : LookupIterator it = key_is_array_index
187 : ? LookupIterator(isolate, js_obj, index, js_obj, c)
188 542 : : LookupIterator(js_obj, key, js_obj, c);
189 :
190 271 : Maybe<bool> maybe = JSReceiver::HasProperty(&it);
191 271 : if (maybe.IsNothing()) return isolate->heap()->exception();
192 : DCHECK(!isolate->has_pending_exception());
193 271 : return isolate->heap()->ToBoolean(maybe.FromJust());
194 :
195 1012 : } else if (object->IsJSProxy()) {
196 421 : if (key.is_null()) {
197 : DCHECK(key_is_array_index);
198 127 : key = isolate->factory()->Uint32ToString(index);
199 : }
200 :
201 : Maybe<bool> result =
202 842 : JSReceiver::HasOwnProperty(Handle<JSProxy>::cast(object), key);
203 421 : if (!result.IsJust()) return isolate->heap()->exception();
204 281 : return isolate->heap()->ToBoolean(result.FromJust());
205 :
206 591 : } else if (object->IsString()) {
207 : return isolate->heap()->ToBoolean(
208 : key_is_array_index
209 104 : ? index < static_cast<uint32_t>(String::cast(*object)->length())
210 412 : : key->Equals(isolate->heap()->length_string()));
211 385 : } else if (object->IsNullOrUndefined(isolate)) {
212 658 : THROW_NEW_ERROR_RETURN_FAILURE(
213 : isolate, NewTypeError(MessageTemplate::kUndefinedOrNullToObject));
214 : }
215 :
216 56 : return isolate->heap()->false_value();
217 : }
218 :
219 5761250 : RUNTIME_FUNCTION(Runtime_AddDictionaryProperty) {
220 2880625 : HandleScope scope(isolate);
221 2880625 : Handle<JSObject> receiver = args.at<JSObject>(0);
222 2880625 : Handle<Name> name = args.at<Name>(1);
223 2880625 : Handle<Object> value = args.at(2);
224 :
225 : DCHECK(name->IsUniqueName());
226 :
227 2880625 : Handle<NameDictionary> dictionary(receiver->property_dictionary(), isolate);
228 : int entry;
229 2880625 : PropertyDetails property_details(kData, NONE, 0, PropertyCellType::kNoCell);
230 : dictionary =
231 2880625 : NameDictionary::Add(dictionary, name, value, property_details, &entry);
232 2880625 : receiver->set_properties(*dictionary);
233 2880625 : return *value;
234 : }
235 :
236 : // ES6 section 19.1.2.2 Object.create ( O [ , Properties ] )
237 : // TODO(verwaest): Support the common cases with precached map directly in
238 : // an Object.create stub.
239 378740 : RUNTIME_FUNCTION(Runtime_ObjectCreate) {
240 189370 : HandleScope scope(isolate);
241 189370 : Handle<Object> prototype = args.at(0);
242 378181 : if (!prototype->IsNull(isolate) && !prototype->IsJSReceiver()) {
243 116 : THROW_NEW_ERROR_RETURN_FAILURE(
244 : isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, prototype));
245 : }
246 :
247 : // Generate the map with the specified {prototype} based on the Object
248 : // function's initial map from the current native context.
249 : // TODO(bmeurer): Use a dedicated cache for Object.create; think about
250 : // slack tracking for Object.create.
251 : Handle<Map> map =
252 189312 : Map::GetObjectCreateMap(Handle<HeapObject>::cast(prototype));
253 :
254 189312 : bool is_dictionary_map = map->is_dictionary_map();
255 : Handle<FixedArray> object_properties;
256 189312 : if (is_dictionary_map) {
257 : // Allocate the actual properties dictionay up front to avoid invalid object
258 : // state.
259 : object_properties =
260 559 : NameDictionary::New(isolate, NameDictionary::kInitialCapacity);
261 : }
262 : // Actually allocate the object.
263 189312 : Handle<JSObject> object = isolate->factory()->NewJSObjectFromMap(map);
264 189312 : if (is_dictionary_map) {
265 559 : object->set_properties(*object_properties);
266 : }
267 :
268 : // Define the properties if properties was specified and is not undefined.
269 189312 : Handle<Object> properties = args.at(1);
270 189312 : if (!properties->IsUndefined(isolate)) {
271 1689 : RETURN_FAILURE_ON_EXCEPTION(
272 : isolate, JSReceiver::DefineProperties(isolate, object, properties));
273 : }
274 :
275 189370 : return *object;
276 : }
277 :
278 24689893 : MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
279 : Handle<Object> object,
280 : Handle<Object> key,
281 : Handle<Object> value,
282 : LanguageMode language_mode) {
283 24689893 : if (object->IsNullOrUndefined(isolate)) {
284 30000 : THROW_NEW_ERROR(
285 : isolate,
286 : NewTypeError(MessageTemplate::kNonObjectPropertyStore, key, object),
287 : Object);
288 : }
289 :
290 : // Check if the given key is an array index.
291 24674893 : bool success = false;
292 : LookupIterator it =
293 24674893 : LookupIterator::PropertyOrElement(isolate, object, key, &success);
294 24674893 : if (!success) return MaybeHandle<Object>();
295 :
296 24674879 : MAYBE_RETURN_NULL(Object::SetProperty(&it, value, language_mode,
297 : Object::MAY_BE_STORE_FROM_KEYED));
298 : return value;
299 : }
300 :
301 :
302 36 : RUNTIME_FUNCTION(Runtime_GetPrototype) {
303 18 : HandleScope scope(isolate);
304 : DCHECK_EQ(1, args.length());
305 36 : CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
306 54 : RETURN_RESULT_OR_FAILURE(isolate, JSReceiver::GetPrototype(isolate, obj));
307 : }
308 :
309 :
310 973412 : RUNTIME_FUNCTION(Runtime_InternalSetPrototype) {
311 486706 : HandleScope scope(isolate);
312 : DCHECK_EQ(2, args.length());
313 973412 : CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
314 486706 : CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
315 486706 : MAYBE_RETURN(
316 : JSReceiver::SetPrototype(obj, prototype, false, Object::THROW_ON_ERROR),
317 : isolate->heap()->exception());
318 486706 : return *obj;
319 : }
320 :
321 48566 : RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
322 24283 : HandleScope scope(isolate);
323 : DCHECK_EQ(2, args.length());
324 48566 : CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
325 48566 : CONVERT_SMI_ARG_CHECKED(properties, 1);
326 : // Conservative upper limit to prevent fuzz tests from going OOM.
327 24283 : if (properties > 100000) return isolate->ThrowIllegalOperation();
328 32291 : if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
329 : JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties,
330 8008 : "OptimizeForAdding");
331 : }
332 24283 : return *object;
333 : }
334 :
335 :
336 1388946 : RUNTIME_FUNCTION(Runtime_GetProperty) {
337 694473 : HandleScope scope(isolate);
338 : DCHECK_EQ(2, args.length());
339 :
340 694473 : CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
341 694473 : CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
342 :
343 1388946 : RETURN_RESULT_OR_FAILURE(isolate,
344 694473 : Runtime::GetObjectProperty(isolate, object, key));
345 : }
346 :
347 : // KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
348 72370328 : RUNTIME_FUNCTION(Runtime_KeyedGetProperty) {
349 36185164 : HandleScope scope(isolate);
350 : DCHECK_EQ(2, args.length());
351 :
352 36185164 : CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
353 36185164 : CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
354 :
355 72370328 : RETURN_RESULT_OR_FAILURE(
356 36185164 : isolate, KeyedGetObjectProperty(isolate, receiver_obj, key_obj));
357 : }
358 :
359 461934 : RUNTIME_FUNCTION(Runtime_AddNamedProperty) {
360 230967 : HandleScope scope(isolate);
361 : DCHECK_EQ(4, args.length());
362 :
363 461934 : CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
364 461934 : CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
365 230967 : CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
366 461934 : CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
367 :
368 : #ifdef DEBUG
369 : uint32_t index = 0;
370 : DCHECK(!name->ToArrayIndex(&index));
371 : LookupIterator it(object, name, object, LookupIterator::OWN_SKIP_INTERCEPTOR);
372 : Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
373 : if (!maybe.IsJust()) return isolate->heap()->exception();
374 : CHECK(!it.IsFound());
375 : #endif
376 :
377 461934 : RETURN_RESULT_OR_FAILURE(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
378 230967 : object, name, value, attrs));
379 : }
380 :
381 :
382 : // Adds an element to an array.
383 : // This is used to create an indexed data property into an array.
384 0 : RUNTIME_FUNCTION(Runtime_AddElement) {
385 0 : HandleScope scope(isolate);
386 : DCHECK_EQ(3, args.length());
387 :
388 0 : CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
389 0 : CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
390 0 : CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
391 :
392 0 : uint32_t index = 0;
393 0 : CHECK(key->ToArrayIndex(&index));
394 :
395 : #ifdef DEBUG
396 : LookupIterator it(isolate, object, index, object,
397 : LookupIterator::OWN_SKIP_INTERCEPTOR);
398 : Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
399 : if (!maybe.IsJust()) return isolate->heap()->exception();
400 : CHECK(!it.IsFound());
401 :
402 : if (object->IsJSArray()) {
403 : Handle<JSArray> array = Handle<JSArray>::cast(object);
404 : CHECK(!JSArray::WouldChangeReadOnlyLength(array, index));
405 : }
406 : #endif
407 :
408 0 : RETURN_RESULT_OR_FAILURE(isolate, JSObject::SetOwnElementIgnoreAttributes(
409 0 : object, index, value, NONE));
410 : }
411 :
412 :
413 64906 : RUNTIME_FUNCTION(Runtime_AppendElement) {
414 32453 : HandleScope scope(isolate);
415 : DCHECK_EQ(2, args.length());
416 :
417 64906 : CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
418 32453 : CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
419 32453 : CHECK(!value->IsTheHole(isolate));
420 :
421 : uint32_t index;
422 32453 : CHECK(array->length()->ToArrayIndex(&index));
423 :
424 64906 : RETURN_FAILURE_ON_EXCEPTION(
425 : isolate, JSObject::AddDataElement(array, index, value, NONE));
426 32453 : JSObject::ValidateElements(array);
427 32453 : return *array;
428 : }
429 :
430 :
431 45662324 : RUNTIME_FUNCTION(Runtime_SetProperty) {
432 22831162 : HandleScope scope(isolate);
433 : DCHECK_EQ(4, args.length());
434 :
435 22831162 : CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
436 22831162 : CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
437 22831162 : CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
438 45662324 : CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 3);
439 :
440 45662324 : RETURN_RESULT_OR_FAILURE(
441 : isolate,
442 22831162 : Runtime::SetObjectProperty(isolate, object, key, value, language_mode));
443 : }
444 :
445 :
446 : namespace {
447 :
448 : // ES6 section 12.5.4.
449 9032519 : Object* DeleteProperty(Isolate* isolate, Handle<Object> object,
450 : Handle<Object> key, LanguageMode language_mode) {
451 : Handle<JSReceiver> receiver;
452 18065038 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
453 : Object::ToObject(isolate, object));
454 : Maybe<bool> result =
455 9032490 : Runtime::DeleteObjectProperty(isolate, receiver, key, language_mode);
456 9032490 : MAYBE_RETURN(result, isolate->heap()->exception());
457 9030242 : return isolate->heap()->ToBoolean(result.FromJust());
458 : }
459 :
460 : } // namespace
461 :
462 18065038 : RUNTIME_FUNCTION(Runtime_DeleteProperty) {
463 9032519 : HandleScope scope(isolate);
464 : DCHECK_EQ(3, args.length());
465 9032519 : CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
466 9032519 : CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
467 18065038 : CONVERT_SMI_ARG_CHECKED(language_mode, 2);
468 : return DeleteProperty(isolate, object, key,
469 9032519 : static_cast<LanguageMode>(language_mode));
470 : }
471 :
472 510 : RUNTIME_FUNCTION(Runtime_ShrinkPropertyDictionary) {
473 255 : HandleScope scope(isolate);
474 : DCHECK_EQ(2, args.length());
475 510 : CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
476 510 : CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
477 255 : Handle<NameDictionary> dictionary(receiver->property_dictionary(), isolate);
478 : Handle<NameDictionary> new_properties =
479 255 : NameDictionary::Shrink(dictionary, key);
480 255 : receiver->set_properties(*new_properties);
481 255 : return Smi::kZero;
482 : }
483 :
484 : // ES6 section 12.9.3, operator in.
485 375516 : RUNTIME_FUNCTION(Runtime_HasProperty) {
486 187758 : HandleScope scope(isolate);
487 : DCHECK_EQ(2, args.length());
488 187758 : CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
489 187758 : CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
490 :
491 : // Check that {object} is actually a receiver.
492 187758 : if (!object->IsJSReceiver()) {
493 808 : THROW_NEW_ERROR_RETURN_FAILURE(
494 : isolate,
495 : NewTypeError(MessageTemplate::kInvalidInOperatorUse, key, object));
496 : }
497 187354 : Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
498 :
499 : // Convert the {key} to a name.
500 : Handle<Name> name;
501 374708 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
502 : Object::ToName(isolate, key));
503 :
504 : // Lookup the {name} on {receiver}.
505 187354 : Maybe<bool> maybe = JSReceiver::HasProperty(receiver, name);
506 187354 : if (!maybe.IsJust()) return isolate->heap()->exception();
507 186510 : return isolate->heap()->ToBoolean(maybe.FromJust());
508 : }
509 :
510 :
511 642024 : RUNTIME_FUNCTION(Runtime_GetOwnPropertyKeys) {
512 321012 : HandleScope scope(isolate);
513 : DCHECK_EQ(2, args.length());
514 642024 : CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
515 642024 : CONVERT_SMI_ARG_CHECKED(filter_value, 1);
516 321012 : PropertyFilter filter = static_cast<PropertyFilter>(filter_value);
517 :
518 : Handle<FixedArray> keys;
519 642024 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
520 : isolate, keys,
521 : KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly, filter,
522 : GetKeysConversion::kConvertToString));
523 :
524 642024 : return *isolate->factory()->NewJSArrayWithElements(keys);
525 : }
526 :
527 :
528 : // Return information on whether an object has a named or indexed interceptor.
529 : // args[0]: object
530 0 : RUNTIME_FUNCTION(Runtime_GetInterceptorInfo) {
531 0 : HandleScope scope(isolate);
532 : DCHECK_EQ(1, args.length());
533 0 : if (!args[0]->IsJSObject()) {
534 : return Smi::kZero;
535 : }
536 0 : CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
537 :
538 : int result = 0;
539 0 : if (obj->HasNamedInterceptor()) result |= 2;
540 0 : if (obj->HasIndexedInterceptor()) result |= 1;
541 :
542 0 : return Smi::FromInt(result);
543 : }
544 :
545 :
546 149384 : RUNTIME_FUNCTION(Runtime_ToFastProperties) {
547 74692 : HandleScope scope(isolate);
548 : DCHECK_EQ(1, args.length());
549 74692 : CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
550 149369 : if (object->IsJSObject() && !object->IsJSGlobalObject()) {
551 : JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0,
552 58567 : "RuntimeToFastProperties");
553 : }
554 74692 : return *object;
555 : }
556 :
557 :
558 60266 : RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) {
559 30133 : HandleScope scope(isolate);
560 : DCHECK_EQ(0, args.length());
561 60266 : return *isolate->factory()->NewHeapNumber(0);
562 : }
563 :
564 :
565 736052 : RUNTIME_FUNCTION(Runtime_NewObject) {
566 368026 : HandleScope scope(isolate);
567 : DCHECK_EQ(2, args.length());
568 736052 : CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
569 736052 : CONVERT_ARG_HANDLE_CHECKED(JSReceiver, new_target, 1);
570 1104078 : RETURN_RESULT_OR_FAILURE(isolate, JSObject::New(target, new_target));
571 : }
572 :
573 :
574 99878 : RUNTIME_FUNCTION(Runtime_FinalizeInstanceSize) {
575 49939 : HandleScope scope(isolate);
576 : DCHECK_EQ(1, args.length());
577 :
578 99878 : CONVERT_ARG_HANDLE_CHECKED(Map, initial_map, 0);
579 49939 : initial_map->CompleteInobjectSlackTracking();
580 :
581 49939 : return isolate->heap()->undefined_value();
582 : }
583 :
584 :
585 28 : RUNTIME_FUNCTION(Runtime_LoadMutableDouble) {
586 14 : HandleScope scope(isolate);
587 : DCHECK_EQ(2, args.length());
588 28 : CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
589 28 : CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1);
590 14 : CHECK((index->value() & 1) == 1);
591 : FieldIndex field_index =
592 14 : FieldIndex::ForLoadByFieldIndex(object->map(), index->value());
593 14 : if (field_index.is_inobject()) {
594 28 : CHECK(field_index.property_index() <
595 : object->map()->GetInObjectProperties());
596 : } else {
597 0 : CHECK(field_index.outobject_array_index() < object->properties()->length());
598 : }
599 : return *JSObject::FastPropertyAt(object, Representation::Double(),
600 28 : field_index);
601 : }
602 :
603 :
604 3000056 : RUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
605 1500028 : HandleScope scope(isolate);
606 : DCHECK_EQ(1, args.length());
607 1500028 : CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
608 1500028 : if (!object->IsJSObject()) return Smi::kZero;
609 1500028 : Handle<JSObject> js_object = Handle<JSObject>::cast(object);
610 : // It could have been a DCHECK but we call this function directly from tests.
611 1500028 : if (!js_object->map()->is_deprecated()) return Smi::kZero;
612 : // This call must not cause lazy deopts, because it's called from deferred
613 : // code where we can't handle lazy deopts for lack of a suitable bailout
614 : // ID. So we just try migration and signal failure if necessary,
615 : // which will also trigger a deopt.
616 28 : if (!JSObject::TryMigrateInstance(js_object)) return Smi::kZero;
617 1500028 : return *object;
618 : }
619 :
620 :
621 0 : RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) {
622 : SealHandleScope shs(isolate);
623 : DCHECK_EQ(1, args.length());
624 0 : CONVERT_ARG_CHECKED(Object, obj, 0);
625 0 : return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy());
626 : }
627 :
628 309786 : static bool IsValidAccessor(Isolate* isolate, Handle<Object> obj) {
629 465909 : return obj->IsNullOrUndefined(isolate) || obj->IsCallable();
630 : }
631 :
632 :
633 : // Implements part of 8.12.9 DefineOwnProperty.
634 : // There are 3 cases that lead here:
635 : // Step 4b - define a new accessor property.
636 : // Steps 9c & 12 - replace an existing data property with an accessor property.
637 : // Step 12 - update an existing accessor property with an accessor or generic
638 : // descriptor.
639 309786 : RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
640 154893 : HandleScope scope(isolate);
641 : DCHECK_EQ(5, args.length());
642 309786 : CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
643 154893 : CHECK(!obj->IsNull(isolate));
644 309786 : CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
645 154893 : CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
646 154893 : CHECK(IsValidAccessor(isolate, getter));
647 154893 : CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
648 154893 : CHECK(IsValidAccessor(isolate, setter));
649 309786 : CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 4);
650 :
651 154893 : RETURN_FAILURE_ON_EXCEPTION(
652 : isolate, JSObject::DefineAccessor(obj, name, getter, setter, attrs));
653 154887 : return isolate->heap()->undefined_value();
654 : }
655 :
656 :
657 668438 : RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) {
658 334219 : HandleScope scope(isolate);
659 : DCHECK_EQ(6, args.length());
660 668438 : CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
661 668438 : CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
662 334219 : CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
663 668438 : CONVERT_SMI_ARG_CHECKED(flag, 3);
664 668438 : CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 4);
665 668438 : CONVERT_SMI_ARG_CHECKED(index, 5);
666 :
667 668438 : StoreDataPropertyInLiteralICNexus nexus(vector, vector->ToSlot(index));
668 334219 : if (nexus.ic_state() == UNINITIALIZED) {
669 317969 : if (name->IsUniqueName()) {
670 635406 : nexus.ConfigureMonomorphic(name, handle(object->map()));
671 : } else {
672 266 : nexus.ConfigureMegamorphic(PROPERTY);
673 : }
674 16250 : } else if (nexus.ic_state() == MONOMORPHIC) {
675 42054 : if (nexus.FindFirstMap() != object->map() ||
676 13926 : nexus.GetFeedbackExtra() != *name) {
677 181 : nexus.ConfigureMegamorphic(PROPERTY);
678 : }
679 : }
680 :
681 : DataPropertyInLiteralFlags flags =
682 334219 : static_cast<DataPropertyInLiteralFlag>(flag);
683 :
684 668438 : PropertyAttributes attrs = (flags & DataPropertyInLiteralFlag::kDontEnum)
685 : ? PropertyAttributes::DONT_ENUM
686 334219 : : PropertyAttributes::NONE;
687 :
688 334219 : if (flags & DataPropertyInLiteralFlag::kSetFunctionName) {
689 : DCHECK(value->IsJSFunction());
690 : JSFunction::SetName(Handle<JSFunction>::cast(value), name,
691 9359 : isolate->factory()->empty_string());
692 : }
693 :
694 : LookupIterator it = LookupIterator::PropertyOrElement(
695 334219 : isolate, object, name, object, LookupIterator::OWN);
696 : // Cannot fail since this should only be called when
697 : // creating an object literal.
698 334219 : CHECK(JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attrs,
699 : Object::DONT_THROW)
700 : .IsJust());
701 334219 : return *object;
702 : }
703 :
704 3636 : RUNTIME_FUNCTION(Runtime_CollectTypeProfile) {
705 1818 : HandleScope scope(isolate);
706 : DCHECK_EQ(3, args.length());
707 3636 : CONVERT_ARG_HANDLE_CHECKED(Smi, position, 0);
708 1818 : CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
709 3636 : CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 2);
710 :
711 : DCHECK(FLAG_type_profile);
712 :
713 1818 : Handle<String> type = Object::TypeOf(isolate, value);
714 1818 : if (value->IsJSReceiver()) {
715 270 : Handle<JSReceiver> object = Handle<JSReceiver>::cast(value);
716 270 : type = JSReceiver::GetConstructorName(object);
717 : }
718 :
719 : DCHECK(vector->metadata()->HasTypeProfileSlot());
720 3636 : CollectTypeProfileNexus nexus(vector, vector->GetTypeProfileSlot());
721 1818 : nexus.Collect(type, position->value());
722 :
723 3636 : return isolate->heap()->undefined_value();
724 : }
725 :
726 : // Return property without being observable by accessors or interceptors.
727 0 : RUNTIME_FUNCTION(Runtime_GetDataProperty) {
728 0 : HandleScope scope(isolate);
729 : DCHECK_EQ(2, args.length());
730 0 : CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
731 0 : CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
732 0 : return *JSReceiver::GetDataProperty(object, name);
733 : }
734 :
735 0 : RUNTIME_FUNCTION(Runtime_GetConstructorName) {
736 0 : HandleScope scope(isolate);
737 : DCHECK_EQ(1, args.length());
738 0 : CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
739 :
740 0 : CHECK(!object->IsNullOrUndefined(isolate));
741 0 : Handle<JSReceiver> recv = Object::ToObject(isolate, object).ToHandleChecked();
742 0 : return *JSReceiver::GetConstructorName(recv);
743 : }
744 :
745 10242 : RUNTIME_FUNCTION(Runtime_HasFastPackedElements) {
746 : SealHandleScope shs(isolate);
747 : DCHECK_EQ(1, args.length());
748 10242 : CONVERT_ARG_CHECKED(HeapObject, obj, 0);
749 : return isolate->heap()->ToBoolean(
750 5121 : IsFastPackedElementsKind(obj->map()->elements_kind()));
751 : }
752 :
753 :
754 0 : RUNTIME_FUNCTION(Runtime_ValueOf) {
755 : SealHandleScope shs(isolate);
756 : DCHECK_EQ(1, args.length());
757 0 : CONVERT_ARG_CHECKED(Object, obj, 0);
758 0 : if (!obj->IsJSValue()) return obj;
759 0 : return JSValue::cast(obj)->value();
760 : }
761 :
762 :
763 4462 : RUNTIME_FUNCTION(Runtime_IsJSReceiver) {
764 : SealHandleScope shs(isolate);
765 : DCHECK_EQ(1, args.length());
766 2231 : CONVERT_ARG_CHECKED(Object, obj, 0);
767 2231 : return isolate->heap()->ToBoolean(obj->IsJSReceiver());
768 : }
769 :
770 :
771 18842 : RUNTIME_FUNCTION(Runtime_ClassOf) {
772 : SealHandleScope shs(isolate);
773 : DCHECK_EQ(1, args.length());
774 9421 : CONVERT_ARG_CHECKED(Object, obj, 0);
775 9421 : if (!obj->IsJSReceiver()) return isolate->heap()->null_value();
776 9421 : return JSReceiver::cast(obj)->class_name();
777 : }
778 :
779 :
780 22146 : RUNTIME_FUNCTION(Runtime_DefineGetterPropertyUnchecked) {
781 11073 : HandleScope scope(isolate);
782 : DCHECK_EQ(4, args.length());
783 22146 : CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
784 22146 : CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
785 22146 : CONVERT_ARG_HANDLE_CHECKED(JSFunction, getter, 2);
786 22146 : CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
787 :
788 11073 : if (String::cast(getter->shared()->name())->length() == 0) {
789 3186 : JSFunction::SetName(getter, name, isolate->factory()->get_string());
790 : }
791 :
792 22146 : RETURN_FAILURE_ON_EXCEPTION(
793 : isolate,
794 : JSObject::DefineAccessor(object, name, getter,
795 : isolate->factory()->null_value(), attrs));
796 11073 : return isolate->heap()->undefined_value();
797 : }
798 :
799 1120 : RUNTIME_FUNCTION(Runtime_CopyDataProperties) {
800 560 : HandleScope scope(isolate);
801 : DCHECK_EQ(2, args.length());
802 1120 : CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
803 560 : CONVERT_ARG_HANDLE_CHECKED(Object, source, 1);
804 :
805 : // 2. If source is undefined or null, let keys be an empty List.
806 1106 : if (source->IsUndefined(isolate) || source->IsNull(isolate)) {
807 28 : return isolate->heap()->undefined_value();
808 : }
809 :
810 532 : MAYBE_RETURN(JSReceiver::SetOrCopyDataProperties(isolate, target, source,
811 : nullptr, false),
812 : isolate->heap()->exception());
813 476 : return isolate->heap()->undefined_value();
814 : }
815 :
816 840 : RUNTIME_FUNCTION(Runtime_CopyDataPropertiesWithExcludedProperties) {
817 420 : HandleScope scope(isolate);
818 : DCHECK_LE(1, args.length());
819 420 : CONVERT_ARG_HANDLE_CHECKED(Object, source, 0);
820 :
821 : // 2. If source is undefined or null, let keys be an empty List.
822 840 : if (source->IsUndefined(isolate) || source->IsNull(isolate)) {
823 0 : return isolate->heap()->undefined_value();
824 : }
825 :
826 840 : ScopedVector<Handle<Object>> excluded_properties(args.length() - 1);
827 294 : for (int i = 1; i < args.length(); i++) {
828 294 : Handle<Object> property = args.at(i);
829 : uint32_t property_num;
830 : // We convert string to number if possible, in cases of computed
831 : // properties resolving to numbers, which would've been strings
832 : // instead because of our call to %ToName() in the desugaring for
833 : // computed properties.
834 546 : if (property->IsString() &&
835 252 : String::cast(*property)->AsArrayIndex(&property_num)) {
836 56 : property = isolate->factory()->NewNumberFromUint(property_num);
837 : }
838 :
839 294 : excluded_properties[i - 1] = property;
840 : }
841 :
842 : Handle<JSObject> target =
843 420 : isolate->factory()->NewJSObject(isolate->object_function());
844 420 : MAYBE_RETURN(JSReceiver::SetOrCopyDataProperties(isolate, target, source,
845 : &excluded_properties, false),
846 : isolate->heap()->exception());
847 420 : return *target;
848 : }
849 :
850 7056 : RUNTIME_FUNCTION(Runtime_DefineSetterPropertyUnchecked) {
851 3528 : HandleScope scope(isolate);
852 : DCHECK_EQ(4, args.length());
853 7056 : CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
854 7056 : CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
855 7056 : CONVERT_ARG_HANDLE_CHECKED(JSFunction, setter, 2);
856 7056 : CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
857 :
858 3528 : if (String::cast(setter->shared()->name())->length() == 0) {
859 294 : JSFunction::SetName(setter, name, isolate->factory()->set_string());
860 : }
861 :
862 7056 : RETURN_FAILURE_ON_EXCEPTION(
863 : isolate,
864 : JSObject::DefineAccessor(object, name, isolate->factory()->null_value(),
865 : setter, attrs));
866 3528 : return isolate->heap()->undefined_value();
867 : }
868 :
869 :
870 0 : RUNTIME_FUNCTION(Runtime_ToObject) {
871 0 : HandleScope scope(isolate);
872 : DCHECK_EQ(1, args.length());
873 0 : CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
874 0 : RETURN_RESULT_OR_FAILURE(isolate, Object::ToObject(isolate, object));
875 : }
876 :
877 :
878 364 : RUNTIME_FUNCTION(Runtime_ToPrimitive) {
879 182 : HandleScope scope(isolate);
880 : DCHECK_EQ(1, args.length());
881 182 : CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
882 546 : RETURN_RESULT_OR_FAILURE(isolate, Object::ToPrimitive(input));
883 : }
884 :
885 :
886 364 : RUNTIME_FUNCTION(Runtime_ToPrimitive_Number) {
887 182 : HandleScope scope(isolate);
888 : DCHECK_EQ(1, args.length());
889 182 : CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
890 364 : RETURN_RESULT_OR_FAILURE(
891 182 : isolate, Object::ToPrimitive(input, ToPrimitiveHint::kNumber));
892 : }
893 :
894 8696 : RUNTIME_FUNCTION(Runtime_ToNumber) {
895 4348 : HandleScope scope(isolate);
896 : DCHECK_EQ(1, args.length());
897 4348 : CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
898 13044 : RETURN_RESULT_OR_FAILURE(isolate, Object::ToNumber(input));
899 : }
900 :
901 :
902 0 : RUNTIME_FUNCTION(Runtime_ToInteger) {
903 0 : HandleScope scope(isolate);
904 : DCHECK_EQ(1, args.length());
905 0 : CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
906 0 : RETURN_RESULT_OR_FAILURE(isolate, Object::ToInteger(isolate, input));
907 : }
908 :
909 :
910 560 : RUNTIME_FUNCTION(Runtime_ToLength) {
911 280 : HandleScope scope(isolate);
912 : DCHECK_EQ(1, args.length());
913 280 : CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
914 840 : RETURN_RESULT_OR_FAILURE(isolate, Object::ToLength(isolate, input));
915 : }
916 :
917 :
918 11616172 : RUNTIME_FUNCTION(Runtime_ToString) {
919 5808086 : HandleScope scope(isolate);
920 : DCHECK_EQ(1, args.length());
921 5808086 : CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
922 17424258 : RETURN_RESULT_OR_FAILURE(isolate, Object::ToString(isolate, input));
923 : }
924 :
925 :
926 1436 : RUNTIME_FUNCTION(Runtime_ToName) {
927 718 : HandleScope scope(isolate);
928 : DCHECK_EQ(1, args.length());
929 718 : CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
930 2154 : RETURN_RESULT_OR_FAILURE(isolate, Object::ToName(isolate, input));
931 : }
932 :
933 :
934 0 : RUNTIME_FUNCTION(Runtime_SameValue) {
935 : SealHandleScope scope(isolate);
936 : DCHECK_EQ(2, args.length());
937 0 : CONVERT_ARG_CHECKED(Object, x, 0);
938 0 : CONVERT_ARG_CHECKED(Object, y, 1);
939 0 : return isolate->heap()->ToBoolean(x->SameValue(y));
940 : }
941 :
942 :
943 1680 : RUNTIME_FUNCTION(Runtime_SameValueZero) {
944 : SealHandleScope scope(isolate);
945 : DCHECK_EQ(2, args.length());
946 840 : CONVERT_ARG_CHECKED(Object, x, 0);
947 840 : CONVERT_ARG_CHECKED(Object, y, 1);
948 840 : return isolate->heap()->ToBoolean(x->SameValueZero(y));
949 : }
950 :
951 :
952 : // TODO(bmeurer): Kill this special wrapper and use TF compatible LessThan,
953 : // GreaterThan, etc. which return true or false.
954 446450 : RUNTIME_FUNCTION(Runtime_Compare) {
955 223225 : HandleScope scope(isolate);
956 : DCHECK_EQ(3, args.length());
957 223225 : CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
958 223225 : CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
959 223225 : CONVERT_ARG_HANDLE_CHECKED(Object, ncr, 2);
960 223225 : Maybe<ComparisonResult> result = Object::Compare(x, y);
961 223225 : if (result.IsJust()) {
962 222829 : switch (result.FromJust()) {
963 : case ComparisonResult::kLessThan:
964 37450 : return Smi::FromInt(LESS);
965 : case ComparisonResult::kEqual:
966 8272 : return Smi::FromInt(EQUAL);
967 : case ComparisonResult::kGreaterThan:
968 43568 : return Smi::FromInt(GREATER);
969 : case ComparisonResult::kUndefined:
970 : return *ncr;
971 : }
972 0 : UNREACHABLE();
973 : }
974 396 : return isolate->heap()->exception();
975 : }
976 :
977 2826 : RUNTIME_FUNCTION(Runtime_HasInPrototypeChain) {
978 1413 : HandleScope scope(isolate);
979 : DCHECK_EQ(2, args.length());
980 2826 : CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
981 1413 : CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
982 : Maybe<bool> result =
983 1413 : JSReceiver::HasInPrototypeChain(isolate, object, prototype);
984 1413 : MAYBE_RETURN(result, isolate->heap()->exception());
985 1294 : return isolate->heap()->ToBoolean(result.FromJust());
986 : }
987 :
988 :
989 : // ES6 section 7.4.7 CreateIterResultObject ( value, done )
990 0 : RUNTIME_FUNCTION(Runtime_CreateIterResultObject) {
991 0 : HandleScope scope(isolate);
992 : DCHECK_EQ(2, args.length());
993 0 : CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
994 0 : CONVERT_ARG_HANDLE_CHECKED(Object, done, 1);
995 0 : return *isolate->factory()->NewJSIteratorResult(value, done->BooleanValue());
996 : }
997 :
998 0 : RUNTIME_FUNCTION(Runtime_CreateKeyValueArray) {
999 0 : HandleScope scope(isolate);
1000 : DCHECK_EQ(2, args.length());
1001 0 : CONVERT_ARG_HANDLE_CHECKED(Object, key, 0);
1002 0 : CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
1003 0 : Handle<FixedArray> elements = isolate->factory()->NewFixedArray(2);
1004 0 : elements->set(0, *key);
1005 0 : elements->set(1, *value);
1006 : return *isolate->factory()->NewJSArrayWithElements(elements, FAST_ELEMENTS,
1007 0 : 2);
1008 : }
1009 :
1010 0 : RUNTIME_FUNCTION(Runtime_IsAccessCheckNeeded) {
1011 : SealHandleScope shs(isolate);
1012 : DCHECK_EQ(1, args.length());
1013 0 : CONVERT_ARG_CHECKED(Object, object, 0);
1014 0 : return isolate->heap()->ToBoolean(object->IsAccessCheckNeeded());
1015 : }
1016 :
1017 :
1018 152192 : RUNTIME_FUNCTION(Runtime_CreateDataProperty) {
1019 76096 : HandleScope scope(isolate);
1020 : DCHECK_EQ(3, args.length());
1021 152192 : CONVERT_ARG_HANDLE_CHECKED(JSReceiver, o, 0);
1022 76096 : CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1023 76096 : CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
1024 : bool success;
1025 : LookupIterator it = LookupIterator::PropertyOrElement(
1026 76096 : isolate, o, key, &success, LookupIterator::OWN);
1027 76096 : if (!success) return isolate->heap()->exception();
1028 76096 : MAYBE_RETURN(
1029 : JSReceiver::CreateDataProperty(&it, value, Object::THROW_ON_ERROR),
1030 : isolate->heap()->exception());
1031 76096 : return *value;
1032 : }
1033 :
1034 : // Checks that 22.2.2.1.1 Runtime Semantics: IterableToList produces exactly the
1035 : // same result as doing nothing.
1036 72774 : RUNTIME_FUNCTION(Runtime_IterableToListCanBeElided) {
1037 36387 : HandleScope scope(isolate);
1038 : DCHECK_EQ(1, args.length());
1039 72774 : CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
1040 :
1041 36387 : if (!obj->IsJSObject()) return isolate->heap()->ToBoolean(false);
1042 :
1043 : // While iteration alone may not have observable side-effects, calling
1044 : // toNumber on an object will. Make sure the arg is not an array of objects.
1045 36387 : ElementsKind kind = JSObject::cast(*obj)->GetElementsKind();
1046 36387 : if (!IsFastNumberElementsKind(kind)) return isolate->heap()->ToBoolean(false);
1047 :
1048 35238 : return isolate->heap()->ToBoolean(!obj->IterationHasObservableEffects());
1049 : }
1050 :
1051 : } // namespace internal
1052 : } // namespace v8
|