Chromium Code Reviews| Index: src/ia32/full-codegen-ia32.cc | 
| diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc | 
| index b42ce95f8db220aaf55491600d95c2e9477a0905..7916b568f1d3153e6d755c8964e3fe82e57b43dd 100644 | 
| --- a/src/ia32/full-codegen-ia32.cc | 
| +++ b/src/ia32/full-codegen-ia32.cc | 
| @@ -266,11 +266,11 @@ void FullCodeGenerator::Generate() { | 
| // For named function expressions, declare the function name as a | 
| // constant. | 
| if (scope()->is_function_scope() && scope()->function() != NULL) { | 
| - VariableProxy* proxy = scope()->function(); | 
| - ASSERT(proxy->var()->mode() == CONST || | 
| - proxy->var()->mode() == CONST_HARMONY); | 
| - ASSERT(proxy->var()->location() != Variable::UNALLOCATED); | 
| - EmitDeclaration(proxy, proxy->var()->mode(), NULL); | 
| + ASSERT(scope()->function()->proxy()->var()->mode() == CONST || | 
| + scope()->function()->proxy()->var()->mode() == CONST_HARMONY); | 
| + ASSERT(scope()->function()->proxy()->var()->location() | 
| + != Variable::UNALLOCATED); | 
| 
 
fschneider
2012/04/11 11:00:42
Break line after the operator to be consistent wit
 
rossberg
2012/04/16 11:25:13
Done (here and in other back-ends).
 
 | 
| + VisitVariableDeclaration(scope()->function()); | 
| } | 
| VisitDeclarations(scope()->declarations()); | 
| } | 
| @@ -750,15 +750,30 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr, | 
| } | 
| -void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy, | 
| - VariableMode mode, | 
| - FunctionLiteral* function) { | 
| +void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) { | 
| + // The variable in the decl always resides in the current function | 
| 
 
fschneider
2012/04/11 11:00:42
s/decl/declaration/
 
rossberg
2012/04/16 11:25:13
Done (here and in other backends).
 
 | 
| + // context. | 
| + ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); | 
| + if (FLAG_debug_code) { | 
| + // Check that we're not inside a with or catch context. | 
| + __ mov(ebx, FieldOperand(esi, HeapObject::kMapOffset)); | 
| + __ cmp(ebx, isolate()->factory()->with_context_map()); | 
| + __ Check(not_equal, "Declaration in with context."); | 
| + __ cmp(ebx, isolate()->factory()->catch_context_map()); | 
| + __ Check(not_equal, "Declaration in catch context."); | 
| + } | 
| +} | 
| + | 
| + | 
| +void FullCodeGenerator::VisitVariableDeclaration( | 
| + VariableDeclaration* declaration) { | 
| // If it was not possible to allocate the variable at compile time, we | 
| // need to "declare" it at runtime to make sure it actually exists in the | 
| // local context. | 
| + VariableProxy* proxy = declaration->proxy(); | 
| + VariableMode mode = declaration->mode(); | 
| Variable* variable = proxy->var(); | 
| - bool binding_needs_init = (function == NULL) && | 
| - (mode == CONST || mode == CONST_HARMONY || mode == LET); | 
| + bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; | 
| switch (variable->location()) { | 
| case Variable::UNALLOCATED: | 
| ++global_count_; | 
| @@ -766,44 +781,17 @@ void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy, | 
| case Variable::PARAMETER: | 
| case Variable::LOCAL: | 
| - if (function != NULL) { | 
| - Comment cmnt(masm_, "[ Declaration"); | 
| - VisitForAccumulatorValue(function); | 
| - __ mov(StackOperand(variable), result_register()); | 
| - } else if (binding_needs_init) { | 
| - Comment cmnt(masm_, "[ Declaration"); | 
| + if (hole_init) { | 
| + Comment cmnt(masm_, "[ VariableDeclaration"); | 
| __ mov(StackOperand(variable), | 
| Immediate(isolate()->factory()->the_hole_value())); | 
| } | 
| break; | 
| case Variable::CONTEXT: | 
| - // The variable in the decl always resides in the current function | 
| - // context. | 
| - ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); | 
| - if (FLAG_debug_code) { | 
| - // Check that we're not inside a with or catch context. | 
| - __ mov(ebx, FieldOperand(esi, HeapObject::kMapOffset)); | 
| - __ cmp(ebx, isolate()->factory()->with_context_map()); | 
| - __ Check(not_equal, "Declaration in with context."); | 
| - __ cmp(ebx, isolate()->factory()->catch_context_map()); | 
| - __ Check(not_equal, "Declaration in catch context."); | 
| - } | 
| - if (function != NULL) { | 
| - Comment cmnt(masm_, "[ Declaration"); | 
| - VisitForAccumulatorValue(function); | 
| - __ mov(ContextOperand(esi, variable->index()), result_register()); | 
| - // We know that we have written a function, which is not a smi. | 
| - __ RecordWriteContextSlot(esi, | 
| - Context::SlotOffset(variable->index()), | 
| - result_register(), | 
| - ecx, | 
| - kDontSaveFPRegs, | 
| - EMIT_REMEMBERED_SET, | 
| - OMIT_SMI_CHECK); | 
| - PrepareForBailoutForId(proxy->id(), NO_REGISTERS); | 
| - } else if (binding_needs_init) { | 
| - Comment cmnt(masm_, "[ Declaration"); | 
| + if (hole_init) { | 
| + Comment cmnt(masm_, "[ VariableDeclaration"); | 
| + EmitDebugCheckDeclarationContext(variable); | 
| __ mov(ContextOperand(esi, variable->index()), | 
| Immediate(isolate()->factory()->the_hole_value())); | 
| // No write barrier since the hole value is in old space. | 
| @@ -812,14 +800,12 @@ void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy, | 
| break; | 
| case Variable::LOOKUP: { | 
| - Comment cmnt(masm_, "[ Declaration"); | 
| + Comment cmnt(masm_, "[ VariableDeclaration"); | 
| __ push(esi); | 
| __ push(Immediate(variable->name())); | 
| - // Declaration nodes are always introduced in one of four modes. | 
| - ASSERT(mode == VAR || | 
| - mode == CONST || | 
| - mode == CONST_HARMONY || | 
| - mode == LET); | 
| + // VariableDeclaration nodes are always introduced in one of four modes. | 
| + ASSERT(mode == VAR || mode == LET || | 
| + mode == CONST || mode == CONST_HARMONY); | 
| PropertyAttributes attr = (mode == CONST || mode == CONST_HARMONY) | 
| ? READ_ONLY : NONE; | 
| __ push(Immediate(Smi::FromInt(attr))); | 
| @@ -827,9 +813,7 @@ void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy, | 
| // Note: For variables we must not push an initial value (such as | 
| // 'undefined') because we may have a (legal) redeclaration and we | 
| // must not destroy the current value. | 
| - if (function != NULL) { | 
| - VisitForStackValue(function); | 
| - } else if (binding_needs_init) { | 
| + if (hole_init) { | 
| __ push(Immediate(isolate()->factory()->the_hole_value())); | 
| } else { | 
| __ push(Immediate(Smi::FromInt(0))); // Indicates no initial value. | 
| @@ -841,6 +825,104 @@ void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy, | 
| } | 
| +void FullCodeGenerator::VisitFunctionDeclaration( | 
| + FunctionDeclaration* declaration) { | 
| + VariableProxy* proxy = declaration->proxy(); | 
| + Variable* variable = proxy->var(); | 
| + switch (variable->location()) { | 
| + case Variable::UNALLOCATED: | 
| + ++global_count_; | 
| + break; | 
| + | 
| + case Variable::PARAMETER: | 
| + case Variable::LOCAL: { | 
| + Comment cmnt(masm_, "[ FunctionDeclaration"); | 
| + VisitForAccumulatorValue(declaration->fun()); | 
| + __ mov(StackOperand(variable), result_register()); | 
| + break; | 
| + } | 
| + | 
| + case Variable::CONTEXT: { | 
| + Comment cmnt(masm_, "[ FunctionDeclaration"); | 
| + EmitDebugCheckDeclarationContext(variable); | 
| + VisitForAccumulatorValue(declaration->fun()); | 
| + __ mov(ContextOperand(esi, variable->index()), result_register()); | 
| + // We know that we have written a function, which is not a smi. | 
| + __ RecordWriteContextSlot(esi, | 
| + Context::SlotOffset(variable->index()), | 
| + result_register(), | 
| + ecx, | 
| + kDontSaveFPRegs, | 
| + EMIT_REMEMBERED_SET, | 
| + OMIT_SMI_CHECK); | 
| + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); | 
| + break; | 
| + } | 
| + | 
| + case Variable::LOOKUP: { | 
| + Comment cmnt(masm_, "[ FunctionDeclaration"); | 
| + __ push(esi); | 
| + __ push(Immediate(variable->name())); | 
| + __ push(Immediate(Smi::FromInt(NONE))); | 
| + VisitForStackValue(declaration->fun()); | 
| + __ CallRuntime(Runtime::kDeclareContextSlot, 4); | 
| + break; | 
| + } | 
| + } | 
| +} | 
| + | 
| + | 
| +void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { | 
| + VariableProxy* proxy = declaration->proxy(); | 
| + Variable* variable = proxy->var(); | 
| + switch (variable->location()) { | 
| + case Variable::UNALLOCATED: | 
| + ++global_count_; | 
| + break; | 
| + | 
| + case Variable::CONTEXT: { | 
| + Comment cmnt(masm_, "[ ModuleDeclaration"); | 
| + EmitDebugCheckDeclarationContext(variable); | 
| + // TODO(rossberg): initialize module instance object | 
| + break; | 
| + } | 
| + | 
| + case Variable::PARAMETER: | 
| + case Variable::LOCAL: | 
| + case Variable::LOOKUP: | 
| + UNREACHABLE(); | 
| + } | 
| +} | 
| + | 
| + | 
| +void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { | 
| + VariableProxy* proxy = declaration->proxy(); | 
| + Variable* variable = proxy->var(); | 
| + switch (variable->location()) { | 
| + case Variable::UNALLOCATED: | 
| + ++global_count_; | 
| + break; | 
| + | 
| + case Variable::CONTEXT: { | 
| + Comment cmnt(masm_, "[ ImportDeclaration"); | 
| + EmitDebugCheckDeclarationContext(variable); | 
| + // TODO(rossberg) | 
| + break; | 
| + } | 
| + | 
| + case Variable::PARAMETER: | 
| + case Variable::LOCAL: | 
| + case Variable::LOOKUP: | 
| + UNREACHABLE(); | 
| + } | 
| +} | 
| + | 
| + | 
| +void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { | 
| + // TODO(rossberg) | 
| +} | 
| + | 
| + | 
| void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 
| // Call the runtime to declare the globals. | 
| __ push(esi); // The context is the first argument. |