Index: src/hydrogen.cc |
=================================================================== |
--- src/hydrogen.cc (revision 8174) |
+++ src/hydrogen.cc (working copy) |
@@ -3577,6 +3577,9 @@ |
if (expr->op() != Token::INIT_CONST) { |
return Bailout("non-initializer assignment to const"); |
} |
+ if (!var->IsStackAllocated()) { |
+ return Bailout("assignment to const context slot"); |
+ } |
// We insert a use of the old value to detect unsupported uses of const |
// variables (e.g. initialization inside a loop). |
HValue* old_value = environment()->Lookup(var); |
@@ -3595,7 +3598,8 @@ |
Bind(var, value); |
ast_context()->ReturnValue(value); |
- } else if (var->IsContextSlot() && var->mode() != Variable::CONST) { |
+ } else if (var->IsContextSlot()) { |
+ ASSERT(var->mode() != Variable::CONST); |
CHECK_ALIVE(VisitForValue(expr->value())); |
HValue* context = BuildContextChainWalk(var); |
int index = var->AsSlot()->index(); |
@@ -4191,14 +4195,6 @@ |
return false; |
} |
- // Check if we can handle all declarations in the inlined functions. |
- VisitDeclarations(target_info.scope()->declarations()); |
- if (HasStackOverflow()) { |
- TraceInline(target, caller, "target has non-trivial declaration"); |
- ClearStackOverflow(); |
- return false; |
- } |
- |
// Don't inline functions that uses the arguments object or that |
// have a mismatching number of parameters. |
int arity = expr->arguments()->length(); |
@@ -4208,6 +4204,15 @@ |
return false; |
} |
+ // All declarations must be inlineable. |
+ ZoneList<Declaration*>* decls = target_info.scope()->declarations(); |
+ int decl_count = decls->length(); |
+ for (int i = 0; i < decl_count; ++i) { |
+ if (!decls->at(i)->IsInlineable()) { |
+ TraceInline(target, caller, "target has non-trivial declaration"); |
+ return false; |
+ } |
+ } |
// All statements in the body must be inlineable. |
for (int i = 0, count = function->body()->length(); i < count; ++i) { |
if (!function->body()->at(i)->IsInlineable()) { |
@@ -4233,6 +4238,9 @@ |
} |
// ---------------------------------------------------------------- |
+ // After this point, we've made a decision to inline this function (so |
+ // TryInline should always return true). |
+ |
// Save the pending call context and type feedback oracle. Set up new ones |
// for the inlined function. |
ASSERT(target_shared->has_deoptimization_support()); |
@@ -4250,12 +4258,12 @@ |
call_kind); |
HBasicBlock* body_entry = CreateBasicBlock(inner_env); |
current_block()->Goto(body_entry); |
- |
body_entry->SetJoinId(expr->ReturnId()); |
set_current_block(body_entry); |
AddInstruction(new(zone()) HEnterInlined(target, |
function, |
call_kind)); |
+ VisitDeclarations(target_info.scope()->declarations()); |
VisitStatements(function->body()); |
if (HasStackOverflow()) { |
// Bail out if the inline function did, as we cannot residualize a call |
@@ -5093,10 +5101,13 @@ |
ASSERT(current_block() != NULL); |
ASSERT(current_block()->HasPredecessor()); |
switch (expr->op()) { |
- case Token::COMMA: return VisitComma(expr); |
- case Token::OR: return VisitAndOr(expr, false); |
- case Token::AND: return VisitAndOr(expr, true); |
- default: return VisitCommon(expr); |
+ case Token::COMMA: |
+ return VisitComma(expr); |
+ case Token::OR: |
+ case Token::AND: |
+ return VisitLogicalExpression(expr); |
+ default: |
+ return VisitArithmeticExpression(expr); |
} |
} |
@@ -5109,7 +5120,8 @@ |
} |
-void HGraphBuilder::VisitAndOr(BinaryOperation* expr, bool is_logical_and) { |
+void HGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) { |
+ bool is_logical_and = expr->op() == Token::AND; |
if (ast_context()->IsTest()) { |
TestContext* context = TestContext::cast(ast_context()); |
// Translate left subexpression. |
@@ -5196,7 +5208,7 @@ |
} |
-void HGraphBuilder::VisitCommon(BinaryOperation* expr) { |
+void HGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { |
CHECK_ALIVE(VisitForValue(expr->left())); |
CHECK_ALIVE(VisitForValue(expr->right())); |
HValue* right = Pop(); |
@@ -5364,19 +5376,14 @@ |
void HGraphBuilder::VisitDeclaration(Declaration* decl) { |
- // We allow only declarations that do not require code generation. |
- // The following all require code generation: global variables, |
- // functions, and variables with slot type LOOKUP |
+ // We support only declarations that do not require code generation. |
Variable* var = decl->proxy()->var(); |
- Slot* slot = var->AsSlot(); |
- if (var->is_global() || |
- !var->IsStackAllocated() || |
- (slot != NULL && slot->type() == Slot::LOOKUP) || |
- decl->fun() != NULL) { |
+ if (!var->IsStackAllocated() || decl->fun() != NULL) { |
return Bailout("unsupported declaration"); |
} |
if (decl->mode() == Variable::CONST) { |
+ ASSERT(var->IsStackAllocated()); |
environment()->Bind(var, graph()->GetConstantHole()); |
} |
} |