| 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 |