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

Side by Side Diff: src/interpreter/bytecode-generator.cc

Issue 1373903005: [Interpreter] Add for/while/do support to the bytecode generator. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Incorporate feedback from mstarzinger which revealed use after destruction bug. Created 5 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/interpreter/bytecode-generator.h" 5 #include "src/interpreter/bytecode-generator.h"
6 6
7 #include <stack> 7 #include <stack>
8 8
9 #include "src/compiler.h" 9 #include "src/compiler.h"
10 #include "src/interpreter/control-flow-builders.h"
10 #include "src/objects.h" 11 #include "src/objects.h"
11 #include "src/scopes.h" 12 #include "src/scopes.h"
12 #include "src/token.h" 13 #include "src/token.h"
13 14
14 namespace v8 { 15 namespace v8 {
15 namespace internal { 16 namespace internal {
16 namespace interpreter { 17 namespace interpreter {
17 18
19
20 // Scoped class for tracking control statements entered by the
21 // visitor. The pattern derives AstGraphBuilder::ControlScope.
22 class BytecodeGenerator::ControlScope BASE_EMBEDDED {
23 public:
24 explicit ControlScope(BytecodeGenerator* generator)
25 : generator_(generator), outer_(generator->control_scope()) {
26 generator_->set_control_scope(this);
27 }
28 virtual ~ControlScope() { generator_->set_control_scope(outer()); }
29
30 void Break(Statement* stmt) { PerformCommand(CMD_BREAK, stmt); }
31 void Continue(Statement* stmt) { PerformCommand(CMD_CONTINUE, stmt); }
32
33 protected:
34 enum Command { CMD_BREAK, CMD_CONTINUE };
35 void PerformCommand(Command command, Statement* statement);
36 virtual bool Execute(Command command, Statement* statement) = 0;
37
38 BytecodeGenerator* generator() const { return generator_; }
39 ControlScope* outer() const { return outer_; }
40
41 private:
42 BytecodeGenerator* generator_;
43 ControlScope* outer_;
44
45 DISALLOW_COPY_AND_ASSIGN(ControlScope);
46 };
47
48
49 // Scoped class for enabling 'break' and 'continue' in iteration
50 // constructs, e.g. do...while, while..., for...
51 class BytecodeGenerator::ControlScopeForIteration
52 : public BytecodeGenerator::ControlScope {
53 public:
54 ControlScopeForIteration(BytecodeGenerator* generator,
55 IterationStatement* statement,
56 LoopBuilder* loop_builder)
57 : ControlScope(generator),
58 statement_(statement),
59 loop_builder_(loop_builder) {}
60
61 protected:
62 virtual bool Execute(Command command, Statement* statement) {
63 if (statement != statement_) return false;
64 switch (command) {
65 case CMD_BREAK:
66 loop_builder_->Break();
67 return true;
68 case CMD_CONTINUE:
69 loop_builder_->Continue();
70 return true;
71 }
72 return false;
73 }
74
75 private:
76 Statement* statement_;
77 LoopBuilder* loop_builder_;
78 };
79
80
81 void BytecodeGenerator::ControlScope::PerformCommand(Command command,
82 Statement* statement) {
83 ControlScope* current = this;
84 do {
85 if (current->Execute(command, statement)) return;
86 current = current->outer();
87 } while (current != nullptr);
rmcilroy 2015/10/01 09:18:56 Do we expect to reach the end of the loop not havi
oth 2015/10/01 11:43:02 Done.
88 }
89
90
18 BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone) 91 BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone)
19 : builder_(isolate, zone) { 92 : builder_(isolate, zone),
93 info_(nullptr),
94 scope_(nullptr),
95 control_scope_(nullptr) {
20 InitializeAstVisitor(isolate, zone); 96 InitializeAstVisitor(isolate, zone);
21 } 97 }
22 98
23 99
24 BytecodeGenerator::~BytecodeGenerator() {} 100 BytecodeGenerator::~BytecodeGenerator() {}
25 101
26 102
27 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode(CompilationInfo* info) { 103 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode(CompilationInfo* info) {
28 set_info(info); 104 set_info(info);
29 set_scope(info->scope()); 105 set_scope(info->scope());
30 106
31 // This a temporary guard (oth). 107 // This a temporary guard (oth).
32 DCHECK(scope()->is_function_scope()); 108 DCHECK(scope()->is_function_scope());
33 109
34 builder().set_parameter_count(info->num_parameters_including_this()); 110 builder()->set_parameter_count(info->num_parameters_including_this());
35 builder().set_locals_count(scope()->num_stack_slots()); 111 builder()->set_locals_count(scope()->num_stack_slots());
36 112
37 // Visit implicit declaration of the function name. 113 // Visit implicit declaration of the function name.
38 if (scope()->is_function_scope() && scope()->function() != NULL) { 114 if (scope()->is_function_scope() && scope()->function() != NULL) {
39 VisitVariableDeclaration(scope()->function()); 115 VisitVariableDeclaration(scope()->function());
40 } 116 }
41 117
42 // Visit declarations within the function scope. 118 // Visit declarations within the function scope.
43 VisitDeclarations(scope()->declarations()); 119 VisitDeclarations(scope()->declarations());
44 120
45 // Visit statements in the function body. 121 // Visit statements in the function body.
46 VisitStatements(info->literal()->body()); 122 VisitStatements(info->literal()->body());
47 123
48 set_scope(nullptr); 124 set_scope(nullptr);
49 set_info(nullptr); 125 set_info(nullptr);
50 return builder_.ToBytecodeArray(); 126 return builder_.ToBytecodeArray();
51 } 127 }
52 128
53 129
54 void BytecodeGenerator::VisitBlock(Block* node) { 130 void BytecodeGenerator::VisitBlock(Block* node) {
55 builder().EnterBlock(); 131 builder()->EnterBlock();
56 if (node->scope() == NULL) { 132 if (node->scope() == NULL) {
57 // Visit statements in the same scope, no declarations. 133 // Visit statements in the same scope, no declarations.
58 VisitStatements(node->statements()); 134 VisitStatements(node->statements());
59 } else { 135 } else {
60 // Visit declarations and statements in a block scope. 136 // Visit declarations and statements in a block scope.
61 if (node->scope()->ContextLocalCount() > 0) { 137 if (node->scope()->ContextLocalCount() > 0) {
62 UNIMPLEMENTED(); 138 UNIMPLEMENTED();
63 } else { 139 } else {
64 VisitDeclarations(node->scope()->declarations()); 140 VisitDeclarations(node->scope()->declarations());
65 VisitStatements(node->statements()); 141 VisitStatements(node->statements());
66 } 142 }
67 } 143 }
68 builder().LeaveBlock(); 144 builder()->LeaveBlock();
69 } 145 }
70 146
71 147
72 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { 148 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
73 Variable* variable = decl->proxy()->var(); 149 Variable* variable = decl->proxy()->var();
74 switch (variable->location()) { 150 switch (variable->location()) {
75 case VariableLocation::GLOBAL: 151 case VariableLocation::GLOBAL:
76 case VariableLocation::UNALLOCATED: 152 case VariableLocation::UNALLOCATED:
77 UNIMPLEMENTED(); 153 UNIMPLEMENTED();
78 break; 154 break;
(...skipping 28 matching lines...) Expand all
107 Visit(stmt->expression()); 183 Visit(stmt->expression());
108 } 184 }
109 185
110 186
111 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { 187 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
112 // TODO(oth): For control-flow it could be useful to signal empty paths here. 188 // TODO(oth): For control-flow it could be useful to signal empty paths here.
113 } 189 }
114 190
115 191
116 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) { 192 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) {
117 BytecodeLabel else_start, else_end;
118 // TODO(oth): Spot easy cases where there code would not need to 193 // TODO(oth): Spot easy cases where there code would not need to
119 // emit the then block or the else block, e.g. condition is 194 // emit the then block or the else block, e.g. condition is
120 // obviously true/1/false/0. 195 // obviously true/1/false/0.
121 Visit(stmt->condition()); 196 Visit(stmt->condition());
122 builder().CastAccumulatorToBoolean(); 197 builder()->CastAccumulatorToBoolean();
123 builder().JumpIfFalse(&else_start); 198 if (stmt->HasElseStatement()) {
rmcilroy 2015/10/01 09:18:55 Can we just have this around the else statement -
oth 2015/10/01 11:43:02 Done.
124 199 BytecodeLabel else_start, else_end;
125 Visit(stmt->then_statement()); 200 builder()->JumpIfFalse(&else_start);
126 builder().Jump(&else_end); 201 Visit(stmt->then_statement());
127 builder().Bind(&else_start); 202 builder()->Jump(&else_end);
128 203 builder()->Bind(&else_start);
129 Visit(stmt->else_statement()); 204 Visit(stmt->else_statement());
130 builder().Bind(&else_end); 205 builder()->Bind(&else_end);
206 } else {
207 BytecodeLabel then_end;
208 builder()->JumpIfFalse(&then_end);
209 Visit(stmt->then_statement());
210 builder()->Bind(&then_end);
211 }
131 } 212 }
132 213
133 214
134 void BytecodeGenerator::VisitSloppyBlockFunctionStatement( 215 void BytecodeGenerator::VisitSloppyBlockFunctionStatement(
135 SloppyBlockFunctionStatement* stmt) { 216 SloppyBlockFunctionStatement* stmt) {
136 Visit(stmt->statement()); 217 Visit(stmt->statement());
137 } 218 }
138 219
139 220
140 void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { 221 void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
141 UNIMPLEMENTED(); 222 control_scope()->Continue(stmt->target());
142 } 223 }
143 224
144 225
145 void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) { 226 void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
146 UNIMPLEMENTED(); 227 control_scope()->Break(stmt->target());
147 } 228 }
148 229
149 230
150 void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 231 void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
151 Visit(stmt->expression()); 232 Visit(stmt->expression());
152 builder().Return(); 233 builder()->Return();
153 } 234 }
154 235
155 236
156 void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) { 237 void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) {
157 UNIMPLEMENTED(); 238 UNIMPLEMENTED();
158 } 239 }
159 240
160 241
161 void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 242 void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
162 UNIMPLEMENTED(); 243 UNIMPLEMENTED();
163 } 244 }
164 245
165 246
166 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { UNIMPLEMENTED(); } 247 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { UNIMPLEMENTED(); }
167 248
168 249
169 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 250 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
170 UNIMPLEMENTED(); 251 LoopBuilder loop_builder(builder());
252 ControlScopeForIteration control_scope(this, stmt, &loop_builder);
253
254 BytecodeLabel body_start;
255 builder()->Bind(&body_start);
256 Visit(stmt->body());
257 builder()->Bind(loop_builder.continue_label());
258 Visit(stmt->cond());
259 builder()->JumpIfTrue(&body_start);
260 builder()->Bind(loop_builder.break_label());
171 } 261 }
172 262
173 263
174 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 264 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
175 UNIMPLEMENTED(); 265 LoopBuilder loop_builder(builder());
266 ControlScopeForIteration control_scope(this, stmt, &loop_builder);
267
268 builder()->Jump(loop_builder.continue_label());
269 BytecodeLabel body_start;
270 builder()->Bind(&body_start);
271 Visit(stmt->body());
272 builder()->Bind(loop_builder.continue_label());
273 Visit(stmt->cond());
274 builder()->JumpIfTrue(&body_start);
275 builder()->Bind(loop_builder.break_label());
176 } 276 }
177 277
178 278
179 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) { 279 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
180 UNIMPLEMENTED(); 280 LoopBuilder loop_builder(builder());
281 ControlScopeForIteration control_scope(this, stmt, &loop_builder);
282
283 if (stmt->init() != nullptr) {
284 Visit(stmt->init());
285 }
286
287 BytecodeLabel condition_start;
288 if (stmt->cond() != nullptr) {
289 builder()->Jump(&condition_start);
290 }
291
292 BytecodeLabel body_start;
293 builder()->Bind(&body_start);
294 Visit(stmt->body());
295 builder()->Bind(loop_builder.continue_label());
296 if (stmt->next() != nullptr) {
297 Visit(stmt->next());
298 }
299
300 builder()->Bind(&condition_start);
rmcilroy 2015/10/01 09:18:55 nit - put this in the if (stmt->cond())
oth 2015/10/01 11:43:02 Done.
301 if (stmt->cond()) {
302 Visit(stmt->cond());
303 builder()->JumpIfTrue(&body_start);
304 } else {
305 builder()->Jump(&body_start);
306 }
307 builder()->Bind(loop_builder.break_label());
181 } 308 }
182 309
183 310
184 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { 311 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
185 UNIMPLEMENTED(); 312 UNIMPLEMENTED();
186 } 313 }
187 314
188 315
189 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { 316 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
190 UNIMPLEMENTED(); 317 UNIMPLEMENTED();
(...skipping 30 matching lines...) Expand all
221 UNIMPLEMENTED(); 348 UNIMPLEMENTED();
222 } 349 }
223 350
224 351
225 void BytecodeGenerator::VisitConditional(Conditional* expr) { UNIMPLEMENTED(); } 352 void BytecodeGenerator::VisitConditional(Conditional* expr) { UNIMPLEMENTED(); }
226 353
227 354
228 void BytecodeGenerator::VisitLiteral(Literal* expr) { 355 void BytecodeGenerator::VisitLiteral(Literal* expr) {
229 Handle<Object> value = expr->value(); 356 Handle<Object> value = expr->value();
230 if (value->IsSmi()) { 357 if (value->IsSmi()) {
231 builder().LoadLiteral(Smi::cast(*value)); 358 builder()->LoadLiteral(Smi::cast(*value));
232 } else if (value->IsUndefined()) { 359 } else if (value->IsUndefined()) {
233 builder().LoadUndefined(); 360 builder()->LoadUndefined();
234 } else if (value->IsTrue()) { 361 } else if (value->IsTrue()) {
235 builder().LoadTrue(); 362 builder()->LoadTrue();
236 } else if (value->IsFalse()) { 363 } else if (value->IsFalse()) {
237 builder().LoadFalse(); 364 builder()->LoadFalse();
238 } else if (value->IsNull()) { 365 } else if (value->IsNull()) {
239 builder().LoadNull(); 366 builder()->LoadNull();
240 } else if (value->IsTheHole()) { 367 } else if (value->IsTheHole()) {
241 builder().LoadTheHole(); 368 builder()->LoadTheHole();
242 } else { 369 } else {
243 builder().LoadLiteral(value); 370 builder()->LoadLiteral(value);
244 } 371 }
245 } 372 }
246 373
247 374
248 void BytecodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 375 void BytecodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
249 UNIMPLEMENTED(); 376 UNIMPLEMENTED();
250 } 377 }
251 378
252 379
253 void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 380 void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
254 UNIMPLEMENTED(); 381 UNIMPLEMENTED();
255 } 382 }
256 383
257 384
258 void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 385 void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
259 UNIMPLEMENTED(); 386 UNIMPLEMENTED();
260 } 387 }
261 388
262 389
263 void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) { 390 void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) {
264 VisitVariableLoad(proxy->var()); 391 VisitVariableLoad(proxy->var());
265 } 392 }
266 393
267 394
268 void BytecodeGenerator::VisitVariableLoad(Variable* variable) { 395 void BytecodeGenerator::VisitVariableLoad(Variable* variable) {
269 switch (variable->location()) { 396 switch (variable->location()) {
270 case VariableLocation::LOCAL: { 397 case VariableLocation::LOCAL: {
271 Register source(variable->index()); 398 Register source(variable->index());
272 builder().LoadAccumulatorWithRegister(source); 399 builder()->LoadAccumulatorWithRegister(source);
273 break; 400 break;
274 } 401 }
275 case VariableLocation::PARAMETER: { 402 case VariableLocation::PARAMETER: {
276 // The parameter indices are shifted by 1 (receiver is variable 403 // The parameter indices are shifted by 1 (receiver is variable
277 // index -1 but is parameter index 0 in BytecodeArrayBuilder). 404 // index -1 but is parameter index 0 in BytecodeArrayBuilder).
278 Register source(builder().Parameter(variable->index() + 1)); 405 Register source(builder()->Parameter(variable->index() + 1));
279 builder().LoadAccumulatorWithRegister(source); 406 builder()->LoadAccumulatorWithRegister(source);
280 break; 407 break;
281 } 408 }
282 case VariableLocation::GLOBAL: { 409 case VariableLocation::GLOBAL: {
283 // Global var, const, or let variable. 410 // Global var, const, or let variable.
284 // TODO(rmcilroy): If context chain depth is short enough, do this using 411 // TODO(rmcilroy): If context chain depth is short enough, do this using
285 // a generic version of LoadGlobalViaContextStub rather than calling the 412 // a generic version of LoadGlobalViaContextStub rather than calling the
286 // runtime. 413 // runtime.
287 DCHECK(variable->IsStaticGlobalObjectProperty()); 414 DCHECK(variable->IsStaticGlobalObjectProperty());
288 builder().LoadGlobal(variable->index()); 415 builder()->LoadGlobal(variable->index());
289 break; 416 break;
290 } 417 }
291 case VariableLocation::UNALLOCATED: 418 case VariableLocation::UNALLOCATED:
292 case VariableLocation::CONTEXT: 419 case VariableLocation::CONTEXT:
293 case VariableLocation::LOOKUP: 420 case VariableLocation::LOOKUP:
294 UNIMPLEMENTED(); 421 UNIMPLEMENTED();
295 } 422 }
296 } 423 }
297 424
298 425
299 void BytecodeGenerator::VisitAssignment(Assignment* expr) { 426 void BytecodeGenerator::VisitAssignment(Assignment* expr) {
300 DCHECK(expr->target()->IsValidReferenceExpression()); 427 DCHECK(expr->target()->IsValidReferenceExpression());
301 TemporaryRegisterScope temporary_register_scope(&builder_); 428 TemporaryRegisterScope temporary_register_scope(&builder_);
302 Register object, key; 429 Register object, key;
303 430
304 // Left-hand side can only be a property, a global or a variable slot. 431 // Left-hand side can only be a property, a global or a variable slot.
305 Property* property = expr->target()->AsProperty(); 432 Property* property = expr->target()->AsProperty();
306 LhsKind assign_type = Property::GetAssignType(property); 433 LhsKind assign_type = Property::GetAssignType(property);
307 434
308 // Evaluate LHS expression. 435 // Evaluate LHS expression.
309 switch (assign_type) { 436 switch (assign_type) {
310 case VARIABLE: 437 case VARIABLE:
311 // Nothing to do to evaluate variable assignment LHS. 438 // Nothing to do to evaluate variable assignment LHS.
312 break; 439 break;
313 case NAMED_PROPERTY: 440 case NAMED_PROPERTY:
314 object = temporary_register_scope.NewRegister(); 441 object = temporary_register_scope.NewRegister();
315 key = temporary_register_scope.NewRegister(); 442 key = temporary_register_scope.NewRegister();
316 Visit(property->obj()); 443 Visit(property->obj());
317 builder().StoreAccumulatorInRegister(object); 444 builder()->StoreAccumulatorInRegister(object);
318 builder().LoadLiteral(property->key()->AsLiteral()->AsPropertyName()); 445 builder()->LoadLiteral(property->key()->AsLiteral()->AsPropertyName());
319 builder().StoreAccumulatorInRegister(key); 446 builder()->StoreAccumulatorInRegister(key);
320 break; 447 break;
321 case KEYED_PROPERTY: 448 case KEYED_PROPERTY:
322 object = temporary_register_scope.NewRegister(); 449 object = temporary_register_scope.NewRegister();
323 key = temporary_register_scope.NewRegister(); 450 key = temporary_register_scope.NewRegister();
324 Visit(property->obj()); 451 Visit(property->obj());
325 builder().StoreAccumulatorInRegister(object); 452 builder()->StoreAccumulatorInRegister(object);
326 Visit(property->key()); 453 Visit(property->key());
327 builder().StoreAccumulatorInRegister(key); 454 builder()->StoreAccumulatorInRegister(key);
328 break; 455 break;
329 case NAMED_SUPER_PROPERTY: 456 case NAMED_SUPER_PROPERTY:
330 case KEYED_SUPER_PROPERTY: 457 case KEYED_SUPER_PROPERTY:
331 UNIMPLEMENTED(); 458 UNIMPLEMENTED();
332 } 459 }
333 460
334 // Evaluate the value and potentially handle compound assignments by loading 461 // Evaluate the value and potentially handle compound assignments by loading
335 // the left-hand side value and performing a binary operation. 462 // the left-hand side value and performing a binary operation.
336 if (expr->is_compound()) { 463 if (expr->is_compound()) {
337 UNIMPLEMENTED(); 464 UNIMPLEMENTED();
338 } else { 465 } else {
339 Visit(expr->value()); 466 Visit(expr->value());
340 } 467 }
341 468
342 // Store the value. 469 // Store the value.
343 FeedbackVectorICSlot slot = expr->AssignmentSlot(); 470 FeedbackVectorICSlot slot = expr->AssignmentSlot();
344 switch (assign_type) { 471 switch (assign_type) {
345 case VARIABLE: { 472 case VARIABLE: {
346 Variable* variable = expr->target()->AsVariableProxy()->var(); 473 Variable* variable = expr->target()->AsVariableProxy()->var();
347 DCHECK(variable->location() == VariableLocation::LOCAL); 474 DCHECK(variable->location() == VariableLocation::LOCAL);
348 Register destination(variable->index()); 475 Register destination(variable->index());
349 builder().StoreAccumulatorInRegister(destination); 476 builder()->StoreAccumulatorInRegister(destination);
350 break; 477 break;
351 } 478 }
352 case NAMED_PROPERTY: 479 case NAMED_PROPERTY:
353 builder().StoreNamedProperty(object, key, feedback_index(slot), 480 builder()->StoreNamedProperty(object, key, feedback_index(slot),
354 language_mode()); 481 language_mode());
355 break; 482 break;
356 case KEYED_PROPERTY: 483 case KEYED_PROPERTY:
357 builder().StoreKeyedProperty(object, key, feedback_index(slot), 484 builder()->StoreKeyedProperty(object, key, feedback_index(slot),
358 language_mode()); 485 language_mode());
359 break; 486 break;
360 case NAMED_SUPER_PROPERTY: 487 case NAMED_SUPER_PROPERTY:
361 case KEYED_SUPER_PROPERTY: 488 case KEYED_SUPER_PROPERTY:
362 UNIMPLEMENTED(); 489 UNIMPLEMENTED();
363 } 490 }
364 } 491 }
365 492
366 493
367 void BytecodeGenerator::VisitYield(Yield* expr) { UNIMPLEMENTED(); } 494 void BytecodeGenerator::VisitYield(Yield* expr) { UNIMPLEMENTED(); }
368 495
369 496
370 void BytecodeGenerator::VisitThrow(Throw* expr) { UNIMPLEMENTED(); } 497 void BytecodeGenerator::VisitThrow(Throw* expr) { UNIMPLEMENTED(); }
371 498
372 499
373 void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) { 500 void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) {
374 LhsKind property_kind = Property::GetAssignType(expr); 501 LhsKind property_kind = Property::GetAssignType(expr);
375 FeedbackVectorICSlot slot = expr->PropertyFeedbackSlot(); 502 FeedbackVectorICSlot slot = expr->PropertyFeedbackSlot();
376 switch (property_kind) { 503 switch (property_kind) {
377 case VARIABLE: 504 case VARIABLE:
378 UNREACHABLE(); 505 UNREACHABLE();
379 case NAMED_PROPERTY: { 506 case NAMED_PROPERTY: {
380 builder().LoadLiteral(expr->key()->AsLiteral()->AsPropertyName()); 507 builder()->LoadLiteral(expr->key()->AsLiteral()->AsPropertyName());
381 builder().LoadNamedProperty(obj, feedback_index(slot), language_mode()); 508 builder()->LoadNamedProperty(obj, feedback_index(slot), language_mode());
382 break; 509 break;
383 } 510 }
384 case KEYED_PROPERTY: { 511 case KEYED_PROPERTY: {
385 Visit(expr->key()); 512 Visit(expr->key());
386 builder().LoadKeyedProperty(obj, feedback_index(slot), language_mode()); 513 builder()->LoadKeyedProperty(obj, feedback_index(slot), language_mode());
387 break; 514 break;
388 } 515 }
389 case NAMED_SUPER_PROPERTY: 516 case NAMED_SUPER_PROPERTY:
390 case KEYED_SUPER_PROPERTY: 517 case KEYED_SUPER_PROPERTY:
391 UNIMPLEMENTED(); 518 UNIMPLEMENTED();
392 } 519 }
393 } 520 }
394 521
395 522
396 void BytecodeGenerator::VisitProperty(Property* expr) { 523 void BytecodeGenerator::VisitProperty(Property* expr) {
397 TemporaryRegisterScope temporary_register_scope(&builder_); 524 TemporaryRegisterScope temporary_register_scope(&builder_);
398 Register obj = temporary_register_scope.NewRegister(); 525 Register obj = temporary_register_scope.NewRegister();
399 Visit(expr->obj()); 526 Visit(expr->obj());
400 builder().StoreAccumulatorInRegister(obj); 527 builder()->StoreAccumulatorInRegister(obj);
401 VisitPropertyLoad(obj, expr); 528 VisitPropertyLoad(obj, expr);
402 } 529 }
403 530
404 531
405 void BytecodeGenerator::VisitCall(Call* expr) { 532 void BytecodeGenerator::VisitCall(Call* expr) {
406 Expression* callee_expr = expr->expression(); 533 Expression* callee_expr = expr->expression();
407 Call::CallType call_type = expr->GetCallType(isolate()); 534 Call::CallType call_type = expr->GetCallType(isolate());
408 535
409 // Prepare the callee and the receiver to the function call. This depends on 536 // Prepare the callee and the receiver to the function call. This depends on
410 // the semantics of the underlying call type. 537 // the semantics of the underlying call type.
411 TemporaryRegisterScope temporary_register_scope(&builder_); 538 TemporaryRegisterScope temporary_register_scope(&builder_);
412 Register callee = temporary_register_scope.NewRegister(); 539 Register callee = temporary_register_scope.NewRegister();
413 Register receiver = temporary_register_scope.NewRegister(); 540 Register receiver = temporary_register_scope.NewRegister();
414 541
415 switch (call_type) { 542 switch (call_type) {
416 case Call::PROPERTY_CALL: { 543 case Call::PROPERTY_CALL: {
417 Property* property = callee_expr->AsProperty(); 544 Property* property = callee_expr->AsProperty();
418 if (property->IsSuperAccess()) { 545 if (property->IsSuperAccess()) {
419 UNIMPLEMENTED(); 546 UNIMPLEMENTED();
420 } 547 }
421 Visit(property->obj()); 548 Visit(property->obj());
422 builder().StoreAccumulatorInRegister(receiver); 549 builder()->StoreAccumulatorInRegister(receiver);
423 // Perform a property load of the callee. 550 // Perform a property load of the callee.
424 VisitPropertyLoad(receiver, property); 551 VisitPropertyLoad(receiver, property);
425 builder().StoreAccumulatorInRegister(callee); 552 builder()->StoreAccumulatorInRegister(callee);
426 break; 553 break;
427 } 554 }
428 case Call::GLOBAL_CALL: { 555 case Call::GLOBAL_CALL: {
429 // Receiver is undefined for global calls. 556 // Receiver is undefined for global calls.
430 builder().LoadUndefined().StoreAccumulatorInRegister(receiver); 557 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver);
431 // Load callee as a global variable. 558 // Load callee as a global variable.
432 VariableProxy* proxy = callee_expr->AsVariableProxy(); 559 VariableProxy* proxy = callee_expr->AsVariableProxy();
433 VisitVariableLoad(proxy->var()); 560 VisitVariableLoad(proxy->var());
434 builder().StoreAccumulatorInRegister(callee); 561 builder()->StoreAccumulatorInRegister(callee);
435 break; 562 break;
436 } 563 }
437 case Call::LOOKUP_SLOT_CALL: 564 case Call::LOOKUP_SLOT_CALL:
438 case Call::SUPER_CALL: 565 case Call::SUPER_CALL:
439 case Call::POSSIBLY_EVAL_CALL: 566 case Call::POSSIBLY_EVAL_CALL:
440 case Call::OTHER_CALL: 567 case Call::OTHER_CALL:
441 UNIMPLEMENTED(); 568 UNIMPLEMENTED();
442 } 569 }
443 570
444 // Evaluate all arguments to the function call and store in sequential 571 // Evaluate all arguments to the function call and store in sequential
445 // registers. 572 // registers.
446 ZoneList<Expression*>* args = expr->arguments(); 573 ZoneList<Expression*>* args = expr->arguments();
447 for (int i = 0; i < args->length(); ++i) { 574 for (int i = 0; i < args->length(); ++i) {
448 Visit(args->at(i)); 575 Visit(args->at(i));
449 Register arg = temporary_register_scope.NewRegister(); 576 Register arg = temporary_register_scope.NewRegister();
450 DCHECK(arg.index() - i == receiver.index() + 1); 577 DCHECK(arg.index() - i == receiver.index() + 1);
451 builder().StoreAccumulatorInRegister(arg); 578 builder()->StoreAccumulatorInRegister(arg);
452 } 579 }
453 580
454 // TODO(rmcilroy): Deal with possible direct eval here? 581 // TODO(rmcilroy): Deal with possible direct eval here?
455 // TODO(rmcilroy): Use CallIC to allow call type feedback. 582 // TODO(rmcilroy): Use CallIC to allow call type feedback.
456 builder().Call(callee, receiver, args->length()); 583 builder()->Call(callee, receiver, args->length());
457 } 584 }
458 585
459 586
460 void BytecodeGenerator::VisitCallNew(CallNew* expr) { UNIMPLEMENTED(); } 587 void BytecodeGenerator::VisitCallNew(CallNew* expr) { UNIMPLEMENTED(); }
461 588
462 589
463 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { UNIMPLEMENTED(); } 590 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { UNIMPLEMENTED(); }
464 591
465 592
466 void BytecodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 593 void BytecodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
(...skipping 22 matching lines...) Expand all
489 616
490 void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) { 617 void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) {
491 Token::Value op = expr->op(); 618 Token::Value op = expr->op();
492 Expression* left = expr->left(); 619 Expression* left = expr->left();
493 Expression* right = expr->right(); 620 Expression* right = expr->right();
494 621
495 TemporaryRegisterScope temporary_register_scope(&builder_); 622 TemporaryRegisterScope temporary_register_scope(&builder_);
496 Register temporary = temporary_register_scope.NewRegister(); 623 Register temporary = temporary_register_scope.NewRegister();
497 624
498 Visit(left); 625 Visit(left);
499 builder().StoreAccumulatorInRegister(temporary); 626 builder()->StoreAccumulatorInRegister(temporary);
500 Visit(right); 627 Visit(right);
501 builder().CompareOperation(op, temporary, language_mode()); 628 builder()->CompareOperation(op, temporary, language_mode());
502 } 629 }
503 630
504 631
505 void BytecodeGenerator::VisitSpread(Spread* expr) { UNREACHABLE(); } 632 void BytecodeGenerator::VisitSpread(Spread* expr) { UNREACHABLE(); }
506 633
507 634
508 void BytecodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) { 635 void BytecodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) {
509 UNREACHABLE(); 636 UNREACHABLE();
510 } 637 }
511 638
(...skipping 16 matching lines...) Expand all
528 655
529 void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* binop) { 656 void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* binop) {
530 Token::Value op = binop->op(); 657 Token::Value op = binop->op();
531 Expression* left = binop->left(); 658 Expression* left = binop->left();
532 Expression* right = binop->right(); 659 Expression* right = binop->right();
533 660
534 TemporaryRegisterScope temporary_register_scope(&builder_); 661 TemporaryRegisterScope temporary_register_scope(&builder_);
535 Register temporary = temporary_register_scope.NewRegister(); 662 Register temporary = temporary_register_scope.NewRegister();
536 663
537 Visit(left); 664 Visit(left);
538 builder().StoreAccumulatorInRegister(temporary); 665 builder()->StoreAccumulatorInRegister(temporary);
539 Visit(right); 666 Visit(right);
540 builder().BinaryOperation(op, temporary); 667 builder()->BinaryOperation(op, temporary);
541 } 668 }
542 669
543 670
544 LanguageMode BytecodeGenerator::language_mode() const { 671 LanguageMode BytecodeGenerator::language_mode() const {
545 return info()->language_mode(); 672 return info()->language_mode();
546 } 673 }
547 674
548 675
549 int BytecodeGenerator::feedback_index(FeedbackVectorICSlot slot) const { 676 int BytecodeGenerator::feedback_index(FeedbackVectorICSlot slot) const {
550 return info()->feedback_vector()->GetIndex(slot); 677 return info()->feedback_vector()->GetIndex(slot);
551 } 678 }
552 679
553 } // namespace interpreter 680 } // namespace interpreter
554 } // namespace internal 681 } // namespace internal
555 } // namespace v8 682 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698