Rename the toplevel code generator from "Fast" to "Full". It was

always ambiguous whether it tried to generate fast code, or generate
it quickly.

Review URL: http://codereview.chromium.org/549108

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3660 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
kmillikin@chromium.org 2010-01-20 15:51:03 +00:00
parent 80c81d96d4
commit 6ad58b53f4
9 changed files with 651 additions and 635 deletions

View File

@ -428,8 +428,8 @@ class CodeGenerator: public AstVisitor {
friend class VirtualFrame;
friend class JumpTarget;
friend class Reference;
friend class FastCodeGenerator;
friend class CodeGenSelector;
friend class FullCodeGenerator;
friend class FullCodeGenSyntaxChecker;
DISALLOW_COPY_AND_ASSIGN(CodeGenerator);
};

View File

@ -52,7 +52,7 @@ namespace internal {
//
// The function builds a JS frame. Please see JavaScriptFrameConstants in
// frames-arm.h for its layout.
void FastCodeGenerator::Generate(FunctionLiteral* fun) {
void FullCodeGenerator::Generate(FunctionLiteral* fun) {
function_ = fun;
SetFunctionPosition(fun);
int locals_count = fun->scope()->num_stack_slots();
@ -167,7 +167,7 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) {
}
void FastCodeGenerator::EmitReturnSequence(int position) {
void FullCodeGenerator::EmitReturnSequence(int position) {
Comment cmnt(masm_, "[ Return sequence");
if (return_label_.is_bound()) {
__ b(&return_label_);
@ -214,7 +214,7 @@ void FastCodeGenerator::EmitReturnSequence(int position) {
}
void FastCodeGenerator::Apply(Expression::Context context, Register reg) {
void FullCodeGenerator::Apply(Expression::Context context, Register reg) {
switch (context) {
case Expression::kUninitialized:
UNREACHABLE();
@ -250,7 +250,7 @@ void FastCodeGenerator::Apply(Expression::Context context, Register reg) {
}
void FastCodeGenerator::Apply(Expression::Context context, Slot* slot) {
void FullCodeGenerator::Apply(Expression::Context context, Slot* slot) {
switch (context) {
case Expression::kUninitialized:
UNREACHABLE();
@ -270,7 +270,7 @@ void FastCodeGenerator::Apply(Expression::Context context, Slot* slot) {
}
void FastCodeGenerator::Apply(Expression::Context context, Literal* lit) {
void FullCodeGenerator::Apply(Expression::Context context, Literal* lit) {
switch (context) {
case Expression::kUninitialized:
UNREACHABLE();
@ -290,7 +290,7 @@ void FastCodeGenerator::Apply(Expression::Context context, Literal* lit) {
}
void FastCodeGenerator::ApplyTOS(Expression::Context context) {
void FullCodeGenerator::ApplyTOS(Expression::Context context) {
switch (context) {
case Expression::kUninitialized:
UNREACHABLE();
@ -323,7 +323,7 @@ void FastCodeGenerator::ApplyTOS(Expression::Context context) {
}
void FastCodeGenerator::DropAndApply(int count,
void FullCodeGenerator::DropAndApply(int count,
Expression::Context context,
Register reg) {
ASSERT(count > 0);
@ -371,7 +371,7 @@ void FastCodeGenerator::DropAndApply(int count,
}
void FastCodeGenerator::Apply(Expression::Context context,
void FullCodeGenerator::Apply(Expression::Context context,
Label* materialize_true,
Label* materialize_false) {
switch (context) {
@ -432,7 +432,7 @@ void FastCodeGenerator::Apply(Expression::Context context,
}
void FastCodeGenerator::DoTest(Expression::Context context) {
void FullCodeGenerator::DoTest(Expression::Context context) {
// The value to test is pushed on the stack, and duplicated on the stack
// if necessary (for value/test and test/value contexts).
ASSERT_NE(NULL, true_label_);
@ -495,7 +495,7 @@ void FastCodeGenerator::DoTest(Expression::Context context) {
}
MemOperand FastCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) {
MemOperand FullCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) {
switch (slot->type()) {
case Slot::PARAMETER:
case Slot::LOCAL:
@ -514,14 +514,14 @@ MemOperand FastCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) {
}
void FastCodeGenerator::Move(Register destination, Slot* source) {
void FullCodeGenerator::Move(Register destination, Slot* source) {
// Use destination as scratch.
MemOperand slot_operand = EmitSlotSearch(source, destination);
__ ldr(destination, slot_operand);
}
void FastCodeGenerator::Move(Slot* dst,
void FullCodeGenerator::Move(Slot* dst,
Register src,
Register scratch1,
Register scratch2) {
@ -537,7 +537,7 @@ void FastCodeGenerator::Move(Slot* dst,
}
void FastCodeGenerator::VisitDeclaration(Declaration* decl) {
void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
Comment cmnt(masm_, "[ Declaration");
Variable* var = decl->proxy()->var();
ASSERT(var != NULL); // Must have been resolved.
@ -637,7 +637,7 @@ void FastCodeGenerator::VisitDeclaration(Declaration* decl) {
}
void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
// Call the runtime to declare the globals.
// The context is the first argument.
__ mov(r1, Operand(pairs));
@ -648,7 +648,7 @@ void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
}
void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
Comment cmnt(masm_, "[ FunctionLiteral");
// Build the function boilerplate and instantiate it.
@ -666,13 +666,13 @@ void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
}
void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
Comment cmnt(masm_, "[ VariableProxy");
EmitVariableLoad(expr->var(), context_);
}
void FastCodeGenerator::EmitVariableLoad(Variable* var,
void FullCodeGenerator::EmitVariableLoad(Variable* var,
Expression::Context context) {
Expression* rewrite = var->rewrite();
if (rewrite == NULL) {
@ -745,7 +745,7 @@ void FastCodeGenerator::EmitVariableLoad(Variable* var,
}
void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
Comment cmnt(masm_, "[ RegExpLiteral");
Label done;
// Registers will be used as follows:
@ -772,7 +772,7 @@ void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
}
void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
Comment cmnt(masm_, "[ ObjectLiteral");
__ ldr(r2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
__ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset));
@ -847,7 +847,7 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
}
void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
Comment cmnt(masm_, "[ ArrayLiteral");
__ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
__ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset));
@ -900,7 +900,7 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
}
void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
__ mov(r2, Operand(key->handle()));
@ -909,14 +909,14 @@ void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
}
void FastCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
}
void FastCodeGenerator::EmitBinaryOp(Token::Value op,
void FullCodeGenerator::EmitBinaryOp(Token::Value op,
Expression::Context context) {
__ pop(r1);
GenericBinaryOpStub stub(op, NO_OVERWRITE);
@ -925,7 +925,7 @@ void FastCodeGenerator::EmitBinaryOp(Token::Value op,
}
void FastCodeGenerator::EmitVariableAssignment(Variable* var,
void FullCodeGenerator::EmitVariableAssignment(Variable* var,
Expression::Context context) {
ASSERT(var != NULL);
ASSERT(var->is_global() || var->slot() != NULL);
@ -975,7 +975,7 @@ void FastCodeGenerator::EmitVariableAssignment(Variable* var,
}
void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
// Assignment to a property, using a named store IC.
Property* prop = expr->target()->AsProperty();
ASSERT(prop != NULL);
@ -1011,7 +1011,7 @@ void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
}
void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
// Assignment to a property, using a keyed store IC.
// If the assignment starts a block of assignments to the same object,
@ -1046,7 +1046,7 @@ void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
}
void FastCodeGenerator::VisitProperty(Property* expr) {
void FullCodeGenerator::VisitProperty(Property* expr) {
Comment cmnt(masm_, "[ Property");
Expression* key = expr->key();
@ -1065,7 +1065,7 @@ void FastCodeGenerator::VisitProperty(Property* expr) {
}
}
void FastCodeGenerator::EmitCallWithIC(Call* expr,
void FullCodeGenerator::EmitCallWithIC(Call* expr,
Handle<Object> ignored,
RelocInfo::Mode mode) {
// Code common for calls using the IC.
@ -1087,7 +1087,7 @@ void FastCodeGenerator::EmitCallWithIC(Call* expr,
}
void FastCodeGenerator::EmitCallWithStub(Call* expr) {
void FullCodeGenerator::EmitCallWithStub(Call* expr) {
// Code common for calls using the call stub.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
@ -1105,7 +1105,7 @@ void FastCodeGenerator::EmitCallWithStub(Call* expr) {
}
void FastCodeGenerator::VisitCall(Call* expr) {
void FullCodeGenerator::VisitCall(Call* expr) {
Comment cmnt(masm_, "[ Call");
Expression* fun = expr->expression();
Variable* var = fun->AsVariableProxy()->AsVariable();
@ -1176,7 +1176,7 @@ void FastCodeGenerator::VisitCall(Call* expr) {
}
void FastCodeGenerator::VisitCallNew(CallNew* expr) {
void FullCodeGenerator::VisitCallNew(CallNew* expr) {
Comment cmnt(masm_, "[ CallNew");
// According to ECMA-262, section 11.2.2, page 44, the function
// expression in new calls must be evaluated before the
@ -1211,7 +1211,7 @@ void FastCodeGenerator::VisitCallNew(CallNew* expr) {
}
void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
Comment cmnt(masm_, "[ CallRuntime");
ZoneList<Expression*>* args = expr->arguments();
@ -1246,7 +1246,7 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
}
void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
switch (expr->op()) {
case Token::VOID: {
Comment cmnt(masm_, "[ UnaryOperation (VOID)");
@ -1357,7 +1357,7 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
}
void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
Comment cmnt(masm_, "[ CountOperation");
// Expression can only be a property, a global or a (parameter or local)
@ -1483,7 +1483,7 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
}
void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
Comment cmnt(masm_, "[ BinaryOperation");
switch (expr->op()) {
case Token::COMMA:
@ -1518,7 +1518,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
}
void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
Comment cmnt(masm_, "[ CompareOperation");
// Always perform the comparison for its control flow. Pack the result
@ -1633,25 +1633,25 @@ void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
}
void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) {
void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
__ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
Apply(context_, r0);
}
Register FastCodeGenerator::result_register() { return r0; }
Register FullCodeGenerator::result_register() { return r0; }
Register FastCodeGenerator::context_register() { return cp; }
Register FullCodeGenerator::context_register() { return cp; }
void FastCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
__ str(value, MemOperand(fp, frame_offset));
}
void FastCodeGenerator::LoadContextField(Register dst, int context_index) {
void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
__ ldr(dst, CodeGenerator::ContextOperand(cp, context_index));
}
@ -1659,7 +1659,7 @@ void FastCodeGenerator::LoadContextField(Register dst, int context_index) {
// ----------------------------------------------------------------------------
// Non-local control flow support.
void FastCodeGenerator::EnterFinallyBlock() {
void FullCodeGenerator::EnterFinallyBlock() {
ASSERT(!result_register().is(r1));
// Store result register while executing finally block.
__ push(result_register());
@ -1672,7 +1672,7 @@ void FastCodeGenerator::EnterFinallyBlock() {
}
void FastCodeGenerator::ExitFinallyBlock() {
void FullCodeGenerator::ExitFinallyBlock() {
ASSERT(!result_register().is(r1));
// Restore result register from stack.
__ pop(r1);

View File

@ -42,29 +42,6 @@ namespace v8 {
namespace internal {
class CodeGenSelector: public AstVisitor {
public:
enum CodeGenTag { NORMAL, FAST };
CodeGenSelector() : has_supported_syntax_(true) {}
CodeGenTag Select(FunctionLiteral* fun);
private:
void VisitDeclarations(ZoneList<Declaration*>* decls);
void VisitStatements(ZoneList<Statement*>* stmts);
// AST node visit functions.
#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
AST_NODE_LIST(DECLARE_VISIT)
#undef DECLARE_VISIT
bool has_supported_syntax_;
DISALLOW_COPY_AND_ASSIGN(CodeGenSelector);
};
static Handle<Code> MakeCode(FunctionLiteral* literal,
Handle<Script> script,
Handle<Context> context,
@ -117,12 +94,11 @@ static Handle<Code> MakeCode(FunctionLiteral* literal,
!FLAG_always_fast_compiler) {
if (FLAG_trace_bailout) PrintF("No hint to try fast\n");
} else {
CodeGenSelector selector;
CodeGenSelector::CodeGenTag code_gen = selector.Select(literal);
if (code_gen == CodeGenSelector::FAST) {
return FastCodeGenerator::MakeCode(literal, script, is_eval);
FullCodeGenSyntaxChecker checker;
checker.Check(literal);
if (checker.has_supported_syntax()) {
return FullCodeGenerator::MakeCode(literal, script, is_eval);
}
ASSERT(code_gen == CodeGenSelector::NORMAL);
}
}
return CodeGenerator::MakeCode(literal, script, is_eval);
@ -494,10 +470,10 @@ Handle<JSFunction> Compiler::BuildBoilerplate(FunctionLiteral* literal,
// Generate code and return it.
bool is_compiled = false;
if (FLAG_fast_compiler && literal->try_fast_codegen()) {
CodeGenSelector selector;
CodeGenSelector::CodeGenTag code_gen = selector.Select(literal);
if (code_gen == CodeGenSelector::FAST) {
code = FastCodeGenerator::MakeCode(literal,
FullCodeGenSyntaxChecker checker;
checker.Check(literal);
if (checker.has_supported_syntax()) {
code = FullCodeGenerator::MakeCode(literal,
script,
false); // Not eval.
is_compiled = true;
@ -571,422 +547,4 @@ void Compiler::SetFunctionInfo(Handle<JSFunction> fun,
}
CodeGenSelector::CodeGenTag CodeGenSelector::Select(FunctionLiteral* fun) {
Scope* scope = fun->scope();
if (scope->num_heap_slots() > 0) {
// We support functions with a local context if they do not have
// parameters that need to be copied into the context.
for (int i = 0, len = scope->num_parameters(); i < len; i++) {
Slot* slot = scope->parameter(i)->slot();
if (slot != NULL && slot->type() == Slot::CONTEXT) {
if (FLAG_trace_bailout) {
PrintF("Function has context-allocated parameters.\n");
}
return NORMAL;
}
}
}
has_supported_syntax_ = true;
VisitDeclarations(scope->declarations());
if (!has_supported_syntax_) return NORMAL;
VisitStatements(fun->body());
return has_supported_syntax_ ? FAST : NORMAL;
}
#define BAILOUT(reason) \
do { \
if (FLAG_trace_bailout) { \
PrintF("%s\n", reason); \
} \
has_supported_syntax_ = false; \
return; \
} while (false)
#define CHECK_BAILOUT \
do { \
if (!has_supported_syntax_) return; \
} while (false)
void CodeGenSelector::VisitDeclarations(ZoneList<Declaration*>* decls) {
for (int i = 0; i < decls->length(); i++) {
Visit(decls->at(i));
CHECK_BAILOUT;
}
}
void CodeGenSelector::VisitStatements(ZoneList<Statement*>* stmts) {
for (int i = 0, len = stmts->length(); i < len; i++) {
Visit(stmts->at(i));
CHECK_BAILOUT;
}
}
void CodeGenSelector::VisitDeclaration(Declaration* decl) {
Property* prop = decl->proxy()->AsProperty();
if (prop != NULL) {
Visit(prop->obj());
Visit(prop->key());
}
if (decl->fun() != NULL) {
Visit(decl->fun());
}
}
void CodeGenSelector::VisitBlock(Block* stmt) {
VisitStatements(stmt->statements());
}
void CodeGenSelector::VisitExpressionStatement(ExpressionStatement* stmt) {
Visit(stmt->expression());
}
void CodeGenSelector::VisitEmptyStatement(EmptyStatement* stmt) {}
void CodeGenSelector::VisitIfStatement(IfStatement* stmt) {
Visit(stmt->condition());
CHECK_BAILOUT;
Visit(stmt->then_statement());
CHECK_BAILOUT;
Visit(stmt->else_statement());
}
void CodeGenSelector::VisitContinueStatement(ContinueStatement* stmt) {}
void CodeGenSelector::VisitBreakStatement(BreakStatement* stmt) {}
void CodeGenSelector::VisitReturnStatement(ReturnStatement* stmt) {
Visit(stmt->expression());
}
void CodeGenSelector::VisitWithEnterStatement(WithEnterStatement* stmt) {
Visit(stmt->expression());
}
void CodeGenSelector::VisitWithExitStatement(WithExitStatement* stmt) {}
void CodeGenSelector::VisitSwitchStatement(SwitchStatement* stmt) {
BAILOUT("SwitchStatement");
}
void CodeGenSelector::VisitDoWhileStatement(DoWhileStatement* stmt) {
Visit(stmt->cond());
CHECK_BAILOUT;
Visit(stmt->body());
}
void CodeGenSelector::VisitWhileStatement(WhileStatement* stmt) {
Visit(stmt->cond());
CHECK_BAILOUT;
Visit(stmt->body());
}
void CodeGenSelector::VisitForStatement(ForStatement* stmt) {
BAILOUT("ForStatement");
}
void CodeGenSelector::VisitForInStatement(ForInStatement* stmt) {
BAILOUT("ForInStatement");
}
void CodeGenSelector::VisitTryCatchStatement(TryCatchStatement* stmt) {
Visit(stmt->try_block());
CHECK_BAILOUT;
Visit(stmt->catch_block());
}
void CodeGenSelector::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
Visit(stmt->try_block());
CHECK_BAILOUT;
Visit(stmt->finally_block());
}
void CodeGenSelector::VisitDebuggerStatement(DebuggerStatement* stmt) {}
void CodeGenSelector::VisitFunctionLiteral(FunctionLiteral* expr) {}
void CodeGenSelector::VisitFunctionBoilerplateLiteral(
FunctionBoilerplateLiteral* expr) {
BAILOUT("FunctionBoilerplateLiteral");
}
void CodeGenSelector::VisitConditional(Conditional* expr) {
Visit(expr->condition());
CHECK_BAILOUT;
Visit(expr->then_expression());
CHECK_BAILOUT;
Visit(expr->else_expression());
}
void CodeGenSelector::VisitSlot(Slot* expr) {
UNREACHABLE();
}
void CodeGenSelector::VisitVariableProxy(VariableProxy* expr) {
Variable* var = expr->var();
if (!var->is_global()) {
Slot* slot = var->slot();
if (slot != NULL) {
Slot::Type type = slot->type();
// When LOOKUP slots are enabled, some currently dead code
// implementing unary typeof will become live.
if (type == Slot::LOOKUP) {
BAILOUT("Lookup slot");
}
} else {
// If not global or a slot, it is a parameter rewritten to an explicit
// property reference on the (shadow) arguments object.
#ifdef DEBUG
Property* property = var->AsProperty();
ASSERT_NOT_NULL(property);
Variable* object = property->obj()->AsVariableProxy()->AsVariable();
ASSERT_NOT_NULL(object);
ASSERT_NOT_NULL(object->slot());
ASSERT_NOT_NULL(property->key()->AsLiteral());
ASSERT(property->key()->AsLiteral()->handle()->IsSmi());
#endif
}
}
}
void CodeGenSelector::VisitLiteral(Literal* expr) {}
void CodeGenSelector::VisitRegExpLiteral(RegExpLiteral* expr) {}
void CodeGenSelector::VisitObjectLiteral(ObjectLiteral* expr) {
ZoneList<ObjectLiteral::Property*>* properties = expr->properties();
for (int i = 0, len = properties->length(); i < len; i++) {
ObjectLiteral::Property* property = properties->at(i);
if (property->IsCompileTimeValue()) continue;
Visit(property->key());
CHECK_BAILOUT;
Visit(property->value());
CHECK_BAILOUT;
}
}
void CodeGenSelector::VisitArrayLiteral(ArrayLiteral* expr) {
ZoneList<Expression*>* subexprs = expr->values();
for (int i = 0, len = subexprs->length(); i < len; i++) {
Expression* subexpr = subexprs->at(i);
if (subexpr->AsLiteral() != NULL) continue;
if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
Visit(subexpr);
CHECK_BAILOUT;
}
}
void CodeGenSelector::VisitCatchExtensionObject(CatchExtensionObject* expr) {
Visit(expr->key());
CHECK_BAILOUT;
Visit(expr->value());
}
void CodeGenSelector::VisitAssignment(Assignment* expr) {
// We support plain non-compound assignments to properties, parameters and
// non-context (stack-allocated) locals, and global variables.
Token::Value op = expr->op();
if (op == Token::INIT_CONST) BAILOUT("initialize constant");
Variable* var = expr->target()->AsVariableProxy()->AsVariable();
Property* prop = expr->target()->AsProperty();
ASSERT(var == NULL || prop == NULL);
if (var != NULL) {
if (var->mode() == Variable::CONST) {
BAILOUT("Assignment to const");
}
// All global variables are supported.
if (!var->is_global()) {
ASSERT(var->slot() != NULL);
Slot::Type type = var->slot()->type();
if (type == Slot::LOOKUP) {
BAILOUT("Lookup slot");
}
}
} else if (prop != NULL) {
Visit(prop->obj());
CHECK_BAILOUT;
Visit(prop->key());
CHECK_BAILOUT;
} else {
// This is a throw reference error.
BAILOUT("non-variable/non-property assignment");
}
Visit(expr->value());
}
void CodeGenSelector::VisitThrow(Throw* expr) {
Visit(expr->exception());
}
void CodeGenSelector::VisitProperty(Property* expr) {
Visit(expr->obj());
CHECK_BAILOUT;
Visit(expr->key());
}
void CodeGenSelector::VisitCall(Call* expr) {
Expression* fun = expr->expression();
ZoneList<Expression*>* args = expr->arguments();
Variable* var = fun->AsVariableProxy()->AsVariable();
// Check for supported calls
if (var != NULL && var->is_possibly_eval()) {
BAILOUT("call to the identifier 'eval'");
} else if (var != NULL && !var->is_this() && var->is_global()) {
// Calls to global variables are supported.
} else if (var != NULL && var->slot() != NULL &&
var->slot()->type() == Slot::LOOKUP) {
BAILOUT("call to a lookup slot");
} else if (fun->AsProperty() != NULL) {
Property* prop = fun->AsProperty();
Visit(prop->obj());
CHECK_BAILOUT;
Visit(prop->key());
CHECK_BAILOUT;
} else {
// Otherwise the call is supported if the function expression is.
Visit(fun);
}
// Check all arguments to the call.
for (int i = 0; i < args->length(); i++) {
Visit(args->at(i));
CHECK_BAILOUT;
}
}
void CodeGenSelector::VisitCallNew(CallNew* expr) {
Visit(expr->expression());
CHECK_BAILOUT;
ZoneList<Expression*>* args = expr->arguments();
// Check all arguments to the call
for (int i = 0; i < args->length(); i++) {
Visit(args->at(i));
CHECK_BAILOUT;
}
}
void CodeGenSelector::VisitCallRuntime(CallRuntime* expr) {
// Check for inline runtime call
if (expr->name()->Get(0) == '_' &&
CodeGenerator::FindInlineRuntimeLUT(expr->name()) != NULL) {
BAILOUT("inlined runtime call");
}
// Check all arguments to the call. (Relies on TEMP meaning STACK.)
for (int i = 0; i < expr->arguments()->length(); i++) {
Visit(expr->arguments()->at(i));
CHECK_BAILOUT;
}
}
void CodeGenSelector::VisitUnaryOperation(UnaryOperation* expr) {
switch (expr->op()) {
case Token::VOID:
case Token::NOT:
case Token::TYPEOF:
Visit(expr->expression());
break;
case Token::BIT_NOT:
BAILOUT("UnaryOperation: BIT_NOT");
case Token::DELETE:
BAILOUT("UnaryOperation: DELETE");
case Token::ADD:
BAILOUT("UnaryOperation: ADD");
case Token::SUB:
BAILOUT("UnaryOperation: SUB");
default:
UNREACHABLE();
}
}
void CodeGenSelector::VisitCountOperation(CountOperation* expr) {
Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
Property* prop = expr->expression()->AsProperty();
ASSERT(var == NULL || prop == NULL);
if (var != NULL) {
// All global variables are supported.
if (!var->is_global()) {
ASSERT(var->slot() != NULL);
Slot::Type type = var->slot()->type();
if (type == Slot::LOOKUP) {
BAILOUT("CountOperation with lookup slot");
}
}
} else if (prop != NULL) {
Visit(prop->obj());
CHECK_BAILOUT;
Visit(prop->key());
CHECK_BAILOUT;
} else {
// This is a throw reference error.
BAILOUT("CountOperation non-variable/non-property expression");
}
}
void CodeGenSelector::VisitBinaryOperation(BinaryOperation* expr) {
Visit(expr->left());
CHECK_BAILOUT;
Visit(expr->right());
}
void CodeGenSelector::VisitCompareOperation(CompareOperation* expr) {
Visit(expr->left());
CHECK_BAILOUT;
Visit(expr->right());
}
void CodeGenSelector::VisitThisFunction(ThisFunction* expr) {}
#undef BAILOUT
#undef CHECK_BAILOUT
} } // namespace v8::internal

View File

@ -36,15 +36,450 @@
namespace v8 {
namespace internal {
#define BAILOUT(reason) \
do { \
if (FLAG_trace_bailout) { \
PrintF("%s\n", reason); \
} \
has_supported_syntax_ = false; \
return; \
} while (false)
#define CHECK_BAILOUT \
do { \
if (!has_supported_syntax_) return; \
} while (false)
void FullCodeGenSyntaxChecker::Check(FunctionLiteral* fun) {
Scope* scope = fun->scope();
if (scope->num_heap_slots() > 0) {
// We support functions with a local context if they do not have
// parameters that need to be copied into the context.
for (int i = 0, len = scope->num_parameters(); i < len; i++) {
Slot* slot = scope->parameter(i)->slot();
if (slot != NULL && slot->type() == Slot::CONTEXT) {
BAILOUT("Function has context-allocated parameters.");
}
}
}
VisitDeclarations(scope->declarations());
CHECK_BAILOUT;
VisitStatements(fun->body());
}
void FullCodeGenSyntaxChecker::VisitDeclarations(
ZoneList<Declaration*>* decls) {
for (int i = 0; i < decls->length(); i++) {
Visit(decls->at(i));
CHECK_BAILOUT;
}
}
void FullCodeGenSyntaxChecker::VisitStatements(ZoneList<Statement*>* stmts) {
for (int i = 0, len = stmts->length(); i < len; i++) {
Visit(stmts->at(i));
CHECK_BAILOUT;
}
}
void FullCodeGenSyntaxChecker::VisitDeclaration(Declaration* decl) {
Property* prop = decl->proxy()->AsProperty();
if (prop != NULL) {
Visit(prop->obj());
Visit(prop->key());
}
if (decl->fun() != NULL) {
Visit(decl->fun());
}
}
void FullCodeGenSyntaxChecker::VisitBlock(Block* stmt) {
VisitStatements(stmt->statements());
}
void FullCodeGenSyntaxChecker::VisitExpressionStatement(
ExpressionStatement* stmt) {
Visit(stmt->expression());
}
void FullCodeGenSyntaxChecker::VisitEmptyStatement(EmptyStatement* stmt) {
// Supported.
}
void FullCodeGenSyntaxChecker::VisitIfStatement(IfStatement* stmt) {
Visit(stmt->condition());
CHECK_BAILOUT;
Visit(stmt->then_statement());
CHECK_BAILOUT;
Visit(stmt->else_statement());
}
void FullCodeGenSyntaxChecker::VisitContinueStatement(ContinueStatement* stmt) {
// Supported.
}
void FullCodeGenSyntaxChecker::VisitBreakStatement(BreakStatement* stmt) {}
void FullCodeGenSyntaxChecker::VisitReturnStatement(ReturnStatement* stmt) {
Visit(stmt->expression());
}
void FullCodeGenSyntaxChecker::VisitWithEnterStatement(
WithEnterStatement* stmt) {
Visit(stmt->expression());
}
void FullCodeGenSyntaxChecker::VisitWithExitStatement(WithExitStatement* stmt) {
// Supported.
}
void FullCodeGenSyntaxChecker::VisitSwitchStatement(SwitchStatement* stmt) {
BAILOUT("SwitchStatement");
}
void FullCodeGenSyntaxChecker::VisitDoWhileStatement(DoWhileStatement* stmt) {
Visit(stmt->cond());
CHECK_BAILOUT;
Visit(stmt->body());
}
void FullCodeGenSyntaxChecker::VisitWhileStatement(WhileStatement* stmt) {
Visit(stmt->cond());
CHECK_BAILOUT;
Visit(stmt->body());
}
void FullCodeGenSyntaxChecker::VisitForStatement(ForStatement* stmt) {
BAILOUT("ForStatement");
}
void FullCodeGenSyntaxChecker::VisitForInStatement(ForInStatement* stmt) {
BAILOUT("ForInStatement");
}
void FullCodeGenSyntaxChecker::VisitTryCatchStatement(TryCatchStatement* stmt) {
Visit(stmt->try_block());
CHECK_BAILOUT;
Visit(stmt->catch_block());
}
void FullCodeGenSyntaxChecker::VisitTryFinallyStatement(
TryFinallyStatement* stmt) {
Visit(stmt->try_block());
CHECK_BAILOUT;
Visit(stmt->finally_block());
}
void FullCodeGenSyntaxChecker::VisitDebuggerStatement(
DebuggerStatement* stmt) {
// Supported.
}
void FullCodeGenSyntaxChecker::VisitFunctionLiteral(FunctionLiteral* expr) {
// Supported.
}
void FullCodeGenSyntaxChecker::VisitFunctionBoilerplateLiteral(
FunctionBoilerplateLiteral* expr) {
BAILOUT("FunctionBoilerplateLiteral");
}
void FullCodeGenSyntaxChecker::VisitConditional(Conditional* expr) {
Visit(expr->condition());
CHECK_BAILOUT;
Visit(expr->then_expression());
CHECK_BAILOUT;
Visit(expr->else_expression());
}
void FullCodeGenSyntaxChecker::VisitSlot(Slot* expr) {
UNREACHABLE();
}
void FullCodeGenSyntaxChecker::VisitVariableProxy(VariableProxy* expr) {
Variable* var = expr->var();
if (!var->is_global()) {
Slot* slot = var->slot();
if (slot != NULL) {
Slot::Type type = slot->type();
// When LOOKUP slots are enabled, some currently dead code
// implementing unary typeof will become live.
if (type == Slot::LOOKUP) {
BAILOUT("Lookup slot");
}
} else {
// If not global or a slot, it is a parameter rewritten to an explicit
// property reference on the (shadow) arguments object.
#ifdef DEBUG
Property* property = var->AsProperty();
ASSERT_NOT_NULL(property);
Variable* object = property->obj()->AsVariableProxy()->AsVariable();
ASSERT_NOT_NULL(object);
ASSERT_NOT_NULL(object->slot());
ASSERT_NOT_NULL(property->key()->AsLiteral());
ASSERT(property->key()->AsLiteral()->handle()->IsSmi());
#endif
}
}
}
void FullCodeGenSyntaxChecker::VisitLiteral(Literal* expr) {
// Supported.
}
void FullCodeGenSyntaxChecker::VisitRegExpLiteral(RegExpLiteral* expr) {
// Supported.
}
void FullCodeGenSyntaxChecker::VisitObjectLiteral(ObjectLiteral* expr) {
ZoneList<ObjectLiteral::Property*>* properties = expr->properties();
for (int i = 0, len = properties->length(); i < len; i++) {
ObjectLiteral::Property* property = properties->at(i);
if (property->IsCompileTimeValue()) continue;
Visit(property->key());
CHECK_BAILOUT;
Visit(property->value());
CHECK_BAILOUT;
}
}
void FullCodeGenSyntaxChecker::VisitArrayLiteral(ArrayLiteral* expr) {
ZoneList<Expression*>* subexprs = expr->values();
for (int i = 0, len = subexprs->length(); i < len; i++) {
Expression* subexpr = subexprs->at(i);
if (subexpr->AsLiteral() != NULL) continue;
if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
Visit(subexpr);
CHECK_BAILOUT;
}
}
void FullCodeGenSyntaxChecker::VisitCatchExtensionObject(
CatchExtensionObject* expr) {
Visit(expr->key());
CHECK_BAILOUT;
Visit(expr->value());
}
void FullCodeGenSyntaxChecker::VisitAssignment(Assignment* expr) {
// We support plain non-compound assignments to properties, parameters and
// non-context (stack-allocated) locals, and global variables.
Token::Value op = expr->op();
if (op == Token::INIT_CONST) BAILOUT("initialize constant");
Variable* var = expr->target()->AsVariableProxy()->AsVariable();
Property* prop = expr->target()->AsProperty();
ASSERT(var == NULL || prop == NULL);
if (var != NULL) {
if (var->mode() == Variable::CONST) {
BAILOUT("Assignment to const");
}
// All global variables are supported.
if (!var->is_global()) {
ASSERT(var->slot() != NULL);
Slot::Type type = var->slot()->type();
if (type == Slot::LOOKUP) {
BAILOUT("Lookup slot");
}
}
} else if (prop != NULL) {
Visit(prop->obj());
CHECK_BAILOUT;
Visit(prop->key());
CHECK_BAILOUT;
} else {
// This is a throw reference error.
BAILOUT("non-variable/non-property assignment");
}
Visit(expr->value());
}
void FullCodeGenSyntaxChecker::VisitThrow(Throw* expr) {
Visit(expr->exception());
}
void FullCodeGenSyntaxChecker::VisitProperty(Property* expr) {
Visit(expr->obj());
CHECK_BAILOUT;
Visit(expr->key());
}
void FullCodeGenSyntaxChecker::VisitCall(Call* expr) {
Expression* fun = expr->expression();
ZoneList<Expression*>* args = expr->arguments();
Variable* var = fun->AsVariableProxy()->AsVariable();
// Check for supported calls
if (var != NULL && var->is_possibly_eval()) {
BAILOUT("call to the identifier 'eval'");
} else if (var != NULL && !var->is_this() && var->is_global()) {
// Calls to global variables are supported.
} else if (var != NULL && var->slot() != NULL &&
var->slot()->type() == Slot::LOOKUP) {
BAILOUT("call to a lookup slot");
} else if (fun->AsProperty() != NULL) {
Property* prop = fun->AsProperty();
Visit(prop->obj());
CHECK_BAILOUT;
Visit(prop->key());
CHECK_BAILOUT;
} else {
// Otherwise the call is supported if the function expression is.
Visit(fun);
}
// Check all arguments to the call.
for (int i = 0; i < args->length(); i++) {
Visit(args->at(i));
CHECK_BAILOUT;
}
}
void FullCodeGenSyntaxChecker::VisitCallNew(CallNew* expr) {
Visit(expr->expression());
CHECK_BAILOUT;
ZoneList<Expression*>* args = expr->arguments();
// Check all arguments to the call
for (int i = 0; i < args->length(); i++) {
Visit(args->at(i));
CHECK_BAILOUT;
}
}
void FullCodeGenSyntaxChecker::VisitCallRuntime(CallRuntime* expr) {
// Check for inline runtime call
if (expr->name()->Get(0) == '_' &&
CodeGenerator::FindInlineRuntimeLUT(expr->name()) != NULL) {
BAILOUT("inlined runtime call");
}
// Check all arguments to the call. (Relies on TEMP meaning STACK.)
for (int i = 0; i < expr->arguments()->length(); i++) {
Visit(expr->arguments()->at(i));
CHECK_BAILOUT;
}
}
void FullCodeGenSyntaxChecker::VisitUnaryOperation(UnaryOperation* expr) {
switch (expr->op()) {
case Token::VOID:
case Token::NOT:
case Token::TYPEOF:
Visit(expr->expression());
break;
case Token::BIT_NOT:
BAILOUT("UnaryOperation: BIT_NOT");
case Token::DELETE:
BAILOUT("UnaryOperation: DELETE");
case Token::ADD:
BAILOUT("UnaryOperation: ADD");
case Token::SUB:
BAILOUT("UnaryOperation: SUB");
default:
UNREACHABLE();
}
}
void FullCodeGenSyntaxChecker::VisitCountOperation(CountOperation* expr) {
Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
Property* prop = expr->expression()->AsProperty();
ASSERT(var == NULL || prop == NULL);
if (var != NULL) {
// All global variables are supported.
if (!var->is_global()) {
ASSERT(var->slot() != NULL);
Slot::Type type = var->slot()->type();
if (type == Slot::LOOKUP) {
BAILOUT("CountOperation with lookup slot");
}
}
} else if (prop != NULL) {
Visit(prop->obj());
CHECK_BAILOUT;
Visit(prop->key());
CHECK_BAILOUT;
} else {
// This is a throw reference error.
BAILOUT("CountOperation non-variable/non-property expression");
}
}
void FullCodeGenSyntaxChecker::VisitBinaryOperation(BinaryOperation* expr) {
Visit(expr->left());
CHECK_BAILOUT;
Visit(expr->right());
}
void FullCodeGenSyntaxChecker::VisitCompareOperation(CompareOperation* expr) {
Visit(expr->left());
CHECK_BAILOUT;
Visit(expr->right());
}
void FullCodeGenSyntaxChecker::VisitThisFunction(ThisFunction* expr) {
// Supported.
}
#undef BAILOUT
#undef CHECK_BAILOUT
#define __ ACCESS_MASM(masm())
Handle<Code> FastCodeGenerator::MakeCode(FunctionLiteral* fun,
Handle<Code> FullCodeGenerator::MakeCode(FunctionLiteral* fun,
Handle<Script> script,
bool is_eval) {
CodeGenerator::MakeCodePrologue(fun);
const int kInitialBufferSize = 4 * KB;
MacroAssembler masm(NULL, kInitialBufferSize);
FastCodeGenerator cgen(&masm, script, is_eval);
FullCodeGenerator cgen(&masm, script, is_eval);
cgen.Generate(fun);
if (cgen.HasStackOverflow()) {
ASSERT(!Top::has_pending_exception());
@ -55,7 +490,7 @@ Handle<Code> FastCodeGenerator::MakeCode(FunctionLiteral* fun,
}
int FastCodeGenerator::SlotOffset(Slot* slot) {
int FullCodeGenerator::SlotOffset(Slot* slot) {
ASSERT(slot != NULL);
// Offset is negative because higher indexes are at lower addresses.
int offset = -slot->index() * kPointerSize;
@ -75,7 +510,7 @@ int FastCodeGenerator::SlotOffset(Slot* slot) {
}
void FastCodeGenerator::VisitDeclarations(
void FullCodeGenerator::VisitDeclarations(
ZoneList<Declaration*>* declarations) {
int length = declarations->length();
int globals = 0;
@ -129,42 +564,42 @@ void FastCodeGenerator::VisitDeclarations(
}
void FastCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) {
void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) {
if (FLAG_debug_info) {
CodeGenerator::RecordPositions(masm_, fun->start_position());
}
}
void FastCodeGenerator::SetReturnPosition(FunctionLiteral* fun) {
void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) {
if (FLAG_debug_info) {
CodeGenerator::RecordPositions(masm_, fun->end_position());
}
}
void FastCodeGenerator::SetStatementPosition(Statement* stmt) {
void FullCodeGenerator::SetStatementPosition(Statement* stmt) {
if (FLAG_debug_info) {
CodeGenerator::RecordPositions(masm_, stmt->statement_pos());
}
}
void FastCodeGenerator::SetStatementPosition(int pos) {
void FullCodeGenerator::SetStatementPosition(int pos) {
if (FLAG_debug_info) {
CodeGenerator::RecordPositions(masm_, pos);
}
}
void FastCodeGenerator::SetSourcePosition(int pos) {
void FullCodeGenerator::SetSourcePosition(int pos) {
if (FLAG_debug_info && pos != RelocInfo::kNoPosition) {
masm_->RecordPosition(pos);
}
}
void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
void FullCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
Label eval_right, done;
// Set up the appropriate context for the left subexpression based
@ -232,7 +667,7 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
}
void FastCodeGenerator::VisitBlock(Block* stmt) {
void FullCodeGenerator::VisitBlock(Block* stmt) {
Comment cmnt(masm_, "[ Block");
Breakable nested_statement(this, stmt);
SetStatementPosition(stmt);
@ -241,20 +676,20 @@ void FastCodeGenerator::VisitBlock(Block* stmt) {
}
void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
Comment cmnt(masm_, "[ ExpressionStatement");
SetStatementPosition(stmt);
VisitForEffect(stmt->expression());
}
void FastCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
void FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
Comment cmnt(masm_, "[ EmptyStatement");
SetStatementPosition(stmt);
}
void FastCodeGenerator::VisitIfStatement(IfStatement* stmt) {
void FullCodeGenerator::VisitIfStatement(IfStatement* stmt) {
Comment cmnt(masm_, "[ IfStatement");
SetStatementPosition(stmt);
Label then_part, else_part, done;
@ -273,7 +708,7 @@ void FastCodeGenerator::VisitIfStatement(IfStatement* stmt) {
}
void FastCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
Comment cmnt(masm_, "[ ContinueStatement");
SetStatementPosition(stmt);
NestedStatement* current = nesting_stack_;
@ -289,7 +724,7 @@ void FastCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
}
void FastCodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
Comment cmnt(masm_, "[ BreakStatement");
SetStatementPosition(stmt);
NestedStatement* current = nesting_stack_;
@ -305,7 +740,7 @@ void FastCodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
}
void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
Comment cmnt(masm_, "[ ReturnStatement");
SetStatementPosition(stmt);
Expression* expr = stmt->expression();
@ -324,7 +759,7 @@ void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
}
void FastCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) {
void FullCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) {
Comment cmnt(masm_, "[ WithEnterStatement");
SetStatementPosition(stmt);
@ -342,7 +777,7 @@ void FastCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) {
}
void FastCodeGenerator::VisitWithExitStatement(WithExitStatement* stmt) {
void FullCodeGenerator::VisitWithExitStatement(WithExitStatement* stmt) {
Comment cmnt(masm_, "[ WithExitStatement");
SetStatementPosition(stmt);
@ -353,12 +788,12 @@ void FastCodeGenerator::VisitWithExitStatement(WithExitStatement* stmt) {
}
void FastCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
UNREACHABLE();
}
void FastCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
Comment cmnt(masm_, "[ DoWhileStatement");
SetStatementPosition(stmt);
Label body, stack_limit_hit, stack_check_success;
@ -388,7 +823,7 @@ void FastCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
}
void FastCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
Comment cmnt(masm_, "[ WhileStatement");
SetStatementPosition(stmt);
Label body, stack_limit_hit, stack_check_success;
@ -419,17 +854,17 @@ void FastCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
}
void FastCodeGenerator::VisitForStatement(ForStatement* stmt) {
void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
UNREACHABLE();
}
void FastCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
UNREACHABLE();
}
void FastCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
Comment cmnt(masm_, "[ TryCatchStatement");
SetStatementPosition(stmt);
// The try block adds a handler to the exception handler chain
@ -472,7 +907,7 @@ void FastCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
}
void FastCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
Comment cmnt(masm_, "[ TryFinallyStatement");
SetStatementPosition(stmt);
// Try finally is compiled by setting up a try-handler on the stack while
@ -536,7 +971,7 @@ void FastCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
}
void FastCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
#ifdef ENABLE_DEBUGGER_SUPPORT
Comment cmnt(masm_, "[ DebuggerStatement");
SetStatementPosition(stmt);
@ -546,13 +981,13 @@ void FastCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
}
void FastCodeGenerator::VisitFunctionBoilerplateLiteral(
void FullCodeGenerator::VisitFunctionBoilerplateLiteral(
FunctionBoilerplateLiteral* expr) {
UNREACHABLE();
}
void FastCodeGenerator::VisitConditional(Conditional* expr) {
void FullCodeGenerator::VisitConditional(Conditional* expr) {
Comment cmnt(masm_, "[ Conditional");
Label true_case, false_case, done;
VisitForControl(expr->condition(), &true_case, &false_case);
@ -573,19 +1008,19 @@ void FastCodeGenerator::VisitConditional(Conditional* expr) {
}
void FastCodeGenerator::VisitSlot(Slot* expr) {
void FullCodeGenerator::VisitSlot(Slot* expr) {
// Slots do not appear directly in the AST.
UNREACHABLE();
}
void FastCodeGenerator::VisitLiteral(Literal* expr) {
void FullCodeGenerator::VisitLiteral(Literal* expr) {
Comment cmnt(masm_, "[ Literal");
Apply(context_, expr);
}
void FastCodeGenerator::VisitAssignment(Assignment* expr) {
void FullCodeGenerator::VisitAssignment(Assignment* expr) {
Comment cmnt(masm_, "[ Assignment");
// Left-hand side can only be a property, a global or a (parameter or local)
// slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
@ -664,7 +1099,7 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
}
void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) {
void FullCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) {
// Call runtime routine to allocate the catch extension object and
// assign the exception value to the catch variable.
Comment cmnt(masm_, "[ CatchExtensionObject");
@ -676,7 +1111,7 @@ void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) {
}
void FastCodeGenerator::VisitThrow(Throw* expr) {
void FullCodeGenerator::VisitThrow(Throw* expr) {
Comment cmnt(masm_, "[ Throw");
VisitForValue(expr->exception(), kStack);
__ CallRuntime(Runtime::kThrow, 1);
@ -684,7 +1119,7 @@ void FastCodeGenerator::VisitThrow(Throw* expr) {
}
int FastCodeGenerator::TryFinally::Exit(int stack_depth) {
int FullCodeGenerator::TryFinally::Exit(int stack_depth) {
// The macros used here must preserve the result register.
__ Drop(stack_depth);
__ PopTryHandler();
@ -693,7 +1128,7 @@ int FastCodeGenerator::TryFinally::Exit(int stack_depth) {
}
int FastCodeGenerator::TryCatch::Exit(int stack_depth) {
int FullCodeGenerator::TryCatch::Exit(int stack_depth) {
// The macros used here must preserve the result register.
__ Drop(stack_depth);
__ PopTryHandler();

View File

@ -35,12 +35,35 @@
namespace v8 {
namespace internal {
// -----------------------------------------------------------------------------
// Fast code generator.
class FastCodeGenerator: public AstVisitor {
class FullCodeGenSyntaxChecker: public AstVisitor {
public:
FastCodeGenerator(MacroAssembler* masm, Handle<Script> script, bool is_eval)
FullCodeGenSyntaxChecker() : has_supported_syntax_(true) {}
void Check(FunctionLiteral* fun);
bool has_supported_syntax() { return has_supported_syntax_; }
private:
void VisitDeclarations(ZoneList<Declaration*>* decls);
void VisitStatements(ZoneList<Statement*>* stmts);
// AST node visit functions.
#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
AST_NODE_LIST(DECLARE_VISIT)
#undef DECLARE_VISIT
bool has_supported_syntax_;
DISALLOW_COPY_AND_ASSIGN(FullCodeGenSyntaxChecker);
};
// -----------------------------------------------------------------------------
// Full code generator.
class FullCodeGenerator: public AstVisitor {
public:
FullCodeGenerator(MacroAssembler* masm, Handle<Script> script, bool is_eval)
: masm_(masm),
function_(NULL),
script_(script),
@ -68,7 +91,7 @@ class FastCodeGenerator: public AstVisitor {
class NestedStatement BASE_EMBEDDED {
public:
explicit NestedStatement(FastCodeGenerator* codegen) : codegen_(codegen) {
explicit NestedStatement(FullCodeGenerator* codegen) : codegen_(codegen) {
// Link into codegen's nesting stack.
previous_ = codegen->nesting_stack_;
codegen->nesting_stack_ = this;
@ -106,14 +129,14 @@ class FastCodeGenerator: public AstVisitor {
protected:
MacroAssembler* masm() { return codegen_->masm(); }
private:
FastCodeGenerator* codegen_;
FullCodeGenerator* codegen_;
NestedStatement* previous_;
DISALLOW_COPY_AND_ASSIGN(NestedStatement);
};
class Breakable : public NestedStatement {
public:
Breakable(FastCodeGenerator* codegen,
Breakable(FullCodeGenerator* codegen,
BreakableStatement* break_target)
: NestedStatement(codegen),
target_(break_target) {}
@ -132,7 +155,7 @@ class FastCodeGenerator: public AstVisitor {
class Iteration : public Breakable {
public:
Iteration(FastCodeGenerator* codegen,
Iteration(FullCodeGenerator* codegen,
IterationStatement* iteration_statement)
: Breakable(codegen, iteration_statement) {}
virtual ~Iteration() {}
@ -149,7 +172,7 @@ class FastCodeGenerator: public AstVisitor {
// The environment inside the try block of a try/catch statement.
class TryCatch : public NestedStatement {
public:
explicit TryCatch(FastCodeGenerator* codegen, Label* catch_entry)
explicit TryCatch(FullCodeGenerator* codegen, Label* catch_entry)
: NestedStatement(codegen), catch_entry_(catch_entry) { }
virtual ~TryCatch() {}
virtual TryCatch* AsTryCatch() { return this; }
@ -163,7 +186,7 @@ class FastCodeGenerator: public AstVisitor {
// The environment inside the try block of a try/finally statement.
class TryFinally : public NestedStatement {
public:
explicit TryFinally(FastCodeGenerator* codegen, Label* finally_entry)
explicit TryFinally(FullCodeGenerator* codegen, Label* finally_entry)
: NestedStatement(codegen), finally_entry_(finally_entry) { }
virtual ~TryFinally() {}
virtual TryFinally* AsTryFinally() { return this; }
@ -179,7 +202,7 @@ class FastCodeGenerator: public AstVisitor {
// the block's parameters from the stack.
class Finally : public NestedStatement {
public:
explicit Finally(FastCodeGenerator* codegen) : NestedStatement(codegen) { }
explicit Finally(FullCodeGenerator* codegen) : NestedStatement(codegen) { }
virtual ~Finally() {}
virtual Finally* AsFinally() { return this; }
virtual int Exit(int stack_depth) {
@ -196,7 +219,7 @@ class FastCodeGenerator: public AstVisitor {
// the block's temporary storage from the stack.
class ForIn : public Iteration {
public:
ForIn(FastCodeGenerator* codegen,
ForIn(FullCodeGenerator* codegen,
ForInStatement* statement)
: Iteration(codegen, statement) { }
virtual ~ForIn() {}
@ -410,7 +433,7 @@ class FastCodeGenerator: public AstVisitor {
friend class NestedStatement;
DISALLOW_COPY_AND_ASSIGN(FastCodeGenerator);
DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator);
};

View File

@ -614,8 +614,8 @@ class CodeGenerator: public AstVisitor {
friend class JumpTarget;
friend class Reference;
friend class Result;
friend class FastCodeGenerator;
friend class CodeGenSelector;
friend class FullCodeGenerator;
friend class FullCodeGenSyntaxChecker;
friend class CodeGeneratorPatcher; // Used in test-log-stack-tracer.cc

View File

@ -51,7 +51,7 @@ namespace internal {
//
// The function builds a JS frame. Please see JavaScriptFrameConstants in
// frames-ia32.h for its layout.
void FastCodeGenerator::Generate(FunctionLiteral* fun) {
void FullCodeGenerator::Generate(FunctionLiteral* fun) {
function_ = fun;
SetFunctionPosition(fun);
@ -160,7 +160,7 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) {
}
void FastCodeGenerator::EmitReturnSequence(int position) {
void FullCodeGenerator::EmitReturnSequence(int position) {
Comment cmnt(masm_, "[ Return sequence");
if (return_label_.is_bound()) {
__ jmp(&return_label_);
@ -193,7 +193,7 @@ void FastCodeGenerator::EmitReturnSequence(int position) {
}
void FastCodeGenerator::Apply(Expression::Context context, Register reg) {
void FullCodeGenerator::Apply(Expression::Context context, Register reg) {
switch (context) {
case Expression::kUninitialized:
UNREACHABLE();
@ -236,7 +236,7 @@ void FastCodeGenerator::Apply(Expression::Context context, Register reg) {
}
void FastCodeGenerator::Apply(Expression::Context context, Slot* slot) {
void FullCodeGenerator::Apply(Expression::Context context, Slot* slot) {
switch (context) {
case Expression::kUninitialized:
UNREACHABLE();
@ -279,7 +279,7 @@ void FastCodeGenerator::Apply(Expression::Context context, Slot* slot) {
}
void FastCodeGenerator::Apply(Expression::Context context, Literal* lit) {
void FullCodeGenerator::Apply(Expression::Context context, Literal* lit) {
switch (context) {
case Expression::kUninitialized:
UNREACHABLE();
@ -320,7 +320,7 @@ void FastCodeGenerator::Apply(Expression::Context context, Literal* lit) {
}
void FastCodeGenerator::ApplyTOS(Expression::Context context) {
void FullCodeGenerator::ApplyTOS(Expression::Context context) {
switch (context) {
case Expression::kUninitialized:
UNREACHABLE();
@ -361,7 +361,7 @@ void FastCodeGenerator::ApplyTOS(Expression::Context context) {
}
void FastCodeGenerator::DropAndApply(int count,
void FullCodeGenerator::DropAndApply(int count,
Expression::Context context,
Register reg) {
ASSERT(count > 0);
@ -413,7 +413,7 @@ void FastCodeGenerator::DropAndApply(int count,
}
void FastCodeGenerator::Apply(Expression::Context context,
void FullCodeGenerator::Apply(Expression::Context context,
Label* materialize_true,
Label* materialize_false) {
switch (context) {
@ -478,7 +478,7 @@ void FastCodeGenerator::Apply(Expression::Context context,
}
void FastCodeGenerator::DoTest(Expression::Context context) {
void FullCodeGenerator::DoTest(Expression::Context context) {
// The value to test is in the accumulator. If the value might be needed
// on the stack (value/test and test/value contexts with a stack location
// desired), then the value is already duplicated on the stack.
@ -612,7 +612,7 @@ void FastCodeGenerator::DoTest(Expression::Context context) {
}
MemOperand FastCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) {
MemOperand FullCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) {
switch (slot->type()) {
case Slot::PARAMETER:
case Slot::LOCAL:
@ -631,13 +631,13 @@ MemOperand FastCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) {
}
void FastCodeGenerator::Move(Register destination, Slot* source) {
void FullCodeGenerator::Move(Register destination, Slot* source) {
MemOperand location = EmitSlotSearch(source, destination);
__ mov(destination, location);
}
void FastCodeGenerator::Move(Slot* dst,
void FullCodeGenerator::Move(Slot* dst,
Register src,
Register scratch1,
Register scratch2) {
@ -653,7 +653,7 @@ void FastCodeGenerator::Move(Slot* dst,
}
void FastCodeGenerator::VisitDeclaration(Declaration* decl) {
void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
Comment cmnt(masm_, "[ Declaration");
Variable* var = decl->proxy()->var();
ASSERT(var != NULL); // Must have been resolved.
@ -751,7 +751,7 @@ void FastCodeGenerator::VisitDeclaration(Declaration* decl) {
}
void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
// Call the runtime to declare the globals.
__ push(esi); // The context is the first argument.
__ push(Immediate(pairs));
@ -761,7 +761,7 @@ void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
}
void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
Comment cmnt(masm_, "[ FunctionLiteral");
// Build the function boilerplate and instantiate it.
@ -779,13 +779,13 @@ void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
}
void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
Comment cmnt(masm_, "[ VariableProxy");
EmitVariableLoad(expr->var(), context_);
}
void FastCodeGenerator::EmitVariableLoad(Variable* var,
void FullCodeGenerator::EmitVariableLoad(Variable* var,
Expression::Context context) {
Expression* rewrite = var->rewrite();
if (rewrite == NULL) {
@ -862,7 +862,7 @@ void FastCodeGenerator::EmitVariableLoad(Variable* var,
}
void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
Comment cmnt(masm_, "[ RegExpLiteral");
Label done;
// Registers will be used as follows:
@ -889,7 +889,7 @@ void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
}
void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
Comment cmnt(masm_, "[ ObjectLiteral");
__ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
__ push(FieldOperand(edi, JSFunction::kLiteralsOffset));
@ -958,7 +958,7 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
}
void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
Comment cmnt(masm_, "[ ArrayLiteral");
__ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
__ push(FieldOperand(ebx, JSFunction::kLiteralsOffset));
@ -1008,7 +1008,7 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
}
void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
__ mov(ecx, Immediate(key->handle()));
@ -1018,7 +1018,7 @@ void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
}
void FastCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET);
@ -1026,7 +1026,7 @@ void FastCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
}
void FastCodeGenerator::EmitBinaryOp(Token::Value op,
void FullCodeGenerator::EmitBinaryOp(Token::Value op,
Expression::Context context) {
__ push(result_register());
GenericBinaryOpStub stub(op,
@ -1037,7 +1037,7 @@ void FastCodeGenerator::EmitBinaryOp(Token::Value op,
}
void FastCodeGenerator::EmitVariableAssignment(Variable* var,
void FullCodeGenerator::EmitVariableAssignment(Variable* var,
Expression::Context context) {
ASSERT(var != NULL);
ASSERT(var->is_global() || var->slot() != NULL);
@ -1086,7 +1086,7 @@ void FastCodeGenerator::EmitVariableAssignment(Variable* var,
}
void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
// Assignment to a property, using a named store IC.
Property* prop = expr->target()->AsProperty();
ASSERT(prop != NULL);
@ -1121,7 +1121,7 @@ void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
}
void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
// Assignment to a property, using a keyed store IC.
// If the assignment starts a block of assignments to the same object,
@ -1157,7 +1157,7 @@ void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
}
void FastCodeGenerator::VisitProperty(Property* expr) {
void FullCodeGenerator::VisitProperty(Property* expr) {
Comment cmnt(masm_, "[ Property");
Expression* key = expr->key();
@ -1177,7 +1177,7 @@ void FastCodeGenerator::VisitProperty(Property* expr) {
}
void FastCodeGenerator::EmitCallWithIC(Call* expr,
void FullCodeGenerator::EmitCallWithIC(Call* expr,
Handle<Object> name,
RelocInfo::Mode mode) {
// Code common for calls using the IC.
@ -1198,7 +1198,7 @@ void FastCodeGenerator::EmitCallWithIC(Call* expr,
}
void FastCodeGenerator::EmitCallWithStub(Call* expr) {
void FullCodeGenerator::EmitCallWithStub(Call* expr) {
// Code common for calls using the call stub.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
@ -1215,7 +1215,7 @@ void FastCodeGenerator::EmitCallWithStub(Call* expr) {
}
void FastCodeGenerator::VisitCall(Call* expr) {
void FullCodeGenerator::VisitCall(Call* expr) {
Comment cmnt(masm_, "[ Call");
Expression* fun = expr->expression();
Variable* var = fun->AsVariableProxy()->AsVariable();
@ -1286,7 +1286,7 @@ void FastCodeGenerator::VisitCall(Call* expr) {
}
void FastCodeGenerator::VisitCallNew(CallNew* expr) {
void FullCodeGenerator::VisitCallNew(CallNew* expr) {
Comment cmnt(masm_, "[ CallNew");
// According to ECMA-262, section 11.2.2, page 44, the function
// expression in new calls must be evaluated before the
@ -1321,7 +1321,7 @@ void FastCodeGenerator::VisitCallNew(CallNew* expr) {
}
void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
Comment cmnt(masm_, "[ CallRuntime");
ZoneList<Expression*>* args = expr->arguments();
@ -1353,7 +1353,7 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
}
void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
switch (expr->op()) {
case Token::VOID: {
Comment cmnt(masm_, "[ UnaryOperation (VOID)");
@ -1463,7 +1463,7 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
}
void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
Comment cmnt(masm_, "[ CountOperation");
// Expression can only be a property, a global or a (parameter or local)
@ -1595,7 +1595,7 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
}
void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
Comment cmnt(masm_, "[ BinaryOperation");
switch (expr->op()) {
case Token::COMMA:
@ -1630,7 +1630,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
}
void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
Comment cmnt(masm_, "[ CompareOperation");
// Always perform the comparison for its control flow. Pack the result
@ -1745,25 +1745,25 @@ void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
}
void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) {
void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
__ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
Apply(context_, eax);
}
Register FastCodeGenerator::result_register() { return eax; }
Register FullCodeGenerator::result_register() { return eax; }
Register FastCodeGenerator::context_register() { return esi; }
Register FullCodeGenerator::context_register() { return esi; }
void FastCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
__ mov(Operand(ebp, frame_offset), value);
}
void FastCodeGenerator::LoadContextField(Register dst, int context_index) {
void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
__ mov(dst, CodeGenerator::ContextOperand(esi, context_index));
}
@ -1771,7 +1771,7 @@ void FastCodeGenerator::LoadContextField(Register dst, int context_index) {
// ----------------------------------------------------------------------------
// Non-local control flow support.
void FastCodeGenerator::EnterFinallyBlock() {
void FullCodeGenerator::EnterFinallyBlock() {
// Cook return address on top of stack (smi encoded Code* delta)
ASSERT(!result_register().is(edx));
__ mov(edx, Operand(esp, 0));
@ -1785,7 +1785,7 @@ void FastCodeGenerator::EnterFinallyBlock() {
}
void FastCodeGenerator::ExitFinallyBlock() {
void FullCodeGenerator::ExitFinallyBlock() {
ASSERT(!result_register().is(edx));
// Restore result register from stack.
__ pop(result_register());

View File

@ -611,8 +611,8 @@ class CodeGenerator: public AstVisitor {
friend class JumpTarget;
friend class Reference;
friend class Result;
friend class FastCodeGenerator;
friend class CodeGenSelector;
friend class FullCodeGenerator;
friend class FullCodeGenSyntaxChecker;
friend class CodeGeneratorPatcher; // Used in test-log-stack-tracer.cc

View File

@ -51,7 +51,7 @@ namespace internal {
//
// The function builds a JS frame. Please see JavaScriptFrameConstants in
// frames-x64.h for its layout.
void FastCodeGenerator::Generate(FunctionLiteral* fun) {
void FullCodeGenerator::Generate(FunctionLiteral* fun) {
function_ = fun;
SetFunctionPosition(fun);
@ -161,7 +161,7 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) {
}
void FastCodeGenerator::EmitReturnSequence(int position) {
void FullCodeGenerator::EmitReturnSequence(int position) {
Comment cmnt(masm_, "[ Return sequence");
if (return_label_.is_bound()) {
__ jmp(&return_label_);
@ -200,7 +200,7 @@ void FastCodeGenerator::EmitReturnSequence(int position) {
}
void FastCodeGenerator::Apply(Expression::Context context, Register reg) {
void FullCodeGenerator::Apply(Expression::Context context, Register reg) {
switch (context) {
case Expression::kUninitialized:
UNREACHABLE();
@ -243,7 +243,7 @@ void FastCodeGenerator::Apply(Expression::Context context, Register reg) {
}
void FastCodeGenerator::Apply(Expression::Context context, Slot* slot) {
void FullCodeGenerator::Apply(Expression::Context context, Slot* slot) {
switch (context) {
case Expression::kUninitialized:
UNREACHABLE();
@ -285,7 +285,7 @@ void FastCodeGenerator::Apply(Expression::Context context, Slot* slot) {
}
void FastCodeGenerator::Apply(Expression::Context context, Literal* lit) {
void FullCodeGenerator::Apply(Expression::Context context, Literal* lit) {
switch (context) {
case Expression::kUninitialized:
UNREACHABLE();
@ -324,7 +324,7 @@ void FastCodeGenerator::Apply(Expression::Context context, Literal* lit) {
}
void FastCodeGenerator::ApplyTOS(Expression::Context context) {
void FullCodeGenerator::ApplyTOS(Expression::Context context) {
switch (context) {
case Expression::kUninitialized:
UNREACHABLE();
@ -364,7 +364,7 @@ void FastCodeGenerator::ApplyTOS(Expression::Context context) {
}
void FastCodeGenerator::DropAndApply(int count,
void FullCodeGenerator::DropAndApply(int count,
Expression::Context context,
Register reg) {
ASSERT(count > 0);
@ -415,7 +415,7 @@ void FastCodeGenerator::DropAndApply(int count,
}
void FastCodeGenerator::Apply(Expression::Context context,
void FullCodeGenerator::Apply(Expression::Context context,
Label* materialize_true,
Label* materialize_false) {
switch (context) {
@ -480,7 +480,7 @@ void FastCodeGenerator::Apply(Expression::Context context,
}
void FastCodeGenerator::DoTest(Expression::Context context) {
void FullCodeGenerator::DoTest(Expression::Context context) {
// The value to test is in the accumulator. If the value might be needed
// on the stack (value/test and test/value contexts with a stack location
// desired), then the value is already duplicated on the stack.
@ -614,7 +614,7 @@ void FastCodeGenerator::DoTest(Expression::Context context) {
}
MemOperand FastCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) {
MemOperand FullCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) {
switch (slot->type()) {
case Slot::PARAMETER:
case Slot::LOCAL:
@ -633,13 +633,13 @@ MemOperand FastCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) {
}
void FastCodeGenerator::Move(Register destination, Slot* source) {
void FullCodeGenerator::Move(Register destination, Slot* source) {
MemOperand location = EmitSlotSearch(source, destination);
__ movq(destination, location);
}
void FastCodeGenerator::Move(Slot* dst,
void FullCodeGenerator::Move(Slot* dst,
Register src,
Register scratch1,
Register scratch2) {
@ -655,7 +655,7 @@ void FastCodeGenerator::Move(Slot* dst,
}
void FastCodeGenerator::VisitDeclaration(Declaration* decl) {
void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
Comment cmnt(masm_, "[ Declaration");
Variable* var = decl->proxy()->var();
ASSERT(var != NULL); // Must have been resolved.
@ -754,7 +754,7 @@ void FastCodeGenerator::VisitDeclaration(Declaration* decl) {
}
void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
// Call the runtime to declare the globals.
__ push(rsi); // The context is the first argument.
__ Push(pairs);
@ -764,7 +764,7 @@ void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
}
void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
Comment cmnt(masm_, "[ FunctionLiteral");
// Build the function boilerplate and instantiate it.
@ -782,13 +782,13 @@ void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
}
void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
Comment cmnt(masm_, "[ VariableProxy");
EmitVariableLoad(expr->var(), context_);
}
void FastCodeGenerator::EmitVariableLoad(Variable* var,
void FullCodeGenerator::EmitVariableLoad(Variable* var,
Expression::Context context) {
Expression* rewrite = var->rewrite();
if (rewrite == NULL) {
@ -864,7 +864,7 @@ void FastCodeGenerator::EmitVariableLoad(Variable* var,
}
void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
Comment cmnt(masm_, "[ RegExpLiteral");
Label done;
// Registers will be used as follows:
@ -890,7 +890,7 @@ void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
}
void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
Comment cmnt(masm_, "[ ObjectLiteral");
__ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
__ push(FieldOperand(rdi, JSFunction::kLiteralsOffset));
@ -960,7 +960,7 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
}
void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
Comment cmnt(masm_, "[ ArrayLiteral");
__ movq(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
__ push(FieldOperand(rbx, JSFunction::kLiteralsOffset));
@ -1010,7 +1010,7 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
}
void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
__ Move(rcx, key->handle());
@ -1020,7 +1020,7 @@ void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
}
void FastCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
@ -1028,7 +1028,7 @@ void FastCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
}
void FastCodeGenerator::EmitBinaryOp(Token::Value op,
void FullCodeGenerator::EmitBinaryOp(Token::Value op,
Expression::Context context) {
__ push(result_register());
GenericBinaryOpStub stub(op,
@ -1039,7 +1039,7 @@ void FastCodeGenerator::EmitBinaryOp(Token::Value op,
}
void FastCodeGenerator::EmitVariableAssignment(Variable* var,
void FullCodeGenerator::EmitVariableAssignment(Variable* var,
Expression::Context context) {
ASSERT(var != NULL);
ASSERT(var->is_global() || var->slot() != NULL);
@ -1086,7 +1086,7 @@ void FastCodeGenerator::EmitVariableAssignment(Variable* var,
}
void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
// Assignment to a property, using a named store IC.
Property* prop = expr->target()->AsProperty();
ASSERT(prop != NULL);
@ -1121,7 +1121,7 @@ void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
}
void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
// Assignment to a property, using a keyed store IC.
// If the assignment starts a block of assignments to the same object,
@ -1157,7 +1157,7 @@ void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
}
void FastCodeGenerator::VisitProperty(Property* expr) {
void FullCodeGenerator::VisitProperty(Property* expr) {
Comment cmnt(masm_, "[ Property");
Expression* key = expr->key();
@ -1177,7 +1177,7 @@ void FastCodeGenerator::VisitProperty(Property* expr) {
}
void FastCodeGenerator::EmitCallWithIC(Call* expr,
void FullCodeGenerator::EmitCallWithIC(Call* expr,
Handle<Object> ignored,
RelocInfo::Mode mode) {
// Code common for calls using the IC.
@ -1200,7 +1200,7 @@ void FastCodeGenerator::EmitCallWithIC(Call* expr,
}
void FastCodeGenerator::EmitCallWithStub(Call* expr) {
void FullCodeGenerator::EmitCallWithStub(Call* expr) {
// Code common for calls using the call stub.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
@ -1218,7 +1218,7 @@ void FastCodeGenerator::EmitCallWithStub(Call* expr) {
}
void FastCodeGenerator::VisitCall(Call* expr) {
void FullCodeGenerator::VisitCall(Call* expr) {
Comment cmnt(masm_, "[ Call");
Expression* fun = expr->expression();
Variable* var = fun->AsVariableProxy()->AsVariable();
@ -1292,7 +1292,7 @@ void FastCodeGenerator::VisitCall(Call* expr) {
}
void FastCodeGenerator::VisitCallNew(CallNew* expr) {
void FullCodeGenerator::VisitCallNew(CallNew* expr) {
Comment cmnt(masm_, "[ CallNew");
// According to ECMA-262, section 11.2.2, page 44, the function
// expression in new calls must be evaluated before the
@ -1327,7 +1327,7 @@ void FastCodeGenerator::VisitCallNew(CallNew* expr) {
}
void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
Comment cmnt(masm_, "[ CallRuntime");
ZoneList<Expression*>* args = expr->arguments();
@ -1360,7 +1360,7 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
}
void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
switch (expr->op()) {
case Token::VOID: {
Comment cmnt(masm_, "[ UnaryOperation (VOID)");
@ -1470,7 +1470,7 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
}
void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
Comment cmnt(masm_, "[ CountOperation");
// Expression can only be a property, a global or a (parameter or local)
@ -1601,7 +1601,7 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
}
}
void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
Comment cmnt(masm_, "[ BinaryOperation");
switch (expr->op()) {
case Token::COMMA:
@ -1636,7 +1636,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
}
void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
Comment cmnt(masm_, "[ CompareOperation");
// Always perform the comparison for its control flow. Pack the result
@ -1748,25 +1748,25 @@ void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
}
void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) {
void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
__ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
Apply(context_, rax);
}
Register FastCodeGenerator::result_register() { return rax; }
Register FullCodeGenerator::result_register() { return rax; }
Register FastCodeGenerator::context_register() { return rsi; }
Register FullCodeGenerator::context_register() { return rsi; }
void FastCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
ASSERT(IsAligned(frame_offset, kPointerSize));
__ movq(Operand(rbp, frame_offset), value);
}
void FastCodeGenerator::LoadContextField(Register dst, int context_index) {
void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
__ movq(dst, CodeGenerator::ContextOperand(rsi, context_index));
}
@ -1775,7 +1775,7 @@ void FastCodeGenerator::LoadContextField(Register dst, int context_index) {
// Non-local control flow support.
void FastCodeGenerator::EnterFinallyBlock() {
void FullCodeGenerator::EnterFinallyBlock() {
ASSERT(!result_register().is(rdx));
ASSERT(!result_register().is(rcx));
// Cook return address on top of stack (smi encoded Code* delta)
@ -1789,7 +1789,7 @@ void FastCodeGenerator::EnterFinallyBlock() {
}
void FastCodeGenerator::ExitFinallyBlock() {
void FullCodeGenerator::ExitFinallyBlock() {
ASSERT(!result_register().is(rdx));
ASSERT(!result_register().is(rcx));
// Restore result register from stack.