blob: 8c9c2305f1a14201a71bd2d3e795cbb682c5f8e0 [file] [log] [blame]
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001// 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005#include "src/runtime/runtime-utils.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006
7#include "src/arguments.h"
8#include "src/bootstrapper.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009#include "src/debug/debug.h"
10#include "src/isolate-inl.h"
Ben Murdochc5610432016-08-08 18:44:38 +010011#include "src/json-stringifier.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000012#include "src/messages.h"
13#include "src/property-descriptor.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040014#include "src/runtime/runtime.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040015
16namespace v8 {
17namespace internal {
18
Emily Bernierd0a1eb72015-03-24 16:35:39 -040019MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
20 Handle<Object> object,
Ben Murdoch097c5b22016-05-18 11:27:45 +010021 Handle<Object> key) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040022 if (object->IsUndefined() || object->IsNull()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000023 THROW_NEW_ERROR(
24 isolate,
25 NewTypeError(MessageTemplate::kNonObjectPropertyLoad, key, object),
26 Object);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040027 }
28
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000029 bool success = false;
30 LookupIterator it =
31 LookupIterator::PropertyOrElement(isolate, object, key, &success);
32 if (!success) return MaybeHandle<Object>();
33
Ben Murdoch097c5b22016-05-18 11:27:45 +010034 return Object::GetProperty(&it);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000035}
36
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000037static MaybeHandle<Object> KeyedGetObjectProperty(Isolate* isolate,
38 Handle<Object> receiver_obj,
Ben Murdoch097c5b22016-05-18 11:27:45 +010039 Handle<Object> key_obj) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000040 // Fast cases for getting named properties of the receiver JSObject
41 // itself.
42 //
43 // The global proxy objects has to be excluded since LookupOwn on
44 // the global proxy object can return a valid result even though the
45 // global proxy object never has properties. This is the case
46 // because the global proxy object forwards everything to its hidden
47 // prototype including own lookups.
48 //
49 // Additionally, we need to make sure that we do not cache results
50 // for objects that require access checks.
51 if (receiver_obj->IsJSObject()) {
52 if (!receiver_obj->IsJSGlobalProxy() &&
53 !receiver_obj->IsAccessCheckNeeded() && key_obj->IsName()) {
54 DisallowHeapAllocation no_allocation;
55 Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
56 Handle<Name> key = Handle<Name>::cast(key_obj);
57 if (receiver->IsJSGlobalObject()) {
58 // Attempt dictionary lookup.
59 GlobalDictionary* dictionary = receiver->global_dictionary();
60 int entry = dictionary->FindEntry(key);
61 if (entry != GlobalDictionary::kNotFound) {
62 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
63 PropertyCell* cell = PropertyCell::cast(dictionary->ValueAt(entry));
64 if (cell->property_details().type() == DATA) {
65 Object* value = cell->value();
66 if (!value->IsTheHole()) return Handle<Object>(value, isolate);
67 // If value is the hole (meaning, absent) do the general lookup.
68 }
69 }
70 } else if (!receiver->HasFastProperties()) {
71 // Attempt dictionary lookup.
72 NameDictionary* dictionary = receiver->property_dictionary();
73 int entry = dictionary->FindEntry(key);
74 if ((entry != NameDictionary::kNotFound) &&
75 (dictionary->DetailsAt(entry).type() == DATA)) {
76 Object* value = dictionary->ValueAt(entry);
77 return Handle<Object>(value, isolate);
78 }
79 }
80 } else if (key_obj->IsSmi()) {
81 // JSObject without a name key. If the key is a Smi, check for a
82 // definite out-of-bounds access to elements, which is a strong indicator
83 // that subsequent accesses will also call the runtime. Proactively
84 // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
85 // doubles for those future calls in the case that the elements would
86 // become FAST_DOUBLE_ELEMENTS.
87 Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
88 ElementsKind elements_kind = js_object->GetElementsKind();
89 if (IsFastDoubleElementsKind(elements_kind)) {
90 if (Smi::cast(*key_obj)->value() >= js_object->elements()->length()) {
91 elements_kind = IsFastHoleyElementsKind(elements_kind)
92 ? FAST_HOLEY_ELEMENTS
93 : FAST_ELEMENTS;
94 JSObject::TransitionElementsKind(js_object, elements_kind);
95 }
96 } else {
97 DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
98 !IsFastElementsKind(elements_kind));
99 }
100 }
101 } else if (receiver_obj->IsString() && key_obj->IsSmi()) {
102 // Fast case for string indexing using [] with a smi index.
103 Handle<String> str = Handle<String>::cast(receiver_obj);
104 int index = Handle<Smi>::cast(key_obj)->value();
105 if (index >= 0 && index < str->length()) {
106 Factory* factory = isolate->factory();
107 return factory->LookupSingleCharacterStringFromCode(
108 String::Flatten(str)->Get(index));
109 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400110 }
111
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000112 // Fall back to GetObjectProperty.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100113 return Runtime::GetObjectProperty(isolate, receiver_obj, key_obj);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000114}
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400115
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000116
117Maybe<bool> Runtime::DeleteObjectProperty(Isolate* isolate,
118 Handle<JSReceiver> receiver,
119 Handle<Object> key,
120 LanguageMode language_mode) {
121 bool success = false;
122 LookupIterator it = LookupIterator::PropertyOrElement(
Ben Murdochc5610432016-08-08 18:44:38 +0100123 isolate, receiver, key, &success, LookupIterator::OWN);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000124 if (!success) return Nothing<bool>();
125
126 return JSReceiver::DeleteProperty(&it, language_mode);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400127}
128
Ben Murdochda12d292016-06-02 14:46:10 +0100129// ES6 19.1.3.2
130RUNTIME_FUNCTION(Runtime_ObjectHasOwnProperty) {
131 HandleScope scope(isolate);
132 Handle<Object> property = args.at<Object>(1);
133
134 Handle<Name> key;
135 uint32_t index;
136 bool key_is_array_index = property->ToArrayIndex(&index);
137
138 if (!key_is_array_index) {
139 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key,
140 Object::ToName(isolate, property));
141 key_is_array_index = key->AsArrayIndex(&index);
142 }
143
144 Handle<Object> object = args.at<Object>(0);
145
146 if (object->IsJSObject()) {
147 Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
148 // Fast case: either the key is a real named property or it is not
149 // an array index and there are no interceptors or hidden
150 // prototypes.
151 // TODO(jkummerow): Make JSReceiver::HasOwnProperty fast enough to
152 // handle all cases directly (without this custom fast path).
153 {
154 LookupIterator::Configuration c = LookupIterator::OWN_SKIP_INTERCEPTOR;
155 LookupIterator it =
156 key_is_array_index ? LookupIterator(isolate, js_obj, index, js_obj, c)
157 : LookupIterator(js_obj, key, js_obj, c);
158 Maybe<bool> maybe = JSReceiver::HasProperty(&it);
159 if (maybe.IsNothing()) return isolate->heap()->exception();
160 DCHECK(!isolate->has_pending_exception());
161 if (maybe.FromJust()) return isolate->heap()->true_value();
162 }
163
164 Map* map = js_obj->map();
165 if (!map->has_hidden_prototype() &&
166 (key_is_array_index ? !map->has_indexed_interceptor()
167 : !map->has_named_interceptor())) {
168 return isolate->heap()->false_value();
169 }
170
171 // Slow case.
Ben Murdochc5610432016-08-08 18:44:38 +0100172 LookupIterator::Configuration c = LookupIterator::OWN;
Ben Murdochda12d292016-06-02 14:46:10 +0100173 LookupIterator it = key_is_array_index
174 ? LookupIterator(isolate, js_obj, index, js_obj, c)
175 : LookupIterator(js_obj, key, js_obj, c);
176
177 Maybe<bool> maybe = JSReceiver::HasProperty(&it);
178 if (maybe.IsNothing()) return isolate->heap()->exception();
179 DCHECK(!isolate->has_pending_exception());
180 return isolate->heap()->ToBoolean(maybe.FromJust());
181
182 } else if (object->IsJSProxy()) {
183 if (key.is_null()) {
184 DCHECK(key_is_array_index);
185 key = isolate->factory()->Uint32ToString(index);
186 }
187
188 Maybe<bool> result =
189 JSReceiver::HasOwnProperty(Handle<JSProxy>::cast(object), key);
190 if (!result.IsJust()) return isolate->heap()->exception();
191 return isolate->heap()->ToBoolean(result.FromJust());
192
193 } else if (object->IsString()) {
194 return isolate->heap()->ToBoolean(
195 key_is_array_index
196 ? index < static_cast<uint32_t>(String::cast(*object)->length())
197 : key->Equals(isolate->heap()->length_string()));
198 } else if (object->IsNull() || object->IsUndefined()) {
199 THROW_NEW_ERROR_RETURN_FAILURE(
200 isolate, NewTypeError(MessageTemplate::kUndefinedOrNullToObject));
201 }
202
203 return isolate->heap()->false_value();
204}
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400205
206MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
207 Handle<Object> object,
208 Handle<Object> key,
209 Handle<Object> value,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000210 LanguageMode language_mode) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400211 if (object->IsUndefined() || object->IsNull()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000212 THROW_NEW_ERROR(
213 isolate,
214 NewTypeError(MessageTemplate::kNonObjectPropertyStore, key, object),
215 Object);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400216 }
217
218 // Check if the given key is an array index.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000219 bool success = false;
220 LookupIterator it =
221 LookupIterator::PropertyOrElement(isolate, object, key, &success);
222 if (!success) return MaybeHandle<Object>();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400223
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000224 MAYBE_RETURN_NULL(Object::SetProperty(&it, value, language_mode,
225 Object::MAY_BE_STORE_FROM_KEYED));
226 return value;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400227}
228
Ben Murdochc5610432016-08-08 18:44:38 +0100229MaybeHandle<Object> Runtime::BasicJsonStringify(Isolate* isolate,
230 Handle<Object> object) {
231 return BasicJsonStringifier(isolate).Stringify(object);
232}
233
234MaybeHandle<Object> Runtime::BasicJsonStringifyString(Isolate* isolate,
235 Handle<String> string) {
236 return BasicJsonStringifier::StringifyString(isolate, string);
237}
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400238
239RUNTIME_FUNCTION(Runtime_GetPrototype) {
240 HandleScope scope(isolate);
241 DCHECK(args.length() == 1);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100242 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000243 Handle<Object> prototype;
244 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, prototype,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100245 JSReceiver::GetPrototype(isolate, obj));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000246 return *prototype;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400247}
248
249
250RUNTIME_FUNCTION(Runtime_InternalSetPrototype) {
251 HandleScope scope(isolate);
252 DCHECK(args.length() == 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000253 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400254 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000255 MAYBE_RETURN(
256 JSReceiver::SetPrototype(obj, prototype, false, Object::THROW_ON_ERROR),
257 isolate->heap()->exception());
258 return *obj;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400259}
260
261
262RUNTIME_FUNCTION(Runtime_SetPrototype) {
263 HandleScope scope(isolate);
264 DCHECK(args.length() == 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000265 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400266 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000267 MAYBE_RETURN(
268 JSReceiver::SetPrototype(obj, prototype, true, Object::THROW_ON_ERROR),
269 isolate->heap()->exception());
270 return *obj;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400271}
272
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400273RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
274 HandleScope scope(isolate);
275 DCHECK(args.length() == 2);
276 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
277 CONVERT_SMI_ARG_CHECKED(properties, 1);
278 // Conservative upper limit to prevent fuzz tests from going OOM.
279 RUNTIME_ASSERT(properties <= 100000);
280 if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
281 JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties,
282 "OptimizeForAdding");
283 }
284 return *object;
285}
286
287
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000288RUNTIME_FUNCTION(Runtime_LoadGlobalViaContext) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400289 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000290 DCHECK_EQ(1, args.length());
291 CONVERT_SMI_ARG_CHECKED(slot, 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400292
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000293 // Go up context chain to the script context.
294 Handle<Context> script_context(isolate->context()->script_context(), isolate);
295 DCHECK(script_context->IsScriptContext());
296 DCHECK(script_context->get(slot)->IsPropertyCell());
297
298 // Lookup the named property on the global object.
299 Handle<ScopeInfo> scope_info(script_context->scope_info(), isolate);
300 Handle<Name> name(scope_info->ContextSlotName(slot), isolate);
301 Handle<JSGlobalObject> global_object(script_context->global_object(),
302 isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100303 LookupIterator it(global_object, name, global_object, LookupIterator::OWN);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000304
305 // Switch to fast mode only if there is a data property and it's not on
306 // a hidden prototype.
307 if (it.state() == LookupIterator::DATA &&
308 it.GetHolder<Object>().is_identical_to(global_object)) {
309 // Now update the cell in the script context.
310 Handle<PropertyCell> cell = it.GetPropertyCell();
311 script_context->set(slot, *cell);
312 } else {
313 // This is not a fast case, so keep this access in a slow mode.
314 // Store empty_property_cell here to release the outdated property cell.
315 script_context->set(slot, isolate->heap()->empty_property_cell());
316 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400317
318 Handle<Object> result;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000319 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400320 return *result;
321}
322
323
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000324namespace {
325
326Object* StoreGlobalViaContext(Isolate* isolate, int slot, Handle<Object> value,
327 LanguageMode language_mode) {
328 // Go up context chain to the script context.
329 Handle<Context> script_context(isolate->context()->script_context(), isolate);
330 DCHECK(script_context->IsScriptContext());
331 DCHECK(script_context->get(slot)->IsPropertyCell());
332
333 // Lookup the named property on the global object.
334 Handle<ScopeInfo> scope_info(script_context->scope_info(), isolate);
335 Handle<Name> name(scope_info->ContextSlotName(slot), isolate);
336 Handle<JSGlobalObject> global_object(script_context->global_object(),
337 isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100338 LookupIterator it(global_object, name, global_object, LookupIterator::OWN);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000339
340 // Switch to fast mode only if there is a data property and it's not on
341 // a hidden prototype.
342 if (it.state() == LookupIterator::DATA &&
343 it.GetHolder<Object>().is_identical_to(global_object)) {
344 // Now update cell in the script context.
345 Handle<PropertyCell> cell = it.GetPropertyCell();
346 script_context->set(slot, *cell);
347 } else {
348 // This is not a fast case, so keep this access in a slow mode.
349 // Store empty_property_cell here to release the outdated property cell.
350 script_context->set(slot, isolate->heap()->empty_property_cell());
351 }
352
353 MAYBE_RETURN(Object::SetProperty(&it, value, language_mode,
354 Object::CERTAINLY_NOT_STORE_FROM_KEYED),
355 isolate->heap()->exception());
356 return *value;
357}
358
359} // namespace
360
361
362RUNTIME_FUNCTION(Runtime_StoreGlobalViaContext_Sloppy) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400363 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000364 DCHECK_EQ(2, args.length());
365 CONVERT_SMI_ARG_CHECKED(slot, 0);
366 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400367
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000368 return StoreGlobalViaContext(isolate, slot, value, SLOPPY);
369}
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400370
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000371
372RUNTIME_FUNCTION(Runtime_StoreGlobalViaContext_Strict) {
373 HandleScope scope(isolate);
374 DCHECK_EQ(2, args.length());
375 CONVERT_SMI_ARG_CHECKED(slot, 0);
376 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
377
378 return StoreGlobalViaContext(isolate, slot, value, STRICT);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400379}
380
381
382RUNTIME_FUNCTION(Runtime_GetProperty) {
383 HandleScope scope(isolate);
384 DCHECK(args.length() == 2);
385
386 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
387 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000388
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400389 Handle<Object> result;
390 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100391 isolate, result, Runtime::GetObjectProperty(isolate, object, key));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000392 return *result;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400393}
394
395
396// KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
397RUNTIME_FUNCTION(Runtime_KeyedGetProperty) {
398 HandleScope scope(isolate);
399 DCHECK(args.length() == 2);
400
401 CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
402 CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
403
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400404 Handle<Object> result;
405 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100406 isolate, result, KeyedGetObjectProperty(isolate, receiver_obj, key_obj));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400407 return *result;
408}
409
410
411RUNTIME_FUNCTION(Runtime_AddNamedProperty) {
412 HandleScope scope(isolate);
413 RUNTIME_ASSERT(args.length() == 4);
414
415 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000416 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400417 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000418 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400419
420#ifdef DEBUG
421 uint32_t index = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000422 DCHECK(!name->ToArrayIndex(&index));
Ben Murdochda12d292016-06-02 14:46:10 +0100423 LookupIterator it(object, name, object, LookupIterator::OWN_SKIP_INTERCEPTOR);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400424 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000425 if (!maybe.IsJust()) return isolate->heap()->exception();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400426 RUNTIME_ASSERT(!it.IsFound());
427#endif
428
429 Handle<Object> result;
430 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
431 isolate, result,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000432 JSObject::SetOwnPropertyIgnoreAttributes(object, name, value, attrs));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400433 return *result;
434}
435
436
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000437// Adds an element to an array.
438// This is used to create an indexed data property into an array.
439RUNTIME_FUNCTION(Runtime_AddElement) {
440 HandleScope scope(isolate);
441 RUNTIME_ASSERT(args.length() == 3);
442
443 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
444 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
445 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
446
447 uint32_t index = 0;
448 CHECK(key->ToArrayIndex(&index));
449
450#ifdef DEBUG
Ben Murdochda12d292016-06-02 14:46:10 +0100451 LookupIterator it(isolate, object, index, object,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000452 LookupIterator::OWN_SKIP_INTERCEPTOR);
453 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
454 if (!maybe.IsJust()) return isolate->heap()->exception();
455 RUNTIME_ASSERT(!it.IsFound());
456
457 if (object->IsJSArray()) {
458 Handle<JSArray> array = Handle<JSArray>::cast(object);
459 RUNTIME_ASSERT(!JSArray::WouldChangeReadOnlyLength(array, index));
460 }
461#endif
462
463 Handle<Object> result;
464 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
465 isolate, result,
466 JSObject::SetOwnElementIgnoreAttributes(object, index, value, NONE));
467 return *result;
468}
469
470
471RUNTIME_FUNCTION(Runtime_AppendElement) {
472 HandleScope scope(isolate);
473 RUNTIME_ASSERT(args.length() == 2);
474
475 CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
476 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
477
478 uint32_t index;
479 CHECK(array->length()->ToArrayIndex(&index));
480
481 Handle<Object> result;
482 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
483 isolate, result, JSObject::AddDataElement(array, index, value, NONE));
484 JSObject::ValidateElements(array);
485 return *array;
486}
487
488
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400489RUNTIME_FUNCTION(Runtime_SetProperty) {
490 HandleScope scope(isolate);
491 RUNTIME_ASSERT(args.length() == 4);
492
493 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
494 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
495 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000496 CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode_arg, 3);
497 LanguageMode language_mode = language_mode_arg;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400498
499 Handle<Object> result;
500 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
501 isolate, result,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000502 Runtime::SetObjectProperty(isolate, object, key, value, language_mode));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400503 return *result;
504}
505
506
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000507namespace {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400508
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000509// ES6 section 12.5.4.
510Object* DeleteProperty(Isolate* isolate, Handle<Object> object,
511 Handle<Object> key, LanguageMode language_mode) {
512 Handle<JSReceiver> receiver;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100513 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
514 Object::ToObject(isolate, object));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000515 Maybe<bool> result =
516 Runtime::DeleteObjectProperty(isolate, receiver, key, language_mode);
517 MAYBE_RETURN(result, isolate->heap()->exception());
518 return isolate->heap()->ToBoolean(result.FromJust());
519}
520
521} // namespace
522
523
524RUNTIME_FUNCTION(Runtime_DeleteProperty_Sloppy) {
525 HandleScope scope(isolate);
526 DCHECK_EQ(2, args.length());
527 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400528 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000529 return DeleteProperty(isolate, object, key, SLOPPY);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400530}
531
532
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000533RUNTIME_FUNCTION(Runtime_DeleteProperty_Strict) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400534 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000535 DCHECK_EQ(2, args.length());
536 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
537 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
538 return DeleteProperty(isolate, object, key, STRICT);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400539}
540
541
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000542// ES6 section 12.9.3, operator in.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400543RUNTIME_FUNCTION(Runtime_HasProperty) {
544 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000545 DCHECK_EQ(2, args.length());
546 CONVERT_ARG_HANDLE_CHECKED(Object, key, 0);
547 CONVERT_ARG_HANDLE_CHECKED(Object, object, 1);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400548
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000549 // Check that {object} is actually a receiver.
550 if (!object->IsJSReceiver()) {
551 THROW_NEW_ERROR_RETURN_FAILURE(
552 isolate,
553 NewTypeError(MessageTemplate::kInvalidInOperatorUse, key, object));
554 }
555 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
556
557 // Convert the {key} to a name.
558 Handle<Name> name;
559 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
560 Object::ToName(isolate, key));
561
562 // Lookup the {name} on {receiver}.
563 Maybe<bool> maybe = JSReceiver::HasProperty(receiver, name);
564 if (!maybe.IsJust()) return isolate->heap()->exception();
565 return isolate->heap()->ToBoolean(maybe.FromJust());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400566}
567
568
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000569RUNTIME_FUNCTION(Runtime_PropertyIsEnumerable) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400570 HandleScope scope(isolate);
571 DCHECK(args.length() == 2);
572
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000573 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400574 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
575
576 Maybe<PropertyAttributes> maybe =
577 JSReceiver::GetOwnPropertyAttributes(object, key);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000578 if (!maybe.IsJust()) return isolate->heap()->exception();
579 if (maybe.FromJust() == ABSENT) return isolate->heap()->false_value();
580 return isolate->heap()->ToBoolean((maybe.FromJust() & DONT_ENUM) == 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400581}
582
583
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000584RUNTIME_FUNCTION(Runtime_GetOwnPropertyKeys) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400585 HandleScope scope(isolate);
586 DCHECK(args.length() == 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000587 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400588 CONVERT_SMI_ARG_CHECKED(filter_value, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000589 PropertyFilter filter = static_cast<PropertyFilter>(filter_value);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400590
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000591 Handle<FixedArray> keys;
592 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100593 isolate, keys,
594 JSReceiver::GetKeys(object, OWN_ONLY, filter, CONVERT_TO_STRING));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400595
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000596 return *isolate->factory()->NewJSArrayWithElements(keys);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400597}
598
599
600// Return information on whether an object has a named or indexed interceptor.
601// args[0]: object
602RUNTIME_FUNCTION(Runtime_GetInterceptorInfo) {
603 HandleScope scope(isolate);
604 DCHECK(args.length() == 1);
605 if (!args[0]->IsJSObject()) {
606 return Smi::FromInt(0);
607 }
608 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
609
610 int result = 0;
611 if (obj->HasNamedInterceptor()) result |= 2;
612 if (obj->HasIndexedInterceptor()) result |= 1;
613
614 return Smi::FromInt(result);
615}
616
617
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400618RUNTIME_FUNCTION(Runtime_ToFastProperties) {
619 HandleScope scope(isolate);
620 DCHECK(args.length() == 1);
621 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000622 if (object->IsJSObject() && !object->IsJSGlobalObject()) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400623 JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0,
624 "RuntimeToFastProperties");
625 }
626 return *object;
627}
628
629
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400630RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) {
631 HandleScope scope(isolate);
632 DCHECK(args.length() == 0);
633 return *isolate->factory()->NewHeapNumber(0);
634}
635
636
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400637RUNTIME_FUNCTION(Runtime_NewObject) {
638 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000639 DCHECK_EQ(2, args.length());
640 CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
641 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, new_target, 1);
642 Handle<JSObject> result;
643 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
644 JSObject::New(target, new_target));
645 return *result;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400646}
647
648
649RUNTIME_FUNCTION(Runtime_FinalizeInstanceSize) {
650 HandleScope scope(isolate);
651 DCHECK(args.length() == 1);
652
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000653 CONVERT_ARG_HANDLE_CHECKED(Map, initial_map, 0);
654 initial_map->CompleteInobjectSlackTracking();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400655
656 return isolate->heap()->undefined_value();
657}
658
659
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400660RUNTIME_FUNCTION(Runtime_LoadMutableDouble) {
661 HandleScope scope(isolate);
662 DCHECK(args.length() == 2);
663 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
664 CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1);
665 RUNTIME_ASSERT((index->value() & 1) == 1);
666 FieldIndex field_index =
667 FieldIndex::ForLoadByFieldIndex(object->map(), index->value());
668 if (field_index.is_inobject()) {
669 RUNTIME_ASSERT(field_index.property_index() <
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000670 object->map()->GetInObjectProperties());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400671 } else {
672 RUNTIME_ASSERT(field_index.outobject_array_index() <
673 object->properties()->length());
674 }
675 return *JSObject::FastPropertyAt(object, Representation::Double(),
676 field_index);
677}
678
679
680RUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
681 HandleScope scope(isolate);
682 DCHECK(args.length() == 1);
683 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
684 if (!object->IsJSObject()) return Smi::FromInt(0);
685 Handle<JSObject> js_object = Handle<JSObject>::cast(object);
686 if (!js_object->map()->is_deprecated()) return Smi::FromInt(0);
687 // This call must not cause lazy deopts, because it's called from deferred
688 // code where we can't handle lazy deopts for lack of a suitable bailout
689 // ID. So we just try migration and signal failure if necessary,
690 // which will also trigger a deopt.
691 if (!JSObject::TryMigrateInstance(js_object)) return Smi::FromInt(0);
692 return *object;
693}
694
695
696RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) {
697 SealHandleScope shs(isolate);
698 DCHECK(args.length() == 1);
699 CONVERT_ARG_CHECKED(Object, obj, 0);
700 return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy());
701}
702
703
704static bool IsValidAccessor(Handle<Object> obj) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000705 return obj->IsUndefined() || obj->IsCallable() || obj->IsNull();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400706}
707
708
709// Implements part of 8.12.9 DefineOwnProperty.
710// There are 3 cases that lead here:
711// Step 4b - define a new accessor property.
712// Steps 9c & 12 - replace an existing data property with an accessor property.
713// Step 12 - update an existing accessor property with an accessor or generic
714// descriptor.
715RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
716 HandleScope scope(isolate);
717 DCHECK(args.length() == 5);
718 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
719 RUNTIME_ASSERT(!obj->IsNull());
720 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
721 CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
722 RUNTIME_ASSERT(IsValidAccessor(getter));
723 CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
724 RUNTIME_ASSERT(IsValidAccessor(setter));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000725 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 4);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400726
727 RETURN_FAILURE_ON_EXCEPTION(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000728 isolate, JSObject::DefineAccessor(obj, name, getter, setter, attrs));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400729 return isolate->heap()->undefined_value();
730}
731
732
Ben Murdoch097c5b22016-05-18 11:27:45 +0100733RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) {
734 HandleScope scope(isolate);
735 DCHECK(args.length() == 5);
736 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
737 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
738 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
739 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
740 CONVERT_SMI_ARG_CHECKED(set_function_name, 4);
741
742 if (FLAG_harmony_function_name && set_function_name) {
743 DCHECK(value->IsJSFunction());
744 JSFunction::SetName(Handle<JSFunction>::cast(value), name,
745 isolate->factory()->empty_string());
746 }
747
Ben Murdochda12d292016-06-02 14:46:10 +0100748 LookupIterator it = LookupIterator::PropertyOrElement(
749 isolate, object, name, object, LookupIterator::OWN);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100750 // Cannot fail since this should only be called when
751 // creating an object literal.
752 CHECK(JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attrs,
753 Object::DONT_THROW)
754 .IsJust());
755 return *object;
756}
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400757
758// Return property without being observable by accessors or interceptors.
759RUNTIME_FUNCTION(Runtime_GetDataProperty) {
760 HandleScope scope(isolate);
761 DCHECK(args.length() == 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000762 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
763 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
764 return *JSReceiver::GetDataProperty(object, name);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400765}
766
767
768RUNTIME_FUNCTION(Runtime_HasFastPackedElements) {
769 SealHandleScope shs(isolate);
770 DCHECK(args.length() == 1);
771 CONVERT_ARG_CHECKED(HeapObject, obj, 0);
772 return isolate->heap()->ToBoolean(
773 IsFastPackedElementsKind(obj->map()->elements_kind()));
774}
775
776
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000777RUNTIME_FUNCTION(Runtime_ValueOf) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400778 SealHandleScope shs(isolate);
779 DCHECK(args.length() == 1);
780 CONVERT_ARG_CHECKED(Object, obj, 0);
781 if (!obj->IsJSValue()) return obj;
782 return JSValue::cast(obj)->value();
783}
784
785
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000786RUNTIME_FUNCTION(Runtime_IsJSReceiver) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400787 SealHandleScope shs(isolate);
788 DCHECK(args.length() == 1);
789 CONVERT_ARG_CHECKED(Object, obj, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000790 return isolate->heap()->ToBoolean(obj->IsJSReceiver());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400791}
792
793
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000794RUNTIME_FUNCTION(Runtime_ClassOf) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400795 SealHandleScope shs(isolate);
796 DCHECK(args.length() == 1);
797 CONVERT_ARG_CHECKED(Object, obj, 0);
798 if (!obj->IsJSReceiver()) return isolate->heap()->null_value();
799 return JSReceiver::cast(obj)->class_name();
800}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000801
802
803RUNTIME_FUNCTION(Runtime_DefineGetterPropertyUnchecked) {
804 HandleScope scope(isolate);
805 DCHECK(args.length() == 4);
806 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
807 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
808 CONVERT_ARG_HANDLE_CHECKED(JSFunction, getter, 2);
809 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
810
Ben Murdoch097c5b22016-05-18 11:27:45 +0100811 if (FLAG_harmony_function_name &&
812 String::cast(getter->shared()->name())->length() == 0) {
813 JSFunction::SetName(getter, name, isolate->factory()->get_string());
814 }
815
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000816 RETURN_FAILURE_ON_EXCEPTION(
817 isolate,
818 JSObject::DefineAccessor(object, name, getter,
819 isolate->factory()->null_value(), attrs));
820 return isolate->heap()->undefined_value();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400821}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000822
823
824RUNTIME_FUNCTION(Runtime_DefineSetterPropertyUnchecked) {
825 HandleScope scope(isolate);
826 DCHECK(args.length() == 4);
827 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
828 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
829 CONVERT_ARG_HANDLE_CHECKED(JSFunction, setter, 2);
830 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
831
Ben Murdoch097c5b22016-05-18 11:27:45 +0100832 if (FLAG_harmony_function_name &&
833 String::cast(setter->shared()->name())->length() == 0) {
834 JSFunction::SetName(setter, name, isolate->factory()->set_string());
835 }
836
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000837 RETURN_FAILURE_ON_EXCEPTION(
838 isolate,
839 JSObject::DefineAccessor(object, name, isolate->factory()->null_value(),
840 setter, attrs));
841 return isolate->heap()->undefined_value();
842}
843
844
845RUNTIME_FUNCTION(Runtime_ToObject) {
846 HandleScope scope(isolate);
847 DCHECK_EQ(1, args.length());
848 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
849 Handle<JSReceiver> receiver;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100850 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
851 Object::ToObject(isolate, object));
852 return *receiver;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000853}
854
855
856RUNTIME_FUNCTION(Runtime_ToPrimitive) {
857 HandleScope scope(isolate);
858 DCHECK_EQ(1, args.length());
859 CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
860 Handle<Object> result;
861 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
862 Object::ToPrimitive(input));
863 return *result;
864}
865
866
867RUNTIME_FUNCTION(Runtime_ToPrimitive_Number) {
868 HandleScope scope(isolate);
869 DCHECK_EQ(1, args.length());
870 CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
871 Handle<Object> result;
872 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
873 isolate, result, Object::ToPrimitive(input, ToPrimitiveHint::kNumber));
874 return *result;
875}
876
877
878RUNTIME_FUNCTION(Runtime_ToPrimitive_String) {
879 HandleScope scope(isolate);
880 DCHECK_EQ(1, args.length());
881 CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
882 Handle<Object> result;
883 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
884 isolate, result, Object::ToPrimitive(input, ToPrimitiveHint::kString));
885 return *result;
886}
887
888
889RUNTIME_FUNCTION(Runtime_ToNumber) {
890 HandleScope scope(isolate);
891 DCHECK_EQ(1, args.length());
892 CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
893 Handle<Object> result;
894 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::ToNumber(input));
895 return *result;
896}
897
898
899RUNTIME_FUNCTION(Runtime_ToInteger) {
900 HandleScope scope(isolate);
901 DCHECK_EQ(1, args.length());
902 CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
903 Handle<Object> result;
904 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
905 Object::ToInteger(isolate, input));
906 return *result;
907}
908
909
910RUNTIME_FUNCTION(Runtime_ToLength) {
911 HandleScope scope(isolate);
912 DCHECK_EQ(1, args.length());
913 CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
914 Handle<Object> result;
915 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
916 Object::ToLength(isolate, input));
917 return *result;
918}
919
920
921RUNTIME_FUNCTION(Runtime_ToString) {
922 HandleScope scope(isolate);
923 DCHECK_EQ(1, args.length());
924 CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
925 Handle<Object> result;
926 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
927 Object::ToString(isolate, input));
928 return *result;
929}
930
931
932RUNTIME_FUNCTION(Runtime_ToName) {
933 HandleScope scope(isolate);
934 DCHECK_EQ(1, args.length());
935 CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
936 Handle<Object> result;
937 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
938 Object::ToName(isolate, input));
939 return *result;
940}
941
942
Ben Murdoch097c5b22016-05-18 11:27:45 +0100943RUNTIME_FUNCTION(Runtime_SameValue) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000944 SealHandleScope scope(isolate);
945 DCHECK_EQ(2, args.length());
946 CONVERT_ARG_CHECKED(Object, x, 0);
947 CONVERT_ARG_CHECKED(Object, y, 1);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100948 return isolate->heap()->ToBoolean(x->SameValue(y));
949}
950
951
952RUNTIME_FUNCTION(Runtime_SameValueZero) {
953 SealHandleScope scope(isolate);
954 DCHECK_EQ(2, args.length());
955 CONVERT_ARG_CHECKED(Object, x, 0);
956 CONVERT_ARG_CHECKED(Object, y, 1);
957 return isolate->heap()->ToBoolean(x->SameValueZero(y));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000958}
959
960
961// TODO(bmeurer): Kill this special wrapper and use TF compatible LessThan,
962// GreaterThan, etc. which return true or false.
963RUNTIME_FUNCTION(Runtime_Compare) {
964 HandleScope scope(isolate);
965 DCHECK_EQ(3, args.length());
966 CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
967 CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
968 CONVERT_ARG_HANDLE_CHECKED(Object, ncr, 2);
969 Maybe<ComparisonResult> result = Object::Compare(x, y);
970 if (result.IsJust()) {
971 switch (result.FromJust()) {
972 case ComparisonResult::kLessThan:
973 return Smi::FromInt(LESS);
974 case ComparisonResult::kEqual:
975 return Smi::FromInt(EQUAL);
976 case ComparisonResult::kGreaterThan:
977 return Smi::FromInt(GREATER);
978 case ComparisonResult::kUndefined:
979 return *ncr;
980 }
981 UNREACHABLE();
982 }
983 return isolate->heap()->exception();
984}
985
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000986RUNTIME_FUNCTION(Runtime_HasInPrototypeChain) {
987 HandleScope scope(isolate);
988 DCHECK_EQ(2, args.length());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100989 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000990 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100991 Maybe<bool> result =
992 JSReceiver::HasInPrototypeChain(isolate, object, prototype);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000993 MAYBE_RETURN(result, isolate->heap()->exception());
994 return isolate->heap()->ToBoolean(result.FromJust());
995}
996
997
998// ES6 section 7.4.7 CreateIterResultObject ( value, done )
999RUNTIME_FUNCTION(Runtime_CreateIterResultObject) {
1000 HandleScope scope(isolate);
1001 DCHECK_EQ(2, args.length());
1002 CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
1003 CONVERT_ARG_HANDLE_CHECKED(Object, done, 1);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001004 Handle<JSObject> result =
1005 isolate->factory()->NewJSObjectFromMap(isolate->iterator_result_map());
1006 result->InObjectPropertyAtPut(JSIteratorResult::kValueIndex, *value);
1007 result->InObjectPropertyAtPut(JSIteratorResult::kDoneIndex, *done);
1008 return *result;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001009}
1010
1011
1012RUNTIME_FUNCTION(Runtime_IsAccessCheckNeeded) {
1013 SealHandleScope shs(isolate);
1014 DCHECK_EQ(1, args.length());
1015 CONVERT_ARG_CHECKED(Object, object, 0);
1016 return isolate->heap()->ToBoolean(object->IsAccessCheckNeeded());
1017}
1018
1019
Ben Murdochc5610432016-08-08 18:44:38 +01001020RUNTIME_FUNCTION(Runtime_CreateDataProperty) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001021 HandleScope scope(isolate);
1022 DCHECK(args.length() == 3);
Ben Murdochc5610432016-08-08 18:44:38 +01001023 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, o, 0);
1024 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1025 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
1026 bool success;
1027 LookupIterator it = LookupIterator::PropertyOrElement(
1028 isolate, o, key, &success, LookupIterator::OWN);
1029 if (!success) return isolate->heap()->exception();
1030 MAYBE_RETURN(
1031 JSReceiver::CreateDataProperty(&it, value, Object::THROW_ON_ERROR),
1032 isolate->heap()->exception());
1033 return *value;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001034}
1035
1036} // namespace internal
1037} // namespace v8