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

Side by Side Diff: src/runtime.cc

Issue 8547007: Partially revert 9734 due to crashes in dev and canary channel. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 1 month 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 11198 matching lines...) Expand 10 before | Expand all | Expand 10 after
11209 }; 11209 };
11210 11210
11211 ScopeIterator(Isolate* isolate, 11211 ScopeIterator(Isolate* isolate,
11212 JavaScriptFrame* frame, 11212 JavaScriptFrame* frame,
11213 int inlined_frame_index) 11213 int inlined_frame_index)
11214 : isolate_(isolate), 11214 : isolate_(isolate),
11215 frame_(frame), 11215 frame_(frame),
11216 inlined_frame_index_(inlined_frame_index), 11216 inlined_frame_index_(inlined_frame_index),
11217 function_(JSFunction::cast(frame->function())), 11217 function_(JSFunction::cast(frame->function())),
11218 context_(Context::cast(frame->context())), 11218 context_(Context::cast(frame->context())),
11219 nested_scope_chain_(4) { 11219 local_done_(false),
11220 at_local_(false) {
11220 11221
11221 // Catch the case when the debugger stops in an internal function. 11222 // Check whether the first scope is actually a local scope.
11222 Handle<SharedFunctionInfo> shared_info(function_->shared()); 11223 // If there is a stack slot for .result then this local scope has been
11223 if (shared_info->script() == isolate->heap()->undefined_value()) { 11224 // created for evaluating top level code and it is not a real local scope.
11224 while (context_->closure() == *function_) {
11225 context_ = Handle<Context>(context_->previous(), isolate_);
11226 }
11227 return;
11228 }
11229
11230 // Check whether we are in global code or function code. If there is a stack
11231 // slot for .result then this function has been created for evaluating
11232 // global code and it is not a real function.
11233 // 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
11234 // saved with the code object does not otherwise have that information. 11226 // saved with the code object does not otherwise have that information.
11235 int index = shared_info->scope_info()-> 11227 int index = function_->shared()->scope_info()->
11236 StackSlotIndex(isolate_->heap()->result_symbol()); 11228 StackSlotIndex(isolate_->heap()->result_symbol());
11237
11238 // Reparse the code and analyze the scopes.
11239 ZoneScope zone_scope(isolate, DELETE_ON_EXIT);
11240 Handle<Script> script(Script::cast(shared_info->script()));
11241 Scope* scope;
11242 if (index >= 0) { 11229 if (index >= 0) {
11243 // Global code 11230 local_done_ = true;
11244 CompilationInfo info(script); 11231 } else if (context_->IsGlobalContext() ||
11245 info.MarkAsGlobal(); 11232 context_->IsFunctionContext()) {
11246 CHECK(ParserApi::Parse(&info)); 11233 at_local_ = true;
11247 CHECK(Scope::Analyze(&info)); 11234 } else if (context_->closure() != *function_) {
11248 scope = info.function()->scope(); 11235 // The context_ is a block or with or catch block from the outer function.
11249 } else { 11236 ASSERT(context_->IsWithContext() ||
11250 // Function code 11237 context_->IsCatchContext() ||
11251 CompilationInfo info(shared_info); 11238 context_->IsBlockContext());
11252 CHECK(ParserApi::Parse(&info)); 11239 at_local_ = true;
11253 CHECK(Scope::Analyze(&info));
11254 scope = info.function()->scope();
11255 } 11240 }
11256
11257 // Retrieve the scope chain for the current position.
11258 int statement_position =
11259 shared_info->code()->SourceStatementPosition(frame_->pc());
11260 scope->GetNestedScopeChain(&nested_scope_chain_, statement_position);
11261 } 11241 }
11262 11242
11263 // More scopes? 11243 // More scopes?
11264 bool Done() { return context_.is_null(); } 11244 bool Done() { return context_.is_null(); }
11265 11245
11266 // Move to the next scope. 11246 // Move to the next scope.
11267 void Next() { 11247 void Next() {
11268 ScopeType scope_type = Type(); 11248 // If at a local scope mark the local scope as passed.
11269 if (scope_type == ScopeTypeGlobal) { 11249 if (at_local_) {
11270 // The global scope is always the last in the chain. 11250 at_local_ = false;
11271 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()) {
11272 context_ = Handle<Context>(); 11263 context_ = Handle<Context>();
11273 return; 11264 return;
11274 } 11265 }
11275 if (nested_scope_chain_.is_empty()) { 11266
11276 context_ = Handle<Context>(context_->previous(), isolate_); 11267 // Move to the next context.
11277 } else { 11268 context_ = Handle<Context>(context_->previous(), isolate_);
11278 if (nested_scope_chain_.last()->HasContext()) { 11269
11279 context_ = Handle<Context>(context_->previous(), isolate_); 11270 // If passing the local scope indicate that the current scope is now the
11280 } 11271 // local scope.
11281 nested_scope_chain_.RemoveLast(); 11272 if (!local_done_ &&
11273 (context_->IsGlobalContext() || context_->IsFunctionContext())) {
11274 at_local_ = true;
11282 } 11275 }
11283 } 11276 }
11284 11277
11285 // Return the type of the current scope. 11278 // Return the type of the current scope.
11286 ScopeType Type() { 11279 ScopeType Type() {
11287 if (!nested_scope_chain_.is_empty()) { 11280 if (at_local_) {
11288 Handle<ScopeInfo> scope_info = nested_scope_chain_.last(); 11281 return ScopeTypeLocal;
11289 switch (scope_info->Type()) {
11290 case FUNCTION_SCOPE:
11291 ASSERT(context_->IsFunctionContext() ||
11292 !scope_info->HasContext());
11293 return ScopeTypeLocal;
11294 case GLOBAL_SCOPE:
11295 ASSERT(context_->IsGlobalContext());
11296 return ScopeTypeGlobal;
11297 case WITH_SCOPE:
11298 ASSERT(context_->IsWithContext());
11299 return ScopeTypeWith;
11300 case CATCH_SCOPE:
11301 ASSERT(context_->IsCatchContext());
11302 return ScopeTypeCatch;
11303 case BLOCK_SCOPE:
11304 ASSERT(!scope_info->HasContext() ||
11305 context_->IsBlockContext());
11306 return ScopeTypeBlock;
11307 case EVAL_SCOPE:
11308 UNREACHABLE();
11309 }
11310 } 11282 }
11311 if (context_->IsGlobalContext()) { 11283 if (context_->IsGlobalContext()) {
11312 ASSERT(context_->global()->IsGlobalObject()); 11284 ASSERT(context_->global()->IsGlobalObject());
11313 return ScopeTypeGlobal; 11285 return ScopeTypeGlobal;
11314 } 11286 }
11315 if (context_->IsFunctionContext()) { 11287 if (context_->IsFunctionContext()) {
11316 return ScopeTypeClosure; 11288 return ScopeTypeClosure;
11317 } 11289 }
11318 if (context_->IsCatchContext()) { 11290 if (context_->IsCatchContext()) {
11319 return ScopeTypeCatch; 11291 return ScopeTypeCatch;
11320 } 11292 }
11321 if (context_->IsBlockContext()) { 11293 if (context_->IsBlockContext()) {
11322 return ScopeTypeBlock; 11294 return ScopeTypeBlock;
11323 } 11295 }
11324 ASSERT(context_->IsWithContext()); 11296 ASSERT(context_->IsWithContext());
11325 return ScopeTypeWith; 11297 return ScopeTypeWith;
11326 } 11298 }
11327 11299
11328 // Return the JavaScript object with the content of the current scope. 11300 // Return the JavaScript object with the content of the current scope.
11329 Handle<JSObject> ScopeObject() { 11301 Handle<JSObject> ScopeObject() {
11330 switch (Type()) { 11302 switch (Type()) {
11331 case ScopeIterator::ScopeTypeGlobal: 11303 case ScopeIterator::ScopeTypeGlobal:
11332 return Handle<JSObject>(CurrentContext()->global()); 11304 return Handle<JSObject>(CurrentContext()->global());
11333 case ScopeIterator::ScopeTypeLocal: 11305 case ScopeIterator::ScopeTypeLocal:
11334 // Materialize the content of the local scope into a JSObject. 11306 // Materialize the content of the local scope into a JSObject.
11335 ASSERT(nested_scope_chain_.length() == 1);
11336 return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_); 11307 return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_);
11337 case ScopeIterator::ScopeTypeWith: 11308 case ScopeIterator::ScopeTypeWith:
11338 // Return the with object. 11309 // Return the with object.
11339 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); 11310 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
11340 case ScopeIterator::ScopeTypeCatch: 11311 case ScopeIterator::ScopeTypeCatch:
11341 return MaterializeCatchScope(isolate_, CurrentContext()); 11312 return MaterializeCatchScope(isolate_, CurrentContext());
11342 case ScopeIterator::ScopeTypeClosure: 11313 case ScopeIterator::ScopeTypeClosure:
11343 // Materialize the content of the closure scope into a JSObject. 11314 // Materialize the content of the closure scope into a JSObject.
11344 return MaterializeClosure(isolate_, CurrentContext()); 11315 return MaterializeClosure(isolate_, CurrentContext());
11345 case ScopeIterator::ScopeTypeBlock: 11316 case ScopeIterator::ScopeTypeBlock:
11346 return MaterializeBlockScope(isolate_, CurrentContext()); 11317 return MaterializeBlockScope(isolate_, CurrentContext());
11347 } 11318 }
11348 UNREACHABLE(); 11319 UNREACHABLE();
11349 return Handle<JSObject>(); 11320 return Handle<JSObject>();
11350 } 11321 }
11351 11322
11352 Handle<ScopeInfo> CurrentScopeInfo() {
11353 if (!nested_scope_chain_.is_empty()) {
11354 return nested_scope_chain_.last();
11355 } else if (context_->IsBlockContext()) {
11356 return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension()));
11357 } else if (context_->IsFunctionContext()) {
11358 return Handle<ScopeInfo>(context_->closure()->shared()->scope_info());
11359 }
11360 return Handle<ScopeInfo>::null();
11361 }
11362
11363 // 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
11364 // be an actual context. 11324 // be an actual context.
11365 Handle<Context> CurrentContext() { 11325 Handle<Context> CurrentContext() {
11366 if (Type() == ScopeTypeGlobal || 11326 if (at_local_ && context_->closure() != *function_) {
11367 nested_scope_chain_.is_empty()) {
11368 return context_;
11369 } else if (nested_scope_chain_.last()->HasContext()) {
11370 return context_;
11371 } else {
11372 return Handle<Context>(); 11327 return Handle<Context>();
11373 } 11328 }
11329 return context_;
11374 } 11330 }
11375 11331
11376 #ifdef DEBUG 11332 #ifdef DEBUG
11377 // Debug print of the content of the current scope. 11333 // Debug print of the content of the current scope.
11378 void DebugPrint() { 11334 void DebugPrint() {
11379 switch (Type()) { 11335 switch (Type()) {
11380 case ScopeIterator::ScopeTypeGlobal: 11336 case ScopeIterator::ScopeTypeGlobal:
11381 PrintF("Global:\n"); 11337 PrintF("Global:\n");
11382 CurrentContext()->Print(); 11338 CurrentContext()->Print();
11383 break; 11339 break;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
11425 PrintF("\n"); 11381 PrintF("\n");
11426 } 11382 }
11427 #endif 11383 #endif
11428 11384
11429 private: 11385 private:
11430 Isolate* isolate_; 11386 Isolate* isolate_;
11431 JavaScriptFrame* frame_; 11387 JavaScriptFrame* frame_;
11432 int inlined_frame_index_; 11388 int inlined_frame_index_;
11433 Handle<JSFunction> function_; 11389 Handle<JSFunction> function_;
11434 Handle<Context> context_; 11390 Handle<Context> context_;
11435 List<Handle<ScopeInfo> > nested_scope_chain_; 11391 bool local_done_;
11392 bool at_local_;
11436 11393
11437 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); 11394 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
11438 }; 11395 };
11439 11396
11440 11397
11441 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) { 11398 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) {
11442 HandleScope scope(isolate); 11399 HandleScope scope(isolate);
11443 ASSERT(args.length() == 2); 11400 ASSERT(args.length() == 2);
11444 11401
11445 // Check arguments. 11402 // Check arguments.
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
11888 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearStepping) { 11845 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearStepping) {
11889 HandleScope scope(isolate); 11846 HandleScope scope(isolate);
11890 ASSERT(args.length() == 0); 11847 ASSERT(args.length() == 0);
11891 isolate->debug()->ClearStepping(); 11848 isolate->debug()->ClearStepping();
11892 return isolate->heap()->undefined_value(); 11849 return isolate->heap()->undefined_value();
11893 } 11850 }
11894 11851
11895 11852
11896 // 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
11897 // is linked to the function context supplied. 11854 // is linked to the function context supplied.
11898 static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate, 11855 static Handle<Context> CopyWithContextChain(Isolate* isolate,
11899 Handle<JSFunction> function, 11856 Handle<JSFunction> function,
11900 Handle<Context> base, 11857 Handle<Context> current,
11901 JavaScriptFrame* frame, 11858 Handle<Context> base) {
11902 int inlined_frame_index) { 11859 // At the end of the chain. Return the base context to link to.
11903 HandleScope scope(isolate); 11860 if (current->IsFunctionContext() || current->IsGlobalContext()) {
11904 List<Handle<ScopeInfo> > scope_chain; 11861 return base;
11905 List<Handle<Context> > context_chain;
11906
11907 ScopeIterator it(isolate, frame, inlined_frame_index);
11908 for (; it.Type() != ScopeIterator::ScopeTypeGlobal &&
11909 it.Type() != ScopeIterator::ScopeTypeLocal ; it.Next()) {
11910 ASSERT(!it.Done());
11911 scope_chain.Add(it.CurrentScopeInfo());
11912 context_chain.Add(it.CurrentContext());
11913 } 11862 }
11914 11863
11915 // At the end of the chain. Return the base context to link to. 11864 // Recursively copy the with and catch contexts.
11916 Handle<Context> context = base; 11865 HandleScope scope(isolate);
11917 11866 Handle<Context> previous(current->previous());
11918 // Iteratively copy and or materialize the nested contexts. 11867 Handle<Context> new_previous =
11919 while (!scope_chain.is_empty()) { 11868 CopyWithContextChain(isolate, function, previous, base);
11920 Handle<ScopeInfo> scope_info = scope_chain.RemoveLast(); 11869 Handle<Context> new_current;
11921 Handle<Context> current = context_chain.RemoveLast(); 11870 if (current->IsCatchContext()) {
11922 ASSERT(!(scope_info->HasContext() & current.is_null())); 11871 Handle<String> name(String::cast(current->extension()));
11923 11872 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX));
11924 if (scope_info->Type() == CATCH_SCOPE) { 11873 new_current =
11925 Handle<String> name(String::cast(current->extension())); 11874 isolate->factory()->NewCatchContext(function,
11926 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX)); 11875 new_previous,
11927 context = 11876 name,
11928 isolate->factory()->NewCatchContext(function, 11877 thrown_object);
11929 context, 11878 } else if (current->IsBlockContext()) {
11930 name, 11879 Handle<ScopeInfo> scope_info(ScopeInfo::cast(current->extension()));
11931 thrown_object); 11880 new_current =
11932 } else if (scope_info->Type() == BLOCK_SCOPE) { 11881 isolate->factory()->NewBlockContext(function, new_previous, scope_info);
11933 // Materialize the contents of the block scope into a JSObject. 11882 // Copy context slots.
11934 Handle<JSObject> block_scope_object = 11883 int num_context_slots = scope_info->ContextLength();
11935 MaterializeBlockScope(isolate, current); 11884 for (int i = Context::MIN_CONTEXT_SLOTS; i < num_context_slots; ++i) {
11936 if (block_scope_object.is_null()) { 11885 new_current->set(i, current->get(i));
11937 return Handle<Context>::null();
11938 }
11939 // Allocate a new function context for the debug evaluation and set the
11940 // extension object.
11941 Handle<Context> new_context =
11942 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS,
11943 function);
11944 new_context->set_extension(*block_scope_object);
11945 new_context->set_previous(*context);
11946 context = new_context;
11947 } else {
11948 ASSERT(scope_info->Type() == WITH_SCOPE);
11949 ASSERT(current->IsWithContext());
11950 Handle<JSObject> extension(JSObject::cast(current->extension()));
11951 context =
11952 isolate->factory()->NewWithContext(function, context, extension);
11953 } 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);
11954 } 11892 }
11955 11893 return scope.CloseAndEscape(new_current);
11956 return scope.CloseAndEscape(context);
11957 } 11894 }
11958 11895
11959 11896
11960 // Helper function to find or create the arguments object for 11897 // Helper function to find or create the arguments object for
11961 // Runtime_DebugEvaluate. 11898 // Runtime_DebugEvaluate.
11962 static Handle<Object> GetArgumentsObject(Isolate* isolate, 11899 static Handle<Object> GetArgumentsObject(Isolate* isolate,
11963 JavaScriptFrame* frame, 11900 JavaScriptFrame* frame,
11964 int inlined_frame_index, 11901 int inlined_frame_index,
11965 Handle<JSFunction> function, 11902 Handle<JSFunction> function,
11966 Handle<ScopeInfo> scope_info, 11903 Handle<ScopeInfo> scope_info,
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
12081 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, 12018 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS,
12082 go_between); 12019 go_between);
12083 context->set_extension(*local_scope); 12020 context->set_extension(*local_scope);
12084 // 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.
12085 Handle<Context> frame_context(Context::cast(frame->context())); 12022 Handle<Context> frame_context(Context::cast(frame->context()));
12086 Handle<Context> function_context; 12023 Handle<Context> function_context;
12087 // Get the function's context if it has one. 12024 // Get the function's context if it has one.
12088 if (scope_info->HasContext()) { 12025 if (scope_info->HasContext()) {
12089 function_context = Handle<Context>(frame_context->declaration_context()); 12026 function_context = Handle<Context>(frame_context->declaration_context());
12090 } 12027 }
12091 context = CopyNestedScopeContextChain(isolate, 12028 context = CopyWithContextChain(isolate, go_between, frame_context, context);
12092 go_between,
12093 context,
12094 frame,
12095 inlined_frame_index);
12096 12029
12097 if (additional_context->IsJSObject()) { 12030 if (additional_context->IsJSObject()) {
12098 Handle<JSObject> extension = Handle<JSObject>::cast(additional_context); 12031 Handle<JSObject> extension = Handle<JSObject>::cast(additional_context);
12099 context = 12032 context =
12100 isolate->factory()->NewWithContext(go_between, context, extension); 12033 isolate->factory()->NewWithContext(go_between, context, extension);
12101 } 12034 }
12102 12035
12103 // 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
12104 // 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
12105 // '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
13540 } else { 13473 } else {
13541 // Handle last resort GC and make sure to allow future allocations 13474 // Handle last resort GC and make sure to allow future allocations
13542 // to grow the heap without causing GCs (if possible). 13475 // to grow the heap without causing GCs (if possible).
13543 isolate->counters()->gc_last_resort_from_js()->Increment(); 13476 isolate->counters()->gc_last_resort_from_js()->Increment();
13544 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); 13477 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags);
13545 } 13478 }
13546 } 13479 }
13547 13480
13548 13481
13549 } } // namespace v8::internal 13482 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698