| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 11164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11175 }; | 11175 }; |
| 11176 | 11176 |
| 11177 ScopeIterator(Isolate* isolate, | 11177 ScopeIterator(Isolate* isolate, |
| 11178 JavaScriptFrame* frame, | 11178 JavaScriptFrame* frame, |
| 11179 int inlined_frame_index) | 11179 int inlined_frame_index) |
| 11180 : isolate_(isolate), | 11180 : isolate_(isolate), |
| 11181 frame_(frame), | 11181 frame_(frame), |
| 11182 inlined_frame_index_(inlined_frame_index), | 11182 inlined_frame_index_(inlined_frame_index), |
| 11183 function_(JSFunction::cast(frame->function())), | 11183 function_(JSFunction::cast(frame->function())), |
| 11184 context_(Context::cast(frame->context())), | 11184 context_(Context::cast(frame->context())), |
| 11185 local_done_(false), | 11185 nested_scope_chain_(4) { |
| 11186 at_local_(false) { | |
| 11187 | 11186 |
| 11188 // Check whether the first scope is actually a local scope. | 11187 // Catch the case when the debugger stops in an internal function. |
| 11189 // If there is a stack slot for .result then this local scope has been | 11188 Handle<SharedFunctionInfo> shared_info(function_->shared()); |
| 11190 // created for evaluating top level code and it is not a real local scope. | 11189 Handle<ScopeInfo> scope_info(shared_info->scope_info()); |
| 11191 // Checking for the existence of .result seems fragile, but the scope info | 11190 if (shared_info->script() == isolate->heap()->undefined_value()) { |
| 11192 // saved with the code object does not otherwise have that information. | 11191 while (context_->closure() == *function_) { |
| 11193 int index = function_->shared()->scope_info()-> | 11192 context_ = Handle<Context>(context_->previous(), isolate_); |
| 11194 StackSlotIndex(isolate_->heap()->result_symbol()); | 11193 } |
| 11195 if (index >= 0) { | 11194 return; |
| 11196 local_done_ = true; | 11195 } |
| 11197 } else if (context_->IsGlobalContext() || | 11196 |
| 11198 context_->IsFunctionContext()) { | 11197 // Get the start of the frame exit code. |
| 11199 at_local_ = true; | 11198 Handle<Code> code(shared_info->code()); |
| 11200 } else if (context_->closure() != *function_) { | 11199 RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::JS_RETURN)); |
| 11201 // The context_ is a block or with or catch block from the outer function. | 11200 RelocInfo* info = it.rinfo(); |
| 11202 ASSERT(context_->IsWithContext() || | 11201 Address frame_exit_code = info->pc(); |
| 11203 context_->IsCatchContext() || | 11202 it.next(); |
| 11204 context_->IsBlockContext()); | 11203 ASSERT(it.done()); |
| 11205 at_local_ = true; | 11204 |
| 11205 Address frame_exit_return = |
| 11206 frame_exit_code + Assembler::kCallInstructionLength; |
| 11207 if (frame_->pc() == frame_exit_return) { |
| 11208 // We are within the return sequence. At the momemt it is not possible to |
| 11209 // get a source position which is consistent with the current scope chain. |
| 11210 // Thus all nested with, catch and block contexts are skipped and we only |
| 11211 // provide the function scope. |
| 11212 if (scope_info->HasContext()) { |
| 11213 context_ = Handle<Context>(context_->declaration_context(), isolate_); |
| 11214 } else { |
| 11215 while (context_->closure() == *function_) { |
| 11216 context_ = Handle<Context>(context_->previous(), isolate_); |
| 11217 } |
| 11218 } |
| 11219 if (scope_info->Type() != EVAL_SCOPE) nested_scope_chain_.Add(scope_info); |
| 11220 } else { |
| 11221 // Reparse the code and analyze the scopes. |
| 11222 ZoneScope zone_scope(isolate, DELETE_ON_EXIT); |
| 11223 Handle<Script> script(Script::cast(shared_info->script())); |
| 11224 Scope* scope = NULL; |
| 11225 |
| 11226 // Check whether we are in global, eval or function code. |
| 11227 Handle<ScopeInfo> scope_info(shared_info->scope_info()); |
| 11228 if (scope_info->Type() != FUNCTION_SCOPE) { |
| 11229 // Global or eval code. |
| 11230 CompilationInfo info(script); |
| 11231 ScriptDataImpl* pre_data = NULL; |
| 11232 if (scope_info->Type() == GLOBAL_SCOPE) { |
| 11233 int flags = kNoParsingFlags; |
| 11234 if (info.is_native() || FLAG_allow_natives_syntax) { |
| 11235 flags |= kAllowNativesSyntax; |
| 11236 } |
| 11237 if (!info.is_native() && FLAG_harmony_scoping) { |
| 11238 flags |= kHarmonyScoping; |
| 11239 } |
| 11240 Handle<String> source(String::cast(script->source())); |
| 11241 if (source->length() >= FLAG_min_preparse_length) { |
| 11242 pre_data = ParserApi::PartialPreParse(source, NULL, flags); |
| 11243 info.SetPreParseData(pre_data); |
| 11244 } |
| 11245 info.MarkAsGlobal(); |
| 11246 } else { |
| 11247 ASSERT(scope_info->Type() == EVAL_SCOPE); |
| 11248 info.MarkAsEval(); |
| 11249 info.SetCallingContext(Handle<Context>(function_->context())); |
| 11250 } |
| 11251 if (ParserApi::Parse(&info) && Scope::Analyze(&info)) { |
| 11252 scope = info.function()->scope(); |
| 11253 } |
| 11254 // Delete preparse data again. |
| 11255 if (pre_data != NULL) { |
| 11256 delete pre_data; |
| 11257 } |
| 11258 } else { |
| 11259 // Function code |
| 11260 CompilationInfo info(shared_info); |
| 11261 if (ParserApi::Parse(&info) && Scope::Analyze(&info)) { |
| 11262 scope = info.function()->scope(); |
| 11263 } |
| 11264 } |
| 11265 |
| 11266 // Retrieve the scope chain for the current position. |
| 11267 if (scope != NULL) { |
| 11268 int source_position = shared_info->code()->SourcePosition(frame_->pc()); |
| 11269 scope->GetNestedScopeChain(&nested_scope_chain_, source_position); |
| 11270 } else { |
| 11271 // A failed reparse indicates that the preparser has diverged from the |
| 11272 // parser or that the preparse data given to the initial parse has been |
| 11273 // faulty. We fail in debug mode but in release mode we only provide the |
| 11274 // information we get from the context chain but nothing about |
| 11275 // completely stack allocated scopes or stack allocated locals. |
| 11276 UNREACHABLE(); |
| 11277 } |
| 11206 } | 11278 } |
| 11207 } | 11279 } |
| 11208 | 11280 |
| 11209 // More scopes? | 11281 // More scopes? |
| 11210 bool Done() { return context_.is_null(); } | 11282 bool Done() { return context_.is_null(); } |
| 11211 | 11283 |
| 11212 // Move to the next scope. | 11284 // Move to the next scope. |
| 11213 void Next() { | 11285 void Next() { |
| 11214 // If at a local scope mark the local scope as passed. | 11286 ScopeType scope_type = Type(); |
| 11215 if (at_local_) { | 11287 if (scope_type == ScopeTypeGlobal) { |
| 11216 at_local_ = false; | 11288 // The global scope is always the last in the chain. |
| 11217 local_done_ = true; | 11289 ASSERT(context_->IsGlobalContext()); |
| 11218 | |
| 11219 // If the current context is not associated with the local scope the | |
| 11220 // current context is the next real scope, so don't move to the next | |
| 11221 // context in this case. | |
| 11222 if (context_->closure() != *function_) { | |
| 11223 return; | |
| 11224 } | |
| 11225 } | |
| 11226 | |
| 11227 // The global scope is always the last in the chain. | |
| 11228 if (context_->IsGlobalContext()) { | |
| 11229 context_ = Handle<Context>(); | 11290 context_ = Handle<Context>(); |
| 11230 return; | 11291 return; |
| 11231 } | 11292 } |
| 11232 | 11293 if (nested_scope_chain_.is_empty()) { |
| 11233 // Move to the next context. | 11294 context_ = Handle<Context>(context_->previous(), isolate_); |
| 11234 context_ = Handle<Context>(context_->previous(), isolate_); | 11295 } else { |
| 11235 | 11296 if (nested_scope_chain_.last()->HasContext()) { |
| 11236 // If passing the local scope indicate that the current scope is now the | 11297 ASSERT(context_->previous() != NULL); |
| 11237 // local scope. | 11298 context_ = Handle<Context>(context_->previous(), isolate_); |
| 11238 if (!local_done_ && | 11299 } |
| 11239 (context_->IsGlobalContext() || context_->IsFunctionContext())) { | 11300 nested_scope_chain_.RemoveLast(); |
| 11240 at_local_ = true; | |
| 11241 } | 11301 } |
| 11242 } | 11302 } |
| 11243 | 11303 |
| 11244 // Return the type of the current scope. | 11304 // Return the type of the current scope. |
| 11245 ScopeType Type() { | 11305 ScopeType Type() { |
| 11246 if (at_local_) { | 11306 if (!nested_scope_chain_.is_empty()) { |
| 11247 return ScopeTypeLocal; | 11307 Handle<ScopeInfo> scope_info = nested_scope_chain_.last(); |
| 11308 switch (scope_info->Type()) { |
| 11309 case FUNCTION_SCOPE: |
| 11310 ASSERT(context_->IsFunctionContext() || |
| 11311 !scope_info->HasContext()); |
| 11312 return ScopeTypeLocal; |
| 11313 case GLOBAL_SCOPE: |
| 11314 ASSERT(context_->IsGlobalContext()); |
| 11315 return ScopeTypeGlobal; |
| 11316 case WITH_SCOPE: |
| 11317 ASSERT(context_->IsWithContext()); |
| 11318 return ScopeTypeWith; |
| 11319 case CATCH_SCOPE: |
| 11320 ASSERT(context_->IsCatchContext()); |
| 11321 return ScopeTypeCatch; |
| 11322 case BLOCK_SCOPE: |
| 11323 ASSERT(!scope_info->HasContext() || |
| 11324 context_->IsBlockContext()); |
| 11325 return ScopeTypeBlock; |
| 11326 case EVAL_SCOPE: |
| 11327 UNREACHABLE(); |
| 11328 } |
| 11248 } | 11329 } |
| 11249 if (context_->IsGlobalContext()) { | 11330 if (context_->IsGlobalContext()) { |
| 11250 ASSERT(context_->global()->IsGlobalObject()); | 11331 ASSERT(context_->global()->IsGlobalObject()); |
| 11251 return ScopeTypeGlobal; | 11332 return ScopeTypeGlobal; |
| 11252 } | 11333 } |
| 11253 if (context_->IsFunctionContext()) { | 11334 if (context_->IsFunctionContext()) { |
| 11254 return ScopeTypeClosure; | 11335 return ScopeTypeClosure; |
| 11255 } | 11336 } |
| 11256 if (context_->IsCatchContext()) { | 11337 if (context_->IsCatchContext()) { |
| 11257 return ScopeTypeCatch; | 11338 return ScopeTypeCatch; |
| 11258 } | 11339 } |
| 11259 if (context_->IsBlockContext()) { | 11340 if (context_->IsBlockContext()) { |
| 11260 return ScopeTypeBlock; | 11341 return ScopeTypeBlock; |
| 11261 } | 11342 } |
| 11262 ASSERT(context_->IsWithContext()); | 11343 ASSERT(context_->IsWithContext()); |
| 11263 return ScopeTypeWith; | 11344 return ScopeTypeWith; |
| 11264 } | 11345 } |
| 11265 | 11346 |
| 11266 // Return the JavaScript object with the content of the current scope. | 11347 // Return the JavaScript object with the content of the current scope. |
| 11267 Handle<JSObject> ScopeObject() { | 11348 Handle<JSObject> ScopeObject() { |
| 11268 switch (Type()) { | 11349 switch (Type()) { |
| 11269 case ScopeIterator::ScopeTypeGlobal: | 11350 case ScopeIterator::ScopeTypeGlobal: |
| 11270 return Handle<JSObject>(CurrentContext()->global()); | 11351 return Handle<JSObject>(CurrentContext()->global()); |
| 11271 case ScopeIterator::ScopeTypeLocal: | 11352 case ScopeIterator::ScopeTypeLocal: |
| 11272 // Materialize the content of the local scope into a JSObject. | 11353 // Materialize the content of the local scope into a JSObject. |
| 11354 ASSERT(nested_scope_chain_.length() == 1); |
| 11273 return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_); | 11355 return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_); |
| 11274 case ScopeIterator::ScopeTypeWith: | 11356 case ScopeIterator::ScopeTypeWith: |
| 11275 // Return the with object. | 11357 // Return the with object. |
| 11276 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); | 11358 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); |
| 11277 case ScopeIterator::ScopeTypeCatch: | 11359 case ScopeIterator::ScopeTypeCatch: |
| 11278 return MaterializeCatchScope(isolate_, CurrentContext()); | 11360 return MaterializeCatchScope(isolate_, CurrentContext()); |
| 11279 case ScopeIterator::ScopeTypeClosure: | 11361 case ScopeIterator::ScopeTypeClosure: |
| 11280 // Materialize the content of the closure scope into a JSObject. | 11362 // Materialize the content of the closure scope into a JSObject. |
| 11281 return MaterializeClosure(isolate_, CurrentContext()); | 11363 return MaterializeClosure(isolate_, CurrentContext()); |
| 11282 case ScopeIterator::ScopeTypeBlock: | 11364 case ScopeIterator::ScopeTypeBlock: |
| 11283 return MaterializeBlockScope(isolate_, CurrentContext()); | 11365 return MaterializeBlockScope(isolate_, CurrentContext()); |
| 11284 } | 11366 } |
| 11285 UNREACHABLE(); | 11367 UNREACHABLE(); |
| 11286 return Handle<JSObject>(); | 11368 return Handle<JSObject>(); |
| 11287 } | 11369 } |
| 11288 | 11370 |
| 11371 Handle<ScopeInfo> CurrentScopeInfo() { |
| 11372 if (!nested_scope_chain_.is_empty()) { |
| 11373 return nested_scope_chain_.last(); |
| 11374 } else if (context_->IsBlockContext()) { |
| 11375 return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension())); |
| 11376 } else if (context_->IsFunctionContext()) { |
| 11377 return Handle<ScopeInfo>(context_->closure()->shared()->scope_info()); |
| 11378 } |
| 11379 return Handle<ScopeInfo>::null(); |
| 11380 } |
| 11381 |
| 11289 // Return the context for this scope. For the local context there might not | 11382 // Return the context for this scope. For the local context there might not |
| 11290 // be an actual context. | 11383 // be an actual context. |
| 11291 Handle<Context> CurrentContext() { | 11384 Handle<Context> CurrentContext() { |
| 11292 if (at_local_ && context_->closure() != *function_) { | 11385 if (Type() == ScopeTypeGlobal || |
| 11386 nested_scope_chain_.is_empty()) { |
| 11387 return context_; |
| 11388 } else if (nested_scope_chain_.last()->HasContext()) { |
| 11389 return context_; |
| 11390 } else { |
| 11293 return Handle<Context>(); | 11391 return Handle<Context>(); |
| 11294 } | 11392 } |
| 11295 return context_; | |
| 11296 } | 11393 } |
| 11297 | 11394 |
| 11298 #ifdef DEBUG | 11395 #ifdef DEBUG |
| 11299 // Debug print of the content of the current scope. | 11396 // Debug print of the content of the current scope. |
| 11300 void DebugPrint() { | 11397 void DebugPrint() { |
| 11301 switch (Type()) { | 11398 switch (Type()) { |
| 11302 case ScopeIterator::ScopeTypeGlobal: | 11399 case ScopeIterator::ScopeTypeGlobal: |
| 11303 PrintF("Global:\n"); | 11400 PrintF("Global:\n"); |
| 11304 CurrentContext()->Print(); | 11401 CurrentContext()->Print(); |
| 11305 break; | 11402 break; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11347 PrintF("\n"); | 11444 PrintF("\n"); |
| 11348 } | 11445 } |
| 11349 #endif | 11446 #endif |
| 11350 | 11447 |
| 11351 private: | 11448 private: |
| 11352 Isolate* isolate_; | 11449 Isolate* isolate_; |
| 11353 JavaScriptFrame* frame_; | 11450 JavaScriptFrame* frame_; |
| 11354 int inlined_frame_index_; | 11451 int inlined_frame_index_; |
| 11355 Handle<JSFunction> function_; | 11452 Handle<JSFunction> function_; |
| 11356 Handle<Context> context_; | 11453 Handle<Context> context_; |
| 11357 bool local_done_; | 11454 List<Handle<ScopeInfo> > nested_scope_chain_; |
| 11358 bool at_local_; | |
| 11359 | 11455 |
| 11360 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); | 11456 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); |
| 11361 }; | 11457 }; |
| 11362 | 11458 |
| 11363 | 11459 |
| 11364 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) { | 11460 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) { |
| 11365 HandleScope scope(isolate); | 11461 HandleScope scope(isolate); |
| 11366 ASSERT(args.length() == 2); | 11462 ASSERT(args.length() == 2); |
| 11367 | 11463 |
| 11368 // Check arguments. | 11464 // Check arguments. |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11811 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearStepping) { | 11907 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearStepping) { |
| 11812 HandleScope scope(isolate); | 11908 HandleScope scope(isolate); |
| 11813 ASSERT(args.length() == 0); | 11909 ASSERT(args.length() == 0); |
| 11814 isolate->debug()->ClearStepping(); | 11910 isolate->debug()->ClearStepping(); |
| 11815 return isolate->heap()->undefined_value(); | 11911 return isolate->heap()->undefined_value(); |
| 11816 } | 11912 } |
| 11817 | 11913 |
| 11818 | 11914 |
| 11819 // Creates a copy of the with context chain. The copy of the context chain is | 11915 // Creates a copy of the with context chain. The copy of the context chain is |
| 11820 // is linked to the function context supplied. | 11916 // is linked to the function context supplied. |
| 11821 static Handle<Context> CopyWithContextChain(Isolate* isolate, | 11917 static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate, |
| 11822 Handle<JSFunction> function, | 11918 Handle<JSFunction> function, |
| 11823 Handle<Context> current, | 11919 Handle<Context> base, |
| 11824 Handle<Context> base) { | 11920 JavaScriptFrame* frame, |
| 11825 // At the end of the chain. Return the base context to link to. | 11921 int inlined_frame_index) { |
| 11826 if (current->IsFunctionContext() || current->IsGlobalContext()) { | 11922 HandleScope scope(isolate); |
| 11827 return base; | 11923 List<Handle<ScopeInfo> > scope_chain; |
| 11924 List<Handle<Context> > context_chain; |
| 11925 |
| 11926 ScopeIterator it(isolate, frame, inlined_frame_index); |
| 11927 for (; it.Type() != ScopeIterator::ScopeTypeGlobal && |
| 11928 it.Type() != ScopeIterator::ScopeTypeLocal ; it.Next()) { |
| 11929 ASSERT(!it.Done()); |
| 11930 scope_chain.Add(it.CurrentScopeInfo()); |
| 11931 context_chain.Add(it.CurrentContext()); |
| 11828 } | 11932 } |
| 11829 | 11933 |
| 11830 // Recursively copy the with and catch contexts. | 11934 // At the end of the chain. Return the base context to link to. |
| 11831 HandleScope scope(isolate); | 11935 Handle<Context> context = base; |
| 11832 Handle<Context> previous(current->previous()); | 11936 |
| 11833 Handle<Context> new_previous = | 11937 // Iteratively copy and or materialize the nested contexts. |
| 11834 CopyWithContextChain(isolate, function, previous, base); | 11938 while (!scope_chain.is_empty()) { |
| 11835 Handle<Context> new_current; | 11939 Handle<ScopeInfo> scope_info = scope_chain.RemoveLast(); |
| 11836 if (current->IsCatchContext()) { | 11940 Handle<Context> current = context_chain.RemoveLast(); |
| 11837 Handle<String> name(String::cast(current->extension())); | 11941 ASSERT(!(scope_info->HasContext() & current.is_null())); |
| 11838 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX)); | 11942 |
| 11839 new_current = | 11943 if (scope_info->Type() == CATCH_SCOPE) { |
| 11840 isolate->factory()->NewCatchContext(function, | 11944 Handle<String> name(String::cast(current->extension())); |
| 11841 new_previous, | 11945 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX)); |
| 11842 name, | 11946 context = |
| 11843 thrown_object); | 11947 isolate->factory()->NewCatchContext(function, |
| 11844 } else if (current->IsBlockContext()) { | 11948 context, |
| 11845 Handle<ScopeInfo> scope_info(ScopeInfo::cast(current->extension())); | 11949 name, |
| 11846 new_current = | 11950 thrown_object); |
| 11847 isolate->factory()->NewBlockContext(function, new_previous, scope_info); | 11951 } else if (scope_info->Type() == BLOCK_SCOPE) { |
| 11848 // Copy context slots. | 11952 // Materialize the contents of the block scope into a JSObject. |
| 11849 int num_context_slots = scope_info->ContextLength(); | 11953 Handle<JSObject> block_scope_object = |
| 11850 for (int i = Context::MIN_CONTEXT_SLOTS; i < num_context_slots; ++i) { | 11954 MaterializeBlockScope(isolate, current); |
| 11851 new_current->set(i, current->get(i)); | 11955 if (block_scope_object.is_null()) { |
| 11956 return Handle<Context>::null(); |
| 11957 } |
| 11958 // Allocate a new function context for the debug evaluation and set the |
| 11959 // extension object. |
| 11960 Handle<Context> new_context = |
| 11961 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, |
| 11962 function); |
| 11963 new_context->set_extension(*block_scope_object); |
| 11964 new_context->set_previous(*context); |
| 11965 context = new_context; |
| 11966 } else { |
| 11967 ASSERT(scope_info->Type() == WITH_SCOPE); |
| 11968 ASSERT(current->IsWithContext()); |
| 11969 Handle<JSObject> extension(JSObject::cast(current->extension())); |
| 11970 context = |
| 11971 isolate->factory()->NewWithContext(function, context, extension); |
| 11852 } | 11972 } |
| 11853 } else { | |
| 11854 ASSERT(current->IsWithContext()); | |
| 11855 Handle<JSObject> extension(JSObject::cast(current->extension())); | |
| 11856 new_current = | |
| 11857 isolate->factory()->NewWithContext(function, new_previous, extension); | |
| 11858 } | 11973 } |
| 11859 return scope.CloseAndEscape(new_current); | 11974 |
| 11975 return scope.CloseAndEscape(context); |
| 11860 } | 11976 } |
| 11861 | 11977 |
| 11862 | 11978 |
| 11863 // Helper function to find or create the arguments object for | 11979 // Helper function to find or create the arguments object for |
| 11864 // Runtime_DebugEvaluate. | 11980 // Runtime_DebugEvaluate. |
| 11865 static Handle<Object> GetArgumentsObject(Isolate* isolate, | 11981 static Handle<Object> GetArgumentsObject(Isolate* isolate, |
| 11866 JavaScriptFrame* frame, | 11982 JavaScriptFrame* frame, |
| 11867 int inlined_frame_index, | 11983 int inlined_frame_index, |
| 11868 Handle<JSFunction> function, | 11984 Handle<JSFunction> function, |
| 11869 Handle<ScopeInfo> scope_info, | 11985 Handle<ScopeInfo> scope_info, |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11984 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, | 12100 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, |
| 11985 go_between); | 12101 go_between); |
| 11986 context->set_extension(*local_scope); | 12102 context->set_extension(*local_scope); |
| 11987 // Copy any with contexts present and chain them in front of this context. | 12103 // Copy any with contexts present and chain them in front of this context. |
| 11988 Handle<Context> frame_context(Context::cast(frame->context())); | 12104 Handle<Context> frame_context(Context::cast(frame->context())); |
| 11989 Handle<Context> function_context; | 12105 Handle<Context> function_context; |
| 11990 // Get the function's context if it has one. | 12106 // Get the function's context if it has one. |
| 11991 if (scope_info->HasContext()) { | 12107 if (scope_info->HasContext()) { |
| 11992 function_context = Handle<Context>(frame_context->declaration_context()); | 12108 function_context = Handle<Context>(frame_context->declaration_context()); |
| 11993 } | 12109 } |
| 11994 context = CopyWithContextChain(isolate, go_between, frame_context, context); | 12110 context = CopyNestedScopeContextChain(isolate, |
| 12111 go_between, |
| 12112 context, |
| 12113 frame, |
| 12114 inlined_frame_index); |
| 11995 | 12115 |
| 11996 if (additional_context->IsJSObject()) { | 12116 if (additional_context->IsJSObject()) { |
| 11997 Handle<JSObject> extension = Handle<JSObject>::cast(additional_context); | 12117 Handle<JSObject> extension = Handle<JSObject>::cast(additional_context); |
| 11998 context = | 12118 context = |
| 11999 isolate->factory()->NewWithContext(go_between, context, extension); | 12119 isolate->factory()->NewWithContext(go_between, context, extension); |
| 12000 } | 12120 } |
| 12001 | 12121 |
| 12002 // Wrap the evaluation statement in a new function compiled in the newly | 12122 // Wrap the evaluation statement in a new function compiled in the newly |
| 12003 // created context. The function has one parameter which has to be called | 12123 // created context. The function has one parameter which has to be called |
| 12004 // 'arguments'. This it to have access to what would have been 'arguments' in | 12124 // 'arguments'. This it to have access to what would have been 'arguments' in |
| (...skipping 1434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13439 } else { | 13559 } else { |
| 13440 // Handle last resort GC and make sure to allow future allocations | 13560 // Handle last resort GC and make sure to allow future allocations |
| 13441 // to grow the heap without causing GCs (if possible). | 13561 // to grow the heap without causing GCs (if possible). |
| 13442 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13562 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 13443 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); | 13563 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 13444 } | 13564 } |
| 13445 } | 13565 } |
| 13446 | 13566 |
| 13447 | 13567 |
| 13448 } } // namespace v8::internal | 13568 } } // namespace v8::internal |
| OLD | NEW |