OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdlib.h> | 5 #include <stdlib.h> |
6 #include <limits> | 6 #include <limits> |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
11 #include "src/allocation-site-scopes.h" | |
12 #include "src/api.h" | 11 #include "src/api.h" |
13 #include "src/arguments.h" | 12 #include "src/arguments.h" |
14 #include "src/bailout-reason.h" | 13 #include "src/bailout-reason.h" |
15 #include "src/base/cpu.h" | 14 #include "src/base/cpu.h" |
16 #include "src/base/platform/platform.h" | 15 #include "src/base/platform/platform.h" |
17 #include "src/bootstrapper.h" | 16 #include "src/bootstrapper.h" |
18 #include "src/codegen.h" | |
19 #include "src/compilation-cache.h" | |
20 #include "src/compiler.h" | |
21 #include "src/conversions.h" | 17 #include "src/conversions.h" |
22 #include "src/deoptimizer.h" | |
23 #include "src/execution.h" | |
24 #include "src/full-codegen.h" | |
25 #include "src/global-handles.h" | 18 #include "src/global-handles.h" |
26 #include "src/isolate-inl.h" | 19 #include "src/isolate-inl.h" |
27 #include "src/parser.h" | |
28 #include "src/prototype.h" | 20 #include "src/prototype.h" |
29 #include "src/runtime/runtime.h" | 21 #include "src/runtime/runtime.h" |
30 #include "src/runtime/runtime-utils.h" | 22 #include "src/runtime/runtime-utils.h" |
31 #include "src/scopeinfo.h" | |
32 #include "src/smart-pointers.h" | |
33 #include "src/utils.h" | 23 #include "src/utils.h" |
34 #include "src/v8threads.h" | |
35 | 24 |
36 | 25 |
37 namespace v8 { | 26 namespace v8 { |
38 namespace internal { | 27 namespace internal { |
39 | 28 |
40 // Header of runtime functions. | 29 // Header of runtime functions. |
41 #define F(name, number_of_args, result_size) \ | 30 #define F(name, number_of_args, result_size) \ |
42 Object* Runtime_##name(int args_length, Object** args_object, \ | 31 Object* Runtime_##name(int args_length, Object** args_object, \ |
43 Isolate* isolate); | 32 Isolate* isolate); |
44 | 33 |
45 #define P(name, number_of_args, result_size) \ | 34 #define P(name, number_of_args, result_size) \ |
46 ObjectPair Runtime_##name(int args_length, Object** args_object, \ | 35 ObjectPair Runtime_##name(int args_length, Object** args_object, \ |
47 Isolate* isolate); | 36 Isolate* isolate); |
48 | 37 |
49 #define I(name, number_of_args, result_size) \ | 38 #define I(name, number_of_args, result_size) \ |
50 Object* RuntimeReference_##name(int args_length, Object** args_object, \ | 39 Object* RuntimeReference_##name(int args_length, Object** args_object, \ |
51 Isolate* isolate); | 40 Isolate* isolate); |
52 | 41 |
53 RUNTIME_FUNCTION_LIST_RETURN_OBJECT(F) | 42 RUNTIME_FUNCTION_LIST_RETURN_OBJECT(F) |
54 RUNTIME_FUNCTION_LIST_RETURN_PAIR(P) | 43 RUNTIME_FUNCTION_LIST_RETURN_PAIR(P) |
55 INLINE_OPTIMIZED_FUNCTION_LIST(F) | 44 INLINE_OPTIMIZED_FUNCTION_LIST(F) |
56 INLINE_FUNCTION_LIST(I) | 45 INLINE_FUNCTION_LIST(I) |
57 | 46 |
58 #undef I | 47 #undef I |
59 #undef F | 48 #undef F |
60 #undef P | 49 #undef P |
61 | 50 |
62 | 51 |
63 static Handle<Map> ComputeObjectLiteralMap( | |
64 Handle<Context> context, Handle<FixedArray> constant_properties, | |
65 bool* is_result_from_cache) { | |
66 Isolate* isolate = context->GetIsolate(); | |
67 int properties_length = constant_properties->length(); | |
68 int number_of_properties = properties_length / 2; | |
69 // Check that there are only internal strings and array indices among keys. | |
70 int number_of_string_keys = 0; | |
71 for (int p = 0; p != properties_length; p += 2) { | |
72 Object* key = constant_properties->get(p); | |
73 uint32_t element_index = 0; | |
74 if (key->IsInternalizedString()) { | |
75 number_of_string_keys++; | |
76 } else if (key->ToArrayIndex(&element_index)) { | |
77 // An index key does not require space in the property backing store. | |
78 number_of_properties--; | |
79 } else { | |
80 // Bail out as a non-internalized-string non-index key makes caching | |
81 // impossible. | |
82 // DCHECK to make sure that the if condition after the loop is false. | |
83 DCHECK(number_of_string_keys != number_of_properties); | |
84 break; | |
85 } | |
86 } | |
87 // If we only have internalized strings and array indices among keys then we | |
88 // can use the map cache in the native context. | |
89 const int kMaxKeys = 10; | |
90 if ((number_of_string_keys == number_of_properties) && | |
91 (number_of_string_keys < kMaxKeys)) { | |
92 // Create the fixed array with the key. | |
93 Handle<FixedArray> keys = | |
94 isolate->factory()->NewFixedArray(number_of_string_keys); | |
95 if (number_of_string_keys > 0) { | |
96 int index = 0; | |
97 for (int p = 0; p < properties_length; p += 2) { | |
98 Object* key = constant_properties->get(p); | |
99 if (key->IsInternalizedString()) { | |
100 keys->set(index++, key); | |
101 } | |
102 } | |
103 DCHECK(index == number_of_string_keys); | |
104 } | |
105 *is_result_from_cache = true; | |
106 return isolate->factory()->ObjectLiteralMapFromCache(context, keys); | |
107 } | |
108 *is_result_from_cache = false; | |
109 return Map::Create(isolate, number_of_properties); | |
110 } | |
111 | |
112 | |
113 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( | |
114 Isolate* isolate, Handle<FixedArray> literals, | |
115 Handle<FixedArray> constant_properties); | |
116 | |
117 | |
118 MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( | |
119 Isolate* isolate, Handle<FixedArray> literals, | |
120 Handle<FixedArray> constant_properties, bool should_have_fast_elements, | |
121 bool has_function_literal) { | |
122 // Get the native context from the literals array. This is the | |
123 // context in which the function was created and we use the object | |
124 // function from this context to create the object literal. We do | |
125 // not use the object function from the current native context | |
126 // because this might be the object function from another context | |
127 // which we should not have access to. | |
128 Handle<Context> context = | |
129 Handle<Context>(JSFunction::NativeContextFromLiterals(*literals)); | |
130 | |
131 // In case we have function literals, we want the object to be in | |
132 // slow properties mode for now. We don't go in the map cache because | |
133 // maps with constant functions can't be shared if the functions are | |
134 // not the same (which is the common case). | |
135 bool is_result_from_cache = false; | |
136 Handle<Map> map = has_function_literal | |
137 ? Handle<Map>(context->object_function()->initial_map()) | |
138 : ComputeObjectLiteralMap(context, constant_properties, | |
139 &is_result_from_cache); | |
140 | |
141 PretenureFlag pretenure_flag = | |
142 isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED; | |
143 | |
144 Handle<JSObject> boilerplate = | |
145 isolate->factory()->NewJSObjectFromMap(map, pretenure_flag); | |
146 | |
147 // Normalize the elements of the boilerplate to save space if needed. | |
148 if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate); | |
149 | |
150 // Add the constant properties to the boilerplate. | |
151 int length = constant_properties->length(); | |
152 bool should_transform = | |
153 !is_result_from_cache && boilerplate->HasFastProperties(); | |
154 bool should_normalize = should_transform || has_function_literal; | |
155 if (should_normalize) { | |
156 // TODO(verwaest): We might not want to ever normalize here. | |
157 JSObject::NormalizeProperties(boilerplate, KEEP_INOBJECT_PROPERTIES, | |
158 length / 2); | |
159 } | |
160 // TODO(verwaest): Support tracking representations in the boilerplate. | |
161 for (int index = 0; index < length; index += 2) { | |
162 Handle<Object> key(constant_properties->get(index + 0), isolate); | |
163 Handle<Object> value(constant_properties->get(index + 1), isolate); | |
164 if (value->IsFixedArray()) { | |
165 // The value contains the constant_properties of a | |
166 // simple object or array literal. | |
167 Handle<FixedArray> array = Handle<FixedArray>::cast(value); | |
168 ASSIGN_RETURN_ON_EXCEPTION( | |
169 isolate, value, CreateLiteralBoilerplate(isolate, literals, array), | |
170 Object); | |
171 } | |
172 MaybeHandle<Object> maybe_result; | |
173 uint32_t element_index = 0; | |
174 if (key->IsInternalizedString()) { | |
175 if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) { | |
176 // Array index as string (uint32). | |
177 if (value->IsUninitialized()) value = handle(Smi::FromInt(0), isolate); | |
178 maybe_result = | |
179 JSObject::SetOwnElement(boilerplate, element_index, value, SLOPPY); | |
180 } else { | |
181 Handle<String> name(String::cast(*key)); | |
182 DCHECK(!name->AsArrayIndex(&element_index)); | |
183 maybe_result = JSObject::SetOwnPropertyIgnoreAttributes( | |
184 boilerplate, name, value, NONE); | |
185 } | |
186 } else if (key->ToArrayIndex(&element_index)) { | |
187 // Array index (uint32). | |
188 if (value->IsUninitialized()) value = handle(Smi::FromInt(0), isolate); | |
189 maybe_result = | |
190 JSObject::SetOwnElement(boilerplate, element_index, value, SLOPPY); | |
191 } else { | |
192 // Non-uint32 number. | |
193 DCHECK(key->IsNumber()); | |
194 double num = key->Number(); | |
195 char arr[100]; | |
196 Vector<char> buffer(arr, arraysize(arr)); | |
197 const char* str = DoubleToCString(num, buffer); | |
198 Handle<String> name = isolate->factory()->NewStringFromAsciiChecked(str); | |
199 maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(boilerplate, name, | |
200 value, NONE); | |
201 } | |
202 // If setting the property on the boilerplate throws an | |
203 // exception, the exception is converted to an empty handle in | |
204 // the handle based operations. In that case, we need to | |
205 // convert back to an exception. | |
206 RETURN_ON_EXCEPTION(isolate, maybe_result, Object); | |
207 } | |
208 | |
209 // Transform to fast properties if necessary. For object literals with | |
210 // containing function literals we defer this operation until after all | |
211 // computed properties have been assigned so that we can generate | |
212 // constant function properties. | |
213 if (should_transform && !has_function_literal) { | |
214 JSObject::MigrateSlowToFast(boilerplate, | |
215 boilerplate->map()->unused_property_fields()); | |
216 } | |
217 | |
218 return boilerplate; | |
219 } | |
220 | |
221 | |
222 MUST_USE_RESULT static MaybeHandle<Object> TransitionElements( | 52 MUST_USE_RESULT static MaybeHandle<Object> TransitionElements( |
223 Handle<Object> object, ElementsKind to_kind, Isolate* isolate) { | 53 Handle<Object> object, ElementsKind to_kind, Isolate* isolate) { |
224 HandleScope scope(isolate); | 54 HandleScope scope(isolate); |
225 if (!object->IsJSObject()) { | 55 if (!object->IsJSObject()) { |
226 isolate->ThrowIllegalOperation(); | 56 isolate->ThrowIllegalOperation(); |
227 return MaybeHandle<Object>(); | 57 return MaybeHandle<Object>(); |
228 } | 58 } |
229 ElementsKind from_kind = | 59 ElementsKind from_kind = |
230 Handle<JSObject>::cast(object)->map()->elements_kind(); | 60 Handle<JSObject>::cast(object)->map()->elements_kind(); |
231 if (Map::IsValidElementsTransition(from_kind, to_kind)) { | 61 if (Map::IsValidElementsTransition(from_kind, to_kind)) { |
232 JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind); | 62 JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind); |
233 return object; | 63 return object; |
234 } | 64 } |
235 isolate->ThrowIllegalOperation(); | 65 isolate->ThrowIllegalOperation(); |
236 return MaybeHandle<Object>(); | 66 return MaybeHandle<Object>(); |
237 } | 67 } |
238 | 68 |
239 | 69 |
240 MaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate( | |
241 Isolate* isolate, Handle<FixedArray> literals, | |
242 Handle<FixedArray> elements) { | |
243 // Create the JSArray. | |
244 Handle<JSFunction> constructor( | |
245 JSFunction::NativeContextFromLiterals(*literals)->array_function()); | |
246 | |
247 PretenureFlag pretenure_flag = | |
248 isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED; | |
249 | |
250 Handle<JSArray> object = Handle<JSArray>::cast( | |
251 isolate->factory()->NewJSObject(constructor, pretenure_flag)); | |
252 | |
253 ElementsKind constant_elements_kind = | |
254 static_cast<ElementsKind>(Smi::cast(elements->get(0))->value()); | |
255 Handle<FixedArrayBase> constant_elements_values( | |
256 FixedArrayBase::cast(elements->get(1))); | |
257 | |
258 { | |
259 DisallowHeapAllocation no_gc; | |
260 DCHECK(IsFastElementsKind(constant_elements_kind)); | |
261 Context* native_context = isolate->context()->native_context(); | |
262 Object* maps_array = native_context->js_array_maps(); | |
263 DCHECK(!maps_array->IsUndefined()); | |
264 Object* map = FixedArray::cast(maps_array)->get(constant_elements_kind); | |
265 object->set_map(Map::cast(map)); | |
266 } | |
267 | |
268 Handle<FixedArrayBase> copied_elements_values; | |
269 if (IsFastDoubleElementsKind(constant_elements_kind)) { | |
270 copied_elements_values = isolate->factory()->CopyFixedDoubleArray( | |
271 Handle<FixedDoubleArray>::cast(constant_elements_values)); | |
272 } else { | |
273 DCHECK(IsFastSmiOrObjectElementsKind(constant_elements_kind)); | |
274 const bool is_cow = (constant_elements_values->map() == | |
275 isolate->heap()->fixed_cow_array_map()); | |
276 if (is_cow) { | |
277 copied_elements_values = constant_elements_values; | |
278 #if DEBUG | |
279 Handle<FixedArray> fixed_array_values = | |
280 Handle<FixedArray>::cast(copied_elements_values); | |
281 for (int i = 0; i < fixed_array_values->length(); i++) { | |
282 DCHECK(!fixed_array_values->get(i)->IsFixedArray()); | |
283 } | |
284 #endif | |
285 } else { | |
286 Handle<FixedArray> fixed_array_values = | |
287 Handle<FixedArray>::cast(constant_elements_values); | |
288 Handle<FixedArray> fixed_array_values_copy = | |
289 isolate->factory()->CopyFixedArray(fixed_array_values); | |
290 copied_elements_values = fixed_array_values_copy; | |
291 for (int i = 0; i < fixed_array_values->length(); i++) { | |
292 if (fixed_array_values->get(i)->IsFixedArray()) { | |
293 // The value contains the constant_properties of a | |
294 // simple object or array literal. | |
295 Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i))); | |
296 Handle<Object> result; | |
297 ASSIGN_RETURN_ON_EXCEPTION( | |
298 isolate, result, CreateLiteralBoilerplate(isolate, literals, fa), | |
299 Object); | |
300 fixed_array_values_copy->set(i, *result); | |
301 } | |
302 } | |
303 } | |
304 } | |
305 object->set_elements(*copied_elements_values); | |
306 object->set_length(Smi::FromInt(copied_elements_values->length())); | |
307 | |
308 JSObject::ValidateElements(object); | |
309 return object; | |
310 } | |
311 | |
312 | |
313 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( | |
314 Isolate* isolate, Handle<FixedArray> literals, Handle<FixedArray> array) { | |
315 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); | |
316 const bool kHasNoFunctionLiteral = false; | |
317 switch (CompileTimeValue::GetLiteralType(array)) { | |
318 case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS: | |
319 return CreateObjectLiteralBoilerplate(isolate, literals, elements, true, | |
320 kHasNoFunctionLiteral); | |
321 case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS: | |
322 return CreateObjectLiteralBoilerplate(isolate, literals, elements, false, | |
323 kHasNoFunctionLiteral); | |
324 case CompileTimeValue::ARRAY_LITERAL: | |
325 return Runtime::CreateArrayLiteralBoilerplate(isolate, literals, | |
326 elements); | |
327 default: | |
328 UNREACHABLE(); | |
329 return MaybeHandle<Object>(); | |
330 } | |
331 } | |
332 | |
333 | |
334 RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { | |
335 HandleScope scope(isolate); | |
336 DCHECK(args.length() == 4); | |
337 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); | |
338 CONVERT_SMI_ARG_CHECKED(literals_index, 1); | |
339 CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2); | |
340 CONVERT_SMI_ARG_CHECKED(flags, 3); | |
341 bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0; | |
342 bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0; | |
343 | |
344 RUNTIME_ASSERT(literals_index >= 0 && literals_index < literals->length()); | |
345 | |
346 // Check if boilerplate exists. If not, create it first. | |
347 Handle<Object> literal_site(literals->get(literals_index), isolate); | |
348 Handle<AllocationSite> site; | |
349 Handle<JSObject> boilerplate; | |
350 if (*literal_site == isolate->heap()->undefined_value()) { | |
351 Handle<Object> raw_boilerplate; | |
352 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
353 isolate, raw_boilerplate, | |
354 CreateObjectLiteralBoilerplate(isolate, literals, constant_properties, | |
355 should_have_fast_elements, | |
356 has_function_literal)); | |
357 boilerplate = Handle<JSObject>::cast(raw_boilerplate); | |
358 | |
359 AllocationSiteCreationContext creation_context(isolate); | |
360 site = creation_context.EnterNewScope(); | |
361 RETURN_FAILURE_ON_EXCEPTION( | |
362 isolate, JSObject::DeepWalk(boilerplate, &creation_context)); | |
363 creation_context.ExitScope(site, boilerplate); | |
364 | |
365 // Update the functions literal and return the boilerplate. | |
366 literals->set(literals_index, *site); | |
367 } else { | |
368 site = Handle<AllocationSite>::cast(literal_site); | |
369 boilerplate = | |
370 Handle<JSObject>(JSObject::cast(site->transition_info()), isolate); | |
371 } | |
372 | |
373 AllocationSiteUsageContext usage_context(isolate, site, true); | |
374 usage_context.EnterNewScope(); | |
375 MaybeHandle<Object> maybe_copy = | |
376 JSObject::DeepCopy(boilerplate, &usage_context); | |
377 usage_context.ExitScope(site, boilerplate); | |
378 Handle<Object> copy; | |
379 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, copy, maybe_copy); | |
380 return *copy; | |
381 } | |
382 | |
383 | |
384 MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite( | |
385 Isolate* isolate, Handle<FixedArray> literals, int literals_index, | |
386 Handle<FixedArray> elements) { | |
387 // Check if boilerplate exists. If not, create it first. | |
388 Handle<Object> literal_site(literals->get(literals_index), isolate); | |
389 Handle<AllocationSite> site; | |
390 if (*literal_site == isolate->heap()->undefined_value()) { | |
391 DCHECK(*elements != isolate->heap()->empty_fixed_array()); | |
392 Handle<Object> boilerplate; | |
393 ASSIGN_RETURN_ON_EXCEPTION( | |
394 isolate, boilerplate, | |
395 Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements), | |
396 AllocationSite); | |
397 | |
398 AllocationSiteCreationContext creation_context(isolate); | |
399 site = creation_context.EnterNewScope(); | |
400 if (JSObject::DeepWalk(Handle<JSObject>::cast(boilerplate), | |
401 &creation_context).is_null()) { | |
402 return Handle<AllocationSite>::null(); | |
403 } | |
404 creation_context.ExitScope(site, Handle<JSObject>::cast(boilerplate)); | |
405 | |
406 literals->set(literals_index, *site); | |
407 } else { | |
408 site = Handle<AllocationSite>::cast(literal_site); | |
409 } | |
410 | |
411 return site; | |
412 } | |
413 | |
414 | |
415 static MaybeHandle<JSObject> CreateArrayLiteralImpl(Isolate* isolate, | |
416 Handle<FixedArray> literals, | |
417 int literals_index, | |
418 Handle<FixedArray> elements, | |
419 int flags) { | |
420 RUNTIME_ASSERT_HANDLIFIED( | |
421 literals_index >= 0 && literals_index < literals->length(), JSObject); | |
422 Handle<AllocationSite> site; | |
423 ASSIGN_RETURN_ON_EXCEPTION( | |
424 isolate, site, | |
425 GetLiteralAllocationSite(isolate, literals, literals_index, elements), | |
426 JSObject); | |
427 | |
428 bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0; | |
429 Handle<JSObject> boilerplate(JSObject::cast(site->transition_info())); | |
430 AllocationSiteUsageContext usage_context(isolate, site, enable_mementos); | |
431 usage_context.EnterNewScope(); | |
432 JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0 | |
433 ? JSObject::kNoHints | |
434 : JSObject::kObjectIsShallow; | |
435 MaybeHandle<JSObject> copy = | |
436 JSObject::DeepCopy(boilerplate, &usage_context, hints); | |
437 usage_context.ExitScope(site, boilerplate); | |
438 return copy; | |
439 } | |
440 | |
441 | |
442 RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) { | |
443 HandleScope scope(isolate); | |
444 DCHECK(args.length() == 4); | |
445 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); | |
446 CONVERT_SMI_ARG_CHECKED(literals_index, 1); | |
447 CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2); | |
448 CONVERT_SMI_ARG_CHECKED(flags, 3); | |
449 | |
450 Handle<JSObject> result; | |
451 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
452 isolate, result, CreateArrayLiteralImpl(isolate, literals, literals_index, | |
453 elements, flags)); | |
454 return *result; | |
455 } | |
456 | |
457 | |
458 RUNTIME_FUNCTION(Runtime_CreateArrayLiteralStubBailout) { | |
459 HandleScope scope(isolate); | |
460 DCHECK(args.length() == 3); | |
461 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); | |
462 CONVERT_SMI_ARG_CHECKED(literals_index, 1); | |
463 CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2); | |
464 | |
465 Handle<JSObject> result; | |
466 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
467 isolate, result, | |
468 CreateArrayLiteralImpl(isolate, literals, literals_index, elements, | |
469 ArrayLiteral::kShallowElements)); | |
470 return *result; | |
471 } | |
472 | |
473 | |
474 RUNTIME_FUNCTION(Runtime_CreateSymbol) { | |
475 HandleScope scope(isolate); | |
476 DCHECK(args.length() == 1); | |
477 CONVERT_ARG_HANDLE_CHECKED(Object, name, 0); | |
478 RUNTIME_ASSERT(name->IsString() || name->IsUndefined()); | |
479 Handle<Symbol> symbol = isolate->factory()->NewSymbol(); | |
480 if (name->IsString()) symbol->set_name(*name); | |
481 return *symbol; | |
482 } | |
483 | |
484 | |
485 RUNTIME_FUNCTION(Runtime_CreatePrivateSymbol) { | |
486 HandleScope scope(isolate); | |
487 DCHECK(args.length() == 1); | |
488 CONVERT_ARG_HANDLE_CHECKED(Object, name, 0); | |
489 RUNTIME_ASSERT(name->IsString() || name->IsUndefined()); | |
490 Handle<Symbol> symbol = isolate->factory()->NewPrivateSymbol(); | |
491 if (name->IsString()) symbol->set_name(*name); | |
492 return *symbol; | |
493 } | |
494 | |
495 | |
496 RUNTIME_FUNCTION(Runtime_CreatePrivateOwnSymbol) { | |
497 HandleScope scope(isolate); | |
498 DCHECK(args.length() == 1); | |
499 CONVERT_ARG_HANDLE_CHECKED(Object, name, 0); | |
500 RUNTIME_ASSERT(name->IsString() || name->IsUndefined()); | |
501 Handle<Symbol> symbol = isolate->factory()->NewPrivateOwnSymbol(); | |
502 if (name->IsString()) symbol->set_name(*name); | |
503 return *symbol; | |
504 } | |
505 | |
506 | |
507 RUNTIME_FUNCTION(Runtime_CreateGlobalPrivateOwnSymbol) { | |
508 HandleScope scope(isolate); | |
509 DCHECK(args.length() == 1); | |
510 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); | |
511 Handle<JSObject> registry = isolate->GetSymbolRegistry(); | |
512 Handle<String> part = isolate->factory()->private_intern_string(); | |
513 Handle<Object> privates; | |
514 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
515 isolate, privates, Object::GetPropertyOrElement(registry, part)); | |
516 Handle<Object> symbol; | |
517 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
518 isolate, symbol, Object::GetPropertyOrElement(privates, name)); | |
519 if (!symbol->IsSymbol()) { | |
520 DCHECK(symbol->IsUndefined()); | |
521 symbol = isolate->factory()->NewPrivateSymbol(); | |
522 Handle<Symbol>::cast(symbol)->set_name(*name); | |
523 Handle<Symbol>::cast(symbol)->set_is_own(true); | |
524 JSObject::SetProperty(Handle<JSObject>::cast(privates), name, symbol, | |
525 STRICT).Assert(); | |
526 } | |
527 return *symbol; | |
528 } | |
529 | |
530 | |
531 RUNTIME_FUNCTION(Runtime_NewSymbolWrapper) { | |
532 HandleScope scope(isolate); | |
533 DCHECK(args.length() == 1); | |
534 CONVERT_ARG_HANDLE_CHECKED(Symbol, symbol, 0); | |
535 return *Object::ToObject(isolate, symbol).ToHandleChecked(); | |
536 } | |
537 | |
538 | |
539 RUNTIME_FUNCTION(Runtime_SymbolDescription) { | |
540 SealHandleScope shs(isolate); | |
541 DCHECK(args.length() == 1); | |
542 CONVERT_ARG_CHECKED(Symbol, symbol, 0); | |
543 return symbol->name(); | |
544 } | |
545 | |
546 | |
547 RUNTIME_FUNCTION(Runtime_SymbolRegistry) { | |
548 HandleScope scope(isolate); | |
549 DCHECK(args.length() == 0); | |
550 return *isolate->GetSymbolRegistry(); | |
551 } | |
552 | |
553 | |
554 RUNTIME_FUNCTION(Runtime_SymbolIsPrivate) { | |
555 SealHandleScope shs(isolate); | |
556 DCHECK(args.length() == 1); | |
557 CONVERT_ARG_CHECKED(Symbol, symbol, 0); | |
558 return isolate->heap()->ToBoolean(symbol->is_private()); | |
559 } | |
560 | |
561 | |
562 RUNTIME_FUNCTION(Runtime_CreateJSProxy) { | |
563 HandleScope scope(isolate); | |
564 DCHECK(args.length() == 2); | |
565 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0); | |
566 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); | |
567 if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value(); | |
568 return *isolate->factory()->NewJSProxy(handler, prototype); | |
569 } | |
570 | |
571 | |
572 RUNTIME_FUNCTION(Runtime_CreateJSFunctionProxy) { | |
573 HandleScope scope(isolate); | |
574 DCHECK(args.length() == 4); | |
575 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0); | |
576 CONVERT_ARG_HANDLE_CHECKED(Object, call_trap, 1); | |
577 RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy()); | |
578 CONVERT_ARG_HANDLE_CHECKED(JSFunction, construct_trap, 2); | |
579 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 3); | |
580 if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value(); | |
581 return *isolate->factory()->NewJSFunctionProxy(handler, call_trap, | |
582 construct_trap, prototype); | |
583 } | |
584 | |
585 | |
586 RUNTIME_FUNCTION(Runtime_IsJSProxy) { | |
587 SealHandleScope shs(isolate); | |
588 DCHECK(args.length() == 1); | |
589 CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); | |
590 return isolate->heap()->ToBoolean(obj->IsJSProxy()); | |
591 } | |
592 | |
593 | |
594 RUNTIME_FUNCTION(Runtime_IsJSFunctionProxy) { | |
595 SealHandleScope shs(isolate); | |
596 DCHECK(args.length() == 1); | |
597 CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); | |
598 return isolate->heap()->ToBoolean(obj->IsJSFunctionProxy()); | |
599 } | |
600 | |
601 | |
602 RUNTIME_FUNCTION(Runtime_GetHandler) { | |
603 SealHandleScope shs(isolate); | |
604 DCHECK(args.length() == 1); | |
605 CONVERT_ARG_CHECKED(JSProxy, proxy, 0); | |
606 return proxy->handler(); | |
607 } | |
608 | |
609 | |
610 RUNTIME_FUNCTION(Runtime_GetCallTrap) { | |
611 SealHandleScope shs(isolate); | |
612 DCHECK(args.length() == 1); | |
613 CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0); | |
614 return proxy->call_trap(); | |
615 } | |
616 | |
617 | |
618 RUNTIME_FUNCTION(Runtime_GetConstructTrap) { | |
619 SealHandleScope shs(isolate); | |
620 DCHECK(args.length() == 1); | |
621 CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0); | |
622 return proxy->construct_trap(); | |
623 } | |
624 | |
625 | |
626 RUNTIME_FUNCTION(Runtime_Fix) { | |
627 HandleScope scope(isolate); | |
628 DCHECK(args.length() == 1); | |
629 CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0); | |
630 JSProxy::Fix(proxy); | |
631 return isolate->heap()->undefined_value(); | |
632 } | |
633 | |
634 | |
635 RUNTIME_FUNCTION(Runtime_GetPrototype) { | 70 RUNTIME_FUNCTION(Runtime_GetPrototype) { |
636 HandleScope scope(isolate); | 71 HandleScope scope(isolate); |
637 DCHECK(args.length() == 1); | 72 DCHECK(args.length() == 1); |
638 CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); | 73 CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); |
639 // We don't expect access checks to be needed on JSProxy objects. | 74 // We don't expect access checks to be needed on JSProxy objects. |
640 DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); | 75 DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); |
641 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); | 76 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); |
642 do { | 77 do { |
643 if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() && | 78 if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() && |
644 !isolate->MayNamedAccess( | 79 !isolate->MayNamedAccess( |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1000 Handle<Map> old_map(object->map()); | 435 Handle<Map> old_map(object->map()); |
1001 RUNTIME_ASSERT(!old_map->is_access_check_needed()); | 436 RUNTIME_ASSERT(!old_map->is_access_check_needed()); |
1002 // Copy map so it won't interfere constructor's initial map. | 437 // Copy map so it won't interfere constructor's initial map. |
1003 Handle<Map> new_map = Map::Copy(old_map); | 438 Handle<Map> new_map = Map::Copy(old_map); |
1004 new_map->set_is_access_check_needed(true); | 439 new_map->set_is_access_check_needed(true); |
1005 JSObject::MigrateToMap(object, new_map); | 440 JSObject::MigrateToMap(object, new_map); |
1006 return isolate->heap()->undefined_value(); | 441 return isolate->heap()->undefined_value(); |
1007 } | 442 } |
1008 | 443 |
1009 | 444 |
1010 static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) { | |
1011 HandleScope scope(isolate); | |
1012 Handle<Object> args[1] = {name}; | |
1013 THROW_NEW_ERROR_RETURN_FAILURE( | |
1014 isolate, NewTypeError("var_redeclaration", HandleVector(args, 1))); | |
1015 } | |
1016 | |
1017 | |
1018 // May throw a RedeclarationError. | |
1019 static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global, | |
1020 Handle<String> name, Handle<Object> value, | |
1021 PropertyAttributes attr, bool is_var, | |
1022 bool is_const, bool is_function) { | |
1023 // Do the lookup own properties only, see ES5 erratum. | |
1024 LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR); | |
1025 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); | |
1026 if (!maybe.has_value) return isolate->heap()->exception(); | |
1027 | |
1028 if (it.IsFound()) { | |
1029 PropertyAttributes old_attributes = maybe.value; | |
1030 // The name was declared before; check for conflicting re-declarations. | |
1031 if (is_const) return ThrowRedeclarationError(isolate, name); | |
1032 | |
1033 // Skip var re-declarations. | |
1034 if (is_var) return isolate->heap()->undefined_value(); | |
1035 | |
1036 DCHECK(is_function); | |
1037 if ((old_attributes & DONT_DELETE) != 0) { | |
1038 // Only allow reconfiguring globals to functions in user code (no | |
1039 // natives, which are marked as read-only). | |
1040 DCHECK((attr & READ_ONLY) == 0); | |
1041 | |
1042 // Check whether we can reconfigure the existing property into a | |
1043 // function. | |
1044 PropertyDetails old_details = it.property_details(); | |
1045 // TODO(verwaest): CALLBACKS invalidly includes ExecutableAccessInfo, | |
1046 // which are actually data properties, not accessor properties. | |
1047 if (old_details.IsReadOnly() || old_details.IsDontEnum() || | |
1048 old_details.type() == CALLBACKS) { | |
1049 return ThrowRedeclarationError(isolate, name); | |
1050 } | |
1051 // If the existing property is not configurable, keep its attributes. Do | |
1052 attr = old_attributes; | |
1053 } | |
1054 } | |
1055 | |
1056 // Define or redefine own property. | |
1057 RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes( | |
1058 global, name, value, attr)); | |
1059 | |
1060 return isolate->heap()->undefined_value(); | |
1061 } | |
1062 | |
1063 | |
1064 RUNTIME_FUNCTION(Runtime_DeclareGlobals) { | |
1065 HandleScope scope(isolate); | |
1066 DCHECK(args.length() == 3); | |
1067 Handle<GlobalObject> global(isolate->global_object()); | |
1068 | |
1069 CONVERT_ARG_HANDLE_CHECKED(Context, context, 0); | |
1070 CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 1); | |
1071 CONVERT_SMI_ARG_CHECKED(flags, 2); | |
1072 | |
1073 // Traverse the name/value pairs and set the properties. | |
1074 int length = pairs->length(); | |
1075 for (int i = 0; i < length; i += 2) { | |
1076 HandleScope scope(isolate); | |
1077 Handle<String> name(String::cast(pairs->get(i))); | |
1078 Handle<Object> initial_value(pairs->get(i + 1), isolate); | |
1079 | |
1080 // We have to declare a global const property. To capture we only | |
1081 // assign to it when evaluating the assignment for "const x = | |
1082 // <expr>" the initial value is the hole. | |
1083 bool is_var = initial_value->IsUndefined(); | |
1084 bool is_const = initial_value->IsTheHole(); | |
1085 bool is_function = initial_value->IsSharedFunctionInfo(); | |
1086 DCHECK(is_var + is_const + is_function == 1); | |
1087 | |
1088 Handle<Object> value; | |
1089 if (is_function) { | |
1090 // Copy the function and update its context. Use it as value. | |
1091 Handle<SharedFunctionInfo> shared = | |
1092 Handle<SharedFunctionInfo>::cast(initial_value); | |
1093 Handle<JSFunction> function = | |
1094 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context, | |
1095 TENURED); | |
1096 value = function; | |
1097 } else { | |
1098 value = isolate->factory()->undefined_value(); | |
1099 } | |
1100 | |
1101 // Compute the property attributes. According to ECMA-262, | |
1102 // the property must be non-configurable except in eval. | |
1103 bool is_native = DeclareGlobalsNativeFlag::decode(flags); | |
1104 bool is_eval = DeclareGlobalsEvalFlag::decode(flags); | |
1105 int attr = NONE; | |
1106 if (is_const) attr |= READ_ONLY; | |
1107 if (is_function && is_native) attr |= READ_ONLY; | |
1108 if (!is_const && !is_eval) attr |= DONT_DELETE; | |
1109 | |
1110 Object* result = DeclareGlobals(isolate, global, name, value, | |
1111 static_cast<PropertyAttributes>(attr), | |
1112 is_var, is_const, is_function); | |
1113 if (isolate->has_pending_exception()) return result; | |
1114 } | |
1115 | |
1116 return isolate->heap()->undefined_value(); | |
1117 } | |
1118 | |
1119 | |
1120 RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) { | |
1121 HandleScope scope(isolate); | |
1122 // args[0] == name | |
1123 // args[1] == language_mode | |
1124 // args[2] == value (optional) | |
1125 | |
1126 // Determine if we need to assign to the variable if it already | |
1127 // exists (based on the number of arguments). | |
1128 RUNTIME_ASSERT(args.length() == 3); | |
1129 | |
1130 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); | |
1131 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 1); | |
1132 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); | |
1133 | |
1134 Handle<GlobalObject> global(isolate->context()->global_object()); | |
1135 Handle<Object> result; | |
1136 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
1137 isolate, result, Object::SetProperty(global, name, value, strict_mode)); | |
1138 return *result; | |
1139 } | |
1140 | |
1141 | |
1142 RUNTIME_FUNCTION(Runtime_InitializeConstGlobal) { | |
1143 HandleScope handle_scope(isolate); | |
1144 // All constants are declared with an initial value. The name | |
1145 // of the constant is the first argument and the initial value | |
1146 // is the second. | |
1147 RUNTIME_ASSERT(args.length() == 2); | |
1148 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); | |
1149 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); | |
1150 | |
1151 Handle<GlobalObject> global = isolate->global_object(); | |
1152 | |
1153 // Lookup the property as own on the global object. | |
1154 LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR); | |
1155 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); | |
1156 DCHECK(maybe.has_value); | |
1157 PropertyAttributes old_attributes = maybe.value; | |
1158 | |
1159 PropertyAttributes attr = | |
1160 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | |
1161 // Set the value if the property is either missing, or the property attributes | |
1162 // allow setting the value without invoking an accessor. | |
1163 if (it.IsFound()) { | |
1164 // Ignore if we can't reconfigure the value. | |
1165 if ((old_attributes & DONT_DELETE) != 0) { | |
1166 if ((old_attributes & READ_ONLY) != 0 || | |
1167 it.state() == LookupIterator::ACCESSOR) { | |
1168 return *value; | |
1169 } | |
1170 attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY); | |
1171 } | |
1172 } | |
1173 | |
1174 RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes( | |
1175 global, name, value, attr)); | |
1176 | |
1177 return *value; | |
1178 } | |
1179 | |
1180 | |
1181 RUNTIME_FUNCTION(Runtime_DeclareLookupSlot) { | |
1182 HandleScope scope(isolate); | |
1183 DCHECK(args.length() == 4); | |
1184 | |
1185 // Declarations are always made in a function, native, or global context. In | |
1186 // the case of eval code, the context passed is the context of the caller, | |
1187 // which may be some nested context and not the declaration context. | |
1188 CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 0); | |
1189 Handle<Context> context(context_arg->declaration_context()); | |
1190 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); | |
1191 CONVERT_SMI_ARG_CHECKED(attr_arg, 2); | |
1192 PropertyAttributes attr = static_cast<PropertyAttributes>(attr_arg); | |
1193 RUNTIME_ASSERT(attr == READ_ONLY || attr == NONE); | |
1194 CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 3); | |
1195 | |
1196 // TODO(verwaest): Unify the encoding indicating "var" with DeclareGlobals. | |
1197 bool is_var = *initial_value == NULL; | |
1198 bool is_const = initial_value->IsTheHole(); | |
1199 bool is_function = initial_value->IsJSFunction(); | |
1200 DCHECK(is_var + is_const + is_function == 1); | |
1201 | |
1202 int index; | |
1203 PropertyAttributes attributes; | |
1204 ContextLookupFlags flags = DONT_FOLLOW_CHAINS; | |
1205 BindingFlags binding_flags; | |
1206 Handle<Object> holder = | |
1207 context->Lookup(name, flags, &index, &attributes, &binding_flags); | |
1208 | |
1209 Handle<JSObject> object; | |
1210 Handle<Object> value = | |
1211 is_function ? initial_value | |
1212 : Handle<Object>::cast(isolate->factory()->undefined_value()); | |
1213 | |
1214 // TODO(verwaest): This case should probably not be covered by this function, | |
1215 // but by DeclareGlobals instead. | |
1216 if ((attributes != ABSENT && holder->IsJSGlobalObject()) || | |
1217 (context_arg->has_extension() && | |
1218 context_arg->extension()->IsJSGlobalObject())) { | |
1219 return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name, | |
1220 value, attr, is_var, is_const, is_function); | |
1221 } | |
1222 | |
1223 if (attributes != ABSENT) { | |
1224 // The name was declared before; check for conflicting re-declarations. | |
1225 if (is_const || (attributes & READ_ONLY) != 0) { | |
1226 return ThrowRedeclarationError(isolate, name); | |
1227 } | |
1228 | |
1229 // Skip var re-declarations. | |
1230 if (is_var) return isolate->heap()->undefined_value(); | |
1231 | |
1232 DCHECK(is_function); | |
1233 if (index >= 0) { | |
1234 DCHECK(holder.is_identical_to(context)); | |
1235 context->set(index, *initial_value); | |
1236 return isolate->heap()->undefined_value(); | |
1237 } | |
1238 | |
1239 object = Handle<JSObject>::cast(holder); | |
1240 | |
1241 } else if (context->has_extension()) { | |
1242 object = handle(JSObject::cast(context->extension())); | |
1243 DCHECK(object->IsJSContextExtensionObject() || object->IsJSGlobalObject()); | |
1244 } else { | |
1245 DCHECK(context->IsFunctionContext()); | |
1246 object = | |
1247 isolate->factory()->NewJSObject(isolate->context_extension_function()); | |
1248 context->set_extension(*object); | |
1249 } | |
1250 | |
1251 RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes( | |
1252 object, name, value, attr)); | |
1253 | |
1254 return isolate->heap()->undefined_value(); | |
1255 } | |
1256 | |
1257 | |
1258 RUNTIME_FUNCTION(Runtime_InitializeLegacyConstLookupSlot) { | |
1259 HandleScope scope(isolate); | |
1260 DCHECK(args.length() == 3); | |
1261 | |
1262 CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); | |
1263 DCHECK(!value->IsTheHole()); | |
1264 // Initializations are always done in a function or native context. | |
1265 CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 1); | |
1266 Handle<Context> context(context_arg->declaration_context()); | |
1267 CONVERT_ARG_HANDLE_CHECKED(String, name, 2); | |
1268 | |
1269 int index; | |
1270 PropertyAttributes attributes; | |
1271 ContextLookupFlags flags = DONT_FOLLOW_CHAINS; | |
1272 BindingFlags binding_flags; | |
1273 Handle<Object> holder = | |
1274 context->Lookup(name, flags, &index, &attributes, &binding_flags); | |
1275 | |
1276 if (index >= 0) { | |
1277 DCHECK(holder->IsContext()); | |
1278 // Property was found in a context. Perform the assignment if the constant | |
1279 // was uninitialized. | |
1280 Handle<Context> context = Handle<Context>::cast(holder); | |
1281 DCHECK((attributes & READ_ONLY) != 0); | |
1282 if (context->get(index)->IsTheHole()) context->set(index, *value); | |
1283 return *value; | |
1284 } | |
1285 | |
1286 PropertyAttributes attr = | |
1287 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | |
1288 | |
1289 // Strict mode handling not needed (legacy const is disallowed in strict | |
1290 // mode). | |
1291 | |
1292 // The declared const was configurable, and may have been deleted in the | |
1293 // meanwhile. If so, re-introduce the variable in the context extension. | |
1294 DCHECK(context_arg->has_extension()); | |
1295 if (attributes == ABSENT) { | |
1296 holder = handle(context_arg->extension(), isolate); | |
1297 } else { | |
1298 // For JSContextExtensionObjects, the initializer can be run multiple times | |
1299 // if in a for loop: for (var i = 0; i < 2; i++) { const x = i; }. Only the | |
1300 // first assignment should go through. For JSGlobalObjects, additionally any | |
1301 // code can run in between that modifies the declared property. | |
1302 DCHECK(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject()); | |
1303 | |
1304 LookupIterator it(holder, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR); | |
1305 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); | |
1306 if (!maybe.has_value) return isolate->heap()->exception(); | |
1307 PropertyAttributes old_attributes = maybe.value; | |
1308 | |
1309 // Ignore if we can't reconfigure the value. | |
1310 if ((old_attributes & DONT_DELETE) != 0) { | |
1311 if ((old_attributes & READ_ONLY) != 0 || | |
1312 it.state() == LookupIterator::ACCESSOR) { | |
1313 return *value; | |
1314 } | |
1315 attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY); | |
1316 } | |
1317 } | |
1318 | |
1319 RETURN_FAILURE_ON_EXCEPTION( | |
1320 isolate, JSObject::SetOwnPropertyIgnoreAttributes( | |
1321 Handle<JSObject>::cast(holder), name, value, attr)); | |
1322 | |
1323 return *value; | |
1324 } | |
1325 | |
1326 | |
1327 RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) { | 445 RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) { |
1328 HandleScope scope(isolate); | 446 HandleScope scope(isolate); |
1329 DCHECK(args.length() == 2); | 447 DCHECK(args.length() == 2); |
1330 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | 448 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |
1331 CONVERT_SMI_ARG_CHECKED(properties, 1); | 449 CONVERT_SMI_ARG_CHECKED(properties, 1); |
1332 // Conservative upper limit to prevent fuzz tests from going OOM. | 450 // Conservative upper limit to prevent fuzz tests from going OOM. |
1333 RUNTIME_ASSERT(properties <= 100000); | 451 RUNTIME_ASSERT(properties <= 100000); |
1334 if (object->HasFastProperties() && !object->IsJSGlobalProxy()) { | 452 if (object->HasFastProperties() && !object->IsJSGlobalProxy()) { |
1335 JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); | 453 JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); |
1336 } | 454 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1374 InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift); | 492 InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift); |
1375 InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift); | 493 InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift); |
1376 InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice); | 494 InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice); |
1377 InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice); | 495 InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice); |
1378 InstallBuiltin(isolate, holder, "concat", Builtins::kArrayConcat); | 496 InstallBuiltin(isolate, holder, "concat", Builtins::kArrayConcat); |
1379 | 497 |
1380 return *holder; | 498 return *holder; |
1381 } | 499 } |
1382 | 500 |
1383 | 501 |
1384 RUNTIME_FUNCTION(Runtime_IsSloppyModeFunction) { | |
1385 SealHandleScope shs(isolate); | |
1386 DCHECK(args.length() == 1); | |
1387 CONVERT_ARG_CHECKED(JSReceiver, callable, 0); | |
1388 if (!callable->IsJSFunction()) { | |
1389 HandleScope scope(isolate); | |
1390 Handle<Object> delegate; | |
1391 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
1392 isolate, delegate, Execution::TryGetFunctionDelegate( | |
1393 isolate, Handle<JSReceiver>(callable))); | |
1394 callable = JSFunction::cast(*delegate); | |
1395 } | |
1396 JSFunction* function = JSFunction::cast(callable); | |
1397 SharedFunctionInfo* shared = function->shared(); | |
1398 return isolate->heap()->ToBoolean(shared->strict_mode() == SLOPPY); | |
1399 } | |
1400 | |
1401 | |
1402 RUNTIME_FUNCTION(Runtime_GetDefaultReceiver) { | |
1403 SealHandleScope shs(isolate); | |
1404 DCHECK(args.length() == 1); | |
1405 CONVERT_ARG_CHECKED(JSReceiver, callable, 0); | |
1406 | |
1407 if (!callable->IsJSFunction()) { | |
1408 HandleScope scope(isolate); | |
1409 Handle<Object> delegate; | |
1410 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
1411 isolate, delegate, Execution::TryGetFunctionDelegate( | |
1412 isolate, Handle<JSReceiver>(callable))); | |
1413 callable = JSFunction::cast(*delegate); | |
1414 } | |
1415 JSFunction* function = JSFunction::cast(callable); | |
1416 | |
1417 SharedFunctionInfo* shared = function->shared(); | |
1418 if (shared->native() || shared->strict_mode() == STRICT) { | |
1419 return isolate->heap()->undefined_value(); | |
1420 } | |
1421 // Returns undefined for strict or native functions, or | |
1422 // the associated global receiver for "normal" functions. | |
1423 | |
1424 return function->global_proxy(); | |
1425 } | |
1426 | |
1427 | |
1428 RUNTIME_FUNCTION(Runtime_FunctionGetName) { | |
1429 SealHandleScope shs(isolate); | |
1430 DCHECK(args.length() == 1); | |
1431 | |
1432 CONVERT_ARG_CHECKED(JSFunction, f, 0); | |
1433 return f->shared()->name(); | |
1434 } | |
1435 | |
1436 | |
1437 RUNTIME_FUNCTION(Runtime_FunctionSetName) { | |
1438 SealHandleScope shs(isolate); | |
1439 DCHECK(args.length() == 2); | |
1440 | |
1441 CONVERT_ARG_CHECKED(JSFunction, f, 0); | |
1442 CONVERT_ARG_CHECKED(String, name, 1); | |
1443 f->shared()->set_name(name); | |
1444 return isolate->heap()->undefined_value(); | |
1445 } | |
1446 | |
1447 | |
1448 RUNTIME_FUNCTION(Runtime_FunctionNameShouldPrintAsAnonymous) { | |
1449 SealHandleScope shs(isolate); | |
1450 DCHECK(args.length() == 1); | |
1451 CONVERT_ARG_CHECKED(JSFunction, f, 0); | |
1452 return isolate->heap()->ToBoolean( | |
1453 f->shared()->name_should_print_as_anonymous()); | |
1454 } | |
1455 | |
1456 | |
1457 RUNTIME_FUNCTION(Runtime_FunctionMarkNameShouldPrintAsAnonymous) { | |
1458 SealHandleScope shs(isolate); | |
1459 DCHECK(args.length() == 1); | |
1460 CONVERT_ARG_CHECKED(JSFunction, f, 0); | |
1461 f->shared()->set_name_should_print_as_anonymous(true); | |
1462 return isolate->heap()->undefined_value(); | |
1463 } | |
1464 | |
1465 | |
1466 RUNTIME_FUNCTION(Runtime_FunctionIsArrow) { | |
1467 SealHandleScope shs(isolate); | |
1468 DCHECK(args.length() == 1); | |
1469 CONVERT_ARG_CHECKED(JSFunction, f, 0); | |
1470 return isolate->heap()->ToBoolean(f->shared()->is_arrow()); | |
1471 } | |
1472 | |
1473 | |
1474 RUNTIME_FUNCTION(Runtime_FunctionIsConciseMethod) { | |
1475 SealHandleScope shs(isolate); | |
1476 DCHECK(args.length() == 1); | |
1477 CONVERT_ARG_CHECKED(JSFunction, f, 0); | |
1478 return isolate->heap()->ToBoolean(f->shared()->is_concise_method()); | |
1479 } | |
1480 | |
1481 | |
1482 RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) { | |
1483 SealHandleScope shs(isolate); | |
1484 DCHECK(args.length() == 1); | |
1485 | |
1486 CONVERT_ARG_CHECKED(JSFunction, f, 0); | |
1487 RUNTIME_ASSERT(f->RemovePrototype()); | |
1488 | |
1489 return isolate->heap()->undefined_value(); | |
1490 } | |
1491 | |
1492 | |
1493 RUNTIME_FUNCTION(Runtime_FunctionGetScript) { | |
1494 HandleScope scope(isolate); | |
1495 DCHECK(args.length() == 1); | |
1496 | |
1497 CONVERT_ARG_CHECKED(JSFunction, fun, 0); | |
1498 Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate); | |
1499 if (!script->IsScript()) return isolate->heap()->undefined_value(); | |
1500 | |
1501 return *Script::GetWrapper(Handle<Script>::cast(script)); | |
1502 } | |
1503 | |
1504 | |
1505 RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) { | |
1506 HandleScope scope(isolate); | |
1507 DCHECK(args.length() == 1); | |
1508 | |
1509 CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0); | |
1510 Handle<SharedFunctionInfo> shared(f->shared()); | |
1511 return *shared->GetSourceCode(); | |
1512 } | |
1513 | |
1514 | |
1515 RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) { | |
1516 SealHandleScope shs(isolate); | |
1517 DCHECK(args.length() == 1); | |
1518 | |
1519 CONVERT_ARG_CHECKED(JSFunction, fun, 0); | |
1520 int pos = fun->shared()->start_position(); | |
1521 return Smi::FromInt(pos); | |
1522 } | |
1523 | |
1524 | |
1525 RUNTIME_FUNCTION(Runtime_FunctionGetPositionForOffset) { | |
1526 SealHandleScope shs(isolate); | |
1527 DCHECK(args.length() == 2); | |
1528 | |
1529 CONVERT_ARG_CHECKED(Code, code, 0); | |
1530 CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]); | |
1531 | |
1532 RUNTIME_ASSERT(0 <= offset && offset < code->Size()); | |
1533 | |
1534 Address pc = code->address() + offset; | |
1535 return Smi::FromInt(code->SourcePosition(pc)); | |
1536 } | |
1537 | |
1538 | |
1539 RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) { | |
1540 SealHandleScope shs(isolate); | |
1541 DCHECK(args.length() == 2); | |
1542 | |
1543 CONVERT_ARG_CHECKED(JSFunction, fun, 0); | |
1544 CONVERT_ARG_CHECKED(String, name, 1); | |
1545 fun->SetInstanceClassName(name); | |
1546 return isolate->heap()->undefined_value(); | |
1547 } | |
1548 | |
1549 | |
1550 RUNTIME_FUNCTION(Runtime_FunctionSetLength) { | |
1551 SealHandleScope shs(isolate); | |
1552 DCHECK(args.length() == 2); | |
1553 | |
1554 CONVERT_ARG_CHECKED(JSFunction, fun, 0); | |
1555 CONVERT_SMI_ARG_CHECKED(length, 1); | |
1556 RUNTIME_ASSERT((length & 0xC0000000) == 0xC0000000 || | |
1557 (length & 0xC0000000) == 0x0); | |
1558 fun->shared()->set_length(length); | |
1559 return isolate->heap()->undefined_value(); | |
1560 } | |
1561 | |
1562 | |
1563 RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) { | |
1564 HandleScope scope(isolate); | |
1565 DCHECK(args.length() == 2); | |
1566 | |
1567 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); | |
1568 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); | |
1569 RUNTIME_ASSERT(fun->should_have_prototype()); | |
1570 Accessors::FunctionSetPrototype(fun, value); | |
1571 return args[0]; // return TOS | |
1572 } | |
1573 | |
1574 | |
1575 RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) { | |
1576 SealHandleScope shs(isolate); | |
1577 DCHECK(args.length() == 1); | |
1578 | |
1579 CONVERT_ARG_CHECKED(JSFunction, f, 0); | |
1580 return isolate->heap()->ToBoolean(f->shared()->IsApiFunction()); | |
1581 } | |
1582 | |
1583 | |
1584 RUNTIME_FUNCTION(Runtime_FunctionIsBuiltin) { | |
1585 SealHandleScope shs(isolate); | |
1586 DCHECK(args.length() == 1); | |
1587 | |
1588 CONVERT_ARG_CHECKED(JSFunction, f, 0); | |
1589 return isolate->heap()->ToBoolean(f->IsBuiltin()); | |
1590 } | |
1591 | |
1592 | |
1593 RUNTIME_FUNCTION(Runtime_SetCode) { | |
1594 HandleScope scope(isolate); | |
1595 DCHECK(args.length() == 2); | |
1596 | |
1597 CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0); | |
1598 CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1); | |
1599 | |
1600 Handle<SharedFunctionInfo> target_shared(target->shared()); | |
1601 Handle<SharedFunctionInfo> source_shared(source->shared()); | |
1602 RUNTIME_ASSERT(!source_shared->bound()); | |
1603 | |
1604 if (!Compiler::EnsureCompiled(source, KEEP_EXCEPTION)) { | |
1605 return isolate->heap()->exception(); | |
1606 } | |
1607 | |
1608 // Mark both, the source and the target, as un-flushable because the | |
1609 // shared unoptimized code makes them impossible to enqueue in a list. | |
1610 DCHECK(target_shared->code()->gc_metadata() == NULL); | |
1611 DCHECK(source_shared->code()->gc_metadata() == NULL); | |
1612 target_shared->set_dont_flush(true); | |
1613 source_shared->set_dont_flush(true); | |
1614 | |
1615 // Set the code, scope info, formal parameter count, and the length | |
1616 // of the target shared function info. | |
1617 target_shared->ReplaceCode(source_shared->code()); | |
1618 target_shared->set_scope_info(source_shared->scope_info()); | |
1619 target_shared->set_length(source_shared->length()); | |
1620 target_shared->set_feedback_vector(source_shared->feedback_vector()); | |
1621 target_shared->set_formal_parameter_count( | |
1622 source_shared->formal_parameter_count()); | |
1623 target_shared->set_script(source_shared->script()); | |
1624 target_shared->set_start_position_and_type( | |
1625 source_shared->start_position_and_type()); | |
1626 target_shared->set_end_position(source_shared->end_position()); | |
1627 bool was_native = target_shared->native(); | |
1628 target_shared->set_compiler_hints(source_shared->compiler_hints()); | |
1629 target_shared->set_native(was_native); | |
1630 target_shared->set_profiler_ticks(source_shared->profiler_ticks()); | |
1631 | |
1632 // Set the code of the target function. | |
1633 target->ReplaceCode(source_shared->code()); | |
1634 DCHECK(target->next_function_link()->IsUndefined()); | |
1635 | |
1636 // Make sure we get a fresh copy of the literal vector to avoid cross | |
1637 // context contamination. | |
1638 Handle<Context> context(source->context()); | |
1639 int number_of_literals = source->NumberOfLiterals(); | |
1640 Handle<FixedArray> literals = | |
1641 isolate->factory()->NewFixedArray(number_of_literals, TENURED); | |
1642 if (number_of_literals > 0) { | |
1643 literals->set(JSFunction::kLiteralNativeContextIndex, | |
1644 context->native_context()); | |
1645 } | |
1646 target->set_context(*context); | |
1647 target->set_literals(*literals); | |
1648 | |
1649 if (isolate->logger()->is_logging_code_events() || | |
1650 isolate->cpu_profiler()->is_profiling()) { | |
1651 isolate->logger()->LogExistingFunction(source_shared, | |
1652 Handle<Code>(source_shared->code())); | |
1653 } | |
1654 | |
1655 return *target; | |
1656 } | |
1657 | |
1658 | |
1659 RUNTIME_FUNCTION(Runtime_ObjectFreeze) { | 502 RUNTIME_FUNCTION(Runtime_ObjectFreeze) { |
1660 HandleScope scope(isolate); | 503 HandleScope scope(isolate); |
1661 DCHECK(args.length() == 1); | 504 DCHECK(args.length() == 1); |
1662 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | 505 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |
1663 | 506 |
1664 // %ObjectFreeze is a fast path and these cases are handled elsewhere. | 507 // %ObjectFreeze is a fast path and these cases are handled elsewhere. |
1665 RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() && | 508 RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() && |
1666 !object->map()->is_observed() && !object->IsJSProxy()); | 509 !object->map()->is_observed() && !object->IsJSProxy()); |
1667 | 510 |
1668 Handle<Object> result; | 511 Handle<Object> result; |
(...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2333 RUNTIME_FUNCTION(Runtime_TransitionElementsKind) { | 1176 RUNTIME_FUNCTION(Runtime_TransitionElementsKind) { |
2334 HandleScope scope(isolate); | 1177 HandleScope scope(isolate); |
2335 RUNTIME_ASSERT(args.length() == 2); | 1178 RUNTIME_ASSERT(args.length() == 2); |
2336 CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); | 1179 CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); |
2337 CONVERT_ARG_HANDLE_CHECKED(Map, map, 1); | 1180 CONVERT_ARG_HANDLE_CHECKED(Map, map, 1); |
2338 JSObject::TransitionElementsKind(array, map->elements_kind()); | 1181 JSObject::TransitionElementsKind(array, map->elements_kind()); |
2339 return *array; | 1182 return *array; |
2340 } | 1183 } |
2341 | 1184 |
2342 | 1185 |
2343 // Set the native flag on the function. | |
2344 // This is used to decide if we should transform null and undefined | |
2345 // into the global object when doing call and apply. | |
2346 RUNTIME_FUNCTION(Runtime_SetNativeFlag) { | |
2347 SealHandleScope shs(isolate); | |
2348 RUNTIME_ASSERT(args.length() == 1); | |
2349 | |
2350 CONVERT_ARG_CHECKED(Object, object, 0); | |
2351 | |
2352 if (object->IsJSFunction()) { | |
2353 JSFunction* func = JSFunction::cast(object); | |
2354 func->shared()->set_native(true); | |
2355 } | |
2356 return isolate->heap()->undefined_value(); | |
2357 } | |
2358 | |
2359 | |
2360 RUNTIME_FUNCTION(Runtime_SetInlineBuiltinFlag) { | |
2361 SealHandleScope shs(isolate); | |
2362 RUNTIME_ASSERT(args.length() == 1); | |
2363 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); | |
2364 | |
2365 if (object->IsJSFunction()) { | |
2366 JSFunction* func = JSFunction::cast(*object); | |
2367 func->shared()->set_inline_builtin(true); | |
2368 } | |
2369 return isolate->heap()->undefined_value(); | |
2370 } | |
2371 | |
2372 | |
2373 RUNTIME_FUNCTION(Runtime_StoreArrayLiteralElement) { | |
2374 HandleScope scope(isolate); | |
2375 RUNTIME_ASSERT(args.length() == 5); | |
2376 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | |
2377 CONVERT_SMI_ARG_CHECKED(store_index, 1); | |
2378 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); | |
2379 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3); | |
2380 CONVERT_SMI_ARG_CHECKED(literal_index, 4); | |
2381 | |
2382 Object* raw_literal_cell = literals->get(literal_index); | |
2383 JSArray* boilerplate = NULL; | |
2384 if (raw_literal_cell->IsAllocationSite()) { | |
2385 AllocationSite* site = AllocationSite::cast(raw_literal_cell); | |
2386 boilerplate = JSArray::cast(site->transition_info()); | |
2387 } else { | |
2388 boilerplate = JSArray::cast(raw_literal_cell); | |
2389 } | |
2390 Handle<JSArray> boilerplate_object(boilerplate); | |
2391 ElementsKind elements_kind = object->GetElementsKind(); | |
2392 DCHECK(IsFastElementsKind(elements_kind)); | |
2393 // Smis should never trigger transitions. | |
2394 DCHECK(!value->IsSmi()); | |
2395 | |
2396 if (value->IsNumber()) { | |
2397 DCHECK(IsFastSmiElementsKind(elements_kind)); | |
2398 ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind) | |
2399 ? FAST_HOLEY_DOUBLE_ELEMENTS | |
2400 : FAST_DOUBLE_ELEMENTS; | |
2401 if (IsMoreGeneralElementsKindTransition( | |
2402 boilerplate_object->GetElementsKind(), transitioned_kind)) { | |
2403 JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind); | |
2404 } | |
2405 JSObject::TransitionElementsKind(object, transitioned_kind); | |
2406 DCHECK(IsFastDoubleElementsKind(object->GetElementsKind())); | |
2407 FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements()); | |
2408 HeapNumber* number = HeapNumber::cast(*value); | |
2409 double_array->set(store_index, number->Number()); | |
2410 } else { | |
2411 if (!IsFastObjectElementsKind(elements_kind)) { | |
2412 ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind) | |
2413 ? FAST_HOLEY_ELEMENTS | |
2414 : FAST_ELEMENTS; | |
2415 JSObject::TransitionElementsKind(object, transitioned_kind); | |
2416 ElementsKind boilerplate_elements_kind = | |
2417 boilerplate_object->GetElementsKind(); | |
2418 if (IsMoreGeneralElementsKindTransition(boilerplate_elements_kind, | |
2419 transitioned_kind)) { | |
2420 JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind); | |
2421 } | |
2422 } | |
2423 FixedArray* object_array = FixedArray::cast(object->elements()); | |
2424 object_array->set(store_index, *value); | |
2425 } | |
2426 return *object; | |
2427 } | |
2428 | |
2429 | |
2430 RUNTIME_FUNCTION(Runtime_DebugPromiseRejectEvent) { | 1186 RUNTIME_FUNCTION(Runtime_DebugPromiseRejectEvent) { |
2431 DCHECK(args.length() == 2); | 1187 DCHECK(args.length() == 2); |
2432 HandleScope scope(isolate); | 1188 HandleScope scope(isolate); |
2433 CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0); | 1189 CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0); |
2434 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); | 1190 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); |
2435 isolate->debug()->OnPromiseReject(promise, value); | 1191 isolate->debug()->OnPromiseReject(promise, value); |
2436 return isolate->heap()->undefined_value(); | 1192 return isolate->heap()->undefined_value(); |
2437 } | 1193 } |
2438 | 1194 |
2439 | 1195 |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2843 Handle<Object> entry_handle(entry, isolate); | 1599 Handle<Object> entry_handle(entry, isolate); |
2844 Handle<Object> entry_str = | 1600 Handle<Object> entry_str = |
2845 isolate->factory()->NumberToString(entry_handle); | 1601 isolate->factory()->NumberToString(entry_handle); |
2846 copy->set(i, *entry_str); | 1602 copy->set(i, *entry_str); |
2847 } | 1603 } |
2848 } | 1604 } |
2849 return *isolate->factory()->NewJSArrayWithElements(copy); | 1605 return *isolate->factory()->NewJSArrayWithElements(copy); |
2850 } | 1606 } |
2851 | 1607 |
2852 | 1608 |
2853 RUNTIME_FUNCTION(Runtime_GetArgumentsProperty) { | |
2854 SealHandleScope shs(isolate); | |
2855 DCHECK(args.length() == 1); | |
2856 CONVERT_ARG_HANDLE_CHECKED(Object, raw_key, 0); | |
2857 | |
2858 // Compute the frame holding the arguments. | |
2859 JavaScriptFrameIterator it(isolate); | |
2860 it.AdvanceToArgumentsFrame(); | |
2861 JavaScriptFrame* frame = it.frame(); | |
2862 | |
2863 // Get the actual number of provided arguments. | |
2864 const uint32_t n = frame->ComputeParametersCount(); | |
2865 | |
2866 // Try to convert the key to an index. If successful and within | |
2867 // index return the the argument from the frame. | |
2868 uint32_t index; | |
2869 if (raw_key->ToArrayIndex(&index) && index < n) { | |
2870 return frame->GetParameter(index); | |
2871 } | |
2872 | |
2873 HandleScope scope(isolate); | |
2874 if (raw_key->IsSymbol()) { | |
2875 Handle<Symbol> symbol = Handle<Symbol>::cast(raw_key); | |
2876 if (symbol->Equals(isolate->native_context()->iterator_symbol())) { | |
2877 return isolate->native_context()->array_values_iterator(); | |
2878 } | |
2879 // Lookup in the initial Object.prototype object. | |
2880 Handle<Object> result; | |
2881 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
2882 isolate, result, | |
2883 Object::GetProperty(isolate->initial_object_prototype(), | |
2884 Handle<Symbol>::cast(raw_key))); | |
2885 return *result; | |
2886 } | |
2887 | |
2888 // Convert the key to a string. | |
2889 Handle<Object> converted; | |
2890 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, converted, | |
2891 Execution::ToString(isolate, raw_key)); | |
2892 Handle<String> key = Handle<String>::cast(converted); | |
2893 | |
2894 // Try to convert the string key into an array index. | |
2895 if (key->AsArrayIndex(&index)) { | |
2896 if (index < n) { | |
2897 return frame->GetParameter(index); | |
2898 } else { | |
2899 Handle<Object> initial_prototype(isolate->initial_object_prototype()); | |
2900 Handle<Object> result; | |
2901 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
2902 isolate, result, | |
2903 Object::GetElement(isolate, initial_prototype, index)); | |
2904 return *result; | |
2905 } | |
2906 } | |
2907 | |
2908 // Handle special arguments properties. | |
2909 if (String::Equals(isolate->factory()->length_string(), key)) { | |
2910 return Smi::FromInt(n); | |
2911 } | |
2912 if (String::Equals(isolate->factory()->callee_string(), key)) { | |
2913 JSFunction* function = frame->function(); | |
2914 if (function->shared()->strict_mode() == STRICT) { | |
2915 THROW_NEW_ERROR_RETURN_FAILURE( | |
2916 isolate, NewTypeError("strict_arguments_callee", | |
2917 HandleVector<Object>(NULL, 0))); | |
2918 } | |
2919 return function; | |
2920 } | |
2921 | |
2922 // Lookup in the initial Object.prototype object. | |
2923 Handle<Object> result; | |
2924 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
2925 isolate, result, | |
2926 Object::GetProperty(isolate->initial_object_prototype(), key)); | |
2927 return *result; | |
2928 } | |
2929 | |
2930 | |
2931 RUNTIME_FUNCTION(Runtime_ToFastProperties) { | 1609 RUNTIME_FUNCTION(Runtime_ToFastProperties) { |
2932 HandleScope scope(isolate); | 1610 HandleScope scope(isolate); |
2933 DCHECK(args.length() == 1); | 1611 DCHECK(args.length() == 1); |
2934 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); | 1612 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); |
2935 if (object->IsJSObject() && !object->IsGlobalObject()) { | 1613 if (object->IsJSObject() && !object->IsGlobalObject()) { |
2936 JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0); | 1614 JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0); |
2937 } | 1615 } |
2938 return *object; | 1616 return *object; |
2939 } | 1617 } |
2940 | 1618 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3027 } | 1705 } |
3028 | 1706 |
3029 | 1707 |
3030 RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) { | 1708 RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) { |
3031 HandleScope scope(isolate); | 1709 HandleScope scope(isolate); |
3032 DCHECK(args.length() == 0); | 1710 DCHECK(args.length() == 0); |
3033 return *isolate->factory()->NewHeapNumber(0); | 1711 return *isolate->factory()->NewHeapNumber(0); |
3034 } | 1712 } |
3035 | 1713 |
3036 | 1714 |
3037 static Handle<JSObject> NewSloppyArguments(Isolate* isolate, | |
3038 Handle<JSFunction> callee, | |
3039 Object** parameters, | |
3040 int argument_count) { | |
3041 Handle<JSObject> result = | |
3042 isolate->factory()->NewArgumentsObject(callee, argument_count); | |
3043 | |
3044 // Allocate the elements if needed. | |
3045 int parameter_count = callee->shared()->formal_parameter_count(); | |
3046 if (argument_count > 0) { | |
3047 if (parameter_count > 0) { | |
3048 int mapped_count = Min(argument_count, parameter_count); | |
3049 Handle<FixedArray> parameter_map = | |
3050 isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED); | |
3051 parameter_map->set_map(isolate->heap()->sloppy_arguments_elements_map()); | |
3052 | |
3053 Handle<Map> map = Map::Copy(handle(result->map())); | |
3054 map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS); | |
3055 | |
3056 result->set_map(*map); | |
3057 result->set_elements(*parameter_map); | |
3058 | |
3059 // Store the context and the arguments array at the beginning of the | |
3060 // parameter map. | |
3061 Handle<Context> context(isolate->context()); | |
3062 Handle<FixedArray> arguments = | |
3063 isolate->factory()->NewFixedArray(argument_count, NOT_TENURED); | |
3064 parameter_map->set(0, *context); | |
3065 parameter_map->set(1, *arguments); | |
3066 | |
3067 // Loop over the actual parameters backwards. | |
3068 int index = argument_count - 1; | |
3069 while (index >= mapped_count) { | |
3070 // These go directly in the arguments array and have no | |
3071 // corresponding slot in the parameter map. | |
3072 arguments->set(index, *(parameters - index - 1)); | |
3073 --index; | |
3074 } | |
3075 | |
3076 Handle<ScopeInfo> scope_info(callee->shared()->scope_info()); | |
3077 while (index >= 0) { | |
3078 // Detect duplicate names to the right in the parameter list. | |
3079 Handle<String> name(scope_info->ParameterName(index)); | |
3080 int context_local_count = scope_info->ContextLocalCount(); | |
3081 bool duplicate = false; | |
3082 for (int j = index + 1; j < parameter_count; ++j) { | |
3083 if (scope_info->ParameterName(j) == *name) { | |
3084 duplicate = true; | |
3085 break; | |
3086 } | |
3087 } | |
3088 | |
3089 if (duplicate) { | |
3090 // This goes directly in the arguments array with a hole in the | |
3091 // parameter map. | |
3092 arguments->set(index, *(parameters - index - 1)); | |
3093 parameter_map->set_the_hole(index + 2); | |
3094 } else { | |
3095 // The context index goes in the parameter map with a hole in the | |
3096 // arguments array. | |
3097 int context_index = -1; | |
3098 for (int j = 0; j < context_local_count; ++j) { | |
3099 if (scope_info->ContextLocalName(j) == *name) { | |
3100 context_index = j; | |
3101 break; | |
3102 } | |
3103 } | |
3104 DCHECK(context_index >= 0); | |
3105 arguments->set_the_hole(index); | |
3106 parameter_map->set( | |
3107 index + 2, | |
3108 Smi::FromInt(Context::MIN_CONTEXT_SLOTS + context_index)); | |
3109 } | |
3110 | |
3111 --index; | |
3112 } | |
3113 } else { | |
3114 // If there is no aliasing, the arguments object elements are not | |
3115 // special in any way. | |
3116 Handle<FixedArray> elements = | |
3117 isolate->factory()->NewFixedArray(argument_count, NOT_TENURED); | |
3118 result->set_elements(*elements); | |
3119 for (int i = 0; i < argument_count; ++i) { | |
3120 elements->set(i, *(parameters - i - 1)); | |
3121 } | |
3122 } | |
3123 } | |
3124 return result; | |
3125 } | |
3126 | |
3127 | |
3128 static Handle<JSObject> NewStrictArguments(Isolate* isolate, | |
3129 Handle<JSFunction> callee, | |
3130 Object** parameters, | |
3131 int argument_count) { | |
3132 Handle<JSObject> result = | |
3133 isolate->factory()->NewArgumentsObject(callee, argument_count); | |
3134 | |
3135 if (argument_count > 0) { | |
3136 Handle<FixedArray> array = | |
3137 isolate->factory()->NewUninitializedFixedArray(argument_count); | |
3138 DisallowHeapAllocation no_gc; | |
3139 WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc); | |
3140 for (int i = 0; i < argument_count; i++) { | |
3141 array->set(i, *--parameters, mode); | |
3142 } | |
3143 result->set_elements(*array); | |
3144 } | |
3145 return result; | |
3146 } | |
3147 | |
3148 | |
3149 RUNTIME_FUNCTION(Runtime_NewArguments) { | |
3150 HandleScope scope(isolate); | |
3151 DCHECK(args.length() == 1); | |
3152 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); | |
3153 JavaScriptFrameIterator it(isolate); | |
3154 | |
3155 // Find the frame that holds the actual arguments passed to the function. | |
3156 it.AdvanceToArgumentsFrame(); | |
3157 JavaScriptFrame* frame = it.frame(); | |
3158 | |
3159 // Determine parameter location on the stack and dispatch on language mode. | |
3160 int argument_count = frame->GetArgumentsLength(); | |
3161 Object** parameters = reinterpret_cast<Object**>(frame->GetParameterSlot(-1)); | |
3162 return callee->shared()->strict_mode() == STRICT | |
3163 ? *NewStrictArguments(isolate, callee, parameters, argument_count) | |
3164 : *NewSloppyArguments(isolate, callee, parameters, argument_count); | |
3165 } | |
3166 | |
3167 | |
3168 RUNTIME_FUNCTION(Runtime_NewSloppyArguments) { | |
3169 HandleScope scope(isolate); | |
3170 DCHECK(args.length() == 3); | |
3171 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); | |
3172 Object** parameters = reinterpret_cast<Object**>(args[1]); | |
3173 CONVERT_SMI_ARG_CHECKED(argument_count, 2); | |
3174 return *NewSloppyArguments(isolate, callee, parameters, argument_count); | |
3175 } | |
3176 | |
3177 | |
3178 RUNTIME_FUNCTION(Runtime_NewStrictArguments) { | |
3179 HandleScope scope(isolate); | |
3180 DCHECK(args.length() == 3); | |
3181 CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0) | |
3182 Object** parameters = reinterpret_cast<Object**>(args[1]); | |
3183 CONVERT_SMI_ARG_CHECKED(argument_count, 2); | |
3184 return *NewStrictArguments(isolate, callee, parameters, argument_count); | |
3185 } | |
3186 | |
3187 | |
3188 RUNTIME_FUNCTION(Runtime_NewClosureFromStubFailure) { | |
3189 HandleScope scope(isolate); | |
3190 DCHECK(args.length() == 1); | |
3191 CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0); | |
3192 Handle<Context> context(isolate->context()); | |
3193 PretenureFlag pretenure_flag = NOT_TENURED; | |
3194 return *isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context, | |
3195 pretenure_flag); | |
3196 } | |
3197 | |
3198 | |
3199 RUNTIME_FUNCTION(Runtime_NewClosure) { | |
3200 HandleScope scope(isolate); | |
3201 DCHECK(args.length() == 3); | |
3202 CONVERT_ARG_HANDLE_CHECKED(Context, context, 0); | |
3203 CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 1); | |
3204 CONVERT_BOOLEAN_ARG_CHECKED(pretenure, 2); | |
3205 | |
3206 // The caller ensures that we pretenure closures that are assigned | |
3207 // directly to properties. | |
3208 PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED; | |
3209 return *isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context, | |
3210 pretenure_flag); | |
3211 } | |
3212 | |
3213 | |
3214 // Find the arguments of the JavaScript function invocation that called | |
3215 // into C++ code. Collect these in a newly allocated array of handles (possibly | |
3216 // prefixed by a number of empty handles). | |
3217 static SmartArrayPointer<Handle<Object> > GetCallerArguments(Isolate* isolate, | |
3218 int prefix_argc, | |
3219 int* total_argc) { | |
3220 // Find frame containing arguments passed to the caller. | |
3221 JavaScriptFrameIterator it(isolate); | |
3222 JavaScriptFrame* frame = it.frame(); | |
3223 List<JSFunction*> functions(2); | |
3224 frame->GetFunctions(&functions); | |
3225 if (functions.length() > 1) { | |
3226 int inlined_jsframe_index = functions.length() - 1; | |
3227 JSFunction* inlined_function = functions[inlined_jsframe_index]; | |
3228 SlotRefValueBuilder slot_refs( | |
3229 frame, inlined_jsframe_index, | |
3230 inlined_function->shared()->formal_parameter_count()); | |
3231 | |
3232 int args_count = slot_refs.args_length(); | |
3233 | |
3234 *total_argc = prefix_argc + args_count; | |
3235 SmartArrayPointer<Handle<Object> > param_data( | |
3236 NewArray<Handle<Object> >(*total_argc)); | |
3237 slot_refs.Prepare(isolate); | |
3238 for (int i = 0; i < args_count; i++) { | |
3239 Handle<Object> val = slot_refs.GetNext(isolate, 0); | |
3240 param_data[prefix_argc + i] = val; | |
3241 } | |
3242 slot_refs.Finish(isolate); | |
3243 | |
3244 return param_data; | |
3245 } else { | |
3246 it.AdvanceToArgumentsFrame(); | |
3247 frame = it.frame(); | |
3248 int args_count = frame->ComputeParametersCount(); | |
3249 | |
3250 *total_argc = prefix_argc + args_count; | |
3251 SmartArrayPointer<Handle<Object> > param_data( | |
3252 NewArray<Handle<Object> >(*total_argc)); | |
3253 for (int i = 0; i < args_count; i++) { | |
3254 Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate); | |
3255 param_data[prefix_argc + i] = val; | |
3256 } | |
3257 return param_data; | |
3258 } | |
3259 } | |
3260 | |
3261 | |
3262 RUNTIME_FUNCTION(Runtime_FunctionBindArguments) { | |
3263 HandleScope scope(isolate); | |
3264 DCHECK(args.length() == 4); | |
3265 CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0); | |
3266 CONVERT_ARG_HANDLE_CHECKED(Object, bindee, 1); | |
3267 CONVERT_ARG_HANDLE_CHECKED(Object, this_object, 2); | |
3268 CONVERT_NUMBER_ARG_HANDLE_CHECKED(new_length, 3); | |
3269 | |
3270 // TODO(lrn): Create bound function in C++ code from premade shared info. | |
3271 bound_function->shared()->set_bound(true); | |
3272 // Get all arguments of calling function (Function.prototype.bind). | |
3273 int argc = 0; | |
3274 SmartArrayPointer<Handle<Object> > arguments = | |
3275 GetCallerArguments(isolate, 0, &argc); | |
3276 // Don't count the this-arg. | |
3277 if (argc > 0) { | |
3278 RUNTIME_ASSERT(arguments[0].is_identical_to(this_object)); | |
3279 argc--; | |
3280 } else { | |
3281 RUNTIME_ASSERT(this_object->IsUndefined()); | |
3282 } | |
3283 // Initialize array of bindings (function, this, and any existing arguments | |
3284 // if the function was already bound). | |
3285 Handle<FixedArray> new_bindings; | |
3286 int i; | |
3287 if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) { | |
3288 Handle<FixedArray> old_bindings( | |
3289 JSFunction::cast(*bindee)->function_bindings()); | |
3290 RUNTIME_ASSERT(old_bindings->length() > JSFunction::kBoundFunctionIndex); | |
3291 new_bindings = | |
3292 isolate->factory()->NewFixedArray(old_bindings->length() + argc); | |
3293 bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex), | |
3294 isolate); | |
3295 i = 0; | |
3296 for (int n = old_bindings->length(); i < n; i++) { | |
3297 new_bindings->set(i, old_bindings->get(i)); | |
3298 } | |
3299 } else { | |
3300 int array_size = JSFunction::kBoundArgumentsStartIndex + argc; | |
3301 new_bindings = isolate->factory()->NewFixedArray(array_size); | |
3302 new_bindings->set(JSFunction::kBoundFunctionIndex, *bindee); | |
3303 new_bindings->set(JSFunction::kBoundThisIndex, *this_object); | |
3304 i = 2; | |
3305 } | |
3306 // Copy arguments, skipping the first which is "this_arg". | |
3307 for (int j = 0; j < argc; j++, i++) { | |
3308 new_bindings->set(i, *arguments[j + 1]); | |
3309 } | |
3310 new_bindings->set_map_no_write_barrier( | |
3311 isolate->heap()->fixed_cow_array_map()); | |
3312 bound_function->set_function_bindings(*new_bindings); | |
3313 | |
3314 // Update length. Have to remove the prototype first so that map migration | |
3315 // is happy about the number of fields. | |
3316 RUNTIME_ASSERT(bound_function->RemovePrototype()); | |
3317 Handle<Map> bound_function_map( | |
3318 isolate->native_context()->bound_function_map()); | |
3319 JSObject::MigrateToMap(bound_function, bound_function_map); | |
3320 Handle<String> length_string = isolate->factory()->length_string(); | |
3321 PropertyAttributes attr = | |
3322 static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY); | |
3323 RETURN_FAILURE_ON_EXCEPTION( | |
3324 isolate, JSObject::SetOwnPropertyIgnoreAttributes( | |
3325 bound_function, length_string, new_length, attr)); | |
3326 return *bound_function; | |
3327 } | |
3328 | |
3329 | |
3330 RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) { | |
3331 HandleScope handles(isolate); | |
3332 DCHECK(args.length() == 1); | |
3333 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0); | |
3334 if (callable->IsJSFunction()) { | |
3335 Handle<JSFunction> function = Handle<JSFunction>::cast(callable); | |
3336 if (function->shared()->bound()) { | |
3337 Handle<FixedArray> bindings(function->function_bindings()); | |
3338 RUNTIME_ASSERT(bindings->map() == isolate->heap()->fixed_cow_array_map()); | |
3339 return *isolate->factory()->NewJSArrayWithElements(bindings); | |
3340 } | |
3341 } | |
3342 return isolate->heap()->undefined_value(); | |
3343 } | |
3344 | |
3345 | |
3346 RUNTIME_FUNCTION(Runtime_NewObjectFromBound) { | |
3347 HandleScope scope(isolate); | |
3348 DCHECK(args.length() == 1); | |
3349 // First argument is a function to use as a constructor. | |
3350 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); | |
3351 RUNTIME_ASSERT(function->shared()->bound()); | |
3352 | |
3353 // The argument is a bound function. Extract its bound arguments | |
3354 // and callable. | |
3355 Handle<FixedArray> bound_args = | |
3356 Handle<FixedArray>(FixedArray::cast(function->function_bindings())); | |
3357 int bound_argc = bound_args->length() - JSFunction::kBoundArgumentsStartIndex; | |
3358 Handle<Object> bound_function( | |
3359 JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)), | |
3360 isolate); | |
3361 DCHECK(!bound_function->IsJSFunction() || | |
3362 !Handle<JSFunction>::cast(bound_function)->shared()->bound()); | |
3363 | |
3364 int total_argc = 0; | |
3365 SmartArrayPointer<Handle<Object> > param_data = | |
3366 GetCallerArguments(isolate, bound_argc, &total_argc); | |
3367 for (int i = 0; i < bound_argc; i++) { | |
3368 param_data[i] = Handle<Object>( | |
3369 bound_args->get(JSFunction::kBoundArgumentsStartIndex + i), isolate); | |
3370 } | |
3371 | |
3372 if (!bound_function->IsJSFunction()) { | |
3373 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
3374 isolate, bound_function, | |
3375 Execution::TryGetConstructorDelegate(isolate, bound_function)); | |
3376 } | |
3377 DCHECK(bound_function->IsJSFunction()); | |
3378 | |
3379 Handle<Object> result; | |
3380 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
3381 isolate, result, Execution::New(Handle<JSFunction>::cast(bound_function), | |
3382 total_argc, param_data.get())); | |
3383 return *result; | |
3384 } | |
3385 | |
3386 | |
3387 static Object* Runtime_NewObjectHelper(Isolate* isolate, | 1715 static Object* Runtime_NewObjectHelper(Isolate* isolate, |
3388 Handle<Object> constructor, | 1716 Handle<Object> constructor, |
3389 Handle<AllocationSite> site) { | 1717 Handle<AllocationSite> site) { |
3390 // If the constructor isn't a proper function we throw a type error. | 1718 // If the constructor isn't a proper function we throw a type error. |
3391 if (!constructor->IsJSFunction()) { | 1719 if (!constructor->IsJSFunction()) { |
3392 Vector<Handle<Object> > arguments = HandleVector(&constructor, 1); | 1720 Vector<Handle<Object> > arguments = HandleVector(&constructor, 1); |
3393 THROW_NEW_ERROR_RETURN_FAILURE(isolate, | 1721 THROW_NEW_ERROR_RETURN_FAILURE(isolate, |
3394 NewTypeError("not_constructor", arguments)); | 1722 NewTypeError("not_constructor", arguments)); |
3395 } | 1723 } |
3396 | 1724 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3488 | 1816 |
3489 | 1817 |
3490 RUNTIME_FUNCTION(Runtime_GetRootNaN) { | 1818 RUNTIME_FUNCTION(Runtime_GetRootNaN) { |
3491 SealHandleScope shs(isolate); | 1819 SealHandleScope shs(isolate); |
3492 DCHECK(args.length() == 0); | 1820 DCHECK(args.length() == 0); |
3493 RUNTIME_ASSERT(isolate->bootstrapper()->IsActive()); | 1821 RUNTIME_ASSERT(isolate->bootstrapper()->IsActive()); |
3494 return isolate->heap()->nan_value(); | 1822 return isolate->heap()->nan_value(); |
3495 } | 1823 } |
3496 | 1824 |
3497 | 1825 |
3498 RUNTIME_FUNCTION(Runtime_Call) { | |
3499 HandleScope scope(isolate); | |
3500 DCHECK(args.length() >= 2); | |
3501 int argc = args.length() - 2; | |
3502 CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1); | |
3503 Object* receiver = args[0]; | |
3504 | |
3505 // If there are too many arguments, allocate argv via malloc. | |
3506 const int argv_small_size = 10; | |
3507 Handle<Object> argv_small_buffer[argv_small_size]; | |
3508 SmartArrayPointer<Handle<Object> > argv_large_buffer; | |
3509 Handle<Object>* argv = argv_small_buffer; | |
3510 if (argc > argv_small_size) { | |
3511 argv = new Handle<Object>[argc]; | |
3512 if (argv == NULL) return isolate->StackOverflow(); | |
3513 argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv); | |
3514 } | |
3515 | |
3516 for (int i = 0; i < argc; ++i) { | |
3517 argv[i] = Handle<Object>(args[1 + i], isolate); | |
3518 } | |
3519 | |
3520 Handle<JSReceiver> hfun(fun); | |
3521 Handle<Object> hreceiver(receiver, isolate); | |
3522 Handle<Object> result; | |
3523 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
3524 isolate, result, | |
3525 Execution::Call(isolate, hfun, hreceiver, argc, argv, true)); | |
3526 return *result; | |
3527 } | |
3528 | |
3529 | |
3530 RUNTIME_FUNCTION(Runtime_Apply) { | |
3531 HandleScope scope(isolate); | |
3532 DCHECK(args.length() == 5); | |
3533 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0); | |
3534 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1); | |
3535 CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2); | |
3536 CONVERT_INT32_ARG_CHECKED(offset, 3); | |
3537 CONVERT_INT32_ARG_CHECKED(argc, 4); | |
3538 RUNTIME_ASSERT(offset >= 0); | |
3539 // Loose upper bound to allow fuzzing. We'll most likely run out of | |
3540 // stack space before hitting this limit. | |
3541 static int kMaxArgc = 1000000; | |
3542 RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc); | |
3543 | |
3544 // If there are too many arguments, allocate argv via malloc. | |
3545 const int argv_small_size = 10; | |
3546 Handle<Object> argv_small_buffer[argv_small_size]; | |
3547 SmartArrayPointer<Handle<Object> > argv_large_buffer; | |
3548 Handle<Object>* argv = argv_small_buffer; | |
3549 if (argc > argv_small_size) { | |
3550 argv = new Handle<Object>[argc]; | |
3551 if (argv == NULL) return isolate->StackOverflow(); | |
3552 argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv); | |
3553 } | |
3554 | |
3555 for (int i = 0; i < argc; ++i) { | |
3556 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
3557 isolate, argv[i], Object::GetElement(isolate, arguments, offset + i)); | |
3558 } | |
3559 | |
3560 Handle<Object> result; | |
3561 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
3562 isolate, result, | |
3563 Execution::Call(isolate, fun, receiver, argc, argv, true)); | |
3564 return *result; | |
3565 } | |
3566 | |
3567 | |
3568 RUNTIME_FUNCTION(Runtime_GetFunctionDelegate) { | |
3569 HandleScope scope(isolate); | |
3570 DCHECK(args.length() == 1); | |
3571 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); | |
3572 RUNTIME_ASSERT(!object->IsJSFunction()); | |
3573 return *Execution::GetFunctionDelegate(isolate, object); | |
3574 } | |
3575 | |
3576 | |
3577 RUNTIME_FUNCTION(Runtime_GetConstructorDelegate) { | |
3578 HandleScope scope(isolate); | |
3579 DCHECK(args.length() == 1); | |
3580 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); | |
3581 RUNTIME_ASSERT(!object->IsJSFunction()); | |
3582 return *Execution::GetConstructorDelegate(isolate, object); | |
3583 } | |
3584 | |
3585 | |
3586 RUNTIME_FUNCTION(Runtime_NewGlobalContext) { | |
3587 HandleScope scope(isolate); | |
3588 DCHECK(args.length() == 2); | |
3589 | |
3590 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); | |
3591 CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1); | |
3592 Handle<Context> result = | |
3593 isolate->factory()->NewGlobalContext(function, scope_info); | |
3594 | |
3595 DCHECK(function->context() == isolate->context()); | |
3596 DCHECK(function->context()->global_object() == result->global_object()); | |
3597 result->global_object()->set_global_context(*result); | |
3598 return *result; | |
3599 } | |
3600 | |
3601 | |
3602 RUNTIME_FUNCTION(Runtime_NewFunctionContext) { | |
3603 HandleScope scope(isolate); | |
3604 DCHECK(args.length() == 1); | |
3605 | |
3606 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); | |
3607 | |
3608 DCHECK(function->context() == isolate->context()); | |
3609 int length = function->shared()->scope_info()->ContextLength(); | |
3610 return *isolate->factory()->NewFunctionContext(length, function); | |
3611 } | |
3612 | |
3613 | |
3614 RUNTIME_FUNCTION(Runtime_PushWithContext) { | |
3615 HandleScope scope(isolate); | |
3616 DCHECK(args.length() == 2); | |
3617 Handle<JSReceiver> extension_object; | |
3618 if (args[0]->IsJSReceiver()) { | |
3619 extension_object = args.at<JSReceiver>(0); | |
3620 } else { | |
3621 // Try to convert the object to a proper JavaScript object. | |
3622 MaybeHandle<JSReceiver> maybe_object = | |
3623 Object::ToObject(isolate, args.at<Object>(0)); | |
3624 if (!maybe_object.ToHandle(&extension_object)) { | |
3625 Handle<Object> handle = args.at<Object>(0); | |
3626 THROW_NEW_ERROR_RETURN_FAILURE( | |
3627 isolate, NewTypeError("with_expression", HandleVector(&handle, 1))); | |
3628 } | |
3629 } | |
3630 | |
3631 Handle<JSFunction> function; | |
3632 if (args[1]->IsSmi()) { | |
3633 // A smi sentinel indicates a context nested inside global code rather | |
3634 // than some function. There is a canonical empty function that can be | |
3635 // gotten from the native context. | |
3636 function = handle(isolate->native_context()->closure()); | |
3637 } else { | |
3638 function = args.at<JSFunction>(1); | |
3639 } | |
3640 | |
3641 Handle<Context> current(isolate->context()); | |
3642 Handle<Context> context = | |
3643 isolate->factory()->NewWithContext(function, current, extension_object); | |
3644 isolate->set_context(*context); | |
3645 return *context; | |
3646 } | |
3647 | |
3648 | |
3649 RUNTIME_FUNCTION(Runtime_PushCatchContext) { | |
3650 HandleScope scope(isolate); | |
3651 DCHECK(args.length() == 3); | |
3652 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); | |
3653 CONVERT_ARG_HANDLE_CHECKED(Object, thrown_object, 1); | |
3654 Handle<JSFunction> function; | |
3655 if (args[2]->IsSmi()) { | |
3656 // A smi sentinel indicates a context nested inside global code rather | |
3657 // than some function. There is a canonical empty function that can be | |
3658 // gotten from the native context. | |
3659 function = handle(isolate->native_context()->closure()); | |
3660 } else { | |
3661 function = args.at<JSFunction>(2); | |
3662 } | |
3663 Handle<Context> current(isolate->context()); | |
3664 Handle<Context> context = isolate->factory()->NewCatchContext( | |
3665 function, current, name, thrown_object); | |
3666 isolate->set_context(*context); | |
3667 return *context; | |
3668 } | |
3669 | |
3670 | |
3671 RUNTIME_FUNCTION(Runtime_PushBlockContext) { | |
3672 HandleScope scope(isolate); | |
3673 DCHECK(args.length() == 2); | |
3674 CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 0); | |
3675 Handle<JSFunction> function; | |
3676 if (args[1]->IsSmi()) { | |
3677 // A smi sentinel indicates a context nested inside global code rather | |
3678 // than some function. There is a canonical empty function that can be | |
3679 // gotten from the native context. | |
3680 function = handle(isolate->native_context()->closure()); | |
3681 } else { | |
3682 function = args.at<JSFunction>(1); | |
3683 } | |
3684 Handle<Context> current(isolate->context()); | |
3685 Handle<Context> context = | |
3686 isolate->factory()->NewBlockContext(function, current, scope_info); | |
3687 isolate->set_context(*context); | |
3688 return *context; | |
3689 } | |
3690 | |
3691 | |
3692 RUNTIME_FUNCTION(Runtime_IsJSModule) { | |
3693 SealHandleScope shs(isolate); | |
3694 DCHECK(args.length() == 1); | |
3695 CONVERT_ARG_CHECKED(Object, obj, 0); | |
3696 return isolate->heap()->ToBoolean(obj->IsJSModule()); | |
3697 } | |
3698 | |
3699 | |
3700 RUNTIME_FUNCTION(Runtime_PushModuleContext) { | |
3701 SealHandleScope shs(isolate); | |
3702 DCHECK(args.length() == 2); | |
3703 CONVERT_SMI_ARG_CHECKED(index, 0); | |
3704 | |
3705 if (!args[1]->IsScopeInfo()) { | |
3706 // Module already initialized. Find hosting context and retrieve context. | |
3707 Context* host = Context::cast(isolate->context())->global_context(); | |
3708 Context* context = Context::cast(host->get(index)); | |
3709 DCHECK(context->previous() == isolate->context()); | |
3710 isolate->set_context(context); | |
3711 return context; | |
3712 } | |
3713 | |
3714 CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1); | |
3715 | |
3716 // Allocate module context. | |
3717 HandleScope scope(isolate); | |
3718 Factory* factory = isolate->factory(); | |
3719 Handle<Context> context = factory->NewModuleContext(scope_info); | |
3720 Handle<JSModule> module = factory->NewJSModule(context, scope_info); | |
3721 context->set_module(*module); | |
3722 Context* previous = isolate->context(); | |
3723 context->set_previous(previous); | |
3724 context->set_closure(previous->closure()); | |
3725 context->set_global_object(previous->global_object()); | |
3726 isolate->set_context(*context); | |
3727 | |
3728 // Find hosting scope and initialize internal variable holding module there. | |
3729 previous->global_context()->set(index, *context); | |
3730 | |
3731 return *context; | |
3732 } | |
3733 | |
3734 | |
3735 RUNTIME_FUNCTION(Runtime_DeclareModules) { | |
3736 HandleScope scope(isolate); | |
3737 DCHECK(args.length() == 1); | |
3738 CONVERT_ARG_HANDLE_CHECKED(FixedArray, descriptions, 0); | |
3739 Context* host_context = isolate->context(); | |
3740 | |
3741 for (int i = 0; i < descriptions->length(); ++i) { | |
3742 Handle<ModuleInfo> description(ModuleInfo::cast(descriptions->get(i))); | |
3743 int host_index = description->host_index(); | |
3744 Handle<Context> context(Context::cast(host_context->get(host_index))); | |
3745 Handle<JSModule> module(context->module()); | |
3746 | |
3747 for (int j = 0; j < description->length(); ++j) { | |
3748 Handle<String> name(description->name(j)); | |
3749 VariableMode mode = description->mode(j); | |
3750 int index = description->index(j); | |
3751 switch (mode) { | |
3752 case VAR: | |
3753 case LET: | |
3754 case CONST: | |
3755 case CONST_LEGACY: { | |
3756 PropertyAttributes attr = | |
3757 IsImmutableVariableMode(mode) ? FROZEN : SEALED; | |
3758 Handle<AccessorInfo> info = | |
3759 Accessors::MakeModuleExport(name, index, attr); | |
3760 Handle<Object> result = | |
3761 JSObject::SetAccessor(module, info).ToHandleChecked(); | |
3762 DCHECK(!result->IsUndefined()); | |
3763 USE(result); | |
3764 break; | |
3765 } | |
3766 case MODULE: { | |
3767 Object* referenced_context = Context::cast(host_context)->get(index); | |
3768 Handle<JSModule> value(Context::cast(referenced_context)->module()); | |
3769 JSObject::SetOwnPropertyIgnoreAttributes(module, name, value, FROZEN) | |
3770 .Assert(); | |
3771 break; | |
3772 } | |
3773 case INTERNAL: | |
3774 case TEMPORARY: | |
3775 case DYNAMIC: | |
3776 case DYNAMIC_GLOBAL: | |
3777 case DYNAMIC_LOCAL: | |
3778 UNREACHABLE(); | |
3779 } | |
3780 } | |
3781 | |
3782 JSObject::PreventExtensions(module).Assert(); | |
3783 } | |
3784 | |
3785 DCHECK(!isolate->has_pending_exception()); | |
3786 return isolate->heap()->undefined_value(); | |
3787 } | |
3788 | |
3789 | |
3790 RUNTIME_FUNCTION(Runtime_DeleteLookupSlot) { | |
3791 HandleScope scope(isolate); | |
3792 DCHECK(args.length() == 2); | |
3793 | |
3794 CONVERT_ARG_HANDLE_CHECKED(Context, context, 0); | |
3795 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); | |
3796 | |
3797 int index; | |
3798 PropertyAttributes attributes; | |
3799 ContextLookupFlags flags = FOLLOW_CHAINS; | |
3800 BindingFlags binding_flags; | |
3801 Handle<Object> holder = | |
3802 context->Lookup(name, flags, &index, &attributes, &binding_flags); | |
3803 | |
3804 // If the slot was not found the result is true. | |
3805 if (holder.is_null()) { | |
3806 return isolate->heap()->true_value(); | |
3807 } | |
3808 | |
3809 // If the slot was found in a context, it should be DONT_DELETE. | |
3810 if (holder->IsContext()) { | |
3811 return isolate->heap()->false_value(); | |
3812 } | |
3813 | |
3814 // The slot was found in a JSObject, either a context extension object, | |
3815 // the global object, or the subject of a with. Try to delete it | |
3816 // (respecting DONT_DELETE). | |
3817 Handle<JSObject> object = Handle<JSObject>::cast(holder); | |
3818 Handle<Object> result; | |
3819 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | |
3820 JSReceiver::DeleteProperty(object, name)); | |
3821 return *result; | |
3822 } | |
3823 | |
3824 | |
3825 static Object* ComputeReceiverForNonGlobal(Isolate* isolate, JSObject* holder) { | |
3826 DCHECK(!holder->IsGlobalObject()); | |
3827 Context* top = isolate->context(); | |
3828 // Get the context extension function. | |
3829 JSFunction* context_extension_function = | |
3830 top->native_context()->context_extension_function(); | |
3831 // If the holder isn't a context extension object, we just return it | |
3832 // as the receiver. This allows arguments objects to be used as | |
3833 // receivers, but only if they are put in the context scope chain | |
3834 // explicitly via a with-statement. | |
3835 Object* constructor = holder->map()->constructor(); | |
3836 if (constructor != context_extension_function) return holder; | |
3837 // Fall back to using the global object as the implicit receiver if | |
3838 // the property turns out to be a local variable allocated in a | |
3839 // context extension object - introduced via eval. | |
3840 return isolate->heap()->undefined_value(); | |
3841 } | |
3842 | |
3843 | |
3844 static ObjectPair LoadLookupSlotHelper(Arguments args, Isolate* isolate, | |
3845 bool throw_error) { | |
3846 HandleScope scope(isolate); | |
3847 DCHECK_EQ(2, args.length()); | |
3848 | |
3849 if (!args[0]->IsContext() || !args[1]->IsString()) { | |
3850 return MakePair(isolate->ThrowIllegalOperation(), NULL); | |
3851 } | |
3852 Handle<Context> context = args.at<Context>(0); | |
3853 Handle<String> name = args.at<String>(1); | |
3854 | |
3855 int index; | |
3856 PropertyAttributes attributes; | |
3857 ContextLookupFlags flags = FOLLOW_CHAINS; | |
3858 BindingFlags binding_flags; | |
3859 Handle<Object> holder = | |
3860 context->Lookup(name, flags, &index, &attributes, &binding_flags); | |
3861 if (isolate->has_pending_exception()) { | |
3862 return MakePair(isolate->heap()->exception(), NULL); | |
3863 } | |
3864 | |
3865 // If the index is non-negative, the slot has been found in a context. | |
3866 if (index >= 0) { | |
3867 DCHECK(holder->IsContext()); | |
3868 // If the "property" we were looking for is a local variable, the | |
3869 // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3. | |
3870 Handle<Object> receiver = isolate->factory()->undefined_value(); | |
3871 Object* value = Context::cast(*holder)->get(index); | |
3872 // Check for uninitialized bindings. | |
3873 switch (binding_flags) { | |
3874 case MUTABLE_CHECK_INITIALIZED: | |
3875 case IMMUTABLE_CHECK_INITIALIZED_HARMONY: | |
3876 if (value->IsTheHole()) { | |
3877 Handle<Object> error; | |
3878 MaybeHandle<Object> maybe_error = | |
3879 isolate->factory()->NewReferenceError("not_defined", | |
3880 HandleVector(&name, 1)); | |
3881 if (maybe_error.ToHandle(&error)) isolate->Throw(*error); | |
3882 return MakePair(isolate->heap()->exception(), NULL); | |
3883 } | |
3884 // FALLTHROUGH | |
3885 case MUTABLE_IS_INITIALIZED: | |
3886 case IMMUTABLE_IS_INITIALIZED: | |
3887 case IMMUTABLE_IS_INITIALIZED_HARMONY: | |
3888 DCHECK(!value->IsTheHole()); | |
3889 return MakePair(value, *receiver); | |
3890 case IMMUTABLE_CHECK_INITIALIZED: | |
3891 if (value->IsTheHole()) { | |
3892 DCHECK((attributes & READ_ONLY) != 0); | |
3893 value = isolate->heap()->undefined_value(); | |
3894 } | |
3895 return MakePair(value, *receiver); | |
3896 case MISSING_BINDING: | |
3897 UNREACHABLE(); | |
3898 return MakePair(NULL, NULL); | |
3899 } | |
3900 } | |
3901 | |
3902 // Otherwise, if the slot was found the holder is a context extension | |
3903 // object, subject of a with, or a global object. We read the named | |
3904 // property from it. | |
3905 if (!holder.is_null()) { | |
3906 Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder); | |
3907 #ifdef DEBUG | |
3908 if (!object->IsJSProxy()) { | |
3909 Maybe<bool> maybe = JSReceiver::HasProperty(object, name); | |
3910 DCHECK(maybe.has_value); | |
3911 DCHECK(maybe.value); | |
3912 } | |
3913 #endif | |
3914 // GetProperty below can cause GC. | |
3915 Handle<Object> receiver_handle( | |
3916 object->IsGlobalObject() | |
3917 ? Object::cast(isolate->heap()->undefined_value()) | |
3918 : object->IsJSProxy() ? static_cast<Object*>(*object) | |
3919 : ComputeReceiverForNonGlobal( | |
3920 isolate, JSObject::cast(*object)), | |
3921 isolate); | |
3922 | |
3923 // No need to unhole the value here. This is taken care of by the | |
3924 // GetProperty function. | |
3925 Handle<Object> value; | |
3926 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
3927 isolate, value, Object::GetProperty(object, name), | |
3928 MakePair(isolate->heap()->exception(), NULL)); | |
3929 return MakePair(*value, *receiver_handle); | |
3930 } | |
3931 | |
3932 if (throw_error) { | |
3933 // The property doesn't exist - throw exception. | |
3934 Handle<Object> error; | |
3935 MaybeHandle<Object> maybe_error = isolate->factory()->NewReferenceError( | |
3936 "not_defined", HandleVector(&name, 1)); | |
3937 if (maybe_error.ToHandle(&error)) isolate->Throw(*error); | |
3938 return MakePair(isolate->heap()->exception(), NULL); | |
3939 } else { | |
3940 // The property doesn't exist - return undefined. | |
3941 return MakePair(isolate->heap()->undefined_value(), | |
3942 isolate->heap()->undefined_value()); | |
3943 } | |
3944 } | |
3945 | |
3946 | |
3947 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlot) { | |
3948 return LoadLookupSlotHelper(args, isolate, true); | |
3949 } | |
3950 | |
3951 | |
3952 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlotNoReferenceError) { | |
3953 return LoadLookupSlotHelper(args, isolate, false); | |
3954 } | |
3955 | |
3956 | |
3957 RUNTIME_FUNCTION(Runtime_StoreLookupSlot) { | |
3958 HandleScope scope(isolate); | |
3959 DCHECK(args.length() == 4); | |
3960 | |
3961 CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); | |
3962 CONVERT_ARG_HANDLE_CHECKED(Context, context, 1); | |
3963 CONVERT_ARG_HANDLE_CHECKED(String, name, 2); | |
3964 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 3); | |
3965 | |
3966 int index; | |
3967 PropertyAttributes attributes; | |
3968 ContextLookupFlags flags = FOLLOW_CHAINS; | |
3969 BindingFlags binding_flags; | |
3970 Handle<Object> holder = | |
3971 context->Lookup(name, flags, &index, &attributes, &binding_flags); | |
3972 // In case of JSProxy, an exception might have been thrown. | |
3973 if (isolate->has_pending_exception()) return isolate->heap()->exception(); | |
3974 | |
3975 // The property was found in a context slot. | |
3976 if (index >= 0) { | |
3977 if ((attributes & READ_ONLY) == 0) { | |
3978 Handle<Context>::cast(holder)->set(index, *value); | |
3979 } else if (strict_mode == STRICT) { | |
3980 // Setting read only property in strict mode. | |
3981 THROW_NEW_ERROR_RETURN_FAILURE( | |
3982 isolate, | |
3983 NewTypeError("strict_cannot_assign", HandleVector(&name, 1))); | |
3984 } | |
3985 return *value; | |
3986 } | |
3987 | |
3988 // Slow case: The property is not in a context slot. It is either in a | |
3989 // context extension object, a property of the subject of a with, or a | |
3990 // property of the global object. | |
3991 Handle<JSReceiver> object; | |
3992 if (attributes != ABSENT) { | |
3993 // The property exists on the holder. | |
3994 object = Handle<JSReceiver>::cast(holder); | |
3995 } else if (strict_mode == STRICT) { | |
3996 // If absent in strict mode: throw. | |
3997 THROW_NEW_ERROR_RETURN_FAILURE( | |
3998 isolate, NewReferenceError("not_defined", HandleVector(&name, 1))); | |
3999 } else { | |
4000 // If absent in sloppy mode: add the property to the global object. | |
4001 object = Handle<JSReceiver>(context->global_object()); | |
4002 } | |
4003 | |
4004 RETURN_FAILURE_ON_EXCEPTION( | |
4005 isolate, Object::SetProperty(object, name, value, strict_mode)); | |
4006 | |
4007 return *value; | |
4008 } | |
4009 | |
4010 | |
4011 RUNTIME_FUNCTION(Runtime_Throw) { | 1826 RUNTIME_FUNCTION(Runtime_Throw) { |
4012 HandleScope scope(isolate); | 1827 HandleScope scope(isolate); |
4013 DCHECK(args.length() == 1); | 1828 DCHECK(args.length() == 1); |
4014 | 1829 |
4015 return isolate->Throw(args[0]); | 1830 return isolate->Throw(args[0]); |
4016 } | 1831 } |
4017 | 1832 |
4018 | 1833 |
4019 RUNTIME_FUNCTION(Runtime_ReThrow) { | 1834 RUNTIME_FUNCTION(Runtime_ReThrow) { |
4020 HandleScope scope(isolate); | 1835 HandleScope scope(isolate); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4071 } | 1886 } |
4072 | 1887 |
4073 | 1888 |
4074 RUNTIME_FUNCTION(Runtime_Interrupt) { | 1889 RUNTIME_FUNCTION(Runtime_Interrupt) { |
4075 SealHandleScope shs(isolate); | 1890 SealHandleScope shs(isolate); |
4076 DCHECK(args.length() == 0); | 1891 DCHECK(args.length() == 0); |
4077 return isolate->stack_guard()->HandleInterrupts(); | 1892 return isolate->stack_guard()->HandleInterrupts(); |
4078 } | 1893 } |
4079 | 1894 |
4080 | 1895 |
4081 static int StackSize(Isolate* isolate) { | |
4082 int n = 0; | |
4083 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) n++; | |
4084 return n; | |
4085 } | |
4086 | |
4087 | |
4088 static void PrintTransition(Isolate* isolate, Object* result) { | |
4089 // indentation | |
4090 { | |
4091 const int nmax = 80; | |
4092 int n = StackSize(isolate); | |
4093 if (n <= nmax) | |
4094 PrintF("%4d:%*s", n, n, ""); | |
4095 else | |
4096 PrintF("%4d:%*s", n, nmax, "..."); | |
4097 } | |
4098 | |
4099 if (result == NULL) { | |
4100 JavaScriptFrame::PrintTop(isolate, stdout, true, false); | |
4101 PrintF(" {\n"); | |
4102 } else { | |
4103 // function result | |
4104 PrintF("} -> "); | |
4105 result->ShortPrint(); | |
4106 PrintF("\n"); | |
4107 } | |
4108 } | |
4109 | |
4110 | |
4111 RUNTIME_FUNCTION(Runtime_TraceEnter) { | |
4112 SealHandleScope shs(isolate); | |
4113 DCHECK(args.length() == 0); | |
4114 PrintTransition(isolate, NULL); | |
4115 return isolate->heap()->undefined_value(); | |
4116 } | |
4117 | |
4118 | |
4119 RUNTIME_FUNCTION(Runtime_TraceExit) { | |
4120 SealHandleScope shs(isolate); | |
4121 DCHECK(args.length() == 1); | |
4122 CONVERT_ARG_CHECKED(Object, obj, 0); | |
4123 PrintTransition(isolate, obj); | |
4124 return obj; // return TOS | |
4125 } | |
4126 | |
4127 | |
4128 RUNTIME_FUNCTION(Runtime_GlobalProxy) { | 1896 RUNTIME_FUNCTION(Runtime_GlobalProxy) { |
4129 SealHandleScope shs(isolate); | 1897 SealHandleScope shs(isolate); |
4130 DCHECK(args.length() == 1); | 1898 DCHECK(args.length() == 1); |
4131 CONVERT_ARG_CHECKED(Object, global, 0); | 1899 CONVERT_ARG_CHECKED(Object, global, 0); |
4132 if (!global->IsJSGlobalObject()) return isolate->heap()->null_value(); | 1900 if (!global->IsJSGlobalObject()) return isolate->heap()->null_value(); |
4133 return JSGlobalObject::cast(global)->global_proxy(); | 1901 return JSGlobalObject::cast(global)->global_proxy(); |
4134 } | 1902 } |
4135 | 1903 |
4136 | 1904 |
4137 RUNTIME_FUNCTION(Runtime_IsAttachedGlobal) { | 1905 RUNTIME_FUNCTION(Runtime_IsAttachedGlobal) { |
(...skipping 1061 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5199 | 2967 |
5200 | 2968 |
5201 RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) { | 2969 RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) { |
5202 SealHandleScope shs(isolate); | 2970 SealHandleScope shs(isolate); |
5203 DCHECK(args.length() == 1); | 2971 DCHECK(args.length() == 1); |
5204 CONVERT_ARG_CHECKED(Object, obj, 0); | 2972 CONVERT_ARG_CHECKED(Object, obj, 0); |
5205 return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy()); | 2973 return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy()); |
5206 } | 2974 } |
5207 | 2975 |
5208 | 2976 |
5209 RUNTIME_FUNCTION(Runtime_IsObserved) { | |
5210 SealHandleScope shs(isolate); | |
5211 DCHECK(args.length() == 1); | |
5212 | |
5213 if (!args[0]->IsJSReceiver()) return isolate->heap()->false_value(); | |
5214 CONVERT_ARG_CHECKED(JSReceiver, obj, 0); | |
5215 DCHECK(!obj->IsJSGlobalProxy() || !obj->map()->is_observed()); | |
5216 return isolate->heap()->ToBoolean(obj->map()->is_observed()); | |
5217 } | |
5218 | |
5219 | |
5220 RUNTIME_FUNCTION(Runtime_SetIsObserved) { | |
5221 HandleScope scope(isolate); | |
5222 DCHECK(args.length() == 1); | |
5223 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0); | |
5224 RUNTIME_ASSERT(!obj->IsJSGlobalProxy()); | |
5225 if (obj->IsJSProxy()) return isolate->heap()->undefined_value(); | |
5226 RUNTIME_ASSERT(!obj->map()->is_observed()); | |
5227 | |
5228 DCHECK(obj->IsJSObject()); | |
5229 JSObject::SetObserved(Handle<JSObject>::cast(obj)); | |
5230 return isolate->heap()->undefined_value(); | |
5231 } | |
5232 | |
5233 | |
5234 RUNTIME_FUNCTION(Runtime_EnqueueMicrotask) { | |
5235 HandleScope scope(isolate); | |
5236 DCHECK(args.length() == 1); | |
5237 CONVERT_ARG_HANDLE_CHECKED(JSFunction, microtask, 0); | |
5238 isolate->EnqueueMicrotask(microtask); | |
5239 return isolate->heap()->undefined_value(); | |
5240 } | |
5241 | |
5242 | |
5243 RUNTIME_FUNCTION(Runtime_RunMicrotasks) { | |
5244 HandleScope scope(isolate); | |
5245 DCHECK(args.length() == 0); | |
5246 isolate->RunMicrotasks(); | |
5247 return isolate->heap()->undefined_value(); | |
5248 } | |
5249 | |
5250 | |
5251 RUNTIME_FUNCTION(Runtime_GetObservationState) { | |
5252 SealHandleScope shs(isolate); | |
5253 DCHECK(args.length() == 0); | |
5254 return isolate->heap()->observation_state(); | |
5255 } | |
5256 | |
5257 | |
5258 static bool ContextsHaveSameOrigin(Handle<Context> context1, | |
5259 Handle<Context> context2) { | |
5260 return context1->security_token() == context2->security_token(); | |
5261 } | |
5262 | |
5263 | |
5264 RUNTIME_FUNCTION(Runtime_ObserverObjectAndRecordHaveSameOrigin) { | |
5265 HandleScope scope(isolate); | |
5266 DCHECK(args.length() == 3); | |
5267 CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0); | |
5268 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1); | |
5269 CONVERT_ARG_HANDLE_CHECKED(JSObject, record, 2); | |
5270 | |
5271 Handle<Context> observer_context(observer->context()->native_context()); | |
5272 Handle<Context> object_context(object->GetCreationContext()); | |
5273 Handle<Context> record_context(record->GetCreationContext()); | |
5274 | |
5275 return isolate->heap()->ToBoolean( | |
5276 ContextsHaveSameOrigin(object_context, observer_context) && | |
5277 ContextsHaveSameOrigin(object_context, record_context)); | |
5278 } | |
5279 | |
5280 | |
5281 RUNTIME_FUNCTION(Runtime_ObjectWasCreatedInCurrentOrigin) { | |
5282 HandleScope scope(isolate); | |
5283 DCHECK(args.length() == 1); | |
5284 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | |
5285 | |
5286 Handle<Context> creation_context(object->GetCreationContext(), isolate); | |
5287 return isolate->heap()->ToBoolean( | |
5288 ContextsHaveSameOrigin(creation_context, isolate->native_context())); | |
5289 } | |
5290 | |
5291 | |
5292 RUNTIME_FUNCTION(Runtime_GetObjectContextObjectObserve) { | |
5293 HandleScope scope(isolate); | |
5294 DCHECK(args.length() == 1); | |
5295 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | |
5296 | |
5297 Handle<Context> context(object->GetCreationContext(), isolate); | |
5298 return context->native_object_observe(); | |
5299 } | |
5300 | |
5301 | |
5302 RUNTIME_FUNCTION(Runtime_GetObjectContextObjectGetNotifier) { | |
5303 HandleScope scope(isolate); | |
5304 DCHECK(args.length() == 1); | |
5305 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | |
5306 | |
5307 Handle<Context> context(object->GetCreationContext(), isolate); | |
5308 return context->native_object_get_notifier(); | |
5309 } | |
5310 | |
5311 | |
5312 RUNTIME_FUNCTION(Runtime_GetObjectContextNotifierPerformChange) { | |
5313 HandleScope scope(isolate); | |
5314 DCHECK(args.length() == 1); | |
5315 CONVERT_ARG_HANDLE_CHECKED(JSObject, object_info, 0); | |
5316 | |
5317 Handle<Context> context(object_info->GetCreationContext(), isolate); | |
5318 return context->native_object_notifier_perform_change(); | |
5319 } | |
5320 | |
5321 | |
5322 static Object* ArrayConstructorCommon(Isolate* isolate, | 2977 static Object* ArrayConstructorCommon(Isolate* isolate, |
5323 Handle<JSFunction> constructor, | 2978 Handle<JSFunction> constructor, |
5324 Handle<AllocationSite> site, | 2979 Handle<AllocationSite> site, |
5325 Arguments* caller_args) { | 2980 Arguments* caller_args) { |
5326 Factory* factory = isolate->factory(); | 2981 Factory* factory = isolate->factory(); |
5327 | 2982 |
5328 bool holey = false; | 2983 bool holey = false; |
5329 bool can_use_type_feedback = true; | 2984 bool can_use_type_feedback = true; |
5330 if (caller_args->length() == 1) { | 2985 if (caller_args->length() == 1) { |
5331 Handle<Object> argument_one = caller_args->at<Object>(0); | 2986 Handle<Object> argument_one = caller_args->at<Object>(0); |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5565 UNIMPLEMENTED(); \ | 3220 UNIMPLEMENTED(); \ |
5566 return NULL; \ | 3221 return NULL; \ |
5567 } | 3222 } |
5568 | 3223 |
5569 U(IsStringWrapperSafeForDefaultValueOf) | 3224 U(IsStringWrapperSafeForDefaultValueOf) |
5570 U(DebugBreakInOptimizedCode) | 3225 U(DebugBreakInOptimizedCode) |
5571 | 3226 |
5572 #undef U | 3227 #undef U |
5573 | 3228 |
5574 | 3229 |
5575 RUNTIME_FUNCTION(RuntimeReference_IsSmi) { | |
5576 SealHandleScope shs(isolate); | |
5577 DCHECK(args.length() == 1); | |
5578 CONVERT_ARG_CHECKED(Object, obj, 0); | |
5579 return isolate->heap()->ToBoolean(obj->IsSmi()); | |
5580 } | |
5581 | |
5582 | |
5583 RUNTIME_FUNCTION(RuntimeReference_IsNonNegativeSmi) { | |
5584 SealHandleScope shs(isolate); | |
5585 DCHECK(args.length() == 1); | |
5586 CONVERT_ARG_CHECKED(Object, obj, 0); | |
5587 return isolate->heap()->ToBoolean(obj->IsSmi() && | |
5588 Smi::cast(obj)->value() >= 0); | |
5589 } | |
5590 | |
5591 | |
5592 RUNTIME_FUNCTION(RuntimeReference_IsArray) { | 3230 RUNTIME_FUNCTION(RuntimeReference_IsArray) { |
5593 SealHandleScope shs(isolate); | 3231 SealHandleScope shs(isolate); |
5594 DCHECK(args.length() == 1); | 3232 DCHECK(args.length() == 1); |
5595 CONVERT_ARG_CHECKED(Object, obj, 0); | 3233 CONVERT_ARG_CHECKED(Object, obj, 0); |
5596 return isolate->heap()->ToBoolean(obj->IsJSArray()); | 3234 return isolate->heap()->ToBoolean(obj->IsJSArray()); |
5597 } | 3235 } |
5598 | 3236 |
5599 | 3237 |
5600 RUNTIME_FUNCTION(RuntimeReference_IsRegExp) { | |
5601 SealHandleScope shs(isolate); | |
5602 DCHECK(args.length() == 1); | |
5603 CONVERT_ARG_CHECKED(Object, obj, 0); | |
5604 return isolate->heap()->ToBoolean(obj->IsJSRegExp()); | |
5605 } | |
5606 | |
5607 | |
5608 RUNTIME_FUNCTION(RuntimeReference_IsConstructCall) { | |
5609 SealHandleScope shs(isolate); | |
5610 DCHECK(args.length() == 0); | |
5611 JavaScriptFrameIterator it(isolate); | |
5612 JavaScriptFrame* frame = it.frame(); | |
5613 return isolate->heap()->ToBoolean(frame->IsConstructor()); | |
5614 } | |
5615 | |
5616 | |
5617 RUNTIME_FUNCTION(RuntimeReference_CallFunction) { | |
5618 SealHandleScope shs(isolate); | |
5619 return __RT_impl_Runtime_Call(args, isolate); | |
5620 } | |
5621 | |
5622 | |
5623 RUNTIME_FUNCTION(RuntimeReference_ArgumentsLength) { | |
5624 SealHandleScope shs(isolate); | |
5625 DCHECK(args.length() == 0); | |
5626 JavaScriptFrameIterator it(isolate); | |
5627 JavaScriptFrame* frame = it.frame(); | |
5628 return Smi::FromInt(frame->GetArgumentsLength()); | |
5629 } | |
5630 | |
5631 | |
5632 RUNTIME_FUNCTION(RuntimeReference_Arguments) { | |
5633 SealHandleScope shs(isolate); | |
5634 return __RT_impl_Runtime_GetArgumentsProperty(args, isolate); | |
5635 } | |
5636 | |
5637 | 3238 |
5638 RUNTIME_FUNCTION(RuntimeReference_ValueOf) { | 3239 RUNTIME_FUNCTION(RuntimeReference_ValueOf) { |
5639 SealHandleScope shs(isolate); | 3240 SealHandleScope shs(isolate); |
5640 DCHECK(args.length() == 1); | 3241 DCHECK(args.length() == 1); |
5641 CONVERT_ARG_CHECKED(Object, obj, 0); | 3242 CONVERT_ARG_CHECKED(Object, obj, 0); |
5642 if (!obj->IsJSValue()) return obj; | 3243 if (!obj->IsJSValue()) return obj; |
5643 return JSValue::cast(obj)->value(); | 3244 return JSValue::cast(obj)->value(); |
5644 } | 3245 } |
5645 | 3246 |
5646 | 3247 |
(...skipping 25 matching lines...) Expand all Loading... |
5672 if (obj->IsNull()) return isolate->heap()->true_value(); | 3273 if (obj->IsNull()) return isolate->heap()->true_value(); |
5673 if (obj->IsUndetectableObject()) return isolate->heap()->false_value(); | 3274 if (obj->IsUndetectableObject()) return isolate->heap()->false_value(); |
5674 Map* map = HeapObject::cast(obj)->map(); | 3275 Map* map = HeapObject::cast(obj)->map(); |
5675 bool is_non_callable_spec_object = | 3276 bool is_non_callable_spec_object = |
5676 map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE && | 3277 map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE && |
5677 map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE; | 3278 map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE; |
5678 return isolate->heap()->ToBoolean(is_non_callable_spec_object); | 3279 return isolate->heap()->ToBoolean(is_non_callable_spec_object); |
5679 } | 3280 } |
5680 | 3281 |
5681 | 3282 |
5682 RUNTIME_FUNCTION(RuntimeReference_IsFunction) { | |
5683 SealHandleScope shs(isolate); | |
5684 DCHECK(args.length() == 1); | |
5685 CONVERT_ARG_CHECKED(Object, obj, 0); | |
5686 return isolate->heap()->ToBoolean(obj->IsJSFunction()); | |
5687 } | |
5688 | |
5689 | |
5690 RUNTIME_FUNCTION(RuntimeReference_IsUndetectableObject) { | 3283 RUNTIME_FUNCTION(RuntimeReference_IsUndetectableObject) { |
5691 SealHandleScope shs(isolate); | 3284 SealHandleScope shs(isolate); |
5692 DCHECK(args.length() == 1); | 3285 DCHECK(args.length() == 1); |
5693 CONVERT_ARG_CHECKED(Object, obj, 0); | 3286 CONVERT_ARG_CHECKED(Object, obj, 0); |
5694 return isolate->heap()->ToBoolean(obj->IsUndetectableObject()); | 3287 return isolate->heap()->ToBoolean(obj->IsUndetectableObject()); |
5695 } | 3288 } |
5696 | 3289 |
5697 | 3290 |
5698 RUNTIME_FUNCTION(RuntimeReference_IsSpecObject) { | 3291 RUNTIME_FUNCTION(RuntimeReference_IsSpecObject) { |
5699 SealHandleScope shs(isolate); | 3292 SealHandleScope shs(isolate); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5815 } | 3408 } |
5816 return NULL; | 3409 return NULL; |
5817 } | 3410 } |
5818 | 3411 |
5819 | 3412 |
5820 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 3413 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
5821 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 3414 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
5822 } | 3415 } |
5823 } | 3416 } |
5824 } // namespace v8::internal | 3417 } // namespace v8::internal |
OLD | NEW |