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

Side by Side Diff: src/runtime.cc

Issue 7549008: Preliminary code for block scopes and block contexts. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Small fix: set harmony flag properly Created 9 years, 4 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/runtime.h ('k') | src/scopeinfo.h » ('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 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 8296 matching lines...) Expand 10 before | Expand all | Expand 10 after
8307 isolate->heap()->AllocateCatchContext(function, 8307 isolate->heap()->AllocateCatchContext(function,
8308 isolate->context(), 8308 isolate->context(),
8309 name, 8309 name,
8310 thrown_object); 8310 thrown_object);
8311 if (!maybe_context->To(&context)) return maybe_context; 8311 if (!maybe_context->To(&context)) return maybe_context;
8312 isolate->set_context(context); 8312 isolate->set_context(context);
8313 return context; 8313 return context;
8314 } 8314 }
8315 8315
8316 8316
8317 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushBlockContext) {
8318 NoHandleAllocation ha;
8319 ASSERT(args.length() == 2);
8320 SerializedScopeInfo* scope_info = SerializedScopeInfo::cast(args[0]);
8321 JSFunction* function;
8322 if (args[1]->IsSmi()) {
8323 // A smi sentinel indicates a context nested inside global code rather
8324 // than some function. There is a canonical empty function that can be
8325 // gotten from the global context.
8326 function = isolate->context()->global_context()->closure();
8327 } else {
8328 function = JSFunction::cast(args[1]);
8329 }
8330 Context* context;
8331 MaybeObject* maybe_context =
8332 isolate->heap()->AllocateBlockContext(function,
8333 isolate->context(),
8334 scope_info);
8335 if (!maybe_context->To(&context)) return maybe_context;
8336 isolate->set_context(context);
8337 return context;
8338 }
8339
8340
8317 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) { 8341 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) {
8318 HandleScope scope(isolate); 8342 HandleScope scope(isolate);
8319 ASSERT(args.length() == 2); 8343 ASSERT(args.length() == 2);
8320 8344
8321 CONVERT_ARG_CHECKED(Context, context, 0); 8345 CONVERT_ARG_CHECKED(Context, context, 0);
8322 CONVERT_ARG_CHECKED(String, name, 1); 8346 CONVERT_ARG_CHECKED(String, name, 1);
8323 8347
8324 int index; 8348 int index;
8325 PropertyAttributes attributes; 8349 PropertyAttributes attributes;
8326 ContextLookupFlags flags = FOLLOW_CHAINS; 8350 ContextLookupFlags flags = FOLLOW_CHAINS;
(...skipping 2305 matching lines...) Expand 10 before | Expand all | Expand 10 after
10632 Handle<JSObject> catch_scope = 10656 Handle<JSObject> catch_scope =
10633 isolate->factory()->NewJSObject(isolate->object_function()); 10657 isolate->factory()->NewJSObject(isolate->object_function());
10634 RETURN_IF_EMPTY_HANDLE_VALUE( 10658 RETURN_IF_EMPTY_HANDLE_VALUE(
10635 isolate, 10659 isolate,
10636 SetProperty(catch_scope, name, thrown_object, NONE, kNonStrictMode), 10660 SetProperty(catch_scope, name, thrown_object, NONE, kNonStrictMode),
10637 Handle<JSObject>()); 10661 Handle<JSObject>());
10638 return catch_scope; 10662 return catch_scope;
10639 } 10663 }
10640 10664
10641 10665
10666 // Create a plain JSObject which materializes the block scope for the specified
10667 // block context.
10668 static Handle<JSObject> MaterializeBlockScope(
10669 Isolate* isolate,
10670 Handle<Context> context) {
10671 ASSERT(context->IsBlockContext());
10672 Handle<SerializedScopeInfo> serialized_scope_info(
10673 SerializedScopeInfo::cast(context->extension()));
10674 ScopeInfo<> scope_info(*serialized_scope_info);
10675
10676 // Allocate and initialize a JSObject with all the arguments, stack locals
10677 // heap locals and extension properties of the debugged function.
10678 Handle<JSObject> block_scope =
10679 isolate->factory()->NewJSObject(isolate->object_function());
10680
10681 // Fill all context locals.
10682 if (scope_info.number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) {
10683 if (!CopyContextLocalsToScopeObject(isolate,
10684 serialized_scope_info, scope_info,
10685 context, block_scope)) {
10686 return Handle<JSObject>();
10687 }
10688 }
10689
10690 return block_scope;
10691 }
10692
10693
10642 // Iterate over the actual scopes visible from a stack frame. All scopes are 10694 // Iterate over the actual scopes visible from a stack frame. All scopes are
10643 // backed by an actual context except the local scope, which is inserted 10695 // backed by an actual context except the local scope, which is inserted
10644 // "artifically" in the context chain. 10696 // "artifically" in the context chain.
10645 class ScopeIterator { 10697 class ScopeIterator {
10646 public: 10698 public:
10647 enum ScopeType { 10699 enum ScopeType {
10648 ScopeTypeGlobal = 0, 10700 ScopeTypeGlobal = 0,
10649 ScopeTypeLocal, 10701 ScopeTypeLocal,
10650 ScopeTypeWith, 10702 ScopeTypeWith,
10651 ScopeTypeClosure, 10703 ScopeTypeClosure,
10652 ScopeTypeCatch 10704 ScopeTypeCatch,
10705 ScopeTypeBlock
10653 }; 10706 };
10654 10707
10655 ScopeIterator(Isolate* isolate, 10708 ScopeIterator(Isolate* isolate,
10656 JavaScriptFrame* frame, 10709 JavaScriptFrame* frame,
10657 int inlined_frame_index) 10710 int inlined_frame_index)
10658 : isolate_(isolate), 10711 : isolate_(isolate),
10659 frame_(frame), 10712 frame_(frame),
10660 inlined_frame_index_(inlined_frame_index), 10713 inlined_frame_index_(inlined_frame_index),
10661 function_(JSFunction::cast(frame->function())), 10714 function_(JSFunction::cast(frame->function())),
10662 context_(Context::cast(frame->context())), 10715 context_(Context::cast(frame->context())),
10663 local_done_(false), 10716 local_done_(false),
10664 at_local_(false) { 10717 at_local_(false) {
10665 10718
10666 // Check whether the first scope is actually a local scope. 10719 // Check whether the first scope is actually a local scope.
10667 if (context_->IsGlobalContext()) { 10720 if (context_->IsGlobalContext()) {
10668 // If there is a stack slot for .result then this local scope has been 10721 // If there is a stack slot for .result then this local scope has been
10669 // created for evaluating top level code and it is not a real local scope. 10722 // created for evaluating top level code and it is not a real local scope.
10670 // Checking for the existence of .result seems fragile, but the scope info 10723 // Checking for the existence of .result seems fragile, but the scope info
10671 // saved with the code object does not otherwise have that information. 10724 // saved with the code object does not otherwise have that information.
10672 int index = function_->shared()->scope_info()-> 10725 int index = function_->shared()->scope_info()->
10673 StackSlotIndex(isolate_->heap()->result_symbol()); 10726 StackSlotIndex(isolate_->heap()->result_symbol());
10674 at_local_ = index < 0; 10727 at_local_ = index < 0;
10675 } else if (context_->IsFunctionContext()) { 10728 } else if (context_->IsFunctionContext()) {
10676 at_local_ = true; 10729 at_local_ = true;
10677 } else if (context_->closure() != *function_) { 10730 } else if (context_->closure() != *function_) {
10678 // The context_ is a with or catch block from the outer function. 10731 // The context_ is a block or with or catch block from the outer function.
10679 ASSERT(context_->IsWithContext() || context_->IsCatchContext()); 10732 ASSERT(context_->IsWithContext() ||
10733 context_->IsCatchContext() ||
10734 context_->IsBlockContext());
10680 at_local_ = true; 10735 at_local_ = true;
10681 } 10736 }
10682 } 10737 }
10683 10738
10684 // More scopes? 10739 // More scopes?
10685 bool Done() { return context_.is_null(); } 10740 bool Done() { return context_.is_null(); }
10686 10741
10687 // Move to the next scope. 10742 // Move to the next scope.
10688 void Next() { 10743 void Next() {
10689 // If at a local scope mark the local scope as passed. 10744 // If at a local scope mark the local scope as passed.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
10724 if (context_->IsGlobalContext()) { 10779 if (context_->IsGlobalContext()) {
10725 ASSERT(context_->global()->IsGlobalObject()); 10780 ASSERT(context_->global()->IsGlobalObject());
10726 return ScopeTypeGlobal; 10781 return ScopeTypeGlobal;
10727 } 10782 }
10728 if (context_->IsFunctionContext()) { 10783 if (context_->IsFunctionContext()) {
10729 return ScopeTypeClosure; 10784 return ScopeTypeClosure;
10730 } 10785 }
10731 if (context_->IsCatchContext()) { 10786 if (context_->IsCatchContext()) {
10732 return ScopeTypeCatch; 10787 return ScopeTypeCatch;
10733 } 10788 }
10789 if (context_->IsBlockContext()) {
10790 return ScopeTypeBlock;
10791 }
10734 ASSERT(context_->IsWithContext()); 10792 ASSERT(context_->IsWithContext());
10735 return ScopeTypeWith; 10793 return ScopeTypeWith;
10736 } 10794 }
10737 10795
10738 // Return the JavaScript object with the content of the current scope. 10796 // Return the JavaScript object with the content of the current scope.
10739 Handle<JSObject> ScopeObject() { 10797 Handle<JSObject> ScopeObject() {
10740 switch (Type()) { 10798 switch (Type()) {
10741 case ScopeIterator::ScopeTypeGlobal: 10799 case ScopeIterator::ScopeTypeGlobal:
10742 return Handle<JSObject>(CurrentContext()->global()); 10800 return Handle<JSObject>(CurrentContext()->global());
10743 case ScopeIterator::ScopeTypeLocal: 10801 case ScopeIterator::ScopeTypeLocal:
10744 // Materialize the content of the local scope into a JSObject. 10802 // Materialize the content of the local scope into a JSObject.
10745 return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_); 10803 return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_);
10746 case ScopeIterator::ScopeTypeWith: 10804 case ScopeIterator::ScopeTypeWith:
10747 // Return the with object. 10805 // Return the with object.
10748 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); 10806 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
10749 case ScopeIterator::ScopeTypeCatch: 10807 case ScopeIterator::ScopeTypeCatch:
10750 return MaterializeCatchScope(isolate_, CurrentContext()); 10808 return MaterializeCatchScope(isolate_, CurrentContext());
10751 case ScopeIterator::ScopeTypeClosure: 10809 case ScopeIterator::ScopeTypeClosure:
10752 // Materialize the content of the closure scope into a JSObject. 10810 // Materialize the content of the closure scope into a JSObject.
10753 return MaterializeClosure(isolate_, CurrentContext()); 10811 return MaterializeClosure(isolate_, CurrentContext());
10812 case ScopeIterator::ScopeTypeBlock:
10813 return MaterializeBlockScope(isolate_, CurrentContext());
10754 } 10814 }
10755 UNREACHABLE(); 10815 UNREACHABLE();
10756 return Handle<JSObject>(); 10816 return Handle<JSObject>();
10757 } 10817 }
10758 10818
10759 // Return the context for this scope. For the local context there might not 10819 // Return the context for this scope. For the local context there might not
10760 // be an actual context. 10820 // be an actual context.
10761 Handle<Context> CurrentContext() { 10821 Handle<Context> CurrentContext() {
10762 if (at_local_ && context_->closure() != *function_) { 10822 if (at_local_ && context_->closure() != *function_) {
10763 return Handle<Context>(); 10823 return Handle<Context>();
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
11300 CopyWithContextChain(isolate, function, previous, base); 11360 CopyWithContextChain(isolate, function, previous, base);
11301 Handle<Context> new_current; 11361 Handle<Context> new_current;
11302 if (current->IsCatchContext()) { 11362 if (current->IsCatchContext()) {
11303 Handle<String> name(String::cast(current->extension())); 11363 Handle<String> name(String::cast(current->extension()));
11304 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX)); 11364 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX));
11305 new_current = 11365 new_current =
11306 isolate->factory()->NewCatchContext(function, 11366 isolate->factory()->NewCatchContext(function,
11307 new_previous, 11367 new_previous,
11308 name, 11368 name,
11309 thrown_object); 11369 thrown_object);
11370 } else if (current->IsBlockContext()) {
11371 Handle<SerializedScopeInfo> scope_info(
11372 SerializedScopeInfo::cast(current->extension()));
11373 new_current =
11374 isolate->factory()->NewBlockContext(function, new_previous, scope_info);
11310 } else { 11375 } else {
11376 ASSERT(current->IsWithContext());
11311 Handle<JSObject> extension(JSObject::cast(current->extension())); 11377 Handle<JSObject> extension(JSObject::cast(current->extension()));
11312 new_current = 11378 new_current =
11313 isolate->factory()->NewWithContext(function, new_previous, extension); 11379 isolate->factory()->NewWithContext(function, new_previous, extension);
11314 } 11380 }
11315 return scope.CloseAndEscape(new_current); 11381 return scope.CloseAndEscape(new_current);
11316 } 11382 }
11317 11383
11318 11384
11319 // Helper function to find or create the arguments object for 11385 // Helper function to find or create the arguments object for
11320 // Runtime_DebugEvaluate. 11386 // Runtime_DebugEvaluate.
(...skipping 1516 matching lines...) Expand 10 before | Expand all | Expand 10 after
12837 } else { 12903 } else {
12838 // Handle last resort GC and make sure to allow future allocations 12904 // Handle last resort GC and make sure to allow future allocations
12839 // to grow the heap without causing GCs (if possible). 12905 // to grow the heap without causing GCs (if possible).
12840 isolate->counters()->gc_last_resort_from_js()->Increment(); 12906 isolate->counters()->gc_last_resort_from_js()->Increment();
12841 isolate->heap()->CollectAllGarbage(false); 12907 isolate->heap()->CollectAllGarbage(false);
12842 } 12908 }
12843 } 12909 }
12844 12910
12845 12911
12846 } } // namespace v8::internal 12912 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/scopeinfo.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698