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