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

Unified Diff: src/compiler.cc

Issue 340005: In the toplevel compiler, shift the responsibility of assigning a... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ast.cc ('k') | src/ia32/fast-codegen-ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler.cc
===================================================================
--- src/compiler.cc (revision 3152)
+++ src/compiler.cc (working copy)
@@ -46,7 +46,10 @@
public:
enum CodeGenTag { NORMAL, FAST };
- CodeGenSelector() : has_supported_syntax_(true) {}
+ CodeGenSelector()
+ : has_supported_syntax_(true),
+ location_(Location::Nowhere()) {
fschneider 2009/10/28 10:06:01 I'm not sure: Should this match the default locati
Kevin Millikin (Chromium) 2009/10/28 11:39:38 Possibly. I wanted it to be nowhere when not insi
+ }
CodeGenTag Select(FunctionLiteral* fun);
@@ -54,6 +57,14 @@
void VisitDeclarations(ZoneList<Declaration*>* decls);
void VisitStatements(ZoneList<Statement*>* stmts);
+ // Visit an expression in effect context with a desired location of
+ // nowhere.
+ void VisitAsEffect(Expression* expr);
+
+ // Visit an expression in value context with a desired location of
+ // temporary.
+ void VisitAsValue(Expression* expr);
+
// AST node visit functions.
#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
AST_NODE_LIST(DECLARE_VISIT)
@@ -61,6 +72,9 @@
bool has_supported_syntax_;
+ // The desired location of the currently visited expression.
+ Location location_;
+
DISALLOW_COPY_AND_ASSIGN(CodeGenSelector);
};
@@ -499,6 +513,30 @@
}
+void CodeGenSelector::VisitAsEffect(Expression* expr) {
+ if (location_.is_nowhere()) {
+ Visit(expr);
+ } else {
+ Location saved = location_;
+ location_ = Location::Nowhere();
+ Visit(expr);
+ location_ = saved;
+ }
+}
+
+
+void CodeGenSelector::VisitAsValue(Expression* expr) {
+ if (location_.is_temporary()) {
+ Visit(expr);
+ } else {
+ Location saved = location_;
+ location_ = Location::Temporary();
+ Visit(expr);
+ location_ = saved;
+ }
+}
+
+
void CodeGenSelector::VisitDeclaration(Declaration* decl) {
Variable* var = decl->proxy()->var();
if (!var->is_global() || var->mode() == Variable::CONST) {
@@ -513,10 +551,7 @@
void CodeGenSelector::VisitExpressionStatement(ExpressionStatement* stmt) {
- Expression* expr = stmt->expression();
- Visit(expr);
- CHECK_BAILOUT;
- expr->set_location(Location::Nowhere());
+ VisitAsEffect(stmt->expression());
}
@@ -541,7 +576,7 @@
void CodeGenSelector::VisitReturnStatement(ReturnStatement* stmt) {
- Visit(stmt->expression());
+ VisitAsValue(stmt->expression());
}
@@ -599,6 +634,7 @@
if (!expr->AllowsLazyCompilation()) {
BAILOUT("FunctionLiteral does not allow lazy compilation");
}
+ expr->set_location(location_);
}
@@ -614,37 +650,72 @@
void CodeGenSelector::VisitSlot(Slot* expr) {
- Slot::Type type = expr->type();
- if (type != Slot::PARAMETER && type != Slot::LOCAL) {
- BAILOUT("non-parameter/non-local slot reference");
- }
+ UNREACHABLE();
}
void CodeGenSelector::VisitVariableProxy(VariableProxy* expr) {
Expression* rewrite = expr->var()->rewrite();
- if (rewrite != NULL) Visit(rewrite);
+ // A rewrite of NULL indicates a global variable.
+ if (rewrite != NULL) {
+ Slot* slot = rewrite->AsSlot();
+ if (slot != NULL) {
+ Slot::Type type = slot->type();
+ if (type != Slot::PARAMETER && type != Slot::LOCAL) {
+ BAILOUT("non-parameter/non-local slot reference");
+ }
William Hesse 2009/10/28 10:28:54 Control flow is tricky here. Reversing sense of s
Kevin Millikin (Chromium) 2009/10/28 11:39:38 I see what you mean. I've changed it.
+ } else {
+ BAILOUT("non-global/non-slot variable reference");
+ }
+ }
+ expr->set_location(location_);
}
void CodeGenSelector::VisitLiteral(Literal* expr) {
- // Literals are supported.
+ expr->set_location(location_);
}
void CodeGenSelector::VisitRegExpLiteral(RegExpLiteral* expr) {
- // RegexpLiterals are supported.
+ expr->set_location(location_);
}
void CodeGenSelector::VisitObjectLiteral(ObjectLiteral* expr) {
- for (int i = 0; i < expr->properties()->length(); i++) {
- ObjectLiteral::Property* property = expr->properties()->at(i);
- Visit(property->key());
+ 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;
+
+ switch (property->kind()) {
+ case ObjectLiteral::Property::CONSTANT:
+ UNREACHABLE();
+
+ // For (non-compile-time) materialized literals and computed
+ // properties with symbolic keys we will use an IC and therefore not
+ // generate code for the key.
+ case ObjectLiteral::Property::COMPUTED: // Fall through.
+ case ObjectLiteral::Property::MATERIALIZED_LITERAL:
+ if (property->key()->handle()->IsSymbol()) {
+ break;
+ }
+ // Fall through.
+
+ // In all other cases we need the key's value on the stack
+ // for a runtime call. (Relies on TEMP meaning STACK.)
+ case ObjectLiteral::Property::GETTER: // Fall through.
+ case ObjectLiteral::Property::SETTER: // Fall through.
+ case ObjectLiteral::Property::PROTOTYPE:
+ VisitAsValue(property->key());
+ CHECK_BAILOUT;
+ break;
+ }
+ VisitAsValue(property->value());
CHECK_BAILOUT;
- Visit(property->value());
- CHECK_BAILOUT;
}
+ expr->set_location(location_);
}
@@ -654,9 +725,10 @@
Expression* subexpr = subexprs->at(i);
if (subexpr->AsLiteral() != NULL) continue;
if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
- Visit(subexpr);
+ VisitAsValue(subexpr);
CHECK_BAILOUT;
}
+ expr->set_location(location_);
}
@@ -668,7 +740,10 @@
void CodeGenSelector::VisitAssignment(Assignment* expr) {
// We support plain non-compound assignments to parameters and
// non-context (stack-allocated) locals.
- if (expr->starts_initialization_block()) BAILOUT("initialization block");
+ if (expr->starts_initialization_block() ||
+ expr->ends_initialization_block()) {
+ BAILOUT("initialization block start");
+ }
Token::Value op = expr->op();
if (op == Token::INIT_CONST) BAILOUT("initialize constant");
@@ -687,7 +762,8 @@
}
}
- Visit(expr->value());
+ VisitAsValue(expr->value());
+ expr->set_location(location_);
}
@@ -718,11 +794,12 @@
} else {
BAILOUT("Call to a non-global function");
}
- // Check all arguments to the call
+ // Check all arguments to the call. (Relies on TEMP meaning STACK.)
for (int i = 0; i < args->length(); i++) {
- Visit(args->at(i));
+ VisitAsValue(args->at(i));
CHECK_BAILOUT;
}
+ expr->set_location(location_);
}
@@ -740,16 +817,18 @@
void CodeGenSelector::VisitCallRuntime(CallRuntime* expr) {
// In case of JS runtime function bail out.
- if (expr->function() == NULL) BAILOUT("CallRuntime");
+ if (expr->function() == NULL) BAILOUT("call JS runtime function");
// Check for inline runtime call
if (expr->name()->Get(0) == '_' &&
CodeGenerator::FindInlineRuntimeLUT(expr->name()) != NULL) {
- BAILOUT("InlineRuntimeCall");
+ 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));
+ VisitAsValue(expr->arguments()->at(i));
CHECK_BAILOUT;
}
+ expr->set_location(location_);
}
@@ -766,14 +845,17 @@
void CodeGenSelector::VisitBinaryOperation(BinaryOperation* expr) {
switch (expr->op()) {
case Token::OR:
- Visit(expr->left());
+ VisitAsValue(expr->left());
CHECK_BAILOUT;
+ // The location for the right subexpression is the same as for the
+ // whole expression.
Visit(expr->right());
break;
default:
BAILOUT("Unsupported binary operation");
}
+ expr->set_location(location_);
}
« no previous file with comments | « src/ast.cc ('k') | src/ia32/fast-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698