OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 2148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2159 NoHandleAllocation ha; | 2159 NoHandleAllocation ha; |
2160 RUNTIME_ASSERT(args.length() == 1); | 2160 RUNTIME_ASSERT(args.length() == 1); |
2161 CONVERT_ARG_CHECKED(JSFunction, function, 0); | 2161 CONVERT_ARG_CHECKED(JSFunction, function, 0); |
2162 | 2162 |
2163 String* name = isolate->heap()->prototype_symbol(); | 2163 String* name = isolate->heap()->prototype_symbol(); |
2164 | 2164 |
2165 if (function->HasFastProperties()) { | 2165 if (function->HasFastProperties()) { |
2166 // Construct a new field descriptor with updated attributes. | 2166 // Construct a new field descriptor with updated attributes. |
2167 DescriptorArray* instance_desc = function->map()->instance_descriptors(); | 2167 DescriptorArray* instance_desc = function->map()->instance_descriptors(); |
2168 | 2168 |
2169 int index = instance_desc->SearchWithCache(name, function->map()); | 2169 int index = instance_desc->SearchWithCache(name); |
2170 ASSERT(index != DescriptorArray::kNotFound); | 2170 ASSERT(index != DescriptorArray::kNotFound); |
2171 PropertyDetails details = instance_desc->GetDetails(index); | 2171 PropertyDetails details = instance_desc->GetDetails(index); |
2172 | 2172 |
2173 CallbacksDescriptor new_desc(name, | 2173 CallbacksDescriptor new_desc(name, |
2174 instance_desc->GetValue(index), | 2174 instance_desc->GetValue(index), |
2175 static_cast<PropertyAttributes>(details.attributes() | READ_ONLY), | 2175 static_cast<PropertyAttributes>(details.attributes() | READ_ONLY), |
2176 details.descriptor_index()); | 2176 details.descriptor_index()); |
2177 | 2177 |
2178 // Create a new map featuring the new field descriptors array. | 2178 // Create a new map featuring the new field descriptors array. |
2179 Map* new_map; | 2179 Map* new_map; |
(...skipping 2845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5025 | 5025 |
5026 RUNTIME_FUNCTION(MaybeObject*, Runtime_ToFastProperties) { | 5026 RUNTIME_FUNCTION(MaybeObject*, Runtime_ToFastProperties) { |
5027 ASSERT(args.length() == 1); | 5027 ASSERT(args.length() == 1); |
5028 Object* object = args[0]; | 5028 Object* object = args[0]; |
5029 return (object->IsJSObject() && !object->IsGlobalObject()) | 5029 return (object->IsJSObject() && !object->IsGlobalObject()) |
5030 ? JSObject::cast(object)->TransformToFastProperties(0) | 5030 ? JSObject::cast(object)->TransformToFastProperties(0) |
5031 : object; | 5031 : object; |
5032 } | 5032 } |
5033 | 5033 |
5034 | 5034 |
| 5035 RUNTIME_FUNCTION(MaybeObject*, Runtime_ToSlowProperties) { |
| 5036 ASSERT(args.length() == 1); |
| 5037 Object* obj = args[0]; |
| 5038 return (obj->IsJSObject() && !obj->IsJSGlobalProxy()) |
| 5039 ? JSObject::cast(obj)->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0) |
| 5040 : obj; |
| 5041 } |
| 5042 |
| 5043 |
5035 RUNTIME_FUNCTION(MaybeObject*, Runtime_ToBool) { | 5044 RUNTIME_FUNCTION(MaybeObject*, Runtime_ToBool) { |
5036 NoHandleAllocation ha; | 5045 NoHandleAllocation ha; |
5037 ASSERT(args.length() == 1); | 5046 ASSERT(args.length() == 1); |
5038 | 5047 |
5039 return args[0]->ToBoolean(); | 5048 return args[0]->ToBoolean(); |
5040 } | 5049 } |
5041 | 5050 |
5042 | 5051 |
5043 // Returns the type string of a value; see ECMA-262, 11.4.3 (p 47). | 5052 // Returns the type string of a value; see ECMA-262, 11.4.3 (p 47). |
5044 // Possible optimizations: put the type string into the oddballs. | 5053 // Possible optimizations: put the type string into the oddballs. |
(...skipping 2848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7893 // If the function is not compiled ignore the lazy | 7902 // If the function is not compiled ignore the lazy |
7894 // recompilation. This can happen if the debugger is activated and | 7903 // recompilation. This can happen if the debugger is activated and |
7895 // the function is returned to the not compiled state. | 7904 // the function is returned to the not compiled state. |
7896 if (!function->shared()->is_compiled()) { | 7905 if (!function->shared()->is_compiled()) { |
7897 function->ReplaceCode(function->shared()->code()); | 7906 function->ReplaceCode(function->shared()->code()); |
7898 return function->code(); | 7907 return function->code(); |
7899 } | 7908 } |
7900 | 7909 |
7901 // If the function is not optimizable or debugger is active continue using the | 7910 // If the function is not optimizable or debugger is active continue using the |
7902 // code from the full compiler. | 7911 // code from the full compiler. |
7903 if (!FLAG_crankshaft || | 7912 if (!function->shared()->code()->optimizable() || |
7904 !function->shared()->code()->optimizable() || | |
7905 isolate->DebuggerHasBreakPoints()) { | 7913 isolate->DebuggerHasBreakPoints()) { |
7906 if (FLAG_trace_opt) { | 7914 if (FLAG_trace_opt) { |
7907 PrintF("[failed to optimize "); | 7915 PrintF("[failed to optimize "); |
7908 function->PrintName(); | 7916 function->PrintName(); |
7909 PrintF(": is code optimizable: %s, is debugger enabled: %s]\n", | 7917 PrintF(": is code optimizable: %s, is debugger enabled: %s]\n", |
7910 function->shared()->code()->optimizable() ? "T" : "F", | 7918 function->shared()->code()->optimizable() ? "T" : "F", |
7911 isolate->DebuggerHasBreakPoints() ? "T" : "F"); | 7919 isolate->DebuggerHasBreakPoints() ? "T" : "F"); |
7912 } | 7920 } |
7913 function->ReplaceCode(function->shared()->code()); | 7921 function->ReplaceCode(function->shared()->code()); |
7914 return function->code(); | 7922 return function->code(); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7955 } | 7963 } |
7956 | 7964 |
7957 bool has_activations() { return has_activations_; } | 7965 bool has_activations() { return has_activations_; } |
7958 | 7966 |
7959 private: | 7967 private: |
7960 JSFunction* function_; | 7968 JSFunction* function_; |
7961 bool has_activations_; | 7969 bool has_activations_; |
7962 }; | 7970 }; |
7963 | 7971 |
7964 | 7972 |
| 7973 static void MaterializeArgumentsObjectInFrame(Isolate* isolate, |
| 7974 JavaScriptFrame* frame) { |
| 7975 Handle<JSFunction> function(JSFunction::cast(frame->function()), isolate); |
| 7976 Handle<Object> arguments; |
| 7977 for (int i = frame->ComputeExpressionsCount() - 1; i >= 0; --i) { |
| 7978 if (frame->GetExpression(i) == isolate->heap()->arguments_marker()) { |
| 7979 if (arguments.is_null()) { |
| 7980 // FunctionGetArguments can't throw an exception, so cast away the |
| 7981 // doubt with an assert. |
| 7982 arguments = Handle<Object>( |
| 7983 Accessors::FunctionGetArguments(*function, |
| 7984 NULL)->ToObjectUnchecked()); |
| 7985 ASSERT(*arguments != isolate->heap()->null_value()); |
| 7986 ASSERT(*arguments != isolate->heap()->undefined_value()); |
| 7987 } |
| 7988 frame->SetExpression(i, *arguments); |
| 7989 if (FLAG_trace_deopt) { |
| 7990 PrintF("Materializing arguments object for frame %p - %p: %p ", |
| 7991 reinterpret_cast<void*>(frame->sp()), |
| 7992 reinterpret_cast<void*>(frame->fp()), |
| 7993 reinterpret_cast<void*>(*arguments)); |
| 7994 arguments->ShortPrint(); |
| 7995 PrintF("\n"); |
| 7996 } |
| 7997 } |
| 7998 } |
| 7999 } |
| 8000 |
| 8001 |
7965 RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) { | 8002 RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) { |
7966 HandleScope scope(isolate); | 8003 HandleScope scope(isolate); |
7967 ASSERT(args.length() == 1); | 8004 ASSERT(args.length() == 1); |
7968 RUNTIME_ASSERT(args[0]->IsSmi()); | 8005 RUNTIME_ASSERT(args[0]->IsSmi()); |
7969 Deoptimizer::BailoutType type = | 8006 Deoptimizer::BailoutType type = |
7970 static_cast<Deoptimizer::BailoutType>(args.smi_at(0)); | 8007 static_cast<Deoptimizer::BailoutType>(args.smi_at(0)); |
7971 Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); | 8008 Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); |
7972 ASSERT(isolate->heap()->IsAllocationAllowed()); | 8009 ASSERT(isolate->heap()->IsAllocationAllowed()); |
| 8010 int jsframes = deoptimizer->jsframe_count(); |
| 8011 |
| 8012 deoptimizer->MaterializeHeapNumbers(); |
| 8013 delete deoptimizer; |
| 8014 |
7973 JavaScriptFrameIterator it(isolate); | 8015 JavaScriptFrameIterator it(isolate); |
7974 | 8016 for (int i = 0; i < jsframes - 1; i++) { |
7975 // Make sure to materialize objects before causing any allocation. | 8017 MaterializeArgumentsObjectInFrame(isolate, it.frame()); |
7976 deoptimizer->MaterializeHeapObjects(&it); | 8018 it.Advance(); |
7977 delete deoptimizer; | 8019 } |
7978 | 8020 |
7979 JavaScriptFrame* frame = it.frame(); | 8021 JavaScriptFrame* frame = it.frame(); |
7980 RUNTIME_ASSERT(frame->function()->IsJSFunction()); | 8022 RUNTIME_ASSERT(frame->function()->IsJSFunction()); |
7981 Handle<JSFunction> function(JSFunction::cast(frame->function()), isolate); | 8023 Handle<JSFunction> function(JSFunction::cast(frame->function()), isolate); |
7982 RUNTIME_ASSERT(type != Deoptimizer::EAGER || function->IsOptimized()); | 8024 MaterializeArgumentsObjectInFrame(isolate, frame); |
| 8025 |
| 8026 if (type == Deoptimizer::EAGER) { |
| 8027 RUNTIME_ASSERT(function->IsOptimized()); |
| 8028 } |
7983 | 8029 |
7984 // Avoid doing too much work when running with --always-opt and keep | 8030 // Avoid doing too much work when running with --always-opt and keep |
7985 // the optimized code around. | 8031 // the optimized code around. |
7986 if (FLAG_always_opt || type == Deoptimizer::LAZY) { | 8032 if (FLAG_always_opt || type == Deoptimizer::LAZY) { |
7987 return isolate->heap()->undefined_value(); | 8033 return isolate->heap()->undefined_value(); |
7988 } | 8034 } |
7989 | 8035 |
7990 // Find other optimized activations of the function or functions that | 8036 // Find other optimized activations of the function or functions that |
7991 // share the same optimized code. | 8037 // share the same optimized code. |
7992 bool has_other_activations = false; | 8038 bool has_other_activations = false; |
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9045 ASSERT_EQ(1, args.length()); | 9091 ASSERT_EQ(1, args.length()); |
9046 CONVERT_ARG_HANDLE_CHECKED(String, source, 0); | 9092 CONVERT_ARG_HANDLE_CHECKED(String, source, 0); |
9047 | 9093 |
9048 // Extract native context. | 9094 // Extract native context. |
9049 Handle<Context> context(isolate->context()->native_context()); | 9095 Handle<Context> context(isolate->context()->native_context()); |
9050 | 9096 |
9051 // Check if native context allows code generation from | 9097 // Check if native context allows code generation from |
9052 // strings. Throw an exception if it doesn't. | 9098 // strings. Throw an exception if it doesn't. |
9053 if (context->allow_code_gen_from_strings()->IsFalse() && | 9099 if (context->allow_code_gen_from_strings()->IsFalse() && |
9054 !CodeGenerationFromStringsAllowed(isolate, context)) { | 9100 !CodeGenerationFromStringsAllowed(isolate, context)) { |
9055 Handle<Object> error_message = | 9101 return isolate->Throw(*isolate->factory()->NewError( |
9056 context->ErrorMessageForCodeGenerationFromStrings(); | 9102 "code_gen_from_strings", HandleVector<Object>(NULL, 0))); |
9057 return isolate->Throw(*isolate->factory()->NewEvalError( | |
9058 "code_gen_from_strings", HandleVector<Object>(&error_message, 1))); | |
9059 } | 9103 } |
9060 | 9104 |
9061 // Compile source string in the native context. | 9105 // Compile source string in the native context. |
9062 Handle<SharedFunctionInfo> shared = Compiler::CompileEval( | 9106 Handle<SharedFunctionInfo> shared = Compiler::CompileEval( |
9063 source, context, true, CLASSIC_MODE, RelocInfo::kNoPosition); | 9107 source, context, true, CLASSIC_MODE, RelocInfo::kNoPosition); |
9064 if (shared.is_null()) return Failure::Exception(); | 9108 if (shared.is_null()) return Failure::Exception(); |
9065 Handle<JSFunction> fun = | 9109 Handle<JSFunction> fun = |
9066 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, | 9110 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, |
9067 context, | 9111 context, |
9068 NOT_TENURED); | 9112 NOT_TENURED); |
9069 return *fun; | 9113 return *fun; |
9070 } | 9114 } |
9071 | 9115 |
9072 | 9116 |
9073 static ObjectPair CompileGlobalEval(Isolate* isolate, | 9117 static ObjectPair CompileGlobalEval(Isolate* isolate, |
9074 Handle<String> source, | 9118 Handle<String> source, |
9075 Handle<Object> receiver, | 9119 Handle<Object> receiver, |
9076 LanguageMode language_mode, | 9120 LanguageMode language_mode, |
9077 int scope_position) { | 9121 int scope_position) { |
9078 Handle<Context> context = Handle<Context>(isolate->context()); | 9122 Handle<Context> context = Handle<Context>(isolate->context()); |
9079 Handle<Context> native_context = Handle<Context>(context->native_context()); | 9123 Handle<Context> native_context = Handle<Context>(context->native_context()); |
9080 | 9124 |
9081 // Check if native context allows code generation from | 9125 // Check if native context allows code generation from |
9082 // strings. Throw an exception if it doesn't. | 9126 // strings. Throw an exception if it doesn't. |
9083 if (native_context->allow_code_gen_from_strings()->IsFalse() && | 9127 if (native_context->allow_code_gen_from_strings()->IsFalse() && |
9084 !CodeGenerationFromStringsAllowed(isolate, native_context)) { | 9128 !CodeGenerationFromStringsAllowed(isolate, native_context)) { |
9085 Handle<Object> error_message = | 9129 isolate->Throw(*isolate->factory()->NewError( |
9086 context->ErrorMessageForCodeGenerationFromStrings(); | 9130 "code_gen_from_strings", HandleVector<Object>(NULL, 0))); |
9087 isolate->Throw(*isolate->factory()->NewEvalError( | |
9088 "code_gen_from_strings", HandleVector<Object>(&error_message, 1))); | |
9089 return MakePair(Failure::Exception(), NULL); | 9131 return MakePair(Failure::Exception(), NULL); |
9090 } | 9132 } |
9091 | 9133 |
9092 // Deal with a normal eval call with a string argument. Compile it | 9134 // Deal with a normal eval call with a string argument. Compile it |
9093 // and return the compiled function bound in the local context. | 9135 // and return the compiled function bound in the local context. |
9094 Handle<SharedFunctionInfo> shared = Compiler::CompileEval( | 9136 Handle<SharedFunctionInfo> shared = Compiler::CompileEval( |
9095 source, | 9137 source, |
9096 Handle<Context>(isolate->context()), | 9138 Handle<Context>(isolate->context()), |
9097 context->IsNativeContext(), | 9139 context->IsNativeContext(), |
9098 language_mode, | 9140 language_mode, |
(...skipping 1732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10831 }; | 10873 }; |
10832 | 10874 |
10833 ScopeIterator(Isolate* isolate, | 10875 ScopeIterator(Isolate* isolate, |
10834 JavaScriptFrame* frame, | 10876 JavaScriptFrame* frame, |
10835 int inlined_jsframe_index) | 10877 int inlined_jsframe_index) |
10836 : isolate_(isolate), | 10878 : isolate_(isolate), |
10837 frame_(frame), | 10879 frame_(frame), |
10838 inlined_jsframe_index_(inlined_jsframe_index), | 10880 inlined_jsframe_index_(inlined_jsframe_index), |
10839 function_(JSFunction::cast(frame->function())), | 10881 function_(JSFunction::cast(frame->function())), |
10840 context_(Context::cast(frame->context())), | 10882 context_(Context::cast(frame->context())), |
10841 nested_scope_chain_(4), | 10883 nested_scope_chain_(4) { |
10842 failed_(false) { | |
10843 | 10884 |
10844 // Catch the case when the debugger stops in an internal function. | 10885 // Catch the case when the debugger stops in an internal function. |
10845 Handle<SharedFunctionInfo> shared_info(function_->shared()); | 10886 Handle<SharedFunctionInfo> shared_info(function_->shared()); |
10846 Handle<ScopeInfo> scope_info(shared_info->scope_info()); | 10887 Handle<ScopeInfo> scope_info(shared_info->scope_info()); |
10847 if (shared_info->script() == isolate->heap()->undefined_value()) { | 10888 if (shared_info->script() == isolate->heap()->undefined_value()) { |
10848 while (context_->closure() == *function_) { | 10889 while (context_->closure() == *function_) { |
10849 context_ = Handle<Context>(context_->previous(), isolate_); | 10890 context_ = Handle<Context>(context_->previous(), isolate_); |
10850 } | 10891 } |
10851 return; | 10892 return; |
10852 } | 10893 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10906 } | 10947 } |
10907 } | 10948 } |
10908 } | 10949 } |
10909 | 10950 |
10910 ScopeIterator(Isolate* isolate, | 10951 ScopeIterator(Isolate* isolate, |
10911 Handle<JSFunction> function) | 10952 Handle<JSFunction> function) |
10912 : isolate_(isolate), | 10953 : isolate_(isolate), |
10913 frame_(NULL), | 10954 frame_(NULL), |
10914 inlined_jsframe_index_(0), | 10955 inlined_jsframe_index_(0), |
10915 function_(function), | 10956 function_(function), |
10916 context_(function->context()), | 10957 context_(function->context()) { |
10917 failed_(false) { | |
10918 if (function->IsBuiltin()) { | 10958 if (function->IsBuiltin()) { |
10919 context_ = Handle<Context>(); | 10959 context_ = Handle<Context>(); |
10920 } | 10960 } |
10921 } | 10961 } |
10922 | 10962 |
10923 // More scopes? | 10963 // More scopes? |
10924 bool Done() { | 10964 bool Done() { return context_.is_null(); } |
10925 ASSERT(!failed_); | |
10926 return context_.is_null(); | |
10927 } | |
10928 | |
10929 bool Failed() { return failed_; } | |
10930 | 10965 |
10931 // Move to the next scope. | 10966 // Move to the next scope. |
10932 void Next() { | 10967 void Next() { |
10933 ASSERT(!failed_); | |
10934 ScopeType scope_type = Type(); | 10968 ScopeType scope_type = Type(); |
10935 if (scope_type == ScopeTypeGlobal) { | 10969 if (scope_type == ScopeTypeGlobal) { |
10936 // The global scope is always the last in the chain. | 10970 // The global scope is always the last in the chain. |
10937 ASSERT(context_->IsNativeContext()); | 10971 ASSERT(context_->IsNativeContext()); |
10938 context_ = Handle<Context>(); | 10972 context_ = Handle<Context>(); |
10939 return; | 10973 return; |
10940 } | 10974 } |
10941 if (nested_scope_chain_.is_empty()) { | 10975 if (nested_scope_chain_.is_empty()) { |
10942 context_ = Handle<Context>(context_->previous(), isolate_); | 10976 context_ = Handle<Context>(context_->previous(), isolate_); |
10943 } else { | 10977 } else { |
10944 if (nested_scope_chain_.last()->HasContext()) { | 10978 if (nested_scope_chain_.last()->HasContext()) { |
10945 ASSERT(context_->previous() != NULL); | 10979 ASSERT(context_->previous() != NULL); |
10946 context_ = Handle<Context>(context_->previous(), isolate_); | 10980 context_ = Handle<Context>(context_->previous(), isolate_); |
10947 } | 10981 } |
10948 nested_scope_chain_.RemoveLast(); | 10982 nested_scope_chain_.RemoveLast(); |
10949 } | 10983 } |
10950 } | 10984 } |
10951 | 10985 |
10952 // Return the type of the current scope. | 10986 // Return the type of the current scope. |
10953 ScopeType Type() { | 10987 ScopeType Type() { |
10954 ASSERT(!failed_); | |
10955 if (!nested_scope_chain_.is_empty()) { | 10988 if (!nested_scope_chain_.is_empty()) { |
10956 Handle<ScopeInfo> scope_info = nested_scope_chain_.last(); | 10989 Handle<ScopeInfo> scope_info = nested_scope_chain_.last(); |
10957 switch (scope_info->Type()) { | 10990 switch (scope_info->Type()) { |
10958 case FUNCTION_SCOPE: | 10991 case FUNCTION_SCOPE: |
10959 ASSERT(context_->IsFunctionContext() || | 10992 ASSERT(context_->IsFunctionContext() || |
10960 !scope_info->HasContext()); | 10993 !scope_info->HasContext()); |
10961 return ScopeTypeLocal; | 10994 return ScopeTypeLocal; |
10962 case MODULE_SCOPE: | 10995 case MODULE_SCOPE: |
10963 ASSERT(context_->IsModuleContext()); | 10996 ASSERT(context_->IsModuleContext()); |
10964 return ScopeTypeModule; | 10997 return ScopeTypeModule; |
(...skipping 29 matching lines...) Expand all Loading... |
10994 } | 11027 } |
10995 if (context_->IsModuleContext()) { | 11028 if (context_->IsModuleContext()) { |
10996 return ScopeTypeModule; | 11029 return ScopeTypeModule; |
10997 } | 11030 } |
10998 ASSERT(context_->IsWithContext()); | 11031 ASSERT(context_->IsWithContext()); |
10999 return ScopeTypeWith; | 11032 return ScopeTypeWith; |
11000 } | 11033 } |
11001 | 11034 |
11002 // Return the JavaScript object with the content of the current scope. | 11035 // Return the JavaScript object with the content of the current scope. |
11003 Handle<JSObject> ScopeObject() { | 11036 Handle<JSObject> ScopeObject() { |
11004 ASSERT(!failed_); | |
11005 switch (Type()) { | 11037 switch (Type()) { |
11006 case ScopeIterator::ScopeTypeGlobal: | 11038 case ScopeIterator::ScopeTypeGlobal: |
11007 return Handle<JSObject>(CurrentContext()->global_object()); | 11039 return Handle<JSObject>(CurrentContext()->global_object()); |
11008 case ScopeIterator::ScopeTypeLocal: | 11040 case ScopeIterator::ScopeTypeLocal: |
11009 // Materialize the content of the local scope into a JSObject. | 11041 // Materialize the content of the local scope into a JSObject. |
11010 ASSERT(nested_scope_chain_.length() == 1); | 11042 ASSERT(nested_scope_chain_.length() == 1); |
11011 return MaterializeLocalScope(isolate_, frame_, inlined_jsframe_index_); | 11043 return MaterializeLocalScope(isolate_, frame_, inlined_jsframe_index_); |
11012 case ScopeIterator::ScopeTypeWith: | 11044 case ScopeIterator::ScopeTypeWith: |
11013 // Return the with object. | 11045 // Return the with object. |
11014 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); | 11046 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); |
11015 case ScopeIterator::ScopeTypeCatch: | 11047 case ScopeIterator::ScopeTypeCatch: |
11016 return MaterializeCatchScope(isolate_, CurrentContext()); | 11048 return MaterializeCatchScope(isolate_, CurrentContext()); |
11017 case ScopeIterator::ScopeTypeClosure: | 11049 case ScopeIterator::ScopeTypeClosure: |
11018 // Materialize the content of the closure scope into a JSObject. | 11050 // Materialize the content of the closure scope into a JSObject. |
11019 return MaterializeClosure(isolate_, CurrentContext()); | 11051 return MaterializeClosure(isolate_, CurrentContext()); |
11020 case ScopeIterator::ScopeTypeBlock: | 11052 case ScopeIterator::ScopeTypeBlock: |
11021 return MaterializeBlockScope(isolate_, CurrentContext()); | 11053 return MaterializeBlockScope(isolate_, CurrentContext()); |
11022 case ScopeIterator::ScopeTypeModule: | 11054 case ScopeIterator::ScopeTypeModule: |
11023 return MaterializeModuleScope(isolate_, CurrentContext()); | 11055 return MaterializeModuleScope(isolate_, CurrentContext()); |
11024 } | 11056 } |
11025 UNREACHABLE(); | 11057 UNREACHABLE(); |
11026 return Handle<JSObject>(); | 11058 return Handle<JSObject>(); |
11027 } | 11059 } |
11028 | 11060 |
11029 Handle<ScopeInfo> CurrentScopeInfo() { | 11061 Handle<ScopeInfo> CurrentScopeInfo() { |
11030 ASSERT(!failed_); | |
11031 if (!nested_scope_chain_.is_empty()) { | 11062 if (!nested_scope_chain_.is_empty()) { |
11032 return nested_scope_chain_.last(); | 11063 return nested_scope_chain_.last(); |
11033 } else if (context_->IsBlockContext()) { | 11064 } else if (context_->IsBlockContext()) { |
11034 return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension())); | 11065 return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension())); |
11035 } else if (context_->IsFunctionContext()) { | 11066 } else if (context_->IsFunctionContext()) { |
11036 return Handle<ScopeInfo>(context_->closure()->shared()->scope_info()); | 11067 return Handle<ScopeInfo>(context_->closure()->shared()->scope_info()); |
11037 } | 11068 } |
11038 return Handle<ScopeInfo>::null(); | 11069 return Handle<ScopeInfo>::null(); |
11039 } | 11070 } |
11040 | 11071 |
11041 // Return the context for this scope. For the local context there might not | 11072 // Return the context for this scope. For the local context there might not |
11042 // be an actual context. | 11073 // be an actual context. |
11043 Handle<Context> CurrentContext() { | 11074 Handle<Context> CurrentContext() { |
11044 ASSERT(!failed_); | |
11045 if (Type() == ScopeTypeGlobal || | 11075 if (Type() == ScopeTypeGlobal || |
11046 nested_scope_chain_.is_empty()) { | 11076 nested_scope_chain_.is_empty()) { |
11047 return context_; | 11077 return context_; |
11048 } else if (nested_scope_chain_.last()->HasContext()) { | 11078 } else if (nested_scope_chain_.last()->HasContext()) { |
11049 return context_; | 11079 return context_; |
11050 } else { | 11080 } else { |
11051 return Handle<Context>(); | 11081 return Handle<Context>(); |
11052 } | 11082 } |
11053 } | 11083 } |
11054 | 11084 |
11055 #ifdef DEBUG | 11085 #ifdef DEBUG |
11056 // Debug print of the content of the current scope. | 11086 // Debug print of the content of the current scope. |
11057 void DebugPrint() { | 11087 void DebugPrint() { |
11058 ASSERT(!failed_); | |
11059 switch (Type()) { | 11088 switch (Type()) { |
11060 case ScopeIterator::ScopeTypeGlobal: | 11089 case ScopeIterator::ScopeTypeGlobal: |
11061 PrintF("Global:\n"); | 11090 PrintF("Global:\n"); |
11062 CurrentContext()->Print(); | 11091 CurrentContext()->Print(); |
11063 break; | 11092 break; |
11064 | 11093 |
11065 case ScopeIterator::ScopeTypeLocal: { | 11094 case ScopeIterator::ScopeTypeLocal: { |
11066 PrintF("Local:\n"); | 11095 PrintF("Local:\n"); |
11067 function_->shared()->scope_info()->Print(); | 11096 function_->shared()->scope_info()->Print(); |
11068 if (!CurrentContext().is_null()) { | 11097 if (!CurrentContext().is_null()) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11106 } | 11135 } |
11107 #endif | 11136 #endif |
11108 | 11137 |
11109 private: | 11138 private: |
11110 Isolate* isolate_; | 11139 Isolate* isolate_; |
11111 JavaScriptFrame* frame_; | 11140 JavaScriptFrame* frame_; |
11112 int inlined_jsframe_index_; | 11141 int inlined_jsframe_index_; |
11113 Handle<JSFunction> function_; | 11142 Handle<JSFunction> function_; |
11114 Handle<Context> context_; | 11143 Handle<Context> context_; |
11115 List<Handle<ScopeInfo> > nested_scope_chain_; | 11144 List<Handle<ScopeInfo> > nested_scope_chain_; |
11116 bool failed_; | |
11117 | 11145 |
11118 void RetrieveScopeChain(Scope* scope, | 11146 void RetrieveScopeChain(Scope* scope, |
11119 Handle<SharedFunctionInfo> shared_info) { | 11147 Handle<SharedFunctionInfo> shared_info) { |
11120 if (scope != NULL) { | 11148 if (scope != NULL) { |
11121 int source_position = shared_info->code()->SourcePosition(frame_->pc()); | 11149 int source_position = shared_info->code()->SourcePosition(frame_->pc()); |
11122 scope->GetNestedScopeChain(&nested_scope_chain_, source_position); | 11150 scope->GetNestedScopeChain(&nested_scope_chain_, source_position); |
11123 } else { | 11151 } else { |
11124 // A failed reparse indicates that the preparser has diverged from the | 11152 // A failed reparse indicates that the preparser has diverged from the |
11125 // parser or that the preparse data given to the initial parse has been | 11153 // parser or that the preparse data given to the initial parse has been |
11126 // faulty. We fail in debug mode but in release mode we only provide the | 11154 // faulty. We fail in debug mode but in release mode we only provide the |
11127 // information we get from the context chain but nothing about | 11155 // information we get from the context chain but nothing about |
11128 // completely stack allocated scopes or stack allocated locals. | 11156 // completely stack allocated scopes or stack allocated locals. |
11129 // Or it could be due to stack overflow. | 11157 UNREACHABLE(); |
11130 ASSERT(isolate_->has_pending_exception()); | |
11131 failed_ = true; | |
11132 } | 11158 } |
11133 } | 11159 } |
11134 | 11160 |
11135 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); | 11161 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); |
11136 }; | 11162 }; |
11137 | 11163 |
11138 | 11164 |
11139 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) { | 11165 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) { |
11140 HandleScope scope(isolate); | 11166 HandleScope scope(isolate); |
11141 ASSERT(args.length() == 2); | 11167 ASSERT(args.length() == 2); |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11546 static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate, | 11572 static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate, |
11547 Handle<JSFunction> function, | 11573 Handle<JSFunction> function, |
11548 Handle<Context> base, | 11574 Handle<Context> base, |
11549 JavaScriptFrame* frame, | 11575 JavaScriptFrame* frame, |
11550 int inlined_jsframe_index) { | 11576 int inlined_jsframe_index) { |
11551 HandleScope scope(isolate); | 11577 HandleScope scope(isolate); |
11552 List<Handle<ScopeInfo> > scope_chain; | 11578 List<Handle<ScopeInfo> > scope_chain; |
11553 List<Handle<Context> > context_chain; | 11579 List<Handle<Context> > context_chain; |
11554 | 11580 |
11555 ScopeIterator it(isolate, frame, inlined_jsframe_index); | 11581 ScopeIterator it(isolate, frame, inlined_jsframe_index); |
11556 if (it.Failed()) return Handle<Context>::null(); | |
11557 | |
11558 for (; it.Type() != ScopeIterator::ScopeTypeGlobal && | 11582 for (; it.Type() != ScopeIterator::ScopeTypeGlobal && |
11559 it.Type() != ScopeIterator::ScopeTypeLocal ; it.Next()) { | 11583 it.Type() != ScopeIterator::ScopeTypeLocal ; it.Next()) { |
11560 ASSERT(!it.Done()); | 11584 ASSERT(!it.Done()); |
11561 scope_chain.Add(it.CurrentScopeInfo()); | 11585 scope_chain.Add(it.CurrentScopeInfo()); |
11562 context_chain.Add(it.CurrentContext()); | 11586 context_chain.Add(it.CurrentContext()); |
11563 } | 11587 } |
11564 | 11588 |
11565 // At the end of the chain. Return the base context to link to. | 11589 // At the end of the chain. Return the base context to link to. |
11566 Handle<Context> context = base; | 11590 Handle<Context> context = base; |
11567 | 11591 |
11568 // Iteratively copy and or materialize the nested contexts. | 11592 // Iteratively copy and or materialize the nested contexts. |
11569 while (!scope_chain.is_empty()) { | 11593 while (!scope_chain.is_empty()) { |
11570 Handle<ScopeInfo> scope_info = scope_chain.RemoveLast(); | 11594 Handle<ScopeInfo> scope_info = scope_chain.RemoveLast(); |
11571 Handle<Context> current = context_chain.RemoveLast(); | 11595 Handle<Context> current = context_chain.RemoveLast(); |
11572 ASSERT(!(scope_info->HasContext() & current.is_null())); | 11596 ASSERT(!(scope_info->HasContext() & current.is_null())); |
11573 | 11597 |
11574 if (scope_info->Type() == CATCH_SCOPE) { | 11598 if (scope_info->Type() == CATCH_SCOPE) { |
11575 Handle<String> name(String::cast(current->extension())); | 11599 Handle<String> name(String::cast(current->extension())); |
11576 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX)); | 11600 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX)); |
11577 context = | 11601 context = |
11578 isolate->factory()->NewCatchContext(function, | 11602 isolate->factory()->NewCatchContext(function, |
11579 context, | 11603 context, |
11580 name, | 11604 name, |
11581 thrown_object); | 11605 thrown_object); |
11582 } else if (scope_info->Type() == BLOCK_SCOPE) { | 11606 } else if (scope_info->Type() == BLOCK_SCOPE) { |
11583 // Materialize the contents of the block scope into a JSObject. | 11607 // Materialize the contents of the block scope into a JSObject. |
11584 Handle<JSObject> block_scope_object = | 11608 Handle<JSObject> block_scope_object = |
11585 MaterializeBlockScope(isolate, current); | 11609 MaterializeBlockScope(isolate, current); |
11586 CHECK(!block_scope_object.is_null()); | 11610 if (block_scope_object.is_null()) { |
| 11611 return Handle<Context>::null(); |
| 11612 } |
11587 // Allocate a new function context for the debug evaluation and set the | 11613 // Allocate a new function context for the debug evaluation and set the |
11588 // extension object. | 11614 // extension object. |
11589 Handle<Context> new_context = | 11615 Handle<Context> new_context = |
11590 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, | 11616 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, |
11591 function); | 11617 function); |
11592 new_context->set_extension(*block_scope_object); | 11618 new_context->set_extension(*block_scope_object); |
11593 new_context->set_previous(*context); | 11619 new_context->set_previous(*context); |
11594 context = new_context; | 11620 context = new_context; |
11595 } else { | 11621 } else { |
11596 ASSERT(scope_info->Type() == WITH_SCOPE); | 11622 ASSERT(scope_info->Type() == WITH_SCOPE); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11737 Handle<Context> function_context; | 11763 Handle<Context> function_context; |
11738 // Get the function's context if it has one. | 11764 // Get the function's context if it has one. |
11739 if (scope_info->HasContext()) { | 11765 if (scope_info->HasContext()) { |
11740 function_context = Handle<Context>(frame_context->declaration_context()); | 11766 function_context = Handle<Context>(frame_context->declaration_context()); |
11741 } | 11767 } |
11742 context = CopyNestedScopeContextChain(isolate, | 11768 context = CopyNestedScopeContextChain(isolate, |
11743 go_between, | 11769 go_between, |
11744 context, | 11770 context, |
11745 frame, | 11771 frame, |
11746 inlined_jsframe_index); | 11772 inlined_jsframe_index); |
11747 if (context.is_null()) { | |
11748 ASSERT(isolate->has_pending_exception()); | |
11749 MaybeObject* exception = isolate->pending_exception(); | |
11750 isolate->clear_pending_exception(); | |
11751 return exception; | |
11752 } | |
11753 | 11773 |
11754 if (additional_context->IsJSObject()) { | 11774 if (additional_context->IsJSObject()) { |
11755 Handle<JSObject> extension = Handle<JSObject>::cast(additional_context); | 11775 Handle<JSObject> extension = Handle<JSObject>::cast(additional_context); |
11756 context = | 11776 context = |
11757 isolate->factory()->NewWithContext(go_between, context, extension); | 11777 isolate->factory()->NewWithContext(go_between, context, extension); |
11758 } | 11778 } |
11759 | 11779 |
11760 // Wrap the evaluation statement in a new function compiled in the newly | 11780 // Wrap the evaluation statement in a new function compiled in the newly |
11761 // created context. The function has one parameter which has to be called | 11781 // created context. The function has one parameter which has to be called |
11762 // 'arguments'. This it to have access to what would have been 'arguments' in | 11782 // 'arguments'. This it to have access to what would have been 'arguments' in |
(...skipping 1516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13279 // Handle last resort GC and make sure to allow future allocations | 13299 // Handle last resort GC and make sure to allow future allocations |
13280 // to grow the heap without causing GCs (if possible). | 13300 // to grow the heap without causing GCs (if possible). |
13281 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13301 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13282 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13302 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13283 "Runtime::PerformGC"); | 13303 "Runtime::PerformGC"); |
13284 } | 13304 } |
13285 } | 13305 } |
13286 | 13306 |
13287 | 13307 |
13288 } } // namespace v8::internal | 13308 } } // namespace v8::internal |
OLD | NEW |