| 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 1776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1787 | 1787 |
| 1788 Object* multiline = args[4]; | 1788 Object* multiline = args[4]; |
| 1789 if (!multiline->IsTrue()) multiline = isolate->heap()->false_value(); | 1789 if (!multiline->IsTrue()) multiline = isolate->heap()->false_value(); |
| 1790 | 1790 |
| 1791 Map* map = regexp->map(); | 1791 Map* map = regexp->map(); |
| 1792 Object* constructor = map->constructor(); | 1792 Object* constructor = map->constructor(); |
| 1793 if (constructor->IsJSFunction() && | 1793 if (constructor->IsJSFunction() && |
| 1794 JSFunction::cast(constructor)->initial_map() == map) { | 1794 JSFunction::cast(constructor)->initial_map() == map) { |
| 1795 // If we still have the original map, set in-object properties directly. | 1795 // If we still have the original map, set in-object properties directly. |
| 1796 regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, source); | 1796 regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, source); |
| 1797 // TODO(lrn): Consider skipping write barrier on booleans as well. | 1797 // Both true and false are immovable immortal objects so no need for write |
| 1798 // Both true and false should be in oldspace at all times. | 1798 // barrier. |
| 1799 regexp->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex, global); | 1799 regexp->InObjectPropertyAtPut( |
| 1800 regexp->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex, ignoreCase); | 1800 JSRegExp::kGlobalFieldIndex, global, SKIP_WRITE_BARRIER); |
| 1801 regexp->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex, multiline); | 1801 regexp->InObjectPropertyAtPut( |
| 1802 JSRegExp::kIgnoreCaseFieldIndex, ignoreCase, SKIP_WRITE_BARRIER); |
| 1803 regexp->InObjectPropertyAtPut( |
| 1804 JSRegExp::kMultilineFieldIndex, multiline, SKIP_WRITE_BARRIER); |
| 1802 regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, | 1805 regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, |
| 1803 Smi::FromInt(0), | 1806 Smi::FromInt(0), |
| 1804 SKIP_WRITE_BARRIER); // It's a Smi. | 1807 SKIP_WRITE_BARRIER); // It's a Smi. |
| 1805 return regexp; | 1808 return regexp; |
| 1806 } | 1809 } |
| 1807 | 1810 |
| 1808 // Map has changed, so use generic, but slower, method. | 1811 // Map has changed, so use generic, but slower, method. |
| 1809 PropertyAttributes final = | 1812 PropertyAttributes final = |
| 1810 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); | 1813 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); |
| 1811 PropertyAttributes writable = | 1814 PropertyAttributes writable = |
| (...skipping 9394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11206 }; | 11209 }; |
| 11207 | 11210 |
| 11208 ScopeIterator(Isolate* isolate, | 11211 ScopeIterator(Isolate* isolate, |
| 11209 JavaScriptFrame* frame, | 11212 JavaScriptFrame* frame, |
| 11210 int inlined_frame_index) | 11213 int inlined_frame_index) |
| 11211 : isolate_(isolate), | 11214 : isolate_(isolate), |
| 11212 frame_(frame), | 11215 frame_(frame), |
| 11213 inlined_frame_index_(inlined_frame_index), | 11216 inlined_frame_index_(inlined_frame_index), |
| 11214 function_(JSFunction::cast(frame->function())), | 11217 function_(JSFunction::cast(frame->function())), |
| 11215 context_(Context::cast(frame->context())), | 11218 context_(Context::cast(frame->context())), |
| 11216 nested_scope_chain_(4) { | 11219 local_done_(false), |
| 11220 at_local_(false) { |
| 11217 | 11221 |
| 11218 // Catch the case when the debugger stops in an internal function. | 11222 // Check whether the first scope is actually a local scope. |
| 11219 Handle<SharedFunctionInfo> shared_info(function_->shared()); | 11223 // If there is a stack slot for .result then this local scope has been |
| 11220 if (shared_info->script() == isolate->heap()->undefined_value()) { | 11224 // created for evaluating top level code and it is not a real local scope. |
| 11221 while (context_->closure() == *function_) { | |
| 11222 context_ = Handle<Context>(context_->previous(), isolate_); | |
| 11223 } | |
| 11224 return; | |
| 11225 } | |
| 11226 | |
| 11227 // Check whether we are in global code or function code. If there is a stack | |
| 11228 // slot for .result then this function has been created for evaluating | |
| 11229 // global code and it is not a real function. | |
| 11230 // Checking for the existence of .result seems fragile, but the scope info | 11225 // Checking for the existence of .result seems fragile, but the scope info |
| 11231 // saved with the code object does not otherwise have that information. | 11226 // saved with the code object does not otherwise have that information. |
| 11232 int index = shared_info->scope_info()-> | 11227 int index = function_->shared()->scope_info()-> |
| 11233 StackSlotIndex(isolate_->heap()->result_symbol()); | 11228 StackSlotIndex(isolate_->heap()->result_symbol()); |
| 11234 | |
| 11235 // Reparse the code and analyze the scopes. | |
| 11236 ZoneScope zone_scope(isolate, DELETE_ON_EXIT); | |
| 11237 Handle<Script> script(Script::cast(shared_info->script())); | |
| 11238 Scope* scope; | |
| 11239 if (index >= 0) { | 11229 if (index >= 0) { |
| 11240 // Global code | 11230 local_done_ = true; |
| 11241 CompilationInfo info(script); | 11231 } else if (context_->IsGlobalContext() || |
| 11242 info.MarkAsGlobal(); | 11232 context_->IsFunctionContext()) { |
| 11243 CHECK(ParserApi::Parse(&info)); | 11233 at_local_ = true; |
| 11244 CHECK(Scope::Analyze(&info)); | 11234 } else if (context_->closure() != *function_) { |
| 11245 scope = info.function()->scope(); | 11235 // The context_ is a block or with or catch block from the outer function. |
| 11246 } else { | 11236 ASSERT(context_->IsWithContext() || |
| 11247 // Function code | 11237 context_->IsCatchContext() || |
| 11248 CompilationInfo info(shared_info); | 11238 context_->IsBlockContext()); |
| 11249 CHECK(ParserApi::Parse(&info)); | 11239 at_local_ = true; |
| 11250 CHECK(Scope::Analyze(&info)); | |
| 11251 scope = info.function()->scope(); | |
| 11252 } | 11240 } |
| 11253 | |
| 11254 // Retrieve the scope chain for the current position. | |
| 11255 int statement_position = | |
| 11256 shared_info->code()->SourceStatementPosition(frame_->pc()); | |
| 11257 scope->GetNestedScopeChain(&nested_scope_chain_, statement_position); | |
| 11258 } | 11241 } |
| 11259 | 11242 |
| 11260 // More scopes? | 11243 // More scopes? |
| 11261 bool Done() { return context_.is_null(); } | 11244 bool Done() { return context_.is_null(); } |
| 11262 | 11245 |
| 11263 // Move to the next scope. | 11246 // Move to the next scope. |
| 11264 void Next() { | 11247 void Next() { |
| 11265 ScopeType scope_type = Type(); | 11248 // If at a local scope mark the local scope as passed. |
| 11266 if (scope_type == ScopeTypeGlobal) { | 11249 if (at_local_) { |
| 11267 // The global scope is always the last in the chain. | 11250 at_local_ = false; |
| 11268 ASSERT(context_->IsGlobalContext()); | 11251 local_done_ = true; |
| 11252 |
| 11253 // If the current context is not associated with the local scope the |
| 11254 // current context is the next real scope, so don't move to the next |
| 11255 // context in this case. |
| 11256 if (context_->closure() != *function_) { |
| 11257 return; |
| 11258 } |
| 11259 } |
| 11260 |
| 11261 // The global scope is always the last in the chain. |
| 11262 if (context_->IsGlobalContext()) { |
| 11269 context_ = Handle<Context>(); | 11263 context_ = Handle<Context>(); |
| 11270 return; | 11264 return; |
| 11271 } | 11265 } |
| 11272 if (nested_scope_chain_.is_empty()) { | 11266 |
| 11273 context_ = Handle<Context>(context_->previous(), isolate_); | 11267 // Move to the next context. |
| 11274 } else { | 11268 context_ = Handle<Context>(context_->previous(), isolate_); |
| 11275 if (nested_scope_chain_.last()->HasContext()) { | 11269 |
| 11276 context_ = Handle<Context>(context_->previous(), isolate_); | 11270 // If passing the local scope indicate that the current scope is now the |
| 11277 } | 11271 // local scope. |
| 11278 nested_scope_chain_.RemoveLast(); | 11272 if (!local_done_ && |
| 11273 (context_->IsGlobalContext() || context_->IsFunctionContext())) { |
| 11274 at_local_ = true; |
| 11279 } | 11275 } |
| 11280 } | 11276 } |
| 11281 | 11277 |
| 11282 // Return the type of the current scope. | 11278 // Return the type of the current scope. |
| 11283 ScopeType Type() { | 11279 ScopeType Type() { |
| 11284 if (!nested_scope_chain_.is_empty()) { | 11280 if (at_local_) { |
| 11285 Handle<ScopeInfo> scope_info = nested_scope_chain_.last(); | 11281 return ScopeTypeLocal; |
| 11286 switch (scope_info->Type()) { | |
| 11287 case FUNCTION_SCOPE: | |
| 11288 ASSERT(context_->IsFunctionContext() || | |
| 11289 !scope_info->HasContext()); | |
| 11290 return ScopeTypeLocal; | |
| 11291 case GLOBAL_SCOPE: | |
| 11292 ASSERT(context_->IsGlobalContext()); | |
| 11293 return ScopeTypeGlobal; | |
| 11294 case WITH_SCOPE: | |
| 11295 ASSERT(context_->IsWithContext()); | |
| 11296 return ScopeTypeWith; | |
| 11297 case CATCH_SCOPE: | |
| 11298 ASSERT(context_->IsCatchContext()); | |
| 11299 return ScopeTypeCatch; | |
| 11300 case BLOCK_SCOPE: | |
| 11301 ASSERT(!scope_info->HasContext() || | |
| 11302 context_->IsBlockContext()); | |
| 11303 return ScopeTypeBlock; | |
| 11304 case EVAL_SCOPE: | |
| 11305 UNREACHABLE(); | |
| 11306 } | |
| 11307 } | 11282 } |
| 11308 if (context_->IsGlobalContext()) { | 11283 if (context_->IsGlobalContext()) { |
| 11309 ASSERT(context_->global()->IsGlobalObject()); | 11284 ASSERT(context_->global()->IsGlobalObject()); |
| 11310 return ScopeTypeGlobal; | 11285 return ScopeTypeGlobal; |
| 11311 } | 11286 } |
| 11312 if (context_->IsFunctionContext()) { | 11287 if (context_->IsFunctionContext()) { |
| 11313 return ScopeTypeClosure; | 11288 return ScopeTypeClosure; |
| 11314 } | 11289 } |
| 11315 if (context_->IsCatchContext()) { | 11290 if (context_->IsCatchContext()) { |
| 11316 return ScopeTypeCatch; | 11291 return ScopeTypeCatch; |
| 11317 } | 11292 } |
| 11318 if (context_->IsBlockContext()) { | 11293 if (context_->IsBlockContext()) { |
| 11319 return ScopeTypeBlock; | 11294 return ScopeTypeBlock; |
| 11320 } | 11295 } |
| 11321 ASSERT(context_->IsWithContext()); | 11296 ASSERT(context_->IsWithContext()); |
| 11322 return ScopeTypeWith; | 11297 return ScopeTypeWith; |
| 11323 } | 11298 } |
| 11324 | 11299 |
| 11325 // Return the JavaScript object with the content of the current scope. | 11300 // Return the JavaScript object with the content of the current scope. |
| 11326 Handle<JSObject> ScopeObject() { | 11301 Handle<JSObject> ScopeObject() { |
| 11327 switch (Type()) { | 11302 switch (Type()) { |
| 11328 case ScopeIterator::ScopeTypeGlobal: | 11303 case ScopeIterator::ScopeTypeGlobal: |
| 11329 return Handle<JSObject>(CurrentContext()->global()); | 11304 return Handle<JSObject>(CurrentContext()->global()); |
| 11330 case ScopeIterator::ScopeTypeLocal: | 11305 case ScopeIterator::ScopeTypeLocal: |
| 11331 // Materialize the content of the local scope into a JSObject. | 11306 // Materialize the content of the local scope into a JSObject. |
| 11332 ASSERT(nested_scope_chain_.length() == 1); | |
| 11333 return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_); | 11307 return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_); |
| 11334 case ScopeIterator::ScopeTypeWith: | 11308 case ScopeIterator::ScopeTypeWith: |
| 11335 // Return the with object. | 11309 // Return the with object. |
| 11336 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); | 11310 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); |
| 11337 case ScopeIterator::ScopeTypeCatch: | 11311 case ScopeIterator::ScopeTypeCatch: |
| 11338 return MaterializeCatchScope(isolate_, CurrentContext()); | 11312 return MaterializeCatchScope(isolate_, CurrentContext()); |
| 11339 case ScopeIterator::ScopeTypeClosure: | 11313 case ScopeIterator::ScopeTypeClosure: |
| 11340 // Materialize the content of the closure scope into a JSObject. | 11314 // Materialize the content of the closure scope into a JSObject. |
| 11341 return MaterializeClosure(isolate_, CurrentContext()); | 11315 return MaterializeClosure(isolate_, CurrentContext()); |
| 11342 case ScopeIterator::ScopeTypeBlock: | 11316 case ScopeIterator::ScopeTypeBlock: |
| 11343 return MaterializeBlockScope(isolate_, CurrentContext()); | 11317 return MaterializeBlockScope(isolate_, CurrentContext()); |
| 11344 } | 11318 } |
| 11345 UNREACHABLE(); | 11319 UNREACHABLE(); |
| 11346 return Handle<JSObject>(); | 11320 return Handle<JSObject>(); |
| 11347 } | 11321 } |
| 11348 | 11322 |
| 11349 Handle<ScopeInfo> CurrentScopeInfo() { | |
| 11350 if (!nested_scope_chain_.is_empty()) { | |
| 11351 return nested_scope_chain_.last(); | |
| 11352 } else if (context_->IsBlockContext()) { | |
| 11353 return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension())); | |
| 11354 } else if (context_->IsFunctionContext()) { | |
| 11355 return Handle<ScopeInfo>(context_->closure()->shared()->scope_info()); | |
| 11356 } | |
| 11357 return Handle<ScopeInfo>::null(); | |
| 11358 } | |
| 11359 | |
| 11360 // Return the context for this scope. For the local context there might not | 11323 // Return the context for this scope. For the local context there might not |
| 11361 // be an actual context. | 11324 // be an actual context. |
| 11362 Handle<Context> CurrentContext() { | 11325 Handle<Context> CurrentContext() { |
| 11363 if (Type() == ScopeTypeGlobal || | 11326 if (at_local_ && context_->closure() != *function_) { |
| 11364 nested_scope_chain_.is_empty()) { | |
| 11365 return context_; | |
| 11366 } else if (nested_scope_chain_.last()->HasContext()) { | |
| 11367 return context_; | |
| 11368 } else { | |
| 11369 return Handle<Context>(); | 11327 return Handle<Context>(); |
| 11370 } | 11328 } |
| 11329 return context_; |
| 11371 } | 11330 } |
| 11372 | 11331 |
| 11373 #ifdef DEBUG | 11332 #ifdef DEBUG |
| 11374 // Debug print of the content of the current scope. | 11333 // Debug print of the content of the current scope. |
| 11375 void DebugPrint() { | 11334 void DebugPrint() { |
| 11376 switch (Type()) { | 11335 switch (Type()) { |
| 11377 case ScopeIterator::ScopeTypeGlobal: | 11336 case ScopeIterator::ScopeTypeGlobal: |
| 11378 PrintF("Global:\n"); | 11337 PrintF("Global:\n"); |
| 11379 CurrentContext()->Print(); | 11338 CurrentContext()->Print(); |
| 11380 break; | 11339 break; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11422 PrintF("\n"); | 11381 PrintF("\n"); |
| 11423 } | 11382 } |
| 11424 #endif | 11383 #endif |
| 11425 | 11384 |
| 11426 private: | 11385 private: |
| 11427 Isolate* isolate_; | 11386 Isolate* isolate_; |
| 11428 JavaScriptFrame* frame_; | 11387 JavaScriptFrame* frame_; |
| 11429 int inlined_frame_index_; | 11388 int inlined_frame_index_; |
| 11430 Handle<JSFunction> function_; | 11389 Handle<JSFunction> function_; |
| 11431 Handle<Context> context_; | 11390 Handle<Context> context_; |
| 11432 List<Handle<ScopeInfo> > nested_scope_chain_; | 11391 bool local_done_; |
| 11392 bool at_local_; |
| 11433 | 11393 |
| 11434 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); | 11394 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); |
| 11435 }; | 11395 }; |
| 11436 | 11396 |
| 11437 | 11397 |
| 11438 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) { | 11398 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) { |
| 11439 HandleScope scope(isolate); | 11399 HandleScope scope(isolate); |
| 11440 ASSERT(args.length() == 2); | 11400 ASSERT(args.length() == 2); |
| 11441 | 11401 |
| 11442 // Check arguments. | 11402 // Check arguments. |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11885 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearStepping) { | 11845 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearStepping) { |
| 11886 HandleScope scope(isolate); | 11846 HandleScope scope(isolate); |
| 11887 ASSERT(args.length() == 0); | 11847 ASSERT(args.length() == 0); |
| 11888 isolate->debug()->ClearStepping(); | 11848 isolate->debug()->ClearStepping(); |
| 11889 return isolate->heap()->undefined_value(); | 11849 return isolate->heap()->undefined_value(); |
| 11890 } | 11850 } |
| 11891 | 11851 |
| 11892 | 11852 |
| 11893 // Creates a copy of the with context chain. The copy of the context chain is | 11853 // Creates a copy of the with context chain. The copy of the context chain is |
| 11894 // is linked to the function context supplied. | 11854 // is linked to the function context supplied. |
| 11895 static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate, | 11855 static Handle<Context> CopyWithContextChain(Isolate* isolate, |
| 11896 Handle<JSFunction> function, | 11856 Handle<JSFunction> function, |
| 11897 Handle<Context> base, | 11857 Handle<Context> current, |
| 11898 JavaScriptFrame* frame, | 11858 Handle<Context> base) { |
| 11899 int inlined_frame_index) { | 11859 // At the end of the chain. Return the base context to link to. |
| 11900 HandleScope scope(isolate); | 11860 if (current->IsFunctionContext() || current->IsGlobalContext()) { |
| 11901 List<Handle<ScopeInfo> > scope_chain; | 11861 return base; |
| 11902 List<Handle<Context> > context_chain; | |
| 11903 | |
| 11904 ScopeIterator it(isolate, frame, inlined_frame_index); | |
| 11905 for (; it.Type() != ScopeIterator::ScopeTypeGlobal && | |
| 11906 it.Type() != ScopeIterator::ScopeTypeLocal ; it.Next()) { | |
| 11907 ASSERT(!it.Done()); | |
| 11908 scope_chain.Add(it.CurrentScopeInfo()); | |
| 11909 context_chain.Add(it.CurrentContext()); | |
| 11910 } | 11862 } |
| 11911 | 11863 |
| 11912 // At the end of the chain. Return the base context to link to. | 11864 // Recursively copy the with and catch contexts. |
| 11913 Handle<Context> context = base; | 11865 HandleScope scope(isolate); |
| 11914 | 11866 Handle<Context> previous(current->previous()); |
| 11915 // Iteratively copy and or materialize the nested contexts. | 11867 Handle<Context> new_previous = |
| 11916 while (!scope_chain.is_empty()) { | 11868 CopyWithContextChain(isolate, function, previous, base); |
| 11917 Handle<ScopeInfo> scope_info = scope_chain.RemoveLast(); | 11869 Handle<Context> new_current; |
| 11918 Handle<Context> current = context_chain.RemoveLast(); | 11870 if (current->IsCatchContext()) { |
| 11919 ASSERT(!(scope_info->HasContext() & current.is_null())); | 11871 Handle<String> name(String::cast(current->extension())); |
| 11920 | 11872 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX)); |
| 11921 if (scope_info->Type() == CATCH_SCOPE) { | 11873 new_current = |
| 11922 Handle<String> name(String::cast(current->extension())); | 11874 isolate->factory()->NewCatchContext(function, |
| 11923 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX)); | 11875 new_previous, |
| 11924 context = | 11876 name, |
| 11925 isolate->factory()->NewCatchContext(function, | 11877 thrown_object); |
| 11926 context, | 11878 } else if (current->IsBlockContext()) { |
| 11927 name, | 11879 Handle<ScopeInfo> scope_info(ScopeInfo::cast(current->extension())); |
| 11928 thrown_object); | 11880 new_current = |
| 11929 } else if (scope_info->Type() == BLOCK_SCOPE) { | 11881 isolate->factory()->NewBlockContext(function, new_previous, scope_info); |
| 11930 // Materialize the contents of the block scope into a JSObject. | 11882 // Copy context slots. |
| 11931 Handle<JSObject> block_scope_object = | 11883 int num_context_slots = scope_info->ContextLength(); |
| 11932 MaterializeBlockScope(isolate, current); | 11884 for (int i = Context::MIN_CONTEXT_SLOTS; i < num_context_slots; ++i) { |
| 11933 if (block_scope_object.is_null()) { | 11885 new_current->set(i, current->get(i)); |
| 11934 return Handle<Context>::null(); | |
| 11935 } | |
| 11936 // Allocate a new function context for the debug evaluation and set the | |
| 11937 // extension object. | |
| 11938 Handle<Context> new_context = | |
| 11939 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, | |
| 11940 function); | |
| 11941 new_context->set_extension(*block_scope_object); | |
| 11942 new_context->set_previous(*context); | |
| 11943 context = new_context; | |
| 11944 } else { | |
| 11945 ASSERT(scope_info->Type() == WITH_SCOPE); | |
| 11946 ASSERT(current->IsWithContext()); | |
| 11947 Handle<JSObject> extension(JSObject::cast(current->extension())); | |
| 11948 context = | |
| 11949 isolate->factory()->NewWithContext(function, context, extension); | |
| 11950 } | 11886 } |
| 11887 } else { |
| 11888 ASSERT(current->IsWithContext()); |
| 11889 Handle<JSObject> extension(JSObject::cast(current->extension())); |
| 11890 new_current = |
| 11891 isolate->factory()->NewWithContext(function, new_previous, extension); |
| 11951 } | 11892 } |
| 11952 | 11893 return scope.CloseAndEscape(new_current); |
| 11953 return scope.CloseAndEscape(context); | |
| 11954 } | 11894 } |
| 11955 | 11895 |
| 11956 | 11896 |
| 11957 // Helper function to find or create the arguments object for | 11897 // Helper function to find or create the arguments object for |
| 11958 // Runtime_DebugEvaluate. | 11898 // Runtime_DebugEvaluate. |
| 11959 static Handle<Object> GetArgumentsObject(Isolate* isolate, | 11899 static Handle<Object> GetArgumentsObject(Isolate* isolate, |
| 11960 JavaScriptFrame* frame, | 11900 JavaScriptFrame* frame, |
| 11961 int inlined_frame_index, | 11901 int inlined_frame_index, |
| 11962 Handle<JSFunction> function, | 11902 Handle<JSFunction> function, |
| 11963 Handle<ScopeInfo> scope_info, | 11903 Handle<ScopeInfo> scope_info, |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12078 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, | 12018 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, |
| 12079 go_between); | 12019 go_between); |
| 12080 context->set_extension(*local_scope); | 12020 context->set_extension(*local_scope); |
| 12081 // Copy any with contexts present and chain them in front of this context. | 12021 // Copy any with contexts present and chain them in front of this context. |
| 12082 Handle<Context> frame_context(Context::cast(frame->context())); | 12022 Handle<Context> frame_context(Context::cast(frame->context())); |
| 12083 Handle<Context> function_context; | 12023 Handle<Context> function_context; |
| 12084 // Get the function's context if it has one. | 12024 // Get the function's context if it has one. |
| 12085 if (scope_info->HasContext()) { | 12025 if (scope_info->HasContext()) { |
| 12086 function_context = Handle<Context>(frame_context->declaration_context()); | 12026 function_context = Handle<Context>(frame_context->declaration_context()); |
| 12087 } | 12027 } |
| 12088 context = CopyNestedScopeContextChain(isolate, | 12028 context = CopyWithContextChain(isolate, go_between, frame_context, context); |
| 12089 go_between, | |
| 12090 context, | |
| 12091 frame, | |
| 12092 inlined_frame_index); | |
| 12093 | 12029 |
| 12094 if (additional_context->IsJSObject()) { | 12030 if (additional_context->IsJSObject()) { |
| 12095 Handle<JSObject> extension = Handle<JSObject>::cast(additional_context); | 12031 Handle<JSObject> extension = Handle<JSObject>::cast(additional_context); |
| 12096 context = | 12032 context = |
| 12097 isolate->factory()->NewWithContext(go_between, context, extension); | 12033 isolate->factory()->NewWithContext(go_between, context, extension); |
| 12098 } | 12034 } |
| 12099 | 12035 |
| 12100 // Wrap the evaluation statement in a new function compiled in the newly | 12036 // Wrap the evaluation statement in a new function compiled in the newly |
| 12101 // created context. The function has one parameter which has to be called | 12037 // created context. The function has one parameter which has to be called |
| 12102 // 'arguments'. This it to have access to what would have been 'arguments' in | 12038 // '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... |
| 13537 } else { | 13473 } else { |
| 13538 // Handle last resort GC and make sure to allow future allocations | 13474 // Handle last resort GC and make sure to allow future allocations |
| 13539 // to grow the heap without causing GCs (if possible). | 13475 // to grow the heap without causing GCs (if possible). |
| 13540 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13476 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 13541 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); | 13477 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 13542 } | 13478 } |
| 13543 } | 13479 } |
| 13544 | 13480 |
| 13545 | 13481 |
| 13546 } } // namespace v8::internal | 13482 } } // namespace v8::internal |
| OLD | NEW |