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

Side by Side Diff: src/hydrogen.cc

Issue 8806012: Hydrogen support for stack local harmony bindings in function scope. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 3210 matching lines...) Expand 10 before | Expand all | Expand 10 after
3221 } 3221 }
3222 return context; 3222 return context;
3223 } 3223 }
3224 3224
3225 3225
3226 void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) { 3226 void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
3227 ASSERT(!HasStackOverflow()); 3227 ASSERT(!HasStackOverflow());
3228 ASSERT(current_block() != NULL); 3228 ASSERT(current_block() != NULL);
3229 ASSERT(current_block()->HasPredecessor()); 3229 ASSERT(current_block()->HasPredecessor());
3230 Variable* variable = expr->var(); 3230 Variable* variable = expr->var();
3231 if (variable->mode() == LET) {
3232 return Bailout("reference to let variable");
3233 }
3234 switch (variable->location()) { 3231 switch (variable->location()) {
3235 case Variable::UNALLOCATED: { 3232 case Variable::UNALLOCATED: {
3233 if (variable->mode() == LET || variable->mode() == CONST_HARMONY) {
3234 return Bailout("reference to global harmony declared variable");
3235 }
3236 // Handle known global constants like 'undefined' specially to avoid a 3236 // Handle known global constants like 'undefined' specially to avoid a
3237 // load from a global cell for them. 3237 // load from a global cell for them.
3238 Handle<Object> constant_value = 3238 Handle<Object> constant_value =
3239 isolate()->factory()->GlobalConstantFor(variable->name()); 3239 isolate()->factory()->GlobalConstantFor(variable->name());
3240 if (!constant_value.is_null()) { 3240 if (!constant_value.is_null()) {
3241 HConstant* instr = 3241 HConstant* instr =
3242 new(zone()) HConstant(constant_value, Representation::Tagged()); 3242 new(zone()) HConstant(constant_value, Representation::Tagged());
3243 return ast_context()->ReturnInstruction(instr, expr->id()); 3243 return ast_context()->ReturnInstruction(instr, expr->id());
3244 } 3244 }
3245 3245
(...skipping 22 matching lines...) Expand all
3268 variable->name(), 3268 variable->name(),
3269 ast_context()->is_for_typeof()); 3269 ast_context()->is_for_typeof());
3270 instr->set_position(expr->position()); 3270 instr->set_position(expr->position());
3271 return ast_context()->ReturnInstruction(instr, expr->id()); 3271 return ast_context()->ReturnInstruction(instr, expr->id());
3272 } 3272 }
3273 } 3273 }
3274 3274
3275 case Variable::PARAMETER: 3275 case Variable::PARAMETER:
3276 case Variable::LOCAL: { 3276 case Variable::LOCAL: {
3277 HValue* value = environment()->Lookup(variable); 3277 HValue* value = environment()->Lookup(variable);
3278 if (variable->mode() == CONST && 3278 if (value == graph()->GetConstantHole()) {
3279 value == graph()->GetConstantHole()) { 3279 ASSERT(variable->mode() == CONST ||
3280 return Bailout("reference to uninitialized const variable"); 3280 variable->mode() == CONST_HARMONY ||
3281 variable->mode() == LET);
3282 return Bailout("reference to uninitialized variable");
3281 } 3283 }
3282 return ast_context()->ReturnValue(value); 3284 return ast_context()->ReturnValue(value);
3283 } 3285 }
3284 3286
3285 case Variable::CONTEXT: { 3287 case Variable::CONTEXT: {
3288 if (variable->mode() == LET || variable->mode() == CONST_HARMONY) {
3289 return Bailout("reference to harmony declared context slot");
3290 }
3286 if (variable->mode() == CONST) { 3291 if (variable->mode() == CONST) {
3287 return Bailout("reference to const context slot"); 3292 return Bailout("reference to const context slot");
3288 } 3293 }
3289 HValue* context = BuildContextChainWalk(variable); 3294 HValue* context = BuildContextChainWalk(variable);
3290 HLoadContextSlot* instr = 3295 HLoadContextSlot* instr =
3291 new(zone()) HLoadContextSlot(context, variable->index()); 3296 new(zone()) HLoadContextSlot(context, variable->index());
3292 return ast_context()->ReturnInstruction(instr, expr->id()); 3297 return ast_context()->ReturnInstruction(instr, expr->id());
3293 } 3298 }
3294 3299
3295 case Variable::LOOKUP: 3300 case Variable::LOOKUP:
(...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after
3956 return Bailout("non-initializer assignment to const"); 3961 return Bailout("non-initializer assignment to const");
3957 } 3962 }
3958 if (!var->IsStackAllocated()) { 3963 if (!var->IsStackAllocated()) {
3959 return Bailout("assignment to const context slot"); 3964 return Bailout("assignment to const context slot");
3960 } 3965 }
3961 // We insert a use of the old value to detect unsupported uses of const 3966 // We insert a use of the old value to detect unsupported uses of const
3962 // variables (e.g. initialization inside a loop). 3967 // variables (e.g. initialization inside a loop).
3963 HValue* old_value = environment()->Lookup(var); 3968 HValue* old_value = environment()->Lookup(var);
3964 AddInstruction(new HUseConst(old_value)); 3969 AddInstruction(new HUseConst(old_value));
3965 } else if (var->mode() == LET) { 3970 } else if (var->mode() == LET) {
3966 return Bailout("unsupported assignment to let"); 3971 if (!var->IsStackAllocated()) {
3972 return Bailout("assignment to let context slot");
3973 }
3974 } else if (var->mode() == CONST_HARMONY) {
3975 if (expr->op() != Token::INIT_CONST_HARMONY) {
3976 return Bailout("non-initializer assignment to const");
3977 }
3978 if (!var->IsStackAllocated()) {
3979 return Bailout("assignment to const context slot");
3980 }
3967 } 3981 }
3968 3982
3969 if (proxy->IsArguments()) return Bailout("assignment to arguments"); 3983 if (proxy->IsArguments()) return Bailout("assignment to arguments");
3970 3984
3971 // Handle the assignment. 3985 // Handle the assignment.
3972 switch (var->location()) { 3986 switch (var->location()) {
3973 case Variable::UNALLOCATED: 3987 case Variable::UNALLOCATED:
3974 CHECK_ALIVE(VisitForValue(expr->value())); 3988 CHECK_ALIVE(VisitForValue(expr->value()));
3975 HandleGlobalVariableAssignment(var, 3989 HandleGlobalVariableAssignment(var,
3976 Top(), 3990 Top(),
3977 expr->position(), 3991 expr->position(),
3978 expr->AssignmentId()); 3992 expr->AssignmentId());
3979 return ast_context()->ReturnValue(Pop()); 3993 return ast_context()->ReturnValue(Pop());
3980 3994
3981 case Variable::PARAMETER: 3995 case Variable::PARAMETER:
3982 case Variable::LOCAL: { 3996 case Variable::LOCAL: {
3997 // Perform an initialization check for let declared variables
3998 // or parameters.
3999 if (var->mode() == LET && expr->op() == Token::ASSIGN) {
4000 HValue* env_value = environment()->Lookup(var);
4001 if (env_value == graph()->GetConstantHole()) {
4002 return Bailout("assignment to let variable before initialization");
4003 }
4004 }
3983 // We do not allow the arguments object to occur in a context where it 4005 // We do not allow the arguments object to occur in a context where it
3984 // may escape, but assignments to stack-allocated locals are 4006 // may escape, but assignments to stack-allocated locals are
3985 // permitted. 4007 // permitted.
3986 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); 4008 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED));
3987 HValue* value = Pop(); 4009 HValue* value = Pop();
3988 Bind(var, value); 4010 Bind(var, value);
3989 return ast_context()->ReturnValue(value); 4011 return ast_context()->ReturnValue(value);
3990 } 4012 }
3991 4013
3992 case Variable::CONTEXT: { 4014 case Variable::CONTEXT: {
(...skipping 2191 matching lines...) Expand 10 before | Expand all | Expand 10 after
6184 6206
6185 6207
6186 void HGraphBuilder::VisitDeclaration(Declaration* decl) { 6208 void HGraphBuilder::VisitDeclaration(Declaration* decl) {
6187 HandleDeclaration(decl->proxy(), decl->mode(), decl->fun()); 6209 HandleDeclaration(decl->proxy(), decl->mode(), decl->fun());
6188 } 6210 }
6189 6211
6190 6212
6191 void HGraphBuilder::HandleDeclaration(VariableProxy* proxy, 6213 void HGraphBuilder::HandleDeclaration(VariableProxy* proxy,
6192 VariableMode mode, 6214 VariableMode mode,
6193 FunctionLiteral* function) { 6215 FunctionLiteral* function) {
6194 if (mode == LET || mode == CONST_HARMONY) {
6195 return Bailout("unsupported harmony declaration");
6196 }
6197 Variable* var = proxy->var(); 6216 Variable* var = proxy->var();
6217 bool binding_needs_init =
6218 (mode == CONST || mode == CONST_HARMONY || mode == LET);
6198 switch (var->location()) { 6219 switch (var->location()) {
6199 case Variable::UNALLOCATED: 6220 case Variable::UNALLOCATED:
6200 return Bailout("unsupported global declaration"); 6221 return Bailout("unsupported global declaration");
6201 case Variable::PARAMETER: 6222 case Variable::PARAMETER:
6202 case Variable::LOCAL: 6223 case Variable::LOCAL:
6203 case Variable::CONTEXT: 6224 case Variable::CONTEXT:
6204 if (mode == CONST || function != NULL) { 6225 if (binding_needs_init || function != NULL) {
6205 HValue* value = NULL; 6226 HValue* value = NULL;
6206 if (mode == CONST) { 6227 if (function != NULL) {
6207 value = graph()->GetConstantHole();
6208 } else {
6209 VisitForValue(function); 6228 VisitForValue(function);
6210 value = Pop(); 6229 value = Pop();
6230 } else {
6231 value = graph()->GetConstantHole();
6211 } 6232 }
6212 if (var->IsContextSlot()) { 6233 if (var->IsContextSlot()) {
6213 HValue* context = environment()->LookupContext(); 6234 HValue* context = environment()->LookupContext();
6214 HStoreContextSlot* store = 6235 HStoreContextSlot* store =
6215 new HStoreContextSlot(context, var->index(), value); 6236 new HStoreContextSlot(context, var->index(), value);
6216 AddInstruction(store); 6237 AddInstruction(store);
6217 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); 6238 if (store->HasObservableSideEffects()) AddSimulate(proxy->id());
6218 } else { 6239 } else {
6219 environment()->Bind(var, value); 6240 environment()->Bind(var, value);
6220 } 6241 }
(...skipping 1006 matching lines...) Expand 10 before | Expand all | Expand 10 after
7227 } 7248 }
7228 } 7249 }
7229 7250
7230 #ifdef DEBUG 7251 #ifdef DEBUG
7231 if (graph_ != NULL) graph_->Verify(false); // No full verify. 7252 if (graph_ != NULL) graph_->Verify(false); // No full verify.
7232 if (allocator_ != NULL) allocator_->Verify(); 7253 if (allocator_ != NULL) allocator_->Verify();
7233 #endif 7254 #endif
7234 } 7255 }
7235 7256
7236 } } // namespace v8::internal 7257 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/harmony/block-let-crankshaft.js » ('j') | test/mjsunit/harmony/block-let-crankshaft.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698