blob: c7f23989eb9e4aba90b30ed51e210d457c6ee608 [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"
11#include "src/messages.h"
12#include "src/property-descriptor.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040013#include "src/runtime/runtime.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040014
15namespace v8 {
16namespace internal {
17
Emily Bernierd0a1eb72015-03-24 16:35:39 -040018MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
19 Handle<Object> object,
Ben Murdoch61f157c2016-09-16 13:49:30 +010020 Handle<Object> key,
21 bool* is_found_out) {
22 if (object->IsUndefined(isolate) || object->IsNull(isolate)) {
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 Murdoch61f157c2016-09-16 13:49:30 +010034 MaybeHandle<Object> result = Object::GetProperty(&it);
35 if (is_found_out) *is_found_out = it.IsFound();
36 return result;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000037}
38
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000039static MaybeHandle<Object> KeyedGetObjectProperty(Isolate* isolate,
40 Handle<Object> receiver_obj,
Ben Murdoch097c5b22016-05-18 11:27:45 +010041 Handle<Object> key_obj) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000042 // 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 if (receiver_obj->IsJSObject()) {
54 if (!receiver_obj->IsJSGlobalProxy() &&
55 !receiver_obj->IsAccessCheckNeeded() && key_obj->IsName()) {
56 DisallowHeapAllocation no_allocation;
57 Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
58 Handle<Name> key = Handle<Name>::cast(key_obj);
59 if (receiver->IsJSGlobalObject()) {
60 // Attempt dictionary lookup.
61 GlobalDictionary* dictionary = receiver->global_dictionary();
62 int entry = dictionary->FindEntry(key);
63 if (entry != GlobalDictionary::kNotFound) {
64 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
65 PropertyCell* cell = PropertyCell::cast(dictionary->ValueAt(entry));
66 if (cell->property_details().type() == DATA) {
67 Object* value = cell->value();
Ben Murdoch61f157c2016-09-16 13:49:30 +010068 if (!value->IsTheHole(isolate)) {
69 return Handle<Object>(value, isolate);
70 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000071 // If value is the hole (meaning, absent) do the general lookup.
72 }
73 }
74 } else if (!receiver->HasFastProperties()) {
75 // Attempt dictionary lookup.
76 NameDictionary* dictionary = receiver->property_dictionary();
77 int entry = dictionary->FindEntry(key);
78 if ((entry != NameDictionary::kNotFound) &&
79 (dictionary->DetailsAt(entry).type() == DATA)) {
80 Object* value = dictionary->ValueAt(entry);
81 return Handle<Object>(value, isolate);
82 }
83 }
84 } else if (key_obj->IsSmi()) {
85 // JSObject without a name key. If the key is a Smi, check for a
86 // definite out-of-bounds access to elements, which is a strong indicator
87 // that subsequent accesses will also call the runtime. Proactively
88 // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
89 // doubles for those future calls in the case that the elements would
90 // become FAST_DOUBLE_ELEMENTS.
91 Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
92 ElementsKind elements_kind = js_object->GetElementsKind();
93 if (IsFastDoubleElementsKind(elements_kind)) {
94 if (Smi::cast(*key_obj)->value() >= js_object->elements()->length()) {
95 elements_kind = IsFastHoleyElementsKind(elements_kind)
96 ? FAST_HOLEY_ELEMENTS
97 : FAST_ELEMENTS;
98 JSObject::TransitionElementsKind(js_object, elements_kind);
99 }
100 } else {
101 DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
102 !IsFastElementsKind(elements_kind));
103 }
104 }
105 } else if (receiver_obj->IsString() && key_obj->IsSmi()) {
106 // Fast case for string indexing using [] with a smi index.
107 Handle<String> str = Handle<String>::cast(receiver_obj);
108 int index = Handle<Smi>::cast(key_obj)->value();
109 if (index >= 0 && index < str->length()) {
110 Factory* factory = isolate->factory();
111 return factory->LookupSingleCharacterStringFromCode(
112 String::Flatten(str)->Get(index));
113 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400114 }
115
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000116 // Fall back to GetObjectProperty.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100117 return Runtime::GetObjectProperty(isolate, receiver_obj, key_obj);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000118}
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400119
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000120
121Maybe<bool> Runtime::DeleteObjectProperty(Isolate* isolate,
122 Handle<JSReceiver> receiver,
123 Handle<Object> key,
124 LanguageMode language_mode) {
125 bool success = false;
126 LookupIterator it = LookupIterator::PropertyOrElement(
Ben Murdochc5610432016-08-08 18:44:38 +0100127 isolate, receiver, key, &success, LookupIterator::OWN);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000128 if (!success) return Nothing<bool>();
129
130 return JSReceiver::DeleteProperty(&it, language_mode);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400131}
132
Ben Murdochda12d292016-06-02 14:46:10 +0100133// ES6 19.1.3.2
134RUNTIME_FUNCTION(Runtime_ObjectHasOwnProperty) {
135 HandleScope scope(isolate);
136 Handle<Object> property = args.at<Object>(1);
137
138 Handle<Name> key;
139 uint32_t index;
140 bool key_is_array_index = property->ToArrayIndex(&index);
141
142 if (!key_is_array_index) {
143 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key,
144 Object::ToName(isolate, property));
145 key_is_array_index = key->AsArrayIndex(&index);
146 }
147
148 Handle<Object> object = args.at<Object>(0);
149
150 if (object->IsJSObject()) {
151 Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
152 // Fast case: either the key is a real named property or it is not
153 // an array index and there are no interceptors or hidden
154 // prototypes.
155 // TODO(jkummerow): Make JSReceiver::HasOwnProperty fast enough to
156 // handle all cases directly (without this custom fast path).
157 {
158 LookupIterator::Configuration c = LookupIterator::OWN_SKIP_INTERCEPTOR;
159 LookupIterator it =
160 key_is_array_index ? LookupIterator(isolate, js_obj, index, js_obj, c)
161 : LookupIterator(js_obj, key, js_obj, c);
162 Maybe<bool> maybe = JSReceiver::HasProperty(&it);
163 if (maybe.IsNothing()) return isolate->heap()->exception();
164 DCHECK(!isolate->has_pending_exception());
165 if (maybe.FromJust()) return isolate->heap()->true_value();
166 }
167
168 Map* map = js_obj->map();
169 if (!map->has_hidden_prototype() &&
170 (key_is_array_index ? !map->has_indexed_interceptor()
171 : !map->has_named_interceptor())) {
172 return isolate->heap()->false_value();
173 }
174
175 // Slow case.
Ben Murdochc5610432016-08-08 18:44:38 +0100176 LookupIterator::Configuration c = LookupIterator::OWN;
Ben Murdochda12d292016-06-02 14:46:10 +0100177 LookupIterator it = key_is_array_index
178 ? LookupIterator(isolate, js_obj, index, js_obj, c)
179 : LookupIterator(js_obj, key, js_obj, c);
180
181 Maybe<bool> maybe = JSReceiver::HasProperty(&it);
182 if (maybe.IsNothing()) return isolate->heap()->exception();
183 DCHECK(!isolate->has_pending_exception());
184 return isolate->heap()->ToBoolean(maybe.FromJust());
185
186 } else if (object->IsJSProxy()) {
187 if (key.is_null()) {
188 DCHECK(key_is_array_index);
189 key = isolate->factory()->Uint32ToString(index);
190 }
191
192 Maybe<bool> result =
193 JSReceiver::HasOwnProperty(Handle<JSProxy>::cast(object), key);
194 if (!result.IsJust()) return isolate->heap()->exception();
195 return isolate->heap()->ToBoolean(result.FromJust());
196
197 } else if (object->IsString()) {
198 return isolate->heap()->ToBoolean(
199 key_is_array_index
200 ? index < static_cast<uint32_t>(String::cast(*object)->length())
201 : key->Equals(isolate->heap()->length_string()));
Ben Murdoch61f157c2016-09-16 13:49:30 +0100202 } else if (object->IsNull(isolate) || object->IsUndefined(isolate)) {
Ben Murdochda12d292016-06-02 14:46:10 +0100203 THROW_NEW_ERROR_RETURN_FAILURE(
204 isolate, NewTypeError(MessageTemplate::kUndefinedOrNullToObject));
205 }
206
207 return isolate->heap()->false_value();
208}
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400209
210MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
211 Handle<Object> object,
212 Handle<Object> key,
213 Handle<Object> value,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000214 LanguageMode language_mode) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100215 if (object->IsUndefined(isolate) || object->IsNull(isolate)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000216 THROW_NEW_ERROR(
217 isolate,
218 NewTypeError(MessageTemplate::kNonObjectPropertyStore, key, object),
219 Object);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400220 }
221
222 // Check if the given key is an array index.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000223 bool success = false;
224 LookupIterator it =
225 LookupIterator::PropertyOrElement(isolate, object, key, &success);
226 if (!success) return MaybeHandle<Object>();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400227
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000228 MAYBE_RETURN_NULL(Object::SetProperty(&it, value, language_mode,
229 Object::MAY_BE_STORE_FROM_KEYED));
230 return value;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400231}
232
233
234RUNTIME_FUNCTION(Runtime_GetPrototype) {
235 HandleScope scope(isolate);
236 DCHECK(args.length() == 1);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100237 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100238 RETURN_RESULT_OR_FAILURE(isolate, JSReceiver::GetPrototype(isolate, obj));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400239}
240
241
242RUNTIME_FUNCTION(Runtime_InternalSetPrototype) {
243 HandleScope scope(isolate);
244 DCHECK(args.length() == 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000245 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400246 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000247 MAYBE_RETURN(
248 JSReceiver::SetPrototype(obj, prototype, false, Object::THROW_ON_ERROR),
249 isolate->heap()->exception());
250 return *obj;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400251}
252
253
254RUNTIME_FUNCTION(Runtime_SetPrototype) {
255 HandleScope scope(isolate);
256 DCHECK(args.length() == 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000257 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400258 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000259 MAYBE_RETURN(
260 JSReceiver::SetPrototype(obj, prototype, true, Object::THROW_ON_ERROR),
261 isolate->heap()->exception());
262 return *obj;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400263}
264
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400265RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
266 HandleScope scope(isolate);
267 DCHECK(args.length() == 2);
268 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
269 CONVERT_SMI_ARG_CHECKED(properties, 1);
270 // Conservative upper limit to prevent fuzz tests from going OOM.
271 RUNTIME_ASSERT(properties <= 100000);
272 if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
273 JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties,
274 "OptimizeForAdding");
275 }
276 return *object;
277}
278
279
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000280namespace {
281
282Object* StoreGlobalViaContext(Isolate* isolate, int slot, Handle<Object> value,
283 LanguageMode language_mode) {
284 // Go up context chain to the script context.
285 Handle<Context> script_context(isolate->context()->script_context(), isolate);
286 DCHECK(script_context->IsScriptContext());
287 DCHECK(script_context->get(slot)->IsPropertyCell());
288
289 // Lookup the named property on the global object.
290 Handle<ScopeInfo> scope_info(script_context->scope_info(), isolate);
291 Handle<Name> name(scope_info->ContextSlotName(slot), isolate);
292 Handle<JSGlobalObject> global_object(script_context->global_object(),
293 isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100294 LookupIterator it(global_object, name, global_object, LookupIterator::OWN);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000295
296 // Switch to fast mode only if there is a data property and it's not on
297 // a hidden prototype.
298 if (it.state() == LookupIterator::DATA &&
299 it.GetHolder<Object>().is_identical_to(global_object)) {
300 // Now update cell in the script context.
301 Handle<PropertyCell> cell = it.GetPropertyCell();
302 script_context->set(slot, *cell);
303 } else {
304 // This is not a fast case, so keep this access in a slow mode.
305 // Store empty_property_cell here to release the outdated property cell.
306 script_context->set(slot, isolate->heap()->empty_property_cell());
307 }
308
309 MAYBE_RETURN(Object::SetProperty(&it, value, language_mode,
310 Object::CERTAINLY_NOT_STORE_FROM_KEYED),
311 isolate->heap()->exception());
312 return *value;
313}
314
315} // namespace
316
317
318RUNTIME_FUNCTION(Runtime_StoreGlobalViaContext_Sloppy) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400319 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000320 DCHECK_EQ(2, args.length());
321 CONVERT_SMI_ARG_CHECKED(slot, 0);
322 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400323
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000324 return StoreGlobalViaContext(isolate, slot, value, SLOPPY);
325}
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400326
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000327
328RUNTIME_FUNCTION(Runtime_StoreGlobalViaContext_Strict) {
329 HandleScope scope(isolate);
330 DCHECK_EQ(2, args.length());
331 CONVERT_SMI_ARG_CHECKED(slot, 0);
332 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
333
334 return StoreGlobalViaContext(isolate, slot, value, STRICT);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400335}
336
337
338RUNTIME_FUNCTION(Runtime_GetProperty) {
339 HandleScope scope(isolate);
340 DCHECK(args.length() == 2);
341
342 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
343 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000344
Ben Murdoch61f157c2016-09-16 13:49:30 +0100345 RETURN_RESULT_OR_FAILURE(isolate,
346 Runtime::GetObjectProperty(isolate, object, key));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400347}
348
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400349// KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
350RUNTIME_FUNCTION(Runtime_KeyedGetProperty) {
351 HandleScope scope(isolate);
352 DCHECK(args.length() == 2);
353
354 CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
355 CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
356
Ben Murdoch61f157c2016-09-16 13:49:30 +0100357 RETURN_RESULT_OR_FAILURE(
358 isolate, KeyedGetObjectProperty(isolate, receiver_obj, key_obj));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400359}
360
361
362RUNTIME_FUNCTION(Runtime_AddNamedProperty) {
363 HandleScope scope(isolate);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100364 DCHECK_EQ(4, args.length());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400365
366 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000367 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400368 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000369 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400370
371#ifdef DEBUG
372 uint32_t index = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000373 DCHECK(!name->ToArrayIndex(&index));
Ben Murdochda12d292016-06-02 14:46:10 +0100374 LookupIterator it(object, name, object, LookupIterator::OWN_SKIP_INTERCEPTOR);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400375 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000376 if (!maybe.IsJust()) return isolate->heap()->exception();
Ben Murdoch61f157c2016-09-16 13:49:30 +0100377 CHECK(!it.IsFound());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400378#endif
379
Ben Murdoch61f157c2016-09-16 13:49:30 +0100380 RETURN_RESULT_OR_FAILURE(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
381 object, name, value, attrs));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400382}
383
384
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000385// Adds an element to an array.
386// This is used to create an indexed data property into an array.
387RUNTIME_FUNCTION(Runtime_AddElement) {
388 HandleScope scope(isolate);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100389 DCHECK_EQ(3, args.length());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000390
391 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
392 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
393 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
394
395 uint32_t index = 0;
396 CHECK(key->ToArrayIndex(&index));
397
398#ifdef DEBUG
Ben Murdochda12d292016-06-02 14:46:10 +0100399 LookupIterator it(isolate, object, index, object,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000400 LookupIterator::OWN_SKIP_INTERCEPTOR);
401 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
402 if (!maybe.IsJust()) return isolate->heap()->exception();
Ben Murdoch61f157c2016-09-16 13:49:30 +0100403 CHECK(!it.IsFound());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000404
405 if (object->IsJSArray()) {
406 Handle<JSArray> array = Handle<JSArray>::cast(object);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100407 CHECK(!JSArray::WouldChangeReadOnlyLength(array, index));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000408 }
409#endif
410
Ben Murdoch61f157c2016-09-16 13:49:30 +0100411 RETURN_RESULT_OR_FAILURE(isolate, JSObject::SetOwnElementIgnoreAttributes(
412 object, index, value, NONE));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000413}
414
415
416RUNTIME_FUNCTION(Runtime_AppendElement) {
417 HandleScope scope(isolate);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100418 DCHECK_EQ(2, args.length());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000419
420 CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
421 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
422
423 uint32_t index;
424 CHECK(array->length()->ToArrayIndex(&index));
425
Ben Murdoch61f157c2016-09-16 13:49:30 +0100426 RETURN_FAILURE_ON_EXCEPTION(
427 isolate, JSObject::AddDataElement(array, index, value, NONE));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000428 JSObject::ValidateElements(array);
429 return *array;
430}
431
432
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400433RUNTIME_FUNCTION(Runtime_SetProperty) {
434 HandleScope scope(isolate);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100435 DCHECK_EQ(4, args.length());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400436
437 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
438 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
439 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000440 CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode_arg, 3);
441 LanguageMode language_mode = language_mode_arg;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400442
Ben Murdoch61f157c2016-09-16 13:49:30 +0100443 RETURN_RESULT_OR_FAILURE(
444 isolate,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000445 Runtime::SetObjectProperty(isolate, object, key, value, language_mode));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400446}
447
448
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000449namespace {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400450
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000451// ES6 section 12.5.4.
452Object* DeleteProperty(Isolate* isolate, Handle<Object> object,
453 Handle<Object> key, LanguageMode language_mode) {
454 Handle<JSReceiver> receiver;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100455 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
456 Object::ToObject(isolate, object));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000457 Maybe<bool> result =
458 Runtime::DeleteObjectProperty(isolate, receiver, key, language_mode);
459 MAYBE_RETURN(result, isolate->heap()->exception());
460 return isolate->heap()->ToBoolean(result.FromJust());
461}
462
463} // namespace
464
465
466RUNTIME_FUNCTION(Runtime_DeleteProperty_Sloppy) {
467 HandleScope scope(isolate);
468 DCHECK_EQ(2, args.length());
469 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400470 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000471 return DeleteProperty(isolate, object, key, SLOPPY);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400472}
473
474
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000475RUNTIME_FUNCTION(Runtime_DeleteProperty_Strict) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400476 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000477 DCHECK_EQ(2, args.length());
478 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
479 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
480 return DeleteProperty(isolate, object, key, STRICT);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400481}
482
483
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000484// ES6 section 12.9.3, operator in.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400485RUNTIME_FUNCTION(Runtime_HasProperty) {
486 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000487 DCHECK_EQ(2, args.length());
488 CONVERT_ARG_HANDLE_CHECKED(Object, key, 0);
489 CONVERT_ARG_HANDLE_CHECKED(Object, object, 1);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400490
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000491 // Check that {object} is actually a receiver.
492 if (!object->IsJSReceiver()) {
493 THROW_NEW_ERROR_RETURN_FAILURE(
494 isolate,
495 NewTypeError(MessageTemplate::kInvalidInOperatorUse, key, object));
496 }
497 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
498
499 // Convert the {key} to a name.
500 Handle<Name> name;
501 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
502 Object::ToName(isolate, key));
503
504 // Lookup the {name} on {receiver}.
505 Maybe<bool> maybe = JSReceiver::HasProperty(receiver, name);
506 if (!maybe.IsJust()) return isolate->heap()->exception();
507 return isolate->heap()->ToBoolean(maybe.FromJust());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400508}
509
510
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000511RUNTIME_FUNCTION(Runtime_PropertyIsEnumerable) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400512 HandleScope scope(isolate);
513 DCHECK(args.length() == 2);
514
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000515 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400516 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
517
518 Maybe<PropertyAttributes> maybe =
519 JSReceiver::GetOwnPropertyAttributes(object, key);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000520 if (!maybe.IsJust()) return isolate->heap()->exception();
521 if (maybe.FromJust() == ABSENT) return isolate->heap()->false_value();
522 return isolate->heap()->ToBoolean((maybe.FromJust() & DONT_ENUM) == 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400523}
524
525
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000526RUNTIME_FUNCTION(Runtime_GetOwnPropertyKeys) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400527 HandleScope scope(isolate);
528 DCHECK(args.length() == 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000529 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400530 CONVERT_SMI_ARG_CHECKED(filter_value, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000531 PropertyFilter filter = static_cast<PropertyFilter>(filter_value);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400532
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000533 Handle<FixedArray> keys;
534 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100535 isolate, keys,
Ben Murdoch61f157c2016-09-16 13:49:30 +0100536 KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly, filter,
537 GetKeysConversion::kConvertToString));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400538
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000539 return *isolate->factory()->NewJSArrayWithElements(keys);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400540}
541
542
543// Return information on whether an object has a named or indexed interceptor.
544// args[0]: object
545RUNTIME_FUNCTION(Runtime_GetInterceptorInfo) {
546 HandleScope scope(isolate);
547 DCHECK(args.length() == 1);
548 if (!args[0]->IsJSObject()) {
549 return Smi::FromInt(0);
550 }
551 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
552
553 int result = 0;
554 if (obj->HasNamedInterceptor()) result |= 2;
555 if (obj->HasIndexedInterceptor()) result |= 1;
556
557 return Smi::FromInt(result);
558}
559
560
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400561RUNTIME_FUNCTION(Runtime_ToFastProperties) {
562 HandleScope scope(isolate);
563 DCHECK(args.length() == 1);
564 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000565 if (object->IsJSObject() && !object->IsJSGlobalObject()) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400566 JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0,
567 "RuntimeToFastProperties");
568 }
569 return *object;
570}
571
572
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400573RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) {
574 HandleScope scope(isolate);
575 DCHECK(args.length() == 0);
576 return *isolate->factory()->NewHeapNumber(0);
577}
578
579
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400580RUNTIME_FUNCTION(Runtime_NewObject) {
581 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000582 DCHECK_EQ(2, args.length());
583 CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
584 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, new_target, 1);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100585 RETURN_RESULT_OR_FAILURE(isolate, JSObject::New(target, new_target));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400586}
587
588
589RUNTIME_FUNCTION(Runtime_FinalizeInstanceSize) {
590 HandleScope scope(isolate);
591 DCHECK(args.length() == 1);
592
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000593 CONVERT_ARG_HANDLE_CHECKED(Map, initial_map, 0);
594 initial_map->CompleteInobjectSlackTracking();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400595
596 return isolate->heap()->undefined_value();
597}
598
599
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400600RUNTIME_FUNCTION(Runtime_LoadMutableDouble) {
601 HandleScope scope(isolate);
602 DCHECK(args.length() == 2);
603 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
604 CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100605 CHECK((index->value() & 1) == 1);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400606 FieldIndex field_index =
607 FieldIndex::ForLoadByFieldIndex(object->map(), index->value());
608 if (field_index.is_inobject()) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100609 CHECK(field_index.property_index() <
610 object->map()->GetInObjectProperties());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400611 } else {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100612 CHECK(field_index.outobject_array_index() < object->properties()->length());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400613 }
614 return *JSObject::FastPropertyAt(object, Representation::Double(),
615 field_index);
616}
617
618
619RUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
620 HandleScope scope(isolate);
621 DCHECK(args.length() == 1);
622 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
623 if (!object->IsJSObject()) return Smi::FromInt(0);
624 Handle<JSObject> js_object = Handle<JSObject>::cast(object);
625 if (!js_object->map()->is_deprecated()) return Smi::FromInt(0);
626 // This call must not cause lazy deopts, because it's called from deferred
627 // code where we can't handle lazy deopts for lack of a suitable bailout
628 // ID. So we just try migration and signal failure if necessary,
629 // which will also trigger a deopt.
630 if (!JSObject::TryMigrateInstance(js_object)) return Smi::FromInt(0);
631 return *object;
632}
633
634
635RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) {
636 SealHandleScope shs(isolate);
637 DCHECK(args.length() == 1);
638 CONVERT_ARG_CHECKED(Object, obj, 0);
639 return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy());
640}
641
Ben Murdoch61f157c2016-09-16 13:49:30 +0100642static bool IsValidAccessor(Isolate* isolate, Handle<Object> obj) {
643 return obj->IsUndefined(isolate) || obj->IsCallable() || obj->IsNull(isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400644}
645
646
647// Implements part of 8.12.9 DefineOwnProperty.
648// There are 3 cases that lead here:
649// Step 4b - define a new accessor property.
650// Steps 9c & 12 - replace an existing data property with an accessor property.
651// Step 12 - update an existing accessor property with an accessor or generic
652// descriptor.
653RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
654 HandleScope scope(isolate);
655 DCHECK(args.length() == 5);
656 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100657 CHECK(!obj->IsNull(isolate));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400658 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
659 CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100660 CHECK(IsValidAccessor(isolate, getter));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400661 CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100662 CHECK(IsValidAccessor(isolate, setter));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000663 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 4);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400664
665 RETURN_FAILURE_ON_EXCEPTION(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000666 isolate, JSObject::DefineAccessor(obj, name, getter, setter, attrs));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400667 return isolate->heap()->undefined_value();
668}
669
670
Ben Murdoch097c5b22016-05-18 11:27:45 +0100671RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) {
672 HandleScope scope(isolate);
673 DCHECK(args.length() == 5);
674 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
675 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
676 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
677 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
678 CONVERT_SMI_ARG_CHECKED(set_function_name, 4);
679
Ben Murdoch61f157c2016-09-16 13:49:30 +0100680 if (set_function_name) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100681 DCHECK(value->IsJSFunction());
682 JSFunction::SetName(Handle<JSFunction>::cast(value), name,
683 isolate->factory()->empty_string());
684 }
685
Ben Murdochda12d292016-06-02 14:46:10 +0100686 LookupIterator it = LookupIterator::PropertyOrElement(
687 isolate, object, name, object, LookupIterator::OWN);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100688 // Cannot fail since this should only be called when
689 // creating an object literal.
690 CHECK(JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attrs,
691 Object::DONT_THROW)
692 .IsJust());
693 return *object;
694}
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400695
696// Return property without being observable by accessors or interceptors.
697RUNTIME_FUNCTION(Runtime_GetDataProperty) {
698 HandleScope scope(isolate);
699 DCHECK(args.length() == 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000700 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
701 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
702 return *JSReceiver::GetDataProperty(object, name);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400703}
704
705
706RUNTIME_FUNCTION(Runtime_HasFastPackedElements) {
707 SealHandleScope shs(isolate);
708 DCHECK(args.length() == 1);
709 CONVERT_ARG_CHECKED(HeapObject, obj, 0);
710 return isolate->heap()->ToBoolean(
711 IsFastPackedElementsKind(obj->map()->elements_kind()));
712}
713
714
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000715RUNTIME_FUNCTION(Runtime_ValueOf) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400716 SealHandleScope shs(isolate);
717 DCHECK(args.length() == 1);
718 CONVERT_ARG_CHECKED(Object, obj, 0);
719 if (!obj->IsJSValue()) return obj;
720 return JSValue::cast(obj)->value();
721}
722
723
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000724RUNTIME_FUNCTION(Runtime_IsJSReceiver) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400725 SealHandleScope shs(isolate);
726 DCHECK(args.length() == 1);
727 CONVERT_ARG_CHECKED(Object, obj, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000728 return isolate->heap()->ToBoolean(obj->IsJSReceiver());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400729}
730
731
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000732RUNTIME_FUNCTION(Runtime_ClassOf) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400733 SealHandleScope shs(isolate);
734 DCHECK(args.length() == 1);
735 CONVERT_ARG_CHECKED(Object, obj, 0);
736 if (!obj->IsJSReceiver()) return isolate->heap()->null_value();
737 return JSReceiver::cast(obj)->class_name();
738}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000739
740
741RUNTIME_FUNCTION(Runtime_DefineGetterPropertyUnchecked) {
742 HandleScope scope(isolate);
743 DCHECK(args.length() == 4);
744 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
745 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
746 CONVERT_ARG_HANDLE_CHECKED(JSFunction, getter, 2);
747 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
748
Ben Murdoch61f157c2016-09-16 13:49:30 +0100749 if (String::cast(getter->shared()->name())->length() == 0) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100750 JSFunction::SetName(getter, name, isolate->factory()->get_string());
751 }
752
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000753 RETURN_FAILURE_ON_EXCEPTION(
754 isolate,
755 JSObject::DefineAccessor(object, name, getter,
756 isolate->factory()->null_value(), attrs));
757 return isolate->heap()->undefined_value();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400758}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000759
760
761RUNTIME_FUNCTION(Runtime_DefineSetterPropertyUnchecked) {
762 HandleScope scope(isolate);
763 DCHECK(args.length() == 4);
764 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
765 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
766 CONVERT_ARG_HANDLE_CHECKED(JSFunction, setter, 2);
767 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
768
Ben Murdoch61f157c2016-09-16 13:49:30 +0100769 if (String::cast(setter->shared()->name())->length() == 0) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100770 JSFunction::SetName(setter, name, isolate->factory()->set_string());
771 }
772
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000773 RETURN_FAILURE_ON_EXCEPTION(
774 isolate,
775 JSObject::DefineAccessor(object, name, isolate->factory()->null_value(),
776 setter, attrs));
777 return isolate->heap()->undefined_value();
778}
779
780
781RUNTIME_FUNCTION(Runtime_ToObject) {
782 HandleScope scope(isolate);
783 DCHECK_EQ(1, args.length());
784 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100785 RETURN_RESULT_OR_FAILURE(isolate, Object::ToObject(isolate, object));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000786}
787
788
789RUNTIME_FUNCTION(Runtime_ToPrimitive) {
790 HandleScope scope(isolate);
791 DCHECK_EQ(1, args.length());
792 CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100793 RETURN_RESULT_OR_FAILURE(isolate, Object::ToPrimitive(input));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000794}
795
796
797RUNTIME_FUNCTION(Runtime_ToPrimitive_Number) {
798 HandleScope scope(isolate);
799 DCHECK_EQ(1, args.length());
800 CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100801 RETURN_RESULT_OR_FAILURE(
802 isolate, Object::ToPrimitive(input, ToPrimitiveHint::kNumber));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000803}
804
805
806RUNTIME_FUNCTION(Runtime_ToPrimitive_String) {
807 HandleScope scope(isolate);
808 DCHECK_EQ(1, args.length());
809 CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100810 RETURN_RESULT_OR_FAILURE(
811 isolate, Object::ToPrimitive(input, ToPrimitiveHint::kString));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000812}
813
814
815RUNTIME_FUNCTION(Runtime_ToNumber) {
816 HandleScope scope(isolate);
817 DCHECK_EQ(1, args.length());
818 CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100819 RETURN_RESULT_OR_FAILURE(isolate, Object::ToNumber(input));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000820}
821
822
823RUNTIME_FUNCTION(Runtime_ToInteger) {
824 HandleScope scope(isolate);
825 DCHECK_EQ(1, args.length());
826 CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100827 RETURN_RESULT_OR_FAILURE(isolate, Object::ToInteger(isolate, input));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000828}
829
830
831RUNTIME_FUNCTION(Runtime_ToLength) {
832 HandleScope scope(isolate);
833 DCHECK_EQ(1, args.length());
834 CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100835 RETURN_RESULT_OR_FAILURE(isolate, Object::ToLength(isolate, input));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000836}
837
838
839RUNTIME_FUNCTION(Runtime_ToString) {
840 HandleScope scope(isolate);
841 DCHECK_EQ(1, args.length());
842 CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100843 RETURN_RESULT_OR_FAILURE(isolate, Object::ToString(isolate, input));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000844}
845
846
847RUNTIME_FUNCTION(Runtime_ToName) {
848 HandleScope scope(isolate);
849 DCHECK_EQ(1, args.length());
850 CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100851 RETURN_RESULT_OR_FAILURE(isolate, Object::ToName(isolate, input));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000852}
853
854
Ben Murdoch097c5b22016-05-18 11:27:45 +0100855RUNTIME_FUNCTION(Runtime_SameValue) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000856 SealHandleScope scope(isolate);
857 DCHECK_EQ(2, args.length());
858 CONVERT_ARG_CHECKED(Object, x, 0);
859 CONVERT_ARG_CHECKED(Object, y, 1);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100860 return isolate->heap()->ToBoolean(x->SameValue(y));
861}
862
863
864RUNTIME_FUNCTION(Runtime_SameValueZero) {
865 SealHandleScope scope(isolate);
866 DCHECK_EQ(2, args.length());
867 CONVERT_ARG_CHECKED(Object, x, 0);
868 CONVERT_ARG_CHECKED(Object, y, 1);
869 return isolate->heap()->ToBoolean(x->SameValueZero(y));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000870}
871
872
873// TODO(bmeurer): Kill this special wrapper and use TF compatible LessThan,
874// GreaterThan, etc. which return true or false.
875RUNTIME_FUNCTION(Runtime_Compare) {
876 HandleScope scope(isolate);
877 DCHECK_EQ(3, args.length());
878 CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
879 CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
880 CONVERT_ARG_HANDLE_CHECKED(Object, ncr, 2);
881 Maybe<ComparisonResult> result = Object::Compare(x, y);
882 if (result.IsJust()) {
883 switch (result.FromJust()) {
884 case ComparisonResult::kLessThan:
885 return Smi::FromInt(LESS);
886 case ComparisonResult::kEqual:
887 return Smi::FromInt(EQUAL);
888 case ComparisonResult::kGreaterThan:
889 return Smi::FromInt(GREATER);
890 case ComparisonResult::kUndefined:
891 return *ncr;
892 }
893 UNREACHABLE();
894 }
895 return isolate->heap()->exception();
896}
897
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000898RUNTIME_FUNCTION(Runtime_HasInPrototypeChain) {
899 HandleScope scope(isolate);
900 DCHECK_EQ(2, args.length());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100901 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000902 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100903 Maybe<bool> result =
904 JSReceiver::HasInPrototypeChain(isolate, object, prototype);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000905 MAYBE_RETURN(result, isolate->heap()->exception());
906 return isolate->heap()->ToBoolean(result.FromJust());
907}
908
909
910// ES6 section 7.4.7 CreateIterResultObject ( value, done )
911RUNTIME_FUNCTION(Runtime_CreateIterResultObject) {
912 HandleScope scope(isolate);
913 DCHECK_EQ(2, args.length());
914 CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
915 CONVERT_ARG_HANDLE_CHECKED(Object, done, 1);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100916 Handle<JSObject> result =
917 isolate->factory()->NewJSObjectFromMap(isolate->iterator_result_map());
918 result->InObjectPropertyAtPut(JSIteratorResult::kValueIndex, *value);
919 result->InObjectPropertyAtPut(JSIteratorResult::kDoneIndex, *done);
920 return *result;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000921}
922
923
924RUNTIME_FUNCTION(Runtime_IsAccessCheckNeeded) {
925 SealHandleScope shs(isolate);
926 DCHECK_EQ(1, args.length());
927 CONVERT_ARG_CHECKED(Object, object, 0);
928 return isolate->heap()->ToBoolean(object->IsAccessCheckNeeded());
929}
930
931
Ben Murdochc5610432016-08-08 18:44:38 +0100932RUNTIME_FUNCTION(Runtime_CreateDataProperty) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000933 HandleScope scope(isolate);
934 DCHECK(args.length() == 3);
Ben Murdochc5610432016-08-08 18:44:38 +0100935 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, o, 0);
936 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
937 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
938 bool success;
939 LookupIterator it = LookupIterator::PropertyOrElement(
940 isolate, o, key, &success, LookupIterator::OWN);
941 if (!success) return isolate->heap()->exception();
942 MAYBE_RETURN(
943 JSReceiver::CreateDataProperty(&it, value, Object::THROW_ON_ERROR),
944 isolate->heap()->exception());
945 return *value;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000946}
947
948} // namespace internal
949} // namespace v8