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

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

Powered by Google App Engine
This is Rietveld 408576698