| Index: src/hydrogen.cc
|
| ===================================================================
|
| --- src/hydrogen.cc (revision 7145)
|
| +++ src/hydrogen.cc (working copy)
|
| @@ -2105,6 +2105,13 @@
|
| }
|
|
|
|
|
| +void HGraphBuilder::VisitForTypeofValue(Expression* expr) {
|
| + ValueContext for_value(this);
|
| + for_value.MarkAsTypeof();
|
| + Visit(expr);
|
| +}
|
| +
|
| +
|
| void HGraphBuilder::VisitForControl(Expression* expr,
|
| HBasicBlock* true_block,
|
| HBasicBlock* false_block) {
|
| @@ -2797,29 +2804,28 @@
|
| }
|
|
|
|
|
| -void HGraphBuilder::LookupGlobalPropertyCell(Variable* var,
|
| +bool HGraphBuilder::LookupGlobalPropertyCell(Variable* var,
|
| LookupResult* lookup,
|
| bool is_store) {
|
| if (var->is_this()) {
|
| - BAILOUT("global this reference");
|
| + Bailout("global this reference");
|
| + return true;
|
| }
|
| if (!info()->has_global_object()) {
|
| - BAILOUT("no global object to optimize VariableProxy");
|
| + Bailout("no global object to optimize VariableProxy");
|
| + return true;
|
| }
|
| Handle<GlobalObject> global(info()->global_object());
|
| global->Lookup(*var->name(), lookup);
|
| - if (!lookup->IsProperty()) {
|
| - BAILOUT("global variable cell not yet introduced");
|
| - }
|
| - if (lookup->type() != NORMAL) {
|
| - BAILOUT("global variable has accessors");
|
| - }
|
| + if (!lookup->IsProperty()) return true;
|
| if (is_store && lookup->IsReadOnly()) {
|
| - BAILOUT("read-only global variable");
|
| + Bailout("store to read-only global variable");
|
| + return true;
|
| }
|
| - if (lookup->holder() != *global) {
|
| - BAILOUT("global property on prototype of global object");
|
| - }
|
| + if (lookup->type() != NORMAL) return true;
|
| + if (!lookup->IsProperty()) return true;
|
| + if (lookup->holder() != *global) return true;
|
| + return false;
|
| }
|
|
|
|
|
| @@ -2855,18 +2861,24 @@
|
| ast_context()->ReturnInstruction(instr, expr->id());
|
| } else if (variable->is_global()) {
|
| LookupResult lookup;
|
| - LookupGlobalPropertyCell(variable, &lookup, false);
|
| + bool is_generic = LookupGlobalPropertyCell(variable, &lookup, false);
|
| CHECK_BAILOUT;
|
| -
|
| Handle<GlobalObject> global(info()->global_object());
|
| - // TODO(3039103): Handle global property load through an IC call when access
|
| - // checks are enabled.
|
| - if (global->IsAccessCheckNeeded()) {
|
| - BAILOUT("global object requires access check");
|
| + HInstruction* instr = NULL;
|
| + if (is_generic || global->IsAccessCheckNeeded()) {
|
| + HContext* context = new HContext;
|
| + AddInstruction(context);
|
| + HGlobalObject* global_object = new HGlobalObject(context);
|
| + AddInstruction(global_object);
|
| + instr = new HLoadGlobalGeneric(context,
|
| + global_object,
|
| + variable->name(),
|
| + ast_context()->IsTypeof());
|
| + } else {
|
| + Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup));
|
| + bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly();
|
| + instr = new HLoadGlobal(cell, check_hole);
|
| }
|
| - Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup));
|
| - bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly();
|
| - HLoadGlobal* instr = new HLoadGlobal(cell, check_hole);
|
| ast_context()->ReturnInstruction(instr, expr->id());
|
| } else {
|
| BAILOUT("reference to a variable which requires dynamic lookup");
|
| @@ -3224,16 +3236,20 @@
|
| int position,
|
| int ast_id) {
|
| LookupResult lookup;
|
| - LookupGlobalPropertyCell(var, &lookup, true);
|
| + bool is_generic = LookupGlobalPropertyCell(var, &lookup, true);
|
| CHECK_BAILOUT;
|
|
|
| bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly();
|
| Handle<GlobalObject> global(info()->global_object());
|
| - Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup));
|
| - HInstruction* instr = new HStoreGlobal(value, cell, check_hole);
|
| - instr->set_position(position);
|
| - AddInstruction(instr);
|
| - if (instr->HasSideEffects()) AddSimulate(ast_id);
|
| + if (!is_generic && !global->IsAccessCheckNeeded()) {
|
| + Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup));
|
| + HStoreGlobal* instr = new HStoreGlobal(value, cell, check_hole);
|
| + instr->set_position(position);
|
| + AddInstruction(instr);
|
| + if (instr->HasSideEffects()) AddSimulate(ast_id);
|
| + } else {
|
| + BAILOUT("unsupported store to global");
|
| + }
|
| }
|
|
|
|
|
| @@ -4534,7 +4550,8 @@
|
| }
|
| ast_context()->ReturnInstruction(instr, expr->id());
|
| } else if (op == Token::TYPEOF) {
|
| - VISIT_FOR_VALUE(expr->expression());
|
| + VisitForTypeofValue(expr->expression());
|
| + if (HasStackOverflow()) return;
|
| HValue* value = Pop();
|
| ast_context()->ReturnInstruction(new HTypeof(value), expr->id());
|
| } else {
|
| @@ -4919,7 +4936,8 @@
|
| if ((expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT) &&
|
| left_unary != NULL && left_unary->op() == Token::TYPEOF &&
|
| right_literal != NULL && right_literal->handle()->IsString()) {
|
| - VISIT_FOR_VALUE(left_unary->expression());
|
| + VisitForTypeofValue(left_unary->expression());
|
| + if (HasStackOverflow()) return;
|
| HValue* left = Pop();
|
| HInstruction* instr = new HTypeofIs(left,
|
| Handle<String>::cast(right_literal->handle()));
|
|
|