Revision: 8231
Author: [email protected]
Date: Thu Jun 9 04:26:01 2011
Log: A collection of context-related refactoring changes.
Introduce separate maps for function and with contexts. Use the function
context map for testing whether a context is a function context (global
contexts are no longer function contexts).
Split the paths for allocating with and catch contexts.
Rename some functions. Generally refactor code to make it simpler.
[email protected]
BUG=
TEST=
Review URL: http://codereview.chromium.org/7003058
http://code.google.com/p/v8/source/detail?r=8231
Modified:
/branches/bleeding_edge/src/arm/code-stubs-arm.cc
/branches/bleeding_edge/src/arm/full-codegen-arm.cc
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/ast.cc
/branches/bleeding_edge/src/ast.h
/branches/bleeding_edge/src/contexts.cc
/branches/bleeding_edge/src/contexts.h
/branches/bleeding_edge/src/factory.cc
/branches/bleeding_edge/src/factory.h
/branches/bleeding_edge/src/full-codegen.cc
/branches/bleeding_edge/src/heap.cc
/branches/bleeding_edge/src/heap.h
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/ia32/code-stubs-ia32.cc
/branches/bleeding_edge/src/ia32/full-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/mark-compact.cc
/branches/bleeding_edge/src/objects-inl.h
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/parser.cc
/branches/bleeding_edge/src/prettyprinter.cc
/branches/bleeding_edge/src/rewriter.cc
/branches/bleeding_edge/src/runtime.cc
/branches/bleeding_edge/src/runtime.h
/branches/bleeding_edge/src/x64/code-stubs-x64.cc
/branches/bleeding_edge/src/x64/full-codegen-x64.cc
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.cc Mon Jun 6 00:47:21
2011
+++ /branches/bleeding_edge/src/arm/code-stubs-arm.cc Thu Jun 9 04:26:01
2011
@@ -158,7 +158,7 @@
__ ldr(r3, MemOperand(sp, 0));
// Setup the object header.
- __ LoadRoot(r2, Heap::kContextMapRootIndex);
+ __ LoadRoot(r2, Heap::kFunctionContextMapRootIndex);
__ str(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
__ mov(r2, Operand(Smi::FromInt(length)));
__ str(r2, FieldMemOperand(r0, FixedArray::kLengthOffset));
@@ -187,7 +187,7 @@
// Need to collect. Call into runtime system.
__ bind(&gc);
- __ TailCallRuntime(Runtime::kNewContext, 1, 1);
+ __ TailCallRuntime(Runtime::kNewFunctionContext, 1, 1);
}
=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Fri Jun 3 00:41:37
2011
+++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Thu Jun 9 04:26:01
2011
@@ -182,7 +182,7 @@
FastNewContextStub stub(heap_slots);
__ CallStub(&stub);
} else {
- __ CallRuntime(Runtime::kNewContext, 1);
+ __ CallRuntime(Runtime::kNewFunctionContext, 1);
}
function_in_register = false;
// Context is returned in both r0 and cp. It replaces the context
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Jun 8
03:51:51 2011
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Thu Jun 9
04:26:01 2011
@@ -189,7 +189,7 @@
FastNewContextStub stub(heap_slots);
__ CallStub(&stub);
} else {
- __ CallRuntime(Runtime::kNewContext, 1);
+ __ CallRuntime(Runtime::kNewFunctionContext, 1);
}
RecordSafepoint(Safepoint::kNoDeoptimizationIndex);
// Context is returned in both r0 and cp. It replaces the context
=======================================
--- /branches/bleeding_edge/src/ast.cc Wed Jun 8 06:55:33 2011
+++ /branches/bleeding_edge/src/ast.cc Thu Jun 9 04:26:01 2011
@@ -362,12 +362,12 @@
}
-bool WithEnterStatement::IsInlineable() const {
+bool EnterWithContextStatement::IsInlineable() const {
return false;
}
-bool WithExitStatement::IsInlineable() const {
+bool ExitContextStatement::IsInlineable() const {
return false;
}
=======================================
--- /branches/bleeding_edge/src/ast.h Wed Jun 8 06:55:33 2011
+++ /branches/bleeding_edge/src/ast.h Thu Jun 9 04:26:01 2011
@@ -60,8 +60,8 @@
V(ContinueStatement) \
V(BreakStatement) \
V(ReturnStatement) \
- V(WithEnterStatement) \
- V(WithExitStatement) \
+ V(EnterWithContextStatement) \
+ V(ExitContextStatement) \
V(SwitchStatement) \
V(DoWhileStatement) \
V(WhileStatement) \
@@ -611,12 +611,12 @@
};
-class WithEnterStatement: public Statement {
+class EnterWithContextStatement: public Statement {
public:
- explicit WithEnterStatement(Expression* expression)
+ explicit EnterWithContextStatement(Expression* expression)
: expression_(expression) { }
- DECLARE_NODE_TYPE(WithEnterStatement)
+ DECLARE_NODE_TYPE(EnterWithContextStatement)
Expression* expression() const { return expression_; }
@@ -627,13 +627,11 @@
};
-class WithExitStatement: public Statement {
+class ExitContextStatement: public Statement {
public:
- WithExitStatement() { }
-
virtual bool IsInlineable() const;
- DECLARE_NODE_TYPE(WithExitStatement)
+ DECLARE_NODE_TYPE(ExitContextStatement)
};
=======================================
--- /branches/bleeding_edge/src/contexts.cc Tue May 24 01:38:42 2011
+++ /branches/bleeding_edge/src/contexts.cc Thu Jun 9 04:26:01 2011
@@ -96,7 +96,7 @@
PrintF("\n");
}
- // check extension/with object
+ // Check extension/with/global object.
if (context->has_extension()) {
Handle<JSObject> extension = Handle<JSObject>(context->extension(),
isolate);
@@ -119,7 +119,8 @@
}
}
- if (context->is_function_context()) {
+ // Only functions can have locals, parameters, and a function name.
+ if (context->IsFunctionContext()) {
// we have context-local slots
// check non-parameter locals in context
@@ -189,9 +190,8 @@
// proceed with enclosing context
if (context->IsGlobalContext()) {
follow_context_chain = false;
- } else if (context->is_function_context()) {
- context =
Handle<Context>(Context::cast(context->closure()->context()),
- isolate);
+ } else if (context->IsFunctionContext()) {
+ context = Handle<Context>(context->closure()->context(), isolate);
} else {
context = Handle<Context>(context->previous(), isolate);
}
@@ -212,11 +212,12 @@
// before the global context and check that there are no context
// extension objects (conservative check for with statements).
while (!context->IsGlobalContext()) {
- // Check if the context is a potentially a with context.
+ // Check if the context is a catch or with context, or has called
+ // non-strict eval.
if (context->has_extension()) return false;
// Not a with context so it must be a function context.
- ASSERT(context->is_function_context());
+ ASSERT(context->IsFunctionContext());
// Check non-parameter locals.
Handle<SerializedScopeInfo> scope_info(
=======================================
--- /branches/bleeding_edge/src/contexts.h Tue May 31 09:38:40 2011
+++ /branches/bleeding_edge/src/contexts.h Thu Jun 9 04:26:01 2011
@@ -289,8 +289,17 @@
// Compute the global context by traversing the context chain.
Context* global_context();
- // Tells if this is a function context (as opposed to a 'with' context).
- bool is_function_context() { return unchecked_previous() == NULL; }
+ // Predicates for context types. IsGlobalContext is defined on Object
+ // because we frequently have to know if arbitrary objects are global
+ // contexts.
+ bool IsFunctionContext() {
+ Map* map = this->map();
+ return map == map->GetHeap()->function_context_map();
+ }
+ bool IsCatchContext() {
+ Map* map = this->map();
+ return map == map->GetHeap()->catch_context_map();
+ }
// Tells whether the global context is marked with out of memory.
inline bool has_out_of_memory();
=======================================
--- /branches/bleeding_edge/src/factory.cc Thu Jun 9 03:03:35 2011
+++ /branches/bleeding_edge/src/factory.cc Thu Jun 9 04:26:01 2011
@@ -247,16 +247,22 @@
isolate()->heap()->AllocateFunctionContext(length, *closure),
Context);
}
+
+
+Handle<Context> Factory::NewCatchContext(Handle<Context> previous,
+ Handle<JSObject> extension) {
+ CALL_HEAP_FUNCTION(
+ isolate(),
+ isolate()->heap()->AllocateCatchContext(*previous, *extension),
+ Context);
+}
Handle<Context> Factory::NewWithContext(Handle<Context> previous,
- Handle<JSObject> extension,
- bool is_catch_context) {
+ Handle<JSObject> extension) {
CALL_HEAP_FUNCTION(
isolate(),
- isolate()->heap()->AllocateWithContext(*previous,
- *extension,
- is_catch_context),
+ isolate()->heap()->AllocateWithContext(*previous, *extension),
Context);
}
=======================================
--- /branches/bleeding_edge/src/factory.h Thu Jun 9 03:03:35 2011
+++ /branches/bleeding_edge/src/factory.h Thu Jun 9 04:26:01 2011
@@ -149,10 +149,13 @@
Handle<Context> NewFunctionContext(int length,
Handle<JSFunction> closure);
+ // Create a catch context.
+ Handle<Context> NewCatchContext(Handle<Context> previous,
+ Handle<JSObject> extension);
+
// Create a 'with' context.
Handle<Context> NewWithContext(Handle<Context> previous,
- Handle<JSObject> extension,
- bool is_catch_context);
+ Handle<JSObject> extension);
// Return the Symbol matching the passed in string.
Handle<String> SymbolFromString(Handle<String> value);
=======================================
--- /branches/bleeding_edge/src/full-codegen.cc Wed Jun 8 06:55:33 2011
+++ /branches/bleeding_edge/src/full-codegen.cc Thu Jun 9 04:26:01 2011
@@ -90,14 +90,14 @@
}
-void BreakableStatementChecker::VisitWithEnterStatement(
- WithEnterStatement* stmt) {
+void BreakableStatementChecker::VisitEnterWithContextStatement(
+ EnterWithContextStatement* stmt) {
Visit(stmt->expression());
}
-void BreakableStatementChecker::VisitWithExitStatement(
- WithExitStatement* stmt) {
+void BreakableStatementChecker::VisitExitContextStatement(
+ ExitContextStatement* stmt) {
}
@@ -952,18 +952,19 @@
}
-void FullCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) {
- Comment cmnt(masm_, "[ WithEnterStatement");
+void FullCodeGenerator::VisitEnterWithContextStatement(
+ EnterWithContextStatement* stmt) {
+ Comment cmnt(masm_, "[ EnterWithContextStatement");
SetStatementPosition(stmt);
VisitForStackValue(stmt->expression());
- __ CallRuntime(Runtime::kPushContext, 1);
+ __ CallRuntime(Runtime::kPushWithContext, 1);
StoreToFrameField(StandardFrameConstants::kContextOffset,
context_register());
}
-void FullCodeGenerator::VisitWithExitStatement(WithExitStatement* stmt) {
- Comment cmnt(masm_, "[ WithExitStatement");
+void FullCodeGenerator::VisitExitContextStatement(ExitContextStatement*
stmt) {
+ Comment cmnt(masm_, "[ ExitContextStatement");
SetStatementPosition(stmt);
// Pop context.
=======================================
--- /branches/bleeding_edge/src/heap.cc Thu Jun 9 03:03:35 2011
+++ /branches/bleeding_edge/src/heap.cc Thu Jun 9 04:26:01 2011
@@ -1894,7 +1894,7 @@
AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
if (!maybe_obj->ToObject(&obj)) return false;
}
- set_context_map(Map::cast(obj));
+ set_function_context_map(Map::cast(obj));
{ MaybeObject* maybe_obj =
AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
@@ -1902,6 +1902,12 @@
}
set_catch_context_map(Map::cast(obj));
+ { MaybeObject* maybe_obj =
+ AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
+ if (!maybe_obj->ToObject(&obj)) return false;
+ }
+ set_with_context_map(Map::cast(obj));
+
{ MaybeObject* maybe_obj =
AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
if (!maybe_obj->ToObject(&obj)) return false;
@@ -3919,38 +3925,47 @@
if (!maybe_result->ToObject(&result)) return maybe_result;
}
Context* context = reinterpret_cast<Context*>(result);
- context->set_map(context_map());
+ context->set_map(function_context_map());
context->set_closure(function);
context->set_fcontext(context);
context->set_previous(NULL);
context->set_extension(NULL);
context->set_global(function->context()->global());
- ASSERT(!context->IsGlobalContext());
- ASSERT(context->is_function_context());
- ASSERT(result->IsContext());
- return result;
+ return context;
+}
+
+
+MaybeObject* Heap::AllocateCatchContext(Context* previous,
+ JSObject* extension) {
+ Object* result;
+ { MaybeObject* maybe_result =
AllocateFixedArray(Context::MIN_CONTEXT_SLOTS);
+ if (!maybe_result->ToObject(&result)) return maybe_result;
+ }
+ Context* context = reinterpret_cast<Context*>(result);
+ context->set_map(catch_context_map());
+ context->set_closure(previous->closure());
+ context->set_fcontext(previous->fcontext());
+ context->set_previous(previous);
+ context->set_extension(extension);
+ context->set_global(previous->global());
+ return context;
}
MaybeObject* Heap::AllocateWithContext(Context* previous,
- JSObject* extension,
- bool is_catch_context) {
+ JSObject* extension) {
Object* result;
{ MaybeObject* maybe_result =
AllocateFixedArray(Context::MIN_CONTEXT_SLOTS);
if (!maybe_result->ToObject(&result)) return maybe_result;
}
Context* context = reinterpret_cast<Context*>(result);
- context->set_map(is_catch_context ? catch_context_map() :
- context_map());
+ context->set_map(with_context_map());
context->set_closure(previous->closure());
context->set_fcontext(previous->fcontext());
context->set_previous(previous);
context->set_extension(extension);
context->set_global(previous->global());
- ASSERT(!context->IsGlobalContext());
- ASSERT(!context->is_function_context());
- ASSERT(result->IsContext());
- return result;
+ return context;
}
=======================================
--- /branches/bleeding_edge/src/heap.h Thu Jun 9 03:03:35 2011
+++ /branches/bleeding_edge/src/heap.h Thu Jun 9 04:26:01 2011
@@ -107,8 +107,9 @@
V(Map, external_unsigned_int_array_map,
ExternalUnsignedIntArrayMap) \
V(Map, external_float_array_map,
ExternalFloatArrayMap) \
V(Map, external_double_array_map,
ExternalDoubleArrayMap) \
- V(Map, context_map,
ContextMap) \
+ V(Map, function_context_map,
FunctionContextMap) \
V(Map, catch_context_map,
CatchContextMap) \
+ V(Map, with_context_map,
WithContextMap) \
V(Map, code_map,
CodeMap) \
V(Map, oddball_map,
OddballMap) \
V(Map, global_property_cell_map,
GlobalPropertyCellMap) \
@@ -645,10 +646,12 @@
MUST_USE_RESULT MaybeObject* AllocateFunctionContext(int length,
JSFunction*
closure);
+ // Allocate a catch context.
+ MUST_USE_RESULT MaybeObject* AllocateCatchContext(Context* previous,
+ JSObject* extension);
// Allocate a 'with' context.
MUST_USE_RESULT MaybeObject* AllocateWithContext(Context* previous,
- JSObject* extension,
- bool is_catch_context);
+ JSObject* extension);
// Allocates a new utility object in the old generation.
MUST_USE_RESULT MaybeObject* AllocateStruct(InstanceType type);
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Thu Jun 9 04:15:03 2011
+++ /branches/bleeding_edge/src/hydrogen.cc Thu Jun 9 04:26:01 2011
@@ -2551,19 +2551,20 @@
}
-void HGraphBuilder::VisitWithEnterStatement(WithEnterStatement* stmt) {
+void HGraphBuilder::VisitEnterWithContextStatement(
+ EnterWithContextStatement* stmt) {
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
- return Bailout("WithEnterStatement");
+ return Bailout("EnterWithContextStatement");
}
-void HGraphBuilder::VisitWithExitStatement(WithExitStatement* stmt) {
+void HGraphBuilder::VisitExitContextStatement(ExitContextStatement* stmt) {
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
- return Bailout("WithExitStatement");
+ return Bailout("ExitContextStatement");
}
=======================================
--- /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Tue Jun 7 00:17:46
2011
+++ /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Thu Jun 9 04:26:01
2011
@@ -129,7 +129,8 @@
// Setup the object header.
Factory* factory = masm->isolate()->factory();
- __ mov(FieldOperand(eax, HeapObject::kMapOffset),
factory->context_map());
+ __ mov(FieldOperand(eax, HeapObject::kMapOffset),
+ factory->function_context_map());
__ mov(FieldOperand(eax, Context::kLengthOffset),
Immediate(Smi::FromInt(length)));
@@ -159,7 +160,7 @@
// Need to collect. Call into runtime system.
__ bind(&gc);
- __ TailCallRuntime(Runtime::kNewContext, 1, 1);
+ __ TailCallRuntime(Runtime::kNewFunctionContext, 1, 1);
}
=======================================
--- /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Fri Jun 3
00:41:37 2011
+++ /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Thu Jun 9
04:26:01 2011
@@ -175,7 +175,7 @@
FastNewContextStub stub(heap_slots);
__ CallStub(&stub);
} else {
- __ CallRuntime(Runtime::kNewContext, 1);
+ __ CallRuntime(Runtime::kNewFunctionContext, 1);
}
function_in_register = false;
// Context is returned in both eax and esi. It replaces the context
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Wed Jun 8
03:51:51 2011
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Thu Jun 9
04:26:01 2011
@@ -184,7 +184,7 @@
FastNewContextStub stub(heap_slots);
__ CallStub(&stub);
} else {
- __ CallRuntime(Runtime::kNewContext, 1);
+ __ CallRuntime(Runtime::kNewFunctionContext, 1);
}
RecordSafepoint(Safepoint::kNoDeoptimizationIndex);
// Context is returned in both eax and esi. It replaces the context
=======================================
--- /branches/bleeding_edge/src/mark-compact.cc Thu Jun 9 03:03:35 2011
+++ /branches/bleeding_edge/src/mark-compact.cc Thu Jun 9 04:26:01 2011
@@ -672,8 +672,9 @@
Map* map = SafeMap(ctx);
Heap* heap = map->heap();
- if (!(map == heap->raw_unchecked_context_map() ||
+ if (!(map == heap->raw_unchecked_function_context_map() ||
map == heap->raw_unchecked_catch_context_map() ||
+ map == heap->raw_unchecked_with_context_map() ||
map == heap->raw_unchecked_global_context_map())) {
return false;
}
=======================================
--- /branches/bleeding_edge/src/objects-inl.h Thu Jun 9 03:03:35 2011
+++ /branches/bleeding_edge/src/objects-inl.h Thu Jun 9 04:26:01 2011
@@ -534,20 +534,15 @@
bool Object::IsContext() {
if (Object::IsHeapObject()) {
- Heap* heap = HeapObject::cast(this)->GetHeap();
- return (HeapObject::cast(this)->map() == heap->context_map() ||
- HeapObject::cast(this)->map() == heap->catch_context_map() ||
- HeapObject::cast(this)->map() == heap->global_context_map());
+ Map* map = HeapObject::cast(this)->map();
+ Heap* heap = map->GetHeap();
+ return (map == heap->function_context_map() ||
+ map == heap->catch_context_map() ||
+ map == heap->with_context_map() ||
+ map == heap->global_context_map());
}
return false;
}
-
-
-bool Object::IsCatchContext() {
- return Object::IsHeapObject() &&
- HeapObject::cast(this)->map() ==
- HeapObject::cast(this)->GetHeap()->catch_context_map();
-}
bool Object::IsGlobalContext() {
=======================================
--- /branches/bleeding_edge/src/objects.h Thu Jun 9 03:03:35 2011
+++ /branches/bleeding_edge/src/objects.h Thu Jun 9 04:26:01 2011
@@ -735,7 +735,6 @@
V(FixedArray) \
V(FixedDoubleArray) \
V(Context) \
- V(CatchContext) \
V(GlobalContext) \
V(JSFunction) \
V(Code) \
=======================================
--- /branches/bleeding_edge/src/parser.cc Thu Jun 9 02:05:15 2011
+++ /branches/bleeding_edge/src/parser.cc Thu Jun 9 04:26:01 2011
@@ -1922,7 +1922,7 @@
Block* result = new(zone()) Block(NULL, 2, false);
if (result != NULL) {
- result->AddStatement(new(zone()) WithEnterStatement(obj));
+ result->AddStatement(new(zone()) EnterWithContextStatement(obj));
// Create body block.
Block* body = new(zone()) Block(NULL, 1, false);
@@ -1930,7 +1930,7 @@
// Create exit block.
Block* exit = new(zone()) Block(NULL, 1, false);
- exit->AddStatement(new(zone()) WithExitStatement());
+ exit->AddStatement(new(zone()) ExitContextStatement());
// Return a try-finally statement.
TryFinallyStatement* wrapper = new(zone()) TryFinallyStatement(body,
exit);
@@ -2089,8 +2089,8 @@
Expect(Token::RPAREN, CHECK_OK);
if (peek() == Token::LBRACE) {
- // Rewrite the catch body B to a single statement block
- // { try B finally { PopContext }}.
+ // Rewrite the catch body B to a single statement block
+ // { try B finally { PopContext }}.
Block* inner_body;
// We need to collect escapes from the body for both the inner
// try/finally used to pop the catch context and any possible outer
@@ -2107,7 +2107,7 @@
// Create exit block.
Block* inner_finally = new(zone()) Block(NULL, 1, false);
- inner_finally->AddStatement(new(zone()) WithExitStatement());
+ inner_finally->AddStatement(new(zone()) ExitContextStatement());
// Create a try/finally statement.
TryFinallyStatement* inner_try_finally =
=======================================
--- /branches/bleeding_edge/src/prettyprinter.cc Wed Jun 8 06:55:33 2011
+++ /branches/bleeding_edge/src/prettyprinter.cc Thu Jun 9 04:26:01 2011
@@ -123,15 +123,16 @@
}
-void PrettyPrinter::VisitWithEnterStatement(WithEnterStatement* node) {
- Print("<enter with> (");
+void PrettyPrinter::VisitEnterWithContextStatement(
+ EnterWithContextStatement* node) {
+ Print("<enter with context> (");
Visit(node->expression());
Print(") ");
}
-void PrettyPrinter::VisitWithExitStatement(WithExitStatement* node) {
- Print("<exit with>");
+void PrettyPrinter::VisitExitContextStatement(ExitContextStatement* node) {
+ Print("<exit context>");
}
@@ -797,13 +798,14 @@
}
-void AstPrinter::VisitWithEnterStatement(WithEnterStatement* node) {
- PrintIndentedVisit("WITH ENTER", node->expression());
+void AstPrinter::VisitEnterWithContextStatement(
+ EnterWithContextStatement* node) {
+ PrintIndentedVisit("ENTER WITH CONTEXT", node->expression());
}
-void AstPrinter::VisitWithExitStatement(WithExitStatement* node) {
- PrintIndented("WITH EXIT\n");
+void AstPrinter::VisitExitContextStatement(ExitContextStatement* node) {
+ PrintIndented("EXIT CONTEXT\n");
}
@@ -1191,14 +1193,15 @@
}
-void JsonAstBuilder::VisitWithEnterStatement(WithEnterStatement* stmt) {
- TagScope tag(this, "WithEnterStatement");
+void JsonAstBuilder::VisitEnterWithContextStatement(
+ EnterWithContextStatement* stmt) {
+ TagScope tag(this, "EnterWithContextStatement");
Visit(stmt->expression());
}
-void JsonAstBuilder::VisitWithExitStatement(WithExitStatement* stmt) {
- TagScope tag(this, "WithExitStatement");
+void JsonAstBuilder::VisitExitContextStatement(ExitContextStatement* stmt)
{
+ TagScope tag(this, "ExitContextStatement");
}
=======================================
--- /branches/bleeding_edge/src/rewriter.cc Wed Jun 8 06:55:33 2011
+++ /branches/bleeding_edge/src/rewriter.cc Thu Jun 9 04:26:01 2011
@@ -197,131 +197,18 @@
void Processor::VisitDeclaration(Declaration* node) {}
void Processor::VisitEmptyStatement(EmptyStatement* node) {}
void Processor::VisitReturnStatement(ReturnStatement* node) {}
-void Processor::VisitWithEnterStatement(WithEnterStatement* node) {}
-void Processor::VisitWithExitStatement(WithExitStatement* node) {}
+void Processor::VisitEnterWithContextStatement(
+ EnterWithContextStatement* node) {
+}
+void Processor::VisitExitContextStatement(ExitContextStatement* node) {}
void Processor::VisitDebuggerStatement(DebuggerStatement* node) {}
// Expressions are never visited yet.
-void Processor::VisitFunctionLiteral(FunctionLiteral* node) {
- USE(node);
- UNREACHABLE();
-}
-
-
-void Processor::VisitSharedFunctionInfoLiteral(
- SharedFunctionInfoLiteral* node) {
- USE(node);
- UNREACHABLE();
-}
-
-
-void Processor::VisitConditional(Conditional* node) {
- USE(node);
- UNREACHABLE();
-}
-
-
-void Processor::VisitVariableProxy(VariableProxy* node) {
- USE(node);
- UNREACHABLE();
-}
-
-
-void Processor::VisitLiteral(Literal* node) {
- USE(node);
- UNREACHABLE();
-}
-
-
-void Processor::VisitRegExpLiteral(RegExpLiteral* node) {
- USE(node);
- UNREACHABLE();
-}
-
-
-void Processor::VisitArrayLiteral(ArrayLiteral* node) {
- USE(node);
- UNREACHABLE();
-}
-
-
-void Processor::VisitObjectLiteral(ObjectLiteral* node) {
- USE(node);
- UNREACHABLE();
-}
-
-
-void Processor::VisitAssignment(Assignment* node) {
- USE(node);
- UNREACHABLE();
-}
-
-
-void Processor::VisitThrow(Throw* node) {
- USE(node);
- UNREACHABLE();
-}
-
-
-void Processor::VisitProperty(Property* node) {
- USE(node);
- UNREACHABLE();
-}
-
-
-void Processor::VisitCall(Call* node) {
- USE(node);
- UNREACHABLE();
-}
-
-
-void Processor::VisitCallNew(CallNew* node) {
- USE(node);
- UNREACHABLE();
-}
-
-
-void Processor::VisitCallRuntime(CallRuntime* node) {
- USE(node);
- UNREACHABLE();
-}
-
-
-void Processor::VisitUnaryOperation(UnaryOperation* node) {
- USE(node);
- UNREACHABLE();
-}
-
-
-void Processor::VisitCountOperation(CountOperation* node) {
- USE(node);
- UNREACHABLE();
-}
-
-
-void Processor::VisitBinaryOperation(BinaryOperation* node) {
- USE(node);
- UNREACHABLE();
-}
-
-
-void Processor::VisitCompareOperation(CompareOperation* node) {
- USE(node);
- UNREACHABLE();
-}
-
-
-void Processor::VisitCompareToNull(CompareToNull* node) {
- USE(node);
- UNREACHABLE();
-}
-
-
-void Processor::VisitThisFunction(ThisFunction* node) {
- USE(node);
- UNREACHABLE();
-}
+#define DEF_VISIT(type) \
+ void Processor::Visit##type(type* expr) { UNREACHABLE(); }
+EXPRESSION_NODE_LIST(DEF_VISIT)
+#undef DEF_VISIT
// Assumes code has been parsed and scopes have been analyzed. Mutates the
=======================================
--- /branches/bleeding_edge/src/runtime.cc Wed Jun 8 01:13:31 2011
+++ /branches/bleeding_edge/src/runtime.cc Thu Jun 9 04:26:01 2011
@@ -7883,7 +7883,7 @@
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NewContext) {
+RUNTIME_FUNCTION(MaybeObject*, Runtime_NewFunctionContext) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
@@ -7901,50 +7901,50 @@
}
-MUST_USE_RESULT static MaybeObject* PushContextHelper(Isolate* isolate,
- Object* object,
- bool
is_catch_context) {
- // Convert the object to a proper JavaScript object.
- Object* js_object = object;
- if (!js_object->IsJSObject()) {
- MaybeObject* maybe_js_object = js_object->ToObject();
- if (!maybe_js_object->ToObject(&js_object)) {
- if (!Failure::cast(maybe_js_object)->IsInternalError()) {
+RUNTIME_FUNCTION(MaybeObject*, Runtime_PushWithContext) {
+ NoHandleAllocation ha;
+ ASSERT(args.length() == 1);
+ JSObject* extension_object;
+ if (args[0]->IsJSObject()) {
+ extension_object = JSObject::cast(args[0]);
+ } else {
+ // Convert the object to a proper JavaScript object.
+ MaybeObject* maybe_js_object = args[0]->ToObject();
+ if (!maybe_js_object->To(&extension_object)) {
+ if (Failure::cast(maybe_js_object)->IsInternalError()) {
+ HandleScope scope(isolate);
+ Handle<Object> handle = args.at<Object>(0);
+ Handle<Object> result =
+ isolate->factory()->NewTypeError("with_expression",
+ HandleVector(&handle, 1));
+ return isolate->Throw(*result);
+ } else {
return maybe_js_object;
}
- HandleScope scope(isolate);
- Handle<Object> handle(object, isolate);
- Handle<Object> result =
- isolate->factory()->NewTypeError("with_expression",
- HandleVector(&handle, 1));
- return isolate->Throw(*result);
}
}
- Object* result;
- { MaybeObject* maybe_result = isolate->heap()->AllocateWithContext(
- isolate->context(), JSObject::cast(js_object), is_catch_context);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
-
- Context* context = Context::cast(result);
+ Context* context;
+ MaybeObject* maybe_context =
+ isolate->heap()->AllocateWithContext(isolate->context(),
+ extension_object);
+ if (!maybe_context->To(&context)) return maybe_context;
isolate->set_context(context);
-
- return result;
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, Runtime_PushContext) {
- NoHandleAllocation ha;
- ASSERT(args.length() == 1);
- return PushContextHelper(isolate, args[0], false);
+ return context;
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
- return PushContextHelper(isolate, args[0], true);
+ JSObject* extension_object = JSObject::cast(args[0]);
+ Context* context;
+ MaybeObject* maybe_context =
+ isolate->heap()->AllocateCatchContext(isolate->context(),
+ extension_object);
+ if (!maybe_context->To(&context)) return maybe_context;
+ isolate->set_context(context);
+ return context;
}
@@ -8607,9 +8607,8 @@
// Stop search when eval is found or when the global context is
// reached.
if (attributes != ABSENT || context->IsGlobalContext()) break;
- if (context->is_function_context()) {
- context =
Handle<Context>(Context::cast(context->closure()->context()),
- isolate);
+ if (context->IsFunctionContext()) {
+ context = Handle<Context>(context->closure()->context(), isolate);
} else {
context = Handle<Context>(context->previous(), isolate);
}
@@ -9842,8 +9841,8 @@
Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info());
ScopeInfo<> info(*scope_info);
- // Get the context.
- Handle<Context> context(Context::cast(it.frame()->context()));
+ // Get the nearest enclosing function context.
+ Handle<Context>
context(Context::cast(it.frame()->context())->fcontext());
// Get the locals names and values into a temporary array.
//
@@ -9859,25 +9858,22 @@
}
// Fill in the values of the locals.
- for (int i = 0; i < info.NumberOfLocals(); i++) {
- if (is_optimized_frame) {
- // If we are inspecting an optimized frame use undefined as the
- // value for all locals.
- //
- // TODO(1140): We should be able to get the correct values
- // for locals in optimized frames.
+ if (is_optimized_frame) {
+ // If we are inspecting an optimized frame use undefined as the
+ // value for all locals.
+ //
+ // TODO(1140): We should be able to get the correct values
+ // for locals in optimized frames.
+ for (int i = 0; i < info.NumberOfLocals(); i++) {
locals->set(i * 2 + 1, isolate->heap()->undefined_value());
- } else if (i < info.number_of_stack_slots()) {
+ }
+ } else {
+ for (int i = 0; i < info.number_of_stack_slots(); i++) {
// Get the value from the stack.
locals->set(i * 2 + 1, it.frame()->GetExpression(i));
- } else {
- // Traverse the context chain to the function context as all local
- // variables stored in the context will be on the function context.
+ }
+ for (int i = info.number_of_stack_slots(); i < info.NumberOfLocals();
i++) {
Handle<String> name = info.LocalName(i);
- while (!context->is_function_context()) {
- context = Handle<Context>(context->previous());
- }
- ASSERT(context->is_function_context());
locals->set(i * 2 + 1,
context->get(scope_info->ContextSlotIndex(*name, NULL)));
}
@@ -10139,7 +10135,7 @@
// context.
static Handle<JSObject> MaterializeClosure(Isolate* isolate,
Handle<Context> context) {
- ASSERT(context->is_function_context());
+ ASSERT(context->IsFunctionContext());
Handle<SharedFunctionInfo> shared(context->closure()->shared());
Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info());
@@ -10238,7 +10234,7 @@
int index = function_->shared()->scope_info()->
StackSlotIndex(isolate_->heap()->result_symbol());
at_local_ = index < 0;
- } else if (context_->is_function_context()) {
+ } else if (context_->IsFunctionContext()) {
at_local_ = true;
} else if (context_->closure() != *function_) {
// The context_ is a with block from the outer function.
@@ -10272,8 +10268,8 @@
}
// Move to the next context.
- if (context_->is_function_context()) {
- context_ =
Handle<Context>(Context::cast(context_->closure()->context()));
+ if (context_->IsFunctionContext()) {
+ context_ = Handle<Context>(context_->closure()->context());
} else {
context_ = Handle<Context>(context_->previous());
}
@@ -10281,7 +10277,7 @@
// If passing the local scope indicate that the current scope is now
the
// local scope.
if (!local_done_ &&
- (context_->IsGlobalContext() ||
(context_->is_function_context()))) {
+ (context_->IsGlobalContext() || context_->IsFunctionContext())) {
at_local_ = true;
}
}
@@ -10295,7 +10291,7 @@
ASSERT(context_->global()->IsGlobalObject());
return ScopeTypeGlobal;
}
- if (context_->is_function_context()) {
+ if (context_->IsFunctionContext()) {
return ScopeTypeClosure;
}
ASSERT(context_->has_extension());
@@ -10863,19 +10859,23 @@
// Creates a copy of the with context chain. The copy of the context chain
is
// is linked to the function context supplied.
-static Handle<Context> CopyWithContextChain(Handle<Context> context_chain,
- Handle<Context>
function_context) {
- // At the bottom of the chain. Return the function context to link to.
- if (context_chain->is_function_context()) {
- return function_context;
+static Handle<Context> CopyWithContextChain(Isolate* isolate,
+ Handle<Context> current,
+ Handle<Context> base) {
+ // At the end of the chain. Return the base context to link to.
+ if (current->IsFunctionContext() || current->IsGlobalContext()) {
+ return base;
}
- // Recursively copy the with contexts.
- Handle<Context> previous(context_chain->previous());
- Handle<JSObject> extension(JSObject::cast(context_chain->extension()));
- Handle<Context> context = CopyWithContextChain(previous,
function_context);
- return context->GetIsolate()->factory()->NewWithContext(
- context, extension, context_chain->IsCatchContext());
+ // Recursively copy the with and catch contexts.
+ HandleScope scope(isolate);
+ Handle<Context> previous(current->previous());
+ Handle<Context> new_previous = CopyWithContextChain(isolate, previous,
base);
+ Handle<JSObject> extension(JSObject::cast(current->extension()));
+ Handle<Context> new_current = current->IsCatchContext()
+ ? isolate->factory()->NewCatchContext(new_previous, extension)
+ : isolate->factory()->NewWithContext(new_previous, extension);
+ return scope.CloseAndEscape(new_current);
}
@@ -11004,11 +11004,11 @@
// Copy any with contexts present and chain them in front of this
context.
Handle<Context> frame_context(Context::cast(frame->context()));
Handle<Context> function_context(frame_context->fcontext());
- context = CopyWithContextChain(frame_context, context);
+ context = CopyWithContextChain(isolate, frame_context, context);
if (additional_context->IsJSObject()) {
- context = isolate->factory()->NewWithContext(context,
- Handle<JSObject>::cast(additional_context), false);
+ Handle<JSObject> extension =
Handle<JSObject>::cast(additional_context);
+ context = isolate->factory()->NewWithContext(context, extension);
}
// Wrap the evaluation statement in a new function compiled in the newly
=======================================
--- /branches/bleeding_edge/src/runtime.h Tue Jun 7 00:17:46 2011
+++ /branches/bleeding_edge/src/runtime.h Thu Jun 9 04:26:01 2011
@@ -297,8 +297,8 @@
F(PromoteScheduledException, 0, 1) \
\
/* Contexts */ \
- F(NewContext, 1, 1) \
- F(PushContext, 1, 1) \
+ F(NewFunctionContext, 1, 1) \
+ F(PushWithContext, 1, 1) \
F(PushCatchContext, 1, 1) \
F(DeleteContextSlot, 2, 1) \
F(LoadContextSlot, 2, 2) \
=======================================
--- /branches/bleeding_edge/src/x64/code-stubs-x64.cc Tue May 31 09:38:40
2011
+++ /branches/bleeding_edge/src/x64/code-stubs-x64.cc Thu Jun 9 04:26:01
2011
@@ -125,7 +125,7 @@
__ movq(rcx, Operand(rsp, 1 * kPointerSize));
// Setup the object header.
- __ LoadRoot(kScratchRegister, Heap::kContextMapRootIndex);
+ __ LoadRoot(kScratchRegister, Heap::kFunctionContextMapRootIndex);
__ movq(FieldOperand(rax, HeapObject::kMapOffset), kScratchRegister);
__ Move(FieldOperand(rax, FixedArray::kLengthOffset),
Smi::FromInt(length));
@@ -152,7 +152,7 @@
// Need to collect. Call into runtime system.
__ bind(&gc);
- __ TailCallRuntime(Runtime::kNewContext, 1, 1);
+ __ TailCallRuntime(Runtime::kNewFunctionContext, 1, 1);
}
=======================================
--- /branches/bleeding_edge/src/x64/full-codegen-x64.cc Fri Jun 3 00:41:37
2011
+++ /branches/bleeding_edge/src/x64/full-codegen-x64.cc Thu Jun 9 04:26:01
2011
@@ -175,7 +175,7 @@
FastNewContextStub stub(heap_slots);
__ CallStub(&stub);
} else {
- __ CallRuntime(Runtime::kNewContext, 1);
+ __ CallRuntime(Runtime::kNewFunctionContext, 1);
}
function_in_register = false;
// Context is returned in both rax and rsi. It replaces the context
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed Jun 8
03:51:51 2011
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Thu Jun 9
04:26:01 2011
@@ -197,7 +197,7 @@
FastNewContextStub stub(heap_slots);
__ CallStub(&stub);
} else {
- __ CallRuntime(Runtime::kNewContext, 1);
+ __ CallRuntime(Runtime::kNewFunctionContext, 1);
}
RecordSafepoint(Safepoint::kNoDeoptimizationIndex);
// Context is returned in both rax and rsi. It replaces the context
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev