Commit 04c00ee9 authored by rmcilroy's avatar rmcilroy Committed by Commit bot

[Interpreter] Implement do expressions.

Implements do expressions for the Ignition.

BUG=v8:4685
LOG=N

Review URL: https://codereview.chromium.org/1632213002

Cr-Commit-Position: refs/heads/master@{#33525}
parent 95aedaa0
......@@ -1222,7 +1222,8 @@ void BytecodeGenerator::VisitNativeFunctionLiteral(
void BytecodeGenerator::VisitDoExpression(DoExpression* expr) {
UNIMPLEMENTED();
VisitBlock(expr->block());
VisitVariableProxy(expr->result());
}
......
......@@ -2426,6 +2426,39 @@ TEST(JumpWithConstantsAndWideConstants) {
}
}
TEST(BytecodeGraphBuilderDoExpressions) {
bool old_flag = FLAG_harmony_do_expressions;
FLAG_harmony_do_expressions = true;
HandleAndZoneScope scope;
Isolate* isolate = scope.main_isolate();
Zone* zone = scope.main_zone();
Factory* factory = isolate->factory();
ExpectedSnippet<0> snippets[] = {
{"var a = do {}; return a;", {factory->undefined_value()}},
{"var a = do { var x = 100; }; return a;", {factory->undefined_value()}},
{"var a = do { var x = 100; }; return a;", {factory->undefined_value()}},
{"var a = do { var x = 100; x++; }; return a;",
{handle(Smi::FromInt(100), isolate)}},
{"var i = 0; for (; i < 5;) { i = do { if (i == 3) { break; }; i + 1; }};"
"return i;",
{handle(Smi::FromInt(3), isolate)}},
};
for (size_t i = 0; i < arraysize(snippets); i++) {
ScopedVector<char> script(1024);
SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
snippets[i].code_snippet, kFunctionName);
BytecodeGraphTester tester(isolate, zone, script.start());
auto callable = tester.GetCallable<>();
Handle<Object> return_value = callable().ToHandleChecked();
CHECK(return_value->SameValue(*snippets[i].return_value()));
}
FLAG_harmony_do_expressions = old_flag;
}
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -7549,6 +7549,68 @@ TEST(WideRegisters) {
}
}
TEST(DoExpression) {
bool old_flag = FLAG_harmony_do_expressions;
FLAG_harmony_do_expressions = true;
InitializedHandleScope handle_scope;
BytecodeGeneratorHelper helper;
ExpectedSnippet<const char*> snippets[] = {
{"var a = do { }; return a;",
2 * kPointerSize,
1,
5,
{
B(Ldar), R(0), //
B(Star), R(1), //
B(Return) //
},
0},
{"var a = do { var x = 100; }; return a;",
3 * kPointerSize,
1,
10,
{
B(LdaSmi8), U8(100), //
B(Star), R(1), //
B(LdaUndefined), //
B(Star), R(0), //
B(Star), R(2), //
B(Return) //
},
0},
{"while(true) { var a = 10; a = do { ++a; break; }; a = 20; }",
2 * kPointerSize,
1,
24,
{
B(LdaSmi8), U8(10), //
B(Star), R(1), //
B(ToNumber), //
B(Inc), //
B(Star), R(1), //
B(Star), R(0), //
B(Jump), U8(12), //
B(Ldar), R(0), //
B(Star), R(1), //
B(LdaSmi8), U8(20), //
B(Star), R(1), //
B(Jump), U8(-20), //
B(LdaUndefined), //
B(Return), //
},
0},
};
for (size_t i = 0; i < arraysize(snippets); i++) {
Handle<BytecodeArray> bytecode_array =
helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
CheckBytecodeArrayEqual(snippets[i], bytecode_array);
}
FLAG_harmony_do_expressions = old_flag;
}
} // namespace interpreter
} // namespace internal
} // namespace v8
......@@ -3825,6 +3825,37 @@ TEST(InterpreterWideParametersSummation) {
// TODO(oth): Test for..in with wide registers.
TEST(InterpreterDoExpression) {
bool old_flag = FLAG_harmony_do_expressions;
FLAG_harmony_do_expressions = true;
HandleAndZoneScope handles;
i::Isolate* isolate = handles.main_isolate();
Factory* factory = isolate->factory();
std::pair<const char*, Handle<Object>> do_expr[] = {
{"var a = do {}; return a;", factory->undefined_value()},
{"var a = do { var x = 100; }; return a;", factory->undefined_value()},
{"var a = do { var x = 100; }; return a;", factory->undefined_value()},
{"var a = do { var x = 100; x++; }; return a;",
handle(Smi::FromInt(100), isolate)},
{"var i = 0; for (; i < 5;) { i = do { if (i == 3) { break; }; i + 1; }};"
"return i;",
handle(Smi::FromInt(3), isolate)},
};
for (size_t i = 0; i < arraysize(do_expr); i++) {
std::string source(InterpreterTester::SourceForBody(do_expr[i].first));
InterpreterTester tester(handles.main_isolate(), source.c_str());
auto callable = tester.GetCallable<>();
Handle<i::Object> return_value = callable().ToHandleChecked();
CHECK(return_value->SameValue(*do_expr[i].second));
}
FLAG_harmony_do_expressions = old_flag;
}
} // namespace interpreter
} // namespace internal
} // namespace v8
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment