OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 } | 607 } |
608 | 608 |
609 | 609 |
610 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHandler) { | 610 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHandler) { |
611 ASSERT(args.length() == 1); | 611 ASSERT(args.length() == 1); |
612 CONVERT_CHECKED(JSProxy, proxy, args[0]); | 612 CONVERT_CHECKED(JSProxy, proxy, args[0]); |
613 return proxy->handler(); | 613 return proxy->handler(); |
614 } | 614 } |
615 | 615 |
616 | 616 |
| 617 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateCatchExtensionObject) { |
| 618 ASSERT(args.length() == 2); |
| 619 CONVERT_CHECKED(String, key, args[0]); |
| 620 Object* value = args[1]; |
| 621 ASSERT(!value->IsFailure()); |
| 622 // Create a catch context extension object. |
| 623 JSFunction* constructor = |
| 624 isolate->context()->global_context()-> |
| 625 context_extension_function(); |
| 626 Object* object; |
| 627 { MaybeObject* maybe_object = isolate->heap()->AllocateJSObject(constructor); |
| 628 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 629 } |
| 630 // Assign the exception value to the catch variable and make sure |
| 631 // that the catch variable is DontDelete. |
| 632 { MaybeObject* maybe_value = |
| 633 // Passing non-strict per ECMA-262 5th Ed. 12.14. Catch, bullet #4. |
| 634 JSObject::cast(object)->SetProperty( |
| 635 key, value, DONT_DELETE, kNonStrictMode); |
| 636 if (!maybe_value->ToObject(&value)) return maybe_value; |
| 637 } |
| 638 return object; |
| 639 } |
| 640 |
| 641 |
617 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) { | 642 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) { |
618 NoHandleAllocation ha; | 643 NoHandleAllocation ha; |
619 ASSERT(args.length() == 1); | 644 ASSERT(args.length() == 1); |
620 Object* obj = args[0]; | 645 Object* obj = args[0]; |
621 if (!obj->IsJSObject()) return isolate->heap()->null_value(); | 646 if (!obj->IsJSObject()) return isolate->heap()->null_value(); |
622 return JSObject::cast(obj)->class_name(); | 647 return JSObject::cast(obj)->class_name(); |
623 } | 648 } |
624 | 649 |
625 | 650 |
626 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) { | 651 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) { |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
869 } | 894 } |
870 | 895 |
871 case JSObject::DICTIONARY_ELEMENT: { | 896 case JSObject::DICTIONARY_ELEMENT: { |
872 Handle<JSObject> holder = obj; | 897 Handle<JSObject> holder = obj; |
873 if (obj->IsJSGlobalProxy()) { | 898 if (obj->IsJSGlobalProxy()) { |
874 Object* proto = obj->GetPrototype(); | 899 Object* proto = obj->GetPrototype(); |
875 if (proto->IsNull()) return heap->undefined_value(); | 900 if (proto->IsNull()) return heap->undefined_value(); |
876 ASSERT(proto->IsJSGlobalObject()); | 901 ASSERT(proto->IsJSGlobalObject()); |
877 holder = Handle<JSObject>(JSObject::cast(proto)); | 902 holder = Handle<JSObject>(JSObject::cast(proto)); |
878 } | 903 } |
879 NumberDictionary* dictionary = holder->element_dictionary(); | 904 FixedArray* elements = FixedArray::cast(holder->elements()); |
| 905 NumberDictionary* dictionary = NULL; |
| 906 if (elements->map() == heap->non_strict_arguments_elements_map()) { |
| 907 dictionary = NumberDictionary::cast(elements->get(1)); |
| 908 } else { |
| 909 dictionary = NumberDictionary::cast(elements); |
| 910 } |
880 int entry = dictionary->FindEntry(index); | 911 int entry = dictionary->FindEntry(index); |
881 ASSERT(entry != NumberDictionary::kNotFound); | 912 ASSERT(entry != NumberDictionary::kNotFound); |
882 PropertyDetails details = dictionary->DetailsAt(entry); | 913 PropertyDetails details = dictionary->DetailsAt(entry); |
883 switch (details.type()) { | 914 switch (details.type()) { |
884 case CALLBACKS: { | 915 case CALLBACKS: { |
885 // This is an accessor property with getter and/or setter. | 916 // This is an accessor property with getter and/or setter. |
886 FixedArray* callbacks = | 917 FixedArray* callbacks = |
887 FixedArray::cast(dictionary->ValueAt(entry)); | 918 FixedArray::cast(dictionary->ValueAt(entry)); |
888 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); | 919 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); |
889 if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) { | 920 if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) { |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1225 ASSERT(args.length() == 4); | 1256 ASSERT(args.length() == 4); |
1226 | 1257 |
1227 CONVERT_ARG_CHECKED(Context, context, 0); | 1258 CONVERT_ARG_CHECKED(Context, context, 0); |
1228 Handle<String> name(String::cast(args[1])); | 1259 Handle<String> name(String::cast(args[1])); |
1229 PropertyAttributes mode = static_cast<PropertyAttributes>(args.smi_at(2)); | 1260 PropertyAttributes mode = static_cast<PropertyAttributes>(args.smi_at(2)); |
1230 RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE); | 1261 RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE); |
1231 Handle<Object> initial_value(args[3], isolate); | 1262 Handle<Object> initial_value(args[3], isolate); |
1232 | 1263 |
1233 // Declarations are always done in the function context. | 1264 // Declarations are always done in the function context. |
1234 context = Handle<Context>(context->fcontext()); | 1265 context = Handle<Context>(context->fcontext()); |
1235 ASSERT(context->IsFunctionContext() || context->IsGlobalContext()); | |
1236 | 1266 |
1237 int index; | 1267 int index; |
1238 PropertyAttributes attributes; | 1268 PropertyAttributes attributes; |
1239 ContextLookupFlags flags = DONT_FOLLOW_CHAINS; | 1269 ContextLookupFlags flags = DONT_FOLLOW_CHAINS; |
1240 Handle<Object> holder = | 1270 Handle<Object> holder = |
1241 context->Lookup(name, flags, &index, &attributes); | 1271 context->Lookup(name, flags, &index, &attributes); |
1242 | 1272 |
1243 if (attributes != ABSENT) { | 1273 if (attributes != ABSENT) { |
1244 // The name was declared before; check for conflicting | 1274 // The name was declared before; check for conflicting |
1245 // re-declarations: This is similar to the code in parser.cc in | 1275 // re-declarations: This is similar to the code in parser.cc in |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1279 } | 1309 } |
1280 } | 1310 } |
1281 | 1311 |
1282 } else { | 1312 } else { |
1283 // The property is not in the function context. It needs to be | 1313 // The property is not in the function context. It needs to be |
1284 // "declared" in the function context's extension context, or in the | 1314 // "declared" in the function context's extension context, or in the |
1285 // global context. | 1315 // global context. |
1286 Handle<JSObject> context_ext; | 1316 Handle<JSObject> context_ext; |
1287 if (context->has_extension()) { | 1317 if (context->has_extension()) { |
1288 // The function context's extension context exists - use it. | 1318 // The function context's extension context exists - use it. |
1289 context_ext = Handle<JSObject>(JSObject::cast(context->extension())); | 1319 context_ext = Handle<JSObject>(context->extension()); |
1290 } else { | 1320 } else { |
1291 // The function context's extension context does not exists - allocate | 1321 // The function context's extension context does not exists - allocate |
1292 // it. | 1322 // it. |
1293 context_ext = isolate->factory()->NewJSObject( | 1323 context_ext = isolate->factory()->NewJSObject( |
1294 isolate->context_extension_function()); | 1324 isolate->context_extension_function()); |
1295 // And store it in the extension slot. | 1325 // And store it in the extension slot. |
1296 context->set_extension(*context_ext); | 1326 context->set_extension(*context_ext); |
1297 } | 1327 } |
1298 ASSERT(*context_ext != NULL); | 1328 ASSERT(*context_ext != NULL); |
1299 | 1329 |
(...skipping 2638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3938 } | 3968 } |
3939 | 3969 |
3940 return Runtime::ForceSetObjectProperty(isolate, | 3970 return Runtime::ForceSetObjectProperty(isolate, |
3941 js_object, | 3971 js_object, |
3942 name, | 3972 name, |
3943 obj_value, | 3973 obj_value, |
3944 attr); | 3974 attr); |
3945 } | 3975 } |
3946 | 3976 |
3947 | 3977 |
3948 // Special case for elements if any of the flags are true. | |
3949 // If elements are in fast case we always implicitly assume that: | |
3950 // DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false. | |
3951 static MaybeObject* NormalizeObjectSetElement(Isolate* isolate, | |
3952 Handle<JSObject> js_object, | |
3953 uint32_t index, | |
3954 Handle<Object> value, | |
3955 PropertyAttributes attr) { | |
3956 // Normalize the elements to enable attributes on the property. | |
3957 NormalizeElements(js_object); | |
3958 Handle<NumberDictionary> dictionary(js_object->element_dictionary()); | |
3959 // Make sure that we never go back to fast case. | |
3960 dictionary->set_requires_slow_elements(); | |
3961 PropertyDetails details = PropertyDetails(attr, NORMAL); | |
3962 Handle<NumberDictionary> extended_dictionary = | |
3963 NumberDictionarySet(dictionary, index, value, details); | |
3964 if (*extended_dictionary != *dictionary) { | |
3965 js_object->set_elements(*extended_dictionary); | |
3966 } | |
3967 return *value; | |
3968 } | |
3969 | |
3970 | |
3971 MaybeObject* Runtime::SetObjectProperty(Isolate* isolate, | 3978 MaybeObject* Runtime::SetObjectProperty(Isolate* isolate, |
3972 Handle<Object> object, | 3979 Handle<Object> object, |
3973 Handle<Object> key, | 3980 Handle<Object> key, |
3974 Handle<Object> value, | 3981 Handle<Object> value, |
3975 PropertyAttributes attr, | 3982 PropertyAttributes attr, |
3976 StrictModeFlag strict_mode) { | 3983 StrictModeFlag strict_mode) { |
3977 HandleScope scope(isolate); | 3984 HandleScope scope(isolate); |
3978 | 3985 |
3979 if (object->IsUndefined() || object->IsNull()) { | 3986 if (object->IsUndefined() || object->IsNull()) { |
3980 Handle<Object> args[2] = { key, object }; | 3987 Handle<Object> args[2] = { key, object }; |
(...skipping 15 matching lines...) Expand all Loading... |
3996 // of a string using [] notation. We need to support this too in | 4003 // of a string using [] notation. We need to support this too in |
3997 // JavaScript. | 4004 // JavaScript. |
3998 // In the case of a String object we just need to redirect the assignment to | 4005 // In the case of a String object we just need to redirect the assignment to |
3999 // the underlying string if the index is in range. Since the underlying | 4006 // the underlying string if the index is in range. Since the underlying |
4000 // string does nothing with the assignment then we can ignore such | 4007 // string does nothing with the assignment then we can ignore such |
4001 // assignments. | 4008 // assignments. |
4002 if (js_object->IsStringObjectWithCharacterAt(index)) { | 4009 if (js_object->IsStringObjectWithCharacterAt(index)) { |
4003 return *value; | 4010 return *value; |
4004 } | 4011 } |
4005 | 4012 |
4006 if (((attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0)) { | |
4007 return NormalizeObjectSetElement(isolate, js_object, index, value, attr); | |
4008 } | |
4009 | |
4010 Handle<Object> result = SetElement(js_object, index, value, strict_mode); | 4013 Handle<Object> result = SetElement(js_object, index, value, strict_mode); |
4011 if (result.is_null()) return Failure::Exception(); | 4014 if (result.is_null()) return Failure::Exception(); |
4012 return *value; | 4015 return *value; |
4013 } | 4016 } |
4014 | 4017 |
4015 if (key->IsString()) { | 4018 if (key->IsString()) { |
4016 Handle<Object> result; | 4019 Handle<Object> result; |
4017 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { | 4020 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { |
4018 if (((attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0)) { | |
4019 return NormalizeObjectSetElement(isolate, | |
4020 js_object, | |
4021 index, | |
4022 value, | |
4023 attr); | |
4024 } | |
4025 result = SetElement(js_object, index, value, strict_mode); | 4021 result = SetElement(js_object, index, value, strict_mode); |
4026 } else { | 4022 } else { |
4027 Handle<String> key_string = Handle<String>::cast(key); | 4023 Handle<String> key_string = Handle<String>::cast(key); |
4028 key_string->TryFlatten(); | 4024 key_string->TryFlatten(); |
4029 result = SetProperty(js_object, key_string, value, attr, strict_mode); | 4025 result = SetProperty(js_object, key_string, value, attr, strict_mode); |
4030 } | 4026 } |
4031 if (result.is_null()) return Failure::Exception(); | 4027 if (result.is_null()) return Failure::Exception(); |
4032 return *value; | 4028 return *value; |
4033 } | 4029 } |
4034 | 4030 |
4035 // Call-back into JavaScript to convert the key to a string. | 4031 // Call-back into JavaScript to convert the key to a string. |
4036 bool has_pending_exception = false; | 4032 bool has_pending_exception = false; |
4037 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); | 4033 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); |
4038 if (has_pending_exception) return Failure::Exception(); | 4034 if (has_pending_exception) return Failure::Exception(); |
4039 Handle<String> name = Handle<String>::cast(converted); | 4035 Handle<String> name = Handle<String>::cast(converted); |
4040 | 4036 |
4041 if (name->AsArrayIndex(&index)) { | 4037 if (name->AsArrayIndex(&index)) { |
4042 return js_object->SetElement(index, *value, strict_mode); | 4038 return js_object->SetElement(index, *value, strict_mode, true); |
4043 } else { | 4039 } else { |
4044 return js_object->SetProperty(*name, *value, attr, strict_mode); | 4040 return js_object->SetProperty(*name, *value, attr, strict_mode); |
4045 } | 4041 } |
4046 } | 4042 } |
4047 | 4043 |
4048 | 4044 |
4049 MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate, | 4045 MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate, |
4050 Handle<JSObject> js_object, | 4046 Handle<JSObject> js_object, |
4051 Handle<Object> key, | 4047 Handle<Object> key, |
4052 Handle<Object> value, | 4048 Handle<Object> value, |
4053 PropertyAttributes attr) { | 4049 PropertyAttributes attr) { |
4054 HandleScope scope(isolate); | 4050 HandleScope scope(isolate); |
4055 | 4051 |
4056 // Check if the given key is an array index. | 4052 // Check if the given key is an array index. |
4057 uint32_t index; | 4053 uint32_t index; |
4058 if (key->ToArrayIndex(&index)) { | 4054 if (key->ToArrayIndex(&index)) { |
4059 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters | 4055 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters |
4060 // of a string using [] notation. We need to support this too in | 4056 // of a string using [] notation. We need to support this too in |
4061 // JavaScript. | 4057 // JavaScript. |
4062 // In the case of a String object we just need to redirect the assignment to | 4058 // In the case of a String object we just need to redirect the assignment to |
4063 // the underlying string if the index is in range. Since the underlying | 4059 // the underlying string if the index is in range. Since the underlying |
4064 // string does nothing with the assignment then we can ignore such | 4060 // string does nothing with the assignment then we can ignore such |
4065 // assignments. | 4061 // assignments. |
4066 if (js_object->IsStringObjectWithCharacterAt(index)) { | 4062 if (js_object->IsStringObjectWithCharacterAt(index)) { |
4067 return *value; | 4063 return *value; |
4068 } | 4064 } |
4069 | 4065 |
4070 return js_object->SetElement(index, *value, kNonStrictMode); | 4066 return js_object->SetElement(index, *value, kNonStrictMode, true); |
4071 } | 4067 } |
4072 | 4068 |
4073 if (key->IsString()) { | 4069 if (key->IsString()) { |
4074 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { | 4070 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { |
4075 return js_object->SetElement(index, *value, kNonStrictMode); | 4071 return js_object->SetElement(index, *value, kNonStrictMode, true); |
4076 } else { | 4072 } else { |
4077 Handle<String> key_string = Handle<String>::cast(key); | 4073 Handle<String> key_string = Handle<String>::cast(key); |
4078 key_string->TryFlatten(); | 4074 key_string->TryFlatten(); |
4079 return js_object->SetLocalPropertyIgnoreAttributes(*key_string, | 4075 return js_object->SetLocalPropertyIgnoreAttributes(*key_string, |
4080 *value, | 4076 *value, |
4081 attr); | 4077 attr); |
4082 } | 4078 } |
4083 } | 4079 } |
4084 | 4080 |
4085 // Call-back into JavaScript to convert the key to a string. | 4081 // Call-back into JavaScript to convert the key to a string. |
4086 bool has_pending_exception = false; | 4082 bool has_pending_exception = false; |
4087 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); | 4083 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); |
4088 if (has_pending_exception) return Failure::Exception(); | 4084 if (has_pending_exception) return Failure::Exception(); |
4089 Handle<String> name = Handle<String>::cast(converted); | 4085 Handle<String> name = Handle<String>::cast(converted); |
4090 | 4086 |
4091 if (name->AsArrayIndex(&index)) { | 4087 if (name->AsArrayIndex(&index)) { |
4092 return js_object->SetElement(index, *value, kNonStrictMode); | 4088 return js_object->SetElement(index, *value, kNonStrictMode, true); |
4093 } else { | 4089 } else { |
4094 return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr); | 4090 return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr); |
4095 } | 4091 } |
4096 } | 4092 } |
4097 | 4093 |
4098 | 4094 |
4099 MaybeObject* Runtime::ForceDeleteObjectProperty(Isolate* isolate, | 4095 MaybeObject* Runtime::ForceDeleteObjectProperty(Isolate* isolate, |
4100 Handle<JSObject> js_object, | 4096 Handle<JSObject> js_object, |
4101 Handle<Object> key) { | 4097 Handle<Object> key) { |
4102 HandleScope scope(isolate); | 4098 HandleScope scope(isolate); |
(...skipping 3233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7336 | 7332 |
7337 elms->set(0, Smi::FromInt(year)); | 7333 elms->set(0, Smi::FromInt(year)); |
7338 elms->set(1, Smi::FromInt(month)); | 7334 elms->set(1, Smi::FromInt(month)); |
7339 elms->set(2, Smi::FromInt(day)); | 7335 elms->set(2, Smi::FromInt(day)); |
7340 | 7336 |
7341 return isolate->heap()->undefined_value(); | 7337 return isolate->heap()->undefined_value(); |
7342 } | 7338 } |
7343 | 7339 |
7344 | 7340 |
7345 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewArgumentsFast) { | 7341 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewArgumentsFast) { |
| 7342 HandleScope scope(isolate); |
| 7343 ASSERT(args.length() == 3); |
| 7344 |
| 7345 Handle<JSFunction> callee = args.at<JSFunction>(0); |
| 7346 Object** parameters = reinterpret_cast<Object**>(args[1]); |
| 7347 const int argument_count = Smi::cast(args[2])->value(); |
| 7348 |
| 7349 Handle<JSObject> result = |
| 7350 isolate->factory()->NewArgumentsObject(callee, argument_count); |
| 7351 // Allocate the elements if needed. |
| 7352 int parameter_count = callee->shared()->formal_parameter_count(); |
| 7353 if (argument_count > 0) { |
| 7354 if (parameter_count > 0) { |
| 7355 int mapped_count = Min(argument_count, parameter_count); |
| 7356 Handle<FixedArray> parameter_map = |
| 7357 isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED); |
| 7358 parameter_map->set_map( |
| 7359 isolate->heap()->non_strict_arguments_elements_map()); |
| 7360 |
| 7361 Handle<Map> old_map(result->map()); |
| 7362 Handle<Map> new_map = |
| 7363 isolate->factory()->CopyMapDropTransitions(old_map); |
| 7364 new_map->set_elements_kind(JSObject::NON_STRICT_ARGUMENTS_ELEMENTS); |
| 7365 |
| 7366 result->set_map(*new_map); |
| 7367 result->set_elements(*parameter_map); |
| 7368 |
| 7369 // Store the context and the arguments array at the beginning of the |
| 7370 // parameter map. |
| 7371 Handle<Context> context(isolate->context()); |
| 7372 Handle<FixedArray> arguments = |
| 7373 isolate->factory()->NewFixedArray(argument_count, NOT_TENURED); |
| 7374 parameter_map->set(0, *context); |
| 7375 parameter_map->set(1, *arguments); |
| 7376 |
| 7377 // Loop over the actual parameters backwards. |
| 7378 int index = argument_count - 1; |
| 7379 while (index >= mapped_count) { |
| 7380 // These go directly in the arguments array and have no |
| 7381 // corresponding slot in the parameter map. |
| 7382 arguments->set(index, *(parameters - index - 1)); |
| 7383 --index; |
| 7384 } |
| 7385 |
| 7386 ScopeInfo<> scope_info(callee->shared()->scope_info()); |
| 7387 while (index >= 0) { |
| 7388 // Detect duplicate names to the right in the parameter list. |
| 7389 Handle<String> name = scope_info.parameter_name(index); |
| 7390 int context_slot_count = scope_info.number_of_context_slots(); |
| 7391 bool duplicate = false; |
| 7392 for (int j = index + 1; j < parameter_count; ++j) { |
| 7393 if (scope_info.parameter_name(j).is_identical_to(name)) { |
| 7394 duplicate = true; |
| 7395 break; |
| 7396 } |
| 7397 } |
| 7398 |
| 7399 if (duplicate) { |
| 7400 // This goes directly in the arguments array with a hole in the |
| 7401 // parameter map. |
| 7402 arguments->set(index, *(parameters - index - 1)); |
| 7403 parameter_map->set_the_hole(index + 2); |
| 7404 } else { |
| 7405 // The context index goes in the parameter map with a hole in the |
| 7406 // arguments array. |
| 7407 int context_index = -1; |
| 7408 for (int j = Context::MIN_CONTEXT_SLOTS; |
| 7409 j < context_slot_count; |
| 7410 ++j) { |
| 7411 if (scope_info.context_slot_name(j).is_identical_to(name)) { |
| 7412 context_index = j; |
| 7413 break; |
| 7414 } |
| 7415 } |
| 7416 ASSERT(context_index >= 0); |
| 7417 arguments->set_the_hole(index); |
| 7418 parameter_map->set(index + 2, Smi::FromInt(context_index)); |
| 7419 } |
| 7420 |
| 7421 --index; |
| 7422 } |
| 7423 } else { |
| 7424 // If there is no aliasing, the arguments object elements are not |
| 7425 // special in any way. |
| 7426 Handle<FixedArray> elements = |
| 7427 isolate->factory()->NewFixedArray(argument_count, NOT_TENURED); |
| 7428 result->set_elements(*elements); |
| 7429 for (int i = 0; i < argument_count; ++i) { |
| 7430 elements->set(i, *(parameters - i - 1)); |
| 7431 } |
| 7432 } |
| 7433 } |
| 7434 return *result; |
| 7435 } |
| 7436 |
| 7437 |
| 7438 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewStrictArgumentsFast) { |
7346 NoHandleAllocation ha; | 7439 NoHandleAllocation ha; |
7347 ASSERT(args.length() == 3); | 7440 ASSERT(args.length() == 3); |
7348 | 7441 |
7349 JSFunction* callee = JSFunction::cast(args[0]); | 7442 JSFunction* callee = JSFunction::cast(args[0]); |
7350 Object** parameters = reinterpret_cast<Object**>(args[1]); | 7443 Object** parameters = reinterpret_cast<Object**>(args[1]); |
7351 const int length = args.smi_at(2); | 7444 const int length = args.smi_at(2); |
7352 | 7445 |
7353 Object* result; | 7446 Object* result; |
7354 { MaybeObject* maybe_result = | 7447 { MaybeObject* maybe_result = |
7355 isolate->heap()->AllocateArgumentsObject(callee, length); | 7448 isolate->heap()->AllocateArgumentsObject(callee, length); |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7777 return Smi::FromInt(function->shared()->opt_count()); | 7870 return Smi::FromInt(function->shared()->opt_count()); |
7778 } | 7871 } |
7779 | 7872 |
7780 | 7873 |
7781 RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) { | 7874 RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) { |
7782 HandleScope scope(isolate); | 7875 HandleScope scope(isolate); |
7783 ASSERT(args.length() == 1); | 7876 ASSERT(args.length() == 1); |
7784 CONVERT_ARG_CHECKED(JSFunction, function, 0); | 7877 CONVERT_ARG_CHECKED(JSFunction, function, 0); |
7785 | 7878 |
7786 // We're not prepared to handle a function with arguments object. | 7879 // We're not prepared to handle a function with arguments object. |
7787 ASSERT(!function->shared()->scope_info()->HasArgumentsShadow()); | 7880 ASSERT(!function->shared()->uses_arguments()); |
7788 | 7881 |
7789 // We have hit a back edge in an unoptimized frame for a function that was | 7882 // We have hit a back edge in an unoptimized frame for a function that was |
7790 // selected for on-stack replacement. Find the unoptimized code object. | 7883 // selected for on-stack replacement. Find the unoptimized code object. |
7791 Handle<Code> unoptimized(function->shared()->code(), isolate); | 7884 Handle<Code> unoptimized(function->shared()->code(), isolate); |
7792 // Keep track of whether we've succeeded in optimizing. | 7885 // Keep track of whether we've succeeded in optimizing. |
7793 bool succeeded = unoptimized->optimizable(); | 7886 bool succeeded = unoptimized->optimizable(); |
7794 if (succeeded) { | 7887 if (succeeded) { |
7795 // If we are trying to do OSR when there are already optimized | 7888 // If we are trying to do OSR when there are already optimized |
7796 // activations of the function, it means (a) the function is directly or | 7889 // activations of the function, it means (a) the function is directly or |
7797 // indirectly recursive and (b) an optimized invocation has been | 7890 // indirectly recursive and (b) an optimized invocation has been |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7954 isolate->heap()->AllocateWithContext(isolate->context(), | 8047 isolate->heap()->AllocateWithContext(isolate->context(), |
7955 extension_object); | 8048 extension_object); |
7956 if (!maybe_context->To(&context)) return maybe_context; | 8049 if (!maybe_context->To(&context)) return maybe_context; |
7957 isolate->set_context(context); | 8050 isolate->set_context(context); |
7958 return context; | 8051 return context; |
7959 } | 8052 } |
7960 | 8053 |
7961 | 8054 |
7962 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) { | 8055 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) { |
7963 NoHandleAllocation ha; | 8056 NoHandleAllocation ha; |
7964 ASSERT(args.length() == 2); | 8057 ASSERT(args.length() == 1); |
7965 String* name = String::cast(args[0]); | 8058 JSObject* extension_object = JSObject::cast(args[0]); |
7966 Object* thrown_object = args[1]; | |
7967 Context* context; | 8059 Context* context; |
7968 MaybeObject* maybe_context = | 8060 MaybeObject* maybe_context = |
7969 isolate->heap()->AllocateCatchContext(isolate->context(), | 8061 isolate->heap()->AllocateCatchContext(isolate->context(), |
7970 name, | 8062 extension_object); |
7971 thrown_object); | |
7972 if (!maybe_context->To(&context)) return maybe_context; | 8063 if (!maybe_context->To(&context)) return maybe_context; |
7973 isolate->set_context(context); | 8064 isolate->set_context(context); |
7974 return context; | 8065 return context; |
7975 } | 8066 } |
7976 | 8067 |
7977 | 8068 |
7978 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) { | 8069 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) { |
7979 HandleScope scope(isolate); | 8070 HandleScope scope(isolate); |
7980 ASSERT(args.length() == 2); | 8071 ASSERT(args.length() == 2); |
7981 | 8072 |
(...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8742 CONVERT_CHECKED(JSArray, array, args[0]); | 8833 CONVERT_CHECKED(JSArray, array, args[0]); |
8743 CONVERT_CHECKED(JSObject, element, args[1]); | 8834 CONVERT_CHECKED(JSObject, element, args[1]); |
8744 RUNTIME_ASSERT(array->HasFastElements()); | 8835 RUNTIME_ASSERT(array->HasFastElements()); |
8745 int length = Smi::cast(array->length())->value(); | 8836 int length = Smi::cast(array->length())->value(); |
8746 FixedArray* elements = FixedArray::cast(array->elements()); | 8837 FixedArray* elements = FixedArray::cast(array->elements()); |
8747 for (int i = 0; i < length; i++) { | 8838 for (int i = 0; i < length; i++) { |
8748 if (elements->get(i) == element) return isolate->heap()->false_value(); | 8839 if (elements->get(i) == element) return isolate->heap()->false_value(); |
8749 } | 8840 } |
8750 Object* obj; | 8841 Object* obj; |
8751 // Strict not needed. Used for cycle detection in Array join implementation. | 8842 // Strict not needed. Used for cycle detection in Array join implementation. |
8752 { MaybeObject* maybe_obj = array->SetFastElement(length, element, | 8843 { MaybeObject* maybe_obj = |
8753 kNonStrictMode); | 8844 array->SetFastElement(length, element, kNonStrictMode, true); |
8754 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 8845 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
8755 } | 8846 } |
8756 return isolate->heap()->true_value(); | 8847 return isolate->heap()->true_value(); |
8757 } | 8848 } |
8758 | 8849 |
8759 | 8850 |
8760 /** | 8851 /** |
8761 * A simple visitor visits every element of Array's. | 8852 * A simple visitor visits every element of Array's. |
8762 * The backend storage can be a fixed array for fast elements case, | 8853 * The backend storage can be a fixed array for fast elements case, |
8763 * or a dictionary for sparse array. Since Dictionary is a subtype | 8854 * or a dictionary for sparse array. Since Dictionary is a subtype |
(...skipping 1290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10054 ScopeInfo<>& scope_info, | 10145 ScopeInfo<>& scope_info, |
10055 Handle<Context> context, | 10146 Handle<Context> context, |
10056 Handle<JSObject> scope_object) { | 10147 Handle<JSObject> scope_object) { |
10057 // Fill all context locals to the context extension. | 10148 // Fill all context locals to the context extension. |
10058 for (int i = Context::MIN_CONTEXT_SLOTS; | 10149 for (int i = Context::MIN_CONTEXT_SLOTS; |
10059 i < scope_info.number_of_context_slots(); | 10150 i < scope_info.number_of_context_slots(); |
10060 i++) { | 10151 i++) { |
10061 int context_index = serialized_scope_info->ContextSlotIndex( | 10152 int context_index = serialized_scope_info->ContextSlotIndex( |
10062 *scope_info.context_slot_name(i), NULL); | 10153 *scope_info.context_slot_name(i), NULL); |
10063 | 10154 |
10064 // Don't include the arguments shadow (.arguments) context variable. | 10155 RETURN_IF_EMPTY_HANDLE_VALUE( |
10065 if (*scope_info.context_slot_name(i) != | 10156 isolate, |
10066 isolate->heap()->arguments_shadow_symbol()) { | 10157 SetProperty(scope_object, |
10067 RETURN_IF_EMPTY_HANDLE_VALUE( | 10158 scope_info.context_slot_name(i), |
10068 isolate, | 10159 Handle<Object>(context->get(context_index), isolate), |
10069 SetProperty(scope_object, | 10160 NONE, |
10070 scope_info.context_slot_name(i), | 10161 kNonStrictMode), |
10071 Handle<Object>(context->get(context_index), isolate), | 10162 false); |
10072 NONE, | |
10073 kNonStrictMode), | |
10074 false); | |
10075 } | |
10076 } | 10163 } |
10077 | 10164 |
10078 return true; | 10165 return true; |
10079 } | 10166 } |
10080 | 10167 |
10081 | 10168 |
10082 // Create a plain JSObject which materializes the local scope for the specified | 10169 // Create a plain JSObject which materializes the local scope for the specified |
10083 // frame. | 10170 // frame. |
10084 static Handle<JSObject> MaterializeLocalScope(Isolate* isolate, | 10171 static Handle<JSObject> MaterializeLocalScope(Isolate* isolate, |
10085 JavaScriptFrame* frame) { | 10172 JavaScriptFrame* frame) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10160 | 10247 |
10161 Handle<SharedFunctionInfo> shared(context->closure()->shared()); | 10248 Handle<SharedFunctionInfo> shared(context->closure()->shared()); |
10162 Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info()); | 10249 Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info()); |
10163 ScopeInfo<> scope_info(*serialized_scope_info); | 10250 ScopeInfo<> scope_info(*serialized_scope_info); |
10164 | 10251 |
10165 // Allocate and initialize a JSObject with all the content of theis function | 10252 // Allocate and initialize a JSObject with all the content of theis function |
10166 // closure. | 10253 // closure. |
10167 Handle<JSObject> closure_scope = | 10254 Handle<JSObject> closure_scope = |
10168 isolate->factory()->NewJSObject(isolate->object_function()); | 10255 isolate->factory()->NewJSObject(isolate->object_function()); |
10169 | 10256 |
10170 // Check whether the arguments shadow object exists. | |
10171 int arguments_shadow_index = | |
10172 shared->scope_info()->ContextSlotIndex( | |
10173 isolate->heap()->arguments_shadow_symbol(), NULL); | |
10174 if (arguments_shadow_index >= 0) { | |
10175 // In this case all the arguments are available in the arguments shadow | |
10176 // object. | |
10177 Handle<JSObject> arguments_shadow( | |
10178 JSObject::cast(context->get(arguments_shadow_index))); | |
10179 for (int i = 0; i < scope_info.number_of_parameters(); ++i) { | |
10180 // We don't expect exception-throwing getters on the arguments shadow. | |
10181 Object* element = arguments_shadow->GetElement(i)->ToObjectUnchecked(); | |
10182 RETURN_IF_EMPTY_HANDLE_VALUE( | |
10183 isolate, | |
10184 SetProperty(closure_scope, | |
10185 scope_info.parameter_name(i), | |
10186 Handle<Object>(element, isolate), | |
10187 NONE, | |
10188 kNonStrictMode), | |
10189 Handle<JSObject>()); | |
10190 } | |
10191 } | |
10192 | |
10193 // Fill all context locals to the context extension. | 10257 // Fill all context locals to the context extension. |
10194 if (!CopyContextLocalsToScopeObject(isolate, | 10258 if (!CopyContextLocalsToScopeObject(isolate, |
10195 serialized_scope_info, scope_info, | 10259 serialized_scope_info, scope_info, |
10196 context, closure_scope)) { | 10260 context, closure_scope)) { |
10197 return Handle<JSObject>(); | 10261 return Handle<JSObject>(); |
10198 } | 10262 } |
10199 | 10263 |
10200 // Finally copy any properties from the function context extension. This will | 10264 // Finally copy any properties from the function context extension. This will |
10201 // be variables introduced by eval. | 10265 // be variables introduced by eval. |
10202 if (context->has_extension()) { | 10266 if (context->has_extension()) { |
(...skipping 11 matching lines...) Expand all Loading... |
10214 NONE, | 10278 NONE, |
10215 kNonStrictMode), | 10279 kNonStrictMode), |
10216 Handle<JSObject>()); | 10280 Handle<JSObject>()); |
10217 } | 10281 } |
10218 } | 10282 } |
10219 | 10283 |
10220 return closure_scope; | 10284 return closure_scope; |
10221 } | 10285 } |
10222 | 10286 |
10223 | 10287 |
10224 // Create a plain JSObject which materializes the scope for the specified | |
10225 // catch context. | |
10226 static Handle<JSObject> MaterializeCatchScope(Isolate* isolate, | |
10227 Handle<Context> context) { | |
10228 ASSERT(context->IsCatchContext()); | |
10229 Handle<String> name(String::cast(context->extension())); | |
10230 Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX)); | |
10231 Handle<JSObject> catch_scope = | |
10232 isolate->factory()->NewJSObject(isolate->object_function()); | |
10233 RETURN_IF_EMPTY_HANDLE_VALUE( | |
10234 isolate, | |
10235 SetProperty(catch_scope, name, thrown_object, NONE, kNonStrictMode), | |
10236 Handle<JSObject>()); | |
10237 return catch_scope; | |
10238 } | |
10239 | |
10240 | |
10241 // Iterate over the actual scopes visible from a stack frame. All scopes are | 10288 // Iterate over the actual scopes visible from a stack frame. All scopes are |
10242 // backed by an actual context except the local scope, which is inserted | 10289 // backed by an actual context except the local scope, which is inserted |
10243 // "artifically" in the context chain. | 10290 // "artifically" in the context chain. |
10244 class ScopeIterator { | 10291 class ScopeIterator { |
10245 public: | 10292 public: |
10246 enum ScopeType { | 10293 enum ScopeType { |
10247 ScopeTypeGlobal = 0, | 10294 ScopeTypeGlobal = 0, |
10248 ScopeTypeLocal, | 10295 ScopeTypeLocal, |
10249 ScopeTypeWith, | 10296 ScopeTypeWith, |
10250 ScopeTypeClosure, | 10297 ScopeTypeClosure, |
| 10298 // Every catch block contains an implicit with block (its parameter is |
| 10299 // a JSContextExtensionObject) that extends current scope with a variable |
| 10300 // holding exception object. Such with blocks are treated as scopes of their |
| 10301 // own type. |
10251 ScopeTypeCatch | 10302 ScopeTypeCatch |
10252 }; | 10303 }; |
10253 | 10304 |
10254 ScopeIterator(Isolate* isolate, JavaScriptFrame* frame) | 10305 ScopeIterator(Isolate* isolate, JavaScriptFrame* frame) |
10255 : isolate_(isolate), | 10306 : isolate_(isolate), |
10256 frame_(frame), | 10307 frame_(frame), |
10257 function_(JSFunction::cast(frame->function())), | 10308 function_(JSFunction::cast(frame->function())), |
10258 context_(Context::cast(frame->context())), | 10309 context_(Context::cast(frame->context())), |
10259 local_done_(false), | 10310 local_done_(false), |
10260 at_local_(false) { | 10311 at_local_(false) { |
10261 | 10312 |
10262 // Check whether the first scope is actually a local scope. | 10313 // Check whether the first scope is actually a local scope. |
10263 if (context_->IsGlobalContext()) { | 10314 if (context_->IsGlobalContext()) { |
10264 // If there is a stack slot for .result then this local scope has been | 10315 // If there is a stack slot for .result then this local scope has been |
10265 // created for evaluating top level code and it is not a real local scope. | 10316 // created for evaluating top level code and it is not a real local scope. |
10266 // Checking for the existence of .result seems fragile, but the scope info | 10317 // Checking for the existence of .result seems fragile, but the scope info |
10267 // saved with the code object does not otherwise have that information. | 10318 // saved with the code object does not otherwise have that information. |
10268 int index = function_->shared()->scope_info()-> | 10319 int index = function_->shared()->scope_info()-> |
10269 StackSlotIndex(isolate_->heap()->result_symbol()); | 10320 StackSlotIndex(isolate_->heap()->result_symbol()); |
10270 at_local_ = index < 0; | 10321 at_local_ = index < 0; |
10271 } else if (context_->IsFunctionContext()) { | 10322 } else if (context_->IsFunctionContext()) { |
10272 at_local_ = true; | 10323 at_local_ = true; |
10273 } else if (context_->closure() != *function_) { | 10324 } else if (context_->closure() != *function_) { |
10274 // The context_ is a with or catch block from the outer function. | 10325 // The context_ is a with block from the outer function. |
10275 ASSERT(context_->IsWithContext() || context_->IsCatchContext()); | 10326 ASSERT(context_->has_extension()); |
10276 at_local_ = true; | 10327 at_local_ = true; |
10277 } | 10328 } |
10278 } | 10329 } |
10279 | 10330 |
10280 // More scopes? | 10331 // More scopes? |
10281 bool Done() { return context_.is_null(); } | 10332 bool Done() { return context_.is_null(); } |
10282 | 10333 |
10283 // Move to the next scope. | 10334 // Move to the next scope. |
10284 void Next() { | 10335 void Next() { |
10285 // If at a local scope mark the local scope as passed. | 10336 // If at a local scope mark the local scope as passed. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10317 if (at_local_) { | 10368 if (at_local_) { |
10318 return ScopeTypeLocal; | 10369 return ScopeTypeLocal; |
10319 } | 10370 } |
10320 if (context_->IsGlobalContext()) { | 10371 if (context_->IsGlobalContext()) { |
10321 ASSERT(context_->global()->IsGlobalObject()); | 10372 ASSERT(context_->global()->IsGlobalObject()); |
10322 return ScopeTypeGlobal; | 10373 return ScopeTypeGlobal; |
10323 } | 10374 } |
10324 if (context_->IsFunctionContext()) { | 10375 if (context_->IsFunctionContext()) { |
10325 return ScopeTypeClosure; | 10376 return ScopeTypeClosure; |
10326 } | 10377 } |
10327 if (context_->IsCatchContext()) { | 10378 ASSERT(context_->has_extension()); |
| 10379 // Current scope is either an explicit with statement or a with statement |
| 10380 // implicitely generated for a catch block. |
| 10381 // If the extension object here is a JSContextExtensionObject then |
| 10382 // current with statement is one frome a catch block otherwise it's a |
| 10383 // regular with statement. |
| 10384 if (context_->extension()->IsJSContextExtensionObject()) { |
10328 return ScopeTypeCatch; | 10385 return ScopeTypeCatch; |
10329 } | 10386 } |
10330 ASSERT(context_->IsWithContext()); | |
10331 return ScopeTypeWith; | 10387 return ScopeTypeWith; |
10332 } | 10388 } |
10333 | 10389 |
10334 // Return the JavaScript object with the content of the current scope. | 10390 // Return the JavaScript object with the content of the current scope. |
10335 Handle<JSObject> ScopeObject() { | 10391 Handle<JSObject> ScopeObject() { |
10336 switch (Type()) { | 10392 switch (Type()) { |
10337 case ScopeIterator::ScopeTypeGlobal: | 10393 case ScopeIterator::ScopeTypeGlobal: |
10338 return Handle<JSObject>(CurrentContext()->global()); | 10394 return Handle<JSObject>(CurrentContext()->global()); |
| 10395 break; |
10339 case ScopeIterator::ScopeTypeLocal: | 10396 case ScopeIterator::ScopeTypeLocal: |
10340 // Materialize the content of the local scope into a JSObject. | 10397 // Materialize the content of the local scope into a JSObject. |
10341 return MaterializeLocalScope(isolate_, frame_); | 10398 return MaterializeLocalScope(isolate_, frame_); |
| 10399 break; |
10342 case ScopeIterator::ScopeTypeWith: | 10400 case ScopeIterator::ScopeTypeWith: |
| 10401 case ScopeIterator::ScopeTypeCatch: |
10343 // Return the with object. | 10402 // Return the with object. |
10344 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); | 10403 return Handle<JSObject>(CurrentContext()->extension()); |
10345 case ScopeIterator::ScopeTypeCatch: | 10404 break; |
10346 return MaterializeCatchScope(isolate_, CurrentContext()); | |
10347 case ScopeIterator::ScopeTypeClosure: | 10405 case ScopeIterator::ScopeTypeClosure: |
10348 // Materialize the content of the closure scope into a JSObject. | 10406 // Materialize the content of the closure scope into a JSObject. |
10349 return MaterializeClosure(isolate_, CurrentContext()); | 10407 return MaterializeClosure(isolate_, CurrentContext()); |
| 10408 break; |
10350 } | 10409 } |
10351 UNREACHABLE(); | 10410 UNREACHABLE(); |
10352 return Handle<JSObject>(); | 10411 return Handle<JSObject>(); |
10353 } | 10412 } |
10354 | 10413 |
10355 // Return the context for this scope. For the local context there might not | 10414 // Return the context for this scope. For the local context there might not |
10356 // be an actual context. | 10415 // be an actual context. |
10357 Handle<Context> CurrentContext() { | 10416 Handle<Context> CurrentContext() { |
10358 if (at_local_ && context_->closure() != *function_) { | 10417 if (at_local_ && context_->closure() != *function_) { |
10359 return Handle<Context>(); | 10418 return Handle<Context>(); |
(...skipping 10 matching lines...) Expand all Loading... |
10370 CurrentContext()->Print(); | 10429 CurrentContext()->Print(); |
10371 break; | 10430 break; |
10372 | 10431 |
10373 case ScopeIterator::ScopeTypeLocal: { | 10432 case ScopeIterator::ScopeTypeLocal: { |
10374 PrintF("Local:\n"); | 10433 PrintF("Local:\n"); |
10375 ScopeInfo<> scope_info(function_->shared()->scope_info()); | 10434 ScopeInfo<> scope_info(function_->shared()->scope_info()); |
10376 scope_info.Print(); | 10435 scope_info.Print(); |
10377 if (!CurrentContext().is_null()) { | 10436 if (!CurrentContext().is_null()) { |
10378 CurrentContext()->Print(); | 10437 CurrentContext()->Print(); |
10379 if (CurrentContext()->has_extension()) { | 10438 if (CurrentContext()->has_extension()) { |
10380 Handle<Object> extension(CurrentContext()->extension()); | 10439 Handle<JSObject> extension = |
| 10440 Handle<JSObject>(CurrentContext()->extension()); |
10381 if (extension->IsJSContextExtensionObject()) { | 10441 if (extension->IsJSContextExtensionObject()) { |
10382 extension->Print(); | 10442 extension->Print(); |
10383 } | 10443 } |
10384 } | 10444 } |
10385 } | 10445 } |
10386 break; | 10446 break; |
10387 } | 10447 } |
10388 | 10448 |
10389 case ScopeIterator::ScopeTypeWith: | 10449 case ScopeIterator::ScopeTypeWith: { |
10390 PrintF("With:\n"); | 10450 PrintF("With:\n"); |
10391 CurrentContext()->extension()->Print(); | 10451 Handle<JSObject> extension = |
| 10452 Handle<JSObject>(CurrentContext()->extension()); |
| 10453 extension->Print(); |
10392 break; | 10454 break; |
| 10455 } |
10393 | 10456 |
10394 case ScopeIterator::ScopeTypeCatch: | 10457 case ScopeIterator::ScopeTypeCatch: { |
10395 PrintF("Catch:\n"); | 10458 PrintF("Catch:\n"); |
10396 CurrentContext()->extension()->Print(); | 10459 Handle<JSObject> extension = |
10397 CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print(); | 10460 Handle<JSObject>(CurrentContext()->extension()); |
| 10461 extension->Print(); |
10398 break; | 10462 break; |
| 10463 } |
10399 | 10464 |
10400 case ScopeIterator::ScopeTypeClosure: | 10465 case ScopeIterator::ScopeTypeClosure: { |
10401 PrintF("Closure:\n"); | 10466 PrintF("Closure:\n"); |
10402 CurrentContext()->Print(); | 10467 CurrentContext()->Print(); |
10403 if (CurrentContext()->has_extension()) { | 10468 if (CurrentContext()->has_extension()) { |
10404 Handle<Object> extension(CurrentContext()->extension()); | 10469 Handle<JSObject> extension = |
| 10470 Handle<JSObject>(CurrentContext()->extension()); |
10405 if (extension->IsJSContextExtensionObject()) { | 10471 if (extension->IsJSContextExtensionObject()) { |
10406 extension->Print(); | 10472 extension->Print(); |
10407 } | 10473 } |
10408 } | 10474 } |
10409 break; | 10475 break; |
| 10476 } |
10410 | 10477 |
10411 default: | 10478 default: |
10412 UNREACHABLE(); | 10479 UNREACHABLE(); |
10413 } | 10480 } |
10414 PrintF("\n"); | 10481 PrintF("\n"); |
10415 } | 10482 } |
10416 #endif | 10483 #endif |
10417 | 10484 |
10418 private: | 10485 private: |
10419 Isolate* isolate_; | 10486 Isolate* isolate_; |
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10878 Handle<Context> base) { | 10945 Handle<Context> base) { |
10879 // At the end of the chain. Return the base context to link to. | 10946 // At the end of the chain. Return the base context to link to. |
10880 if (current->IsFunctionContext() || current->IsGlobalContext()) { | 10947 if (current->IsFunctionContext() || current->IsGlobalContext()) { |
10881 return base; | 10948 return base; |
10882 } | 10949 } |
10883 | 10950 |
10884 // Recursively copy the with and catch contexts. | 10951 // Recursively copy the with and catch contexts. |
10885 HandleScope scope(isolate); | 10952 HandleScope scope(isolate); |
10886 Handle<Context> previous(current->previous()); | 10953 Handle<Context> previous(current->previous()); |
10887 Handle<Context> new_previous = CopyWithContextChain(isolate, previous, base); | 10954 Handle<Context> new_previous = CopyWithContextChain(isolate, previous, base); |
10888 Handle<Context> new_current; | 10955 Handle<JSObject> extension(JSObject::cast(current->extension())); |
10889 if (current->IsCatchContext()) { | 10956 Handle<Context> new_current = current->IsCatchContext() |
10890 Handle<String> name(String::cast(current->extension())); | 10957 ? isolate->factory()->NewCatchContext(new_previous, extension) |
10891 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX)); | 10958 : isolate->factory()->NewWithContext(new_previous, extension); |
10892 new_current = | |
10893 isolate->factory()->NewCatchContext(new_previous, name, thrown_object); | |
10894 } else { | |
10895 Handle<JSObject> extension(JSObject::cast(current->extension())); | |
10896 new_current = | |
10897 isolate->factory()->NewWithContext(new_previous, extension); | |
10898 } | |
10899 return scope.CloseAndEscape(new_current); | 10959 return scope.CloseAndEscape(new_current); |
10900 } | 10960 } |
10901 | 10961 |
10902 | 10962 |
10903 // Helper function to find or create the arguments object for | 10963 // Helper function to find or create the arguments object for |
10904 // Runtime_DebugEvaluate. | 10964 // Runtime_DebugEvaluate. |
10905 static Handle<Object> GetArgumentsObject(Isolate* isolate, | 10965 static Handle<Object> GetArgumentsObject(Isolate* isolate, |
10906 JavaScriptFrame* frame, | 10966 JavaScriptFrame* frame, |
10907 Handle<JSFunction> function, | 10967 Handle<JSFunction> function, |
10908 Handle<SerializedScopeInfo> scope_info, | 10968 Handle<SerializedScopeInfo> scope_info, |
(...skipping 1475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12384 } else { | 12444 } else { |
12385 // Handle last resort GC and make sure to allow future allocations | 12445 // Handle last resort GC and make sure to allow future allocations |
12386 // to grow the heap without causing GCs (if possible). | 12446 // to grow the heap without causing GCs (if possible). |
12387 isolate->counters()->gc_last_resort_from_js()->Increment(); | 12447 isolate->counters()->gc_last_resort_from_js()->Increment(); |
12388 isolate->heap()->CollectAllGarbage(false); | 12448 isolate->heap()->CollectAllGarbage(false); |
12389 } | 12449 } |
12390 } | 12450 } |
12391 | 12451 |
12392 | 12452 |
12393 } } // namespace v8::internal | 12453 } } // namespace v8::internal |
OLD | NEW |