Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(312)

Side by Side Diff: src/runtime.cc

Issue 10914290: Fix debugger's eval when close to stack overflow. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/debug.cc ('k') | test/mjsunit/regress/regress-2318.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 10825 matching lines...) Expand 10 before | Expand all | Expand 10 after
10836 }; 10836 };
10837 10837
10838 ScopeIterator(Isolate* isolate, 10838 ScopeIterator(Isolate* isolate,
10839 JavaScriptFrame* frame, 10839 JavaScriptFrame* frame,
10840 int inlined_jsframe_index) 10840 int inlined_jsframe_index)
10841 : isolate_(isolate), 10841 : isolate_(isolate),
10842 frame_(frame), 10842 frame_(frame),
10843 inlined_jsframe_index_(inlined_jsframe_index), 10843 inlined_jsframe_index_(inlined_jsframe_index),
10844 function_(JSFunction::cast(frame->function())), 10844 function_(JSFunction::cast(frame->function())),
10845 context_(Context::cast(frame->context())), 10845 context_(Context::cast(frame->context())),
10846 nested_scope_chain_(4) { 10846 nested_scope_chain_(4),
10847 failed_(false) {
10847 10848
10848 // Catch the case when the debugger stops in an internal function. 10849 // Catch the case when the debugger stops in an internal function.
10849 Handle<SharedFunctionInfo> shared_info(function_->shared()); 10850 Handle<SharedFunctionInfo> shared_info(function_->shared());
10850 Handle<ScopeInfo> scope_info(shared_info->scope_info()); 10851 Handle<ScopeInfo> scope_info(shared_info->scope_info());
10851 if (shared_info->script() == isolate->heap()->undefined_value()) { 10852 if (shared_info->script() == isolate->heap()->undefined_value()) {
10852 while (context_->closure() == *function_) { 10853 while (context_->closure() == *function_) {
10853 context_ = Handle<Context>(context_->previous(), isolate_); 10854 context_ = Handle<Context>(context_->previous(), isolate_);
10854 } 10855 }
10855 return; 10856 return;
10856 } 10857 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
10910 } 10911 }
10911 } 10912 }
10912 } 10913 }
10913 10914
10914 ScopeIterator(Isolate* isolate, 10915 ScopeIterator(Isolate* isolate,
10915 Handle<JSFunction> function) 10916 Handle<JSFunction> function)
10916 : isolate_(isolate), 10917 : isolate_(isolate),
10917 frame_(NULL), 10918 frame_(NULL),
10918 inlined_jsframe_index_(0), 10919 inlined_jsframe_index_(0),
10919 function_(function), 10920 function_(function),
10920 context_(function->context()) { 10921 context_(function->context()),
10922 failed_(false) {
10921 if (function->IsBuiltin()) { 10923 if (function->IsBuiltin()) {
10922 context_ = Handle<Context>(); 10924 context_ = Handle<Context>();
10923 } 10925 }
10924 } 10926 }
10925 10927
10926 // More scopes? 10928 // More scopes?
10927 bool Done() { return context_.is_null(); } 10929 bool Done() {
10930 ASSERT(!failed_);
10931 return context_.is_null();
10932 }
10933
10934 bool Failed() { return failed_; }
10928 10935
10929 // Move to the next scope. 10936 // Move to the next scope.
10930 void Next() { 10937 void Next() {
10938 ASSERT(!failed_);
10931 ScopeType scope_type = Type(); 10939 ScopeType scope_type = Type();
10932 if (scope_type == ScopeTypeGlobal) { 10940 if (scope_type == ScopeTypeGlobal) {
10933 // The global scope is always the last in the chain. 10941 // The global scope is always the last in the chain.
10934 ASSERT(context_->IsNativeContext()); 10942 ASSERT(context_->IsNativeContext());
10935 context_ = Handle<Context>(); 10943 context_ = Handle<Context>();
10936 return; 10944 return;
10937 } 10945 }
10938 if (nested_scope_chain_.is_empty()) { 10946 if (nested_scope_chain_.is_empty()) {
10939 context_ = Handle<Context>(context_->previous(), isolate_); 10947 context_ = Handle<Context>(context_->previous(), isolate_);
10940 } else { 10948 } else {
10941 if (nested_scope_chain_.last()->HasContext()) { 10949 if (nested_scope_chain_.last()->HasContext()) {
10942 ASSERT(context_->previous() != NULL); 10950 ASSERT(context_->previous() != NULL);
10943 context_ = Handle<Context>(context_->previous(), isolate_); 10951 context_ = Handle<Context>(context_->previous(), isolate_);
10944 } 10952 }
10945 nested_scope_chain_.RemoveLast(); 10953 nested_scope_chain_.RemoveLast();
10946 } 10954 }
10947 } 10955 }
10948 10956
10949 // Return the type of the current scope. 10957 // Return the type of the current scope.
10950 ScopeType Type() { 10958 ScopeType Type() {
10959 ASSERT(!failed_);
10951 if (!nested_scope_chain_.is_empty()) { 10960 if (!nested_scope_chain_.is_empty()) {
10952 Handle<ScopeInfo> scope_info = nested_scope_chain_.last(); 10961 Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
10953 switch (scope_info->Type()) { 10962 switch (scope_info->Type()) {
10954 case FUNCTION_SCOPE: 10963 case FUNCTION_SCOPE:
10955 ASSERT(context_->IsFunctionContext() || 10964 ASSERT(context_->IsFunctionContext() ||
10956 !scope_info->HasContext()); 10965 !scope_info->HasContext());
10957 return ScopeTypeLocal; 10966 return ScopeTypeLocal;
10958 case MODULE_SCOPE: 10967 case MODULE_SCOPE:
10959 ASSERT(context_->IsModuleContext()); 10968 ASSERT(context_->IsModuleContext());
10960 return ScopeTypeModule; 10969 return ScopeTypeModule;
(...skipping 29 matching lines...) Expand all
10990 } 10999 }
10991 if (context_->IsModuleContext()) { 11000 if (context_->IsModuleContext()) {
10992 return ScopeTypeModule; 11001 return ScopeTypeModule;
10993 } 11002 }
10994 ASSERT(context_->IsWithContext()); 11003 ASSERT(context_->IsWithContext());
10995 return ScopeTypeWith; 11004 return ScopeTypeWith;
10996 } 11005 }
10997 11006
10998 // Return the JavaScript object with the content of the current scope. 11007 // Return the JavaScript object with the content of the current scope.
10999 Handle<JSObject> ScopeObject() { 11008 Handle<JSObject> ScopeObject() {
11009 ASSERT(!failed_);
11000 switch (Type()) { 11010 switch (Type()) {
11001 case ScopeIterator::ScopeTypeGlobal: 11011 case ScopeIterator::ScopeTypeGlobal:
11002 return Handle<JSObject>(CurrentContext()->global_object()); 11012 return Handle<JSObject>(CurrentContext()->global_object());
11003 case ScopeIterator::ScopeTypeLocal: 11013 case ScopeIterator::ScopeTypeLocal:
11004 // Materialize the content of the local scope into a JSObject. 11014 // Materialize the content of the local scope into a JSObject.
11005 ASSERT(nested_scope_chain_.length() == 1); 11015 ASSERT(nested_scope_chain_.length() == 1);
11006 return MaterializeLocalScope(isolate_, frame_, inlined_jsframe_index_); 11016 return MaterializeLocalScope(isolate_, frame_, inlined_jsframe_index_);
11007 case ScopeIterator::ScopeTypeWith: 11017 case ScopeIterator::ScopeTypeWith:
11008 // Return the with object. 11018 // Return the with object.
11009 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); 11019 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
11010 case ScopeIterator::ScopeTypeCatch: 11020 case ScopeIterator::ScopeTypeCatch:
11011 return MaterializeCatchScope(isolate_, CurrentContext()); 11021 return MaterializeCatchScope(isolate_, CurrentContext());
11012 case ScopeIterator::ScopeTypeClosure: 11022 case ScopeIterator::ScopeTypeClosure:
11013 // Materialize the content of the closure scope into a JSObject. 11023 // Materialize the content of the closure scope into a JSObject.
11014 return MaterializeClosure(isolate_, CurrentContext()); 11024 return MaterializeClosure(isolate_, CurrentContext());
11015 case ScopeIterator::ScopeTypeBlock: 11025 case ScopeIterator::ScopeTypeBlock:
11016 return MaterializeBlockScope(isolate_, CurrentContext()); 11026 return MaterializeBlockScope(isolate_, CurrentContext());
11017 case ScopeIterator::ScopeTypeModule: 11027 case ScopeIterator::ScopeTypeModule:
11018 return MaterializeModuleScope(isolate_, CurrentContext()); 11028 return MaterializeModuleScope(isolate_, CurrentContext());
11019 } 11029 }
11020 UNREACHABLE(); 11030 UNREACHABLE();
11021 return Handle<JSObject>(); 11031 return Handle<JSObject>();
11022 } 11032 }
11023 11033
11024 Handle<ScopeInfo> CurrentScopeInfo() { 11034 Handle<ScopeInfo> CurrentScopeInfo() {
11035 ASSERT(!failed_);
11025 if (!nested_scope_chain_.is_empty()) { 11036 if (!nested_scope_chain_.is_empty()) {
11026 return nested_scope_chain_.last(); 11037 return nested_scope_chain_.last();
11027 } else if (context_->IsBlockContext()) { 11038 } else if (context_->IsBlockContext()) {
11028 return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension())); 11039 return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension()));
11029 } else if (context_->IsFunctionContext()) { 11040 } else if (context_->IsFunctionContext()) {
11030 return Handle<ScopeInfo>(context_->closure()->shared()->scope_info()); 11041 return Handle<ScopeInfo>(context_->closure()->shared()->scope_info());
11031 } 11042 }
11032 return Handle<ScopeInfo>::null(); 11043 return Handle<ScopeInfo>::null();
11033 } 11044 }
11034 11045
11035 // Return the context for this scope. For the local context there might not 11046 // Return the context for this scope. For the local context there might not
11036 // be an actual context. 11047 // be an actual context.
11037 Handle<Context> CurrentContext() { 11048 Handle<Context> CurrentContext() {
11049 ASSERT(!failed_);
11038 if (Type() == ScopeTypeGlobal || 11050 if (Type() == ScopeTypeGlobal ||
11039 nested_scope_chain_.is_empty()) { 11051 nested_scope_chain_.is_empty()) {
11040 return context_; 11052 return context_;
11041 } else if (nested_scope_chain_.last()->HasContext()) { 11053 } else if (nested_scope_chain_.last()->HasContext()) {
11042 return context_; 11054 return context_;
11043 } else { 11055 } else {
11044 return Handle<Context>(); 11056 return Handle<Context>();
11045 } 11057 }
11046 } 11058 }
11047 11059
11048 #ifdef DEBUG 11060 #ifdef DEBUG
11049 // Debug print of the content of the current scope. 11061 // Debug print of the content of the current scope.
11050 void DebugPrint() { 11062 void DebugPrint() {
11063 ASSERT(!failed_);
11051 switch (Type()) { 11064 switch (Type()) {
11052 case ScopeIterator::ScopeTypeGlobal: 11065 case ScopeIterator::ScopeTypeGlobal:
11053 PrintF("Global:\n"); 11066 PrintF("Global:\n");
11054 CurrentContext()->Print(); 11067 CurrentContext()->Print();
11055 break; 11068 break;
11056 11069
11057 case ScopeIterator::ScopeTypeLocal: { 11070 case ScopeIterator::ScopeTypeLocal: {
11058 PrintF("Local:\n"); 11071 PrintF("Local:\n");
11059 function_->shared()->scope_info()->Print(); 11072 function_->shared()->scope_info()->Print();
11060 if (!CurrentContext().is_null()) { 11073 if (!CurrentContext().is_null()) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
11098 } 11111 }
11099 #endif 11112 #endif
11100 11113
11101 private: 11114 private:
11102 Isolate* isolate_; 11115 Isolate* isolate_;
11103 JavaScriptFrame* frame_; 11116 JavaScriptFrame* frame_;
11104 int inlined_jsframe_index_; 11117 int inlined_jsframe_index_;
11105 Handle<JSFunction> function_; 11118 Handle<JSFunction> function_;
11106 Handle<Context> context_; 11119 Handle<Context> context_;
11107 List<Handle<ScopeInfo> > nested_scope_chain_; 11120 List<Handle<ScopeInfo> > nested_scope_chain_;
11121 bool failed_;
11108 11122
11109 void RetrieveScopeChain(Scope* scope, 11123 void RetrieveScopeChain(Scope* scope,
11110 Handle<SharedFunctionInfo> shared_info) { 11124 Handle<SharedFunctionInfo> shared_info) {
11111 if (scope != NULL) { 11125 if (scope != NULL) {
11112 int source_position = shared_info->code()->SourcePosition(frame_->pc()); 11126 int source_position = shared_info->code()->SourcePosition(frame_->pc());
11113 scope->GetNestedScopeChain(&nested_scope_chain_, source_position); 11127 scope->GetNestedScopeChain(&nested_scope_chain_, source_position);
11114 } else { 11128 } else {
11115 // A failed reparse indicates that the preparser has diverged from the 11129 // A failed reparse indicates that the preparser has diverged from the
11116 // parser or that the preparse data given to the initial parse has been 11130 // parser or that the preparse data given to the initial parse has been
11117 // faulty. We fail in debug mode but in release mode we only provide the 11131 // faulty. We fail in debug mode but in release mode we only provide the
11118 // information we get from the context chain but nothing about 11132 // information we get from the context chain but nothing about
11119 // completely stack allocated scopes or stack allocated locals. 11133 // completely stack allocated scopes or stack allocated locals.
11120 UNREACHABLE(); 11134 // Or it could be due to stack overflow.
11135 ASSERT(isolate_->has_pending_exception());
11136 failed_ = true;
11121 } 11137 }
11122 } 11138 }
11123 11139
11124 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); 11140 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
11125 }; 11141 };
11126 11142
11127 11143
11128 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) { 11144 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) {
11129 HandleScope scope(isolate); 11145 HandleScope scope(isolate);
11130 ASSERT(args.length() == 2); 11146 ASSERT(args.length() == 2);
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
11535 static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate, 11551 static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate,
11536 Handle<JSFunction> function, 11552 Handle<JSFunction> function,
11537 Handle<Context> base, 11553 Handle<Context> base,
11538 JavaScriptFrame* frame, 11554 JavaScriptFrame* frame,
11539 int inlined_jsframe_index) { 11555 int inlined_jsframe_index) {
11540 HandleScope scope(isolate); 11556 HandleScope scope(isolate);
11541 List<Handle<ScopeInfo> > scope_chain; 11557 List<Handle<ScopeInfo> > scope_chain;
11542 List<Handle<Context> > context_chain; 11558 List<Handle<Context> > context_chain;
11543 11559
11544 ScopeIterator it(isolate, frame, inlined_jsframe_index); 11560 ScopeIterator it(isolate, frame, inlined_jsframe_index);
11561 if (it.Failed()) return Handle<Context>::null();
11562
11545 for (; it.Type() != ScopeIterator::ScopeTypeGlobal && 11563 for (; it.Type() != ScopeIterator::ScopeTypeGlobal &&
11546 it.Type() != ScopeIterator::ScopeTypeLocal ; it.Next()) { 11564 it.Type() != ScopeIterator::ScopeTypeLocal ; it.Next()) {
11547 ASSERT(!it.Done()); 11565 ASSERT(!it.Done());
11548 scope_chain.Add(it.CurrentScopeInfo()); 11566 scope_chain.Add(it.CurrentScopeInfo());
11549 context_chain.Add(it.CurrentContext()); 11567 context_chain.Add(it.CurrentContext());
11550 } 11568 }
11551 11569
11552 // At the end of the chain. Return the base context to link to. 11570 // At the end of the chain. Return the base context to link to.
11553 Handle<Context> context = base; 11571 Handle<Context> context = base;
11554 11572
11555 // Iteratively copy and or materialize the nested contexts. 11573 // Iteratively copy and or materialize the nested contexts.
11556 while (!scope_chain.is_empty()) { 11574 while (!scope_chain.is_empty()) {
11557 Handle<ScopeInfo> scope_info = scope_chain.RemoveLast(); 11575 Handle<ScopeInfo> scope_info = scope_chain.RemoveLast();
11558 Handle<Context> current = context_chain.RemoveLast(); 11576 Handle<Context> current = context_chain.RemoveLast();
11559 ASSERT(!(scope_info->HasContext() & current.is_null())); 11577 ASSERT(!(scope_info->HasContext() & current.is_null()));
11560 11578
11561 if (scope_info->Type() == CATCH_SCOPE) { 11579 if (scope_info->Type() == CATCH_SCOPE) {
11562 Handle<String> name(String::cast(current->extension())); 11580 Handle<String> name(String::cast(current->extension()));
11563 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX)); 11581 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX));
11564 context = 11582 context =
11565 isolate->factory()->NewCatchContext(function, 11583 isolate->factory()->NewCatchContext(function,
11566 context, 11584 context,
11567 name, 11585 name,
11568 thrown_object); 11586 thrown_object);
11569 } else if (scope_info->Type() == BLOCK_SCOPE) { 11587 } else if (scope_info->Type() == BLOCK_SCOPE) {
11570 // Materialize the contents of the block scope into a JSObject. 11588 // Materialize the contents of the block scope into a JSObject.
11571 Handle<JSObject> block_scope_object = 11589 Handle<JSObject> block_scope_object =
11572 MaterializeBlockScope(isolate, current); 11590 MaterializeBlockScope(isolate, current);
11573 if (block_scope_object.is_null()) { 11591 CHECK(!block_scope_object.is_null());
11574 return Handle<Context>::null();
11575 }
11576 // Allocate a new function context for the debug evaluation and set the 11592 // Allocate a new function context for the debug evaluation and set the
11577 // extension object. 11593 // extension object.
11578 Handle<Context> new_context = 11594 Handle<Context> new_context =
11579 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, 11595 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS,
11580 function); 11596 function);
11581 new_context->set_extension(*block_scope_object); 11597 new_context->set_extension(*block_scope_object);
11582 new_context->set_previous(*context); 11598 new_context->set_previous(*context);
11583 context = new_context; 11599 context = new_context;
11584 } else { 11600 } else {
11585 ASSERT(scope_info->Type() == WITH_SCOPE); 11601 ASSERT(scope_info->Type() == WITH_SCOPE);
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
11726 Handle<Context> function_context; 11742 Handle<Context> function_context;
11727 // Get the function's context if it has one. 11743 // Get the function's context if it has one.
11728 if (scope_info->HasContext()) { 11744 if (scope_info->HasContext()) {
11729 function_context = Handle<Context>(frame_context->declaration_context()); 11745 function_context = Handle<Context>(frame_context->declaration_context());
11730 } 11746 }
11731 context = CopyNestedScopeContextChain(isolate, 11747 context = CopyNestedScopeContextChain(isolate,
11732 go_between, 11748 go_between,
11733 context, 11749 context,
11734 frame, 11750 frame,
11735 inlined_jsframe_index); 11751 inlined_jsframe_index);
11752 if (context.is_null()) {
11753 ASSERT(isolate->has_pending_exception());
11754 MaybeObject* exception = isolate->pending_exception();
11755 isolate->clear_pending_exception();
11756 return exception;
11757 }
11736 11758
11737 if (additional_context->IsJSObject()) { 11759 if (additional_context->IsJSObject()) {
11738 Handle<JSObject> extension = Handle<JSObject>::cast(additional_context); 11760 Handle<JSObject> extension = Handle<JSObject>::cast(additional_context);
11739 context = 11761 context =
11740 isolate->factory()->NewWithContext(go_between, context, extension); 11762 isolate->factory()->NewWithContext(go_between, context, extension);
11741 } 11763 }
11742 11764
11743 // Wrap the evaluation statement in a new function compiled in the newly 11765 // Wrap the evaluation statement in a new function compiled in the newly
11744 // created context. The function has one parameter which has to be called 11766 // created context. The function has one parameter which has to be called
11745 // 'arguments'. This it to have access to what would have been 'arguments' in 11767 // '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
13262 // Handle last resort GC and make sure to allow future allocations 13284 // Handle last resort GC and make sure to allow future allocations
13263 // to grow the heap without causing GCs (if possible). 13285 // to grow the heap without causing GCs (if possible).
13264 isolate->counters()->gc_last_resort_from_js()->Increment(); 13286 isolate->counters()->gc_last_resort_from_js()->Increment();
13265 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13287 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13266 "Runtime::PerformGC"); 13288 "Runtime::PerformGC");
13267 } 13289 }
13268 } 13290 }
13269 13291
13270 13292
13271 } } // namespace v8::internal 13293 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/debug.cc ('k') | test/mjsunit/regress/regress-2318.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698