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

Unified Diff: src/interpreter/bytecode-generator.cc

Issue 1422033002: [Interpreter] Add support for for..in. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fixes for 32-bit. 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 side-by-side diff with in-line comments
Download patch
Index: src/interpreter/bytecode-generator.cc
diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
index 8c791db5e3d9ddbab25e65145c45bccffcb413e1..7c57b84501a8a1b99fdaea6a1e23ab651422a1e7 100644
--- a/src/interpreter/bytecode-generator.cc
+++ b/src/interpreter/bytecode-generator.cc
@@ -593,8 +593,116 @@ void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
}
+void BytecodeGenerator::VisitForInAssignment(Expression* expr,
+ FeedbackVectorSlot slot) {
+ DCHECK(expr->IsValidReferenceExpression());
+
+ // Evaluate assignment starting with the value to be stored in the
+ // accumulator.
+ Property* property = expr->AsProperty();
+ LhsKind assign_type = Property::GetAssignType(property);
+ switch (assign_type) {
+ case VARIABLE: {
+ Variable* variable = expr->AsVariableProxy()->var();
+ VisitVariableAssignment(variable, slot);
+ break;
+ }
+ case NAMED_PROPERTY: {
+ TemporaryRegisterScope temporary_register_scope(builder());
+ Register value = temporary_register_scope.NewRegister();
rmcilroy 2015/10/26 14:04:01 nit - use expression_result()->NewRegister() ?
oth 2015/10/28 11:53:12 This would cause us to allocate an extra register
+ builder()->StoreAccumulatorInRegister(value);
+ Register object = VisitForRegisterValue(property->obj());
+ size_t name_index = builder()->GetConstantPoolEntry(
+ property->key()->AsLiteral()->AsPropertyName());
+ builder()->StoreNamedProperty(object, name_index, feedback_index(slot),
+ language_mode());
+ break;
+ }
+ case KEYED_PROPERTY: {
+ TemporaryRegisterScope temporary_register_scope(builder());
+ Register value = temporary_register_scope.NewRegister();
rmcilroy 2015/10/26 14:04:01 ditto
oth 2015/10/28 11:53:12 This would cause us to allocate an extra register
+ builder()->StoreAccumulatorInRegister(value);
+ Register object = VisitForRegisterValue(property->obj());
+ Register key = VisitForRegisterValue(property->key());
+ builder()->LoadAccumulatorWithRegister(value);
+ builder()->StoreKeyedProperty(object, key, feedback_index(slot),
+ language_mode());
+ break;
+ }
+ case NAMED_SUPER_PROPERTY:
+ case KEYED_SUPER_PROPERTY:
+ UNIMPLEMENTED();
+ }
+}
+
+
void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
- UNIMPLEMENTED();
+ EffectResultScope result_scope(this);
rmcilroy 2015/10/26 14:04:01 Is this needed? Shouldn't we just be using VisitFo
oth 2015/10/28 11:53:12 This is needed. RegisterResultScope can allocate a
+
+ if (stmt->subject()->IsNullLiteral() ||
+ stmt->subject()->IsUndefinedLiteral(isolate())) {
+ // ForIn generates lots of code, skip if it wouldn't produce any effects.
+ return;
+ }
+
+ TemporaryRegisterScope temporary_register_scope(builder());
+ LoopBuilder loop_builder(builder());
+ ControlScopeForIteration control_scope(this, stmt, &loop_builder);
+
+ // Prepare the state for executing ForIn.
+ builder()->EnterBlock();
+ VisitForAccumulatorValue(stmt->subject());
+ builder()->ForInPrepare();
+ Register for_in_state = temporary_register_scope.NewRegister();
rmcilroy 2015/10/26 14:04:01 nit - move this up (and use execution_result()->Ne
oth 2015/10/28 11:53:11 Done.
+ builder()->StoreAccumulatorInRegister(for_in_state);
rmcilroy 2015/10/26 14:04:01 nit - use builder chaining?
oth 2015/10/28 11:53:11 Done-ish. Changed to chain in blocks that are logi
+ builder()->LoadUndefined();
+ builder()->CompareOperation(Token::Value::EQ_STRICT, for_in_state,
+ Strength::WEAK);
rmcilroy 2015/10/26 14:04:01 /s/Strength::WEAK/language_mode_strength()
oth 2015/10/28 11:53:12 Done.
+ loop_builder.BreakIfTrue();
+
+ // The loop
rmcilroy 2015/10/26 14:04:01 nit -full stop
oth 2015/10/28 11:53:11 Done.
+ BytecodeLabel condition_label, break_label, continue_label;
+
+ Register index = temporary_register_scope.NewRegister();
+ builder()->LoadLiteral(Smi::FromInt(0));
+ builder()->StoreAccumulatorInRegister(index);
+
+ // Check loop termination (accumulator holds index).
+ builder()->Bind(&condition_label);
+ builder()->ForInDone(for_in_state);
+ loop_builder.BreakIfTrue();
+
+ // Get next item
rmcilroy 2015/10/26 14:04:01 nit - full stop
oth 2015/10/28 11:53:11 Done.
+ builder()->LoadAccumulatorWithRegister(index);
+ builder()->ForInNext(for_in_state);
+
+ // Start again if item is undefined.
+ Register value = temporary_register_scope.NewRegister();
+ builder()->StoreAccumulatorInRegister(value);
+ builder()->LoadUndefined();
rmcilroy 2015/10/26 14:04:01 Would it be worth maintaining a temprorary registe
oth 2015/10/28 11:53:11 This is superb! Done.
+ builder()->CompareOperation(Token::Value::EQ_STRICT, value, Strength::WEAK);
+ loop_builder.ContinueIfTrue();
+ builder()->LoadAccumulatorWithRegister(value);
+
+ // Store the value in the each variable.
+ VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot());
+ // NB the user's loop variable will be assigned the value of each so
+ // even an empty body will have this assignment.
+ Visit(stmt->body());
+
+ // Increment index and start loop again.
+ builder()->Bind(&continue_label);
+ builder()->LoadLiteral(Smi::FromInt(1));
+ builder()->BinaryOperation(Token::Value::ADD, index, Strength::WEAK);
rmcilroy 2015/10/26 14:04:01 You could use builder()->CountOperation(Token::Val
oth 2015/10/28 11:53:12 Done.
+ builder()->StoreAccumulatorInRegister(index);
+ builder()->Jump(&condition_label);
+
+ // End of loop
+ builder()->Bind(&break_label);
+ builder()->LeaveBlock();
+
+ loop_builder.SetBreakTarget(break_label);
+ loop_builder.SetContinueTarget(continue_label);
}

Powered by Google App Engine
This is Rietveld 408576698