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