| Index: src/x64/fast-codegen-x64.cc
|
| ===================================================================
|
| --- src/x64/fast-codegen-x64.cc (revision 3095)
|
| +++ src/x64/fast-codegen-x64.cc (working copy)
|
| @@ -74,6 +74,10 @@
|
| __ bind(&ok);
|
| }
|
|
|
| + { Comment cmnt(masm_, "[ Declarations");
|
| + VisitDeclarations(fun->scope()->declarations());
|
| + }
|
| +
|
| { Comment cmnt(masm_, "[ Body");
|
| VisitStatements(fun->body());
|
| }
|
| @@ -102,6 +106,23 @@
|
| }
|
|
|
|
|
| +void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
|
| + // Call the runtime to declare the globals.
|
| + __ Push(pairs);
|
| + __ push(rsi); // The context is the second argument.
|
| + __ Push(Smi::FromInt(is_eval_ ? 1 : 0));
|
| + __ CallRuntime(Runtime::kDeclareGlobals, 3);
|
| + // Return value is ignored.
|
| +}
|
| +
|
| +
|
| +void FastCodeGenerator::VisitBlock(Block* stmt) {
|
| + Comment cmnt(masm_, "[ Block");
|
| + SetStatementPosition(stmt);
|
| + VisitStatements(stmt->statements());
|
| +}
|
| +
|
| +
|
| void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
|
| Comment cmnt(masm_, "[ ExpressionStatement");
|
| SetStatementPosition(stmt);
|
| @@ -143,6 +164,28 @@
|
| }
|
|
|
|
|
| +void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
|
| + Comment cmnt(masm_, "[ FunctionLiteral");
|
| +
|
| + // Build the function boilerplate and instantiate it.
|
| + Handle<JSFunction> boilerplate = BuildBoilerplate(expr);
|
| + if (HasStackOverflow()) return;
|
| +
|
| + ASSERT(boilerplate->IsBoilerplate());
|
| +
|
| + // Create a new closure.
|
| + __ Push(boilerplate);
|
| + __ push(rsi);
|
| + __ CallRuntime(Runtime::kNewClosure, 2);
|
| +
|
| + if (expr->location().is_temporary()) {
|
| + __ push(rax);
|
| + } else {
|
| + ASSERT(expr->location().is_nowhere());
|
| + }
|
| +}
|
| +
|
| +
|
| void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
|
| Comment cmnt(masm_, "[ VariableProxy");
|
| Expression* rewrite = expr->var()->rewrite();
|
| @@ -227,4 +270,68 @@
|
| }
|
|
|
|
|
| +void FastCodeGenerator::VisitCall(Call* expr) {
|
| + Expression* fun = expr->expression();
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| + Variable* var = fun->AsVariableProxy()->AsVariable();
|
| + ASSERT(var != NULL && !var->is_this() && var->is_global());
|
| + ASSERT(!var->is_possibly_eval());
|
| +
|
| + __ Push(var->name());
|
| + // Push global object (receiver).
|
| + __ push(CodeGenerator::GlobalObject());
|
| + int arg_count = args->length();
|
| + for (int i = 0; i < arg_count; i++) {
|
| + Visit(args->at(i));
|
| + ASSERT(!args->at(i)->location().is_nowhere());
|
| + if (args->at(i)->location().is_constant()) {
|
| + ASSERT(args->at(i)->AsLiteral() != NULL);
|
| + __ Push(args->at(i)->AsLiteral()->handle());
|
| + }
|
| + }
|
| + // Record source position for debugger
|
| + SetSourcePosition(expr->position());
|
| + // Call the IC initialization code.
|
| + Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
|
| + NOT_IN_LOOP);
|
| + __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
|
| + // Restore context register.
|
| + __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
| + // Discard the function left on TOS.
|
| + if (expr->location().is_temporary()) {
|
| + __ movq(Operand(rsp, 0), rax);
|
| + } else {
|
| + ASSERT(expr->location().is_nowhere());
|
| + __ pop(rax);
|
| + }
|
| +}
|
| +
|
| +
|
| +void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
| + Comment cmnt(masm_, "[ CallRuntime");
|
| + ZoneList<Expression*>* args = expr->arguments();
|
| + Runtime::Function* function = expr->function();
|
| +
|
| + ASSERT(function != NULL);
|
| +
|
| + // Push the arguments ("left-to-right").
|
| + int arg_count = args->length();
|
| + for (int i = 0; i < arg_count; i++) {
|
| + Visit(args->at(i));
|
| + ASSERT(!args->at(i)->location().is_nowhere());
|
| + if (args->at(i)->location().is_constant()) {
|
| + ASSERT(args->at(i)->AsLiteral() != NULL);
|
| + __ Push(args->at(i)->AsLiteral()->handle());
|
| + }
|
| + }
|
| +
|
| + __ CallRuntime(function, arg_count);
|
| + if (expr->location().is_temporary()) {
|
| + __ push(rax);
|
| + } else {
|
| + ASSERT(expr->location().is_nowhere());
|
| + }
|
| +}
|
| +
|
| +
|
| } } // namespace v8::internal
|
|
|