Commit 67c99a99 authored by mythria's avatar mythria Committed by Commit bot

[Interpreter] Adds wide variant of CreateLiterals. Adds CreateLiterals to BytecodeGraphBuilder.

Adds implementation and tests for CreateObjectLiteral, CreateArrayLiteral and CreateRegExpLiteral
to bytecode graph builder. Also changes these bytecodes to expect three operands instead of using
accumulator to pass one of the operands. This is done to avoid looking into the earlier nodes to
fetch operands in the bytecode graph builder. Also adds support for wide variant of these
bytecodes to bytecode generator and bytecode graph builder.

BUG=v8:4280
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#32710}
parent 82fd0047
...@@ -702,21 +702,82 @@ void BytecodeGraphBuilder::VisitCreateUnmappedArguments( ...@@ -702,21 +702,82 @@ void BytecodeGraphBuilder::VisitCreateUnmappedArguments(
} }
void BytecodeGraphBuilder::BuildCreateLiteral(const Operator* op) {
Node* literal = NewNode(op, GetFunctionClosure());
AddEmptyFrameStateInputs(literal);
environment()->BindAccumulator(literal);
}
void BytecodeGraphBuilder::BuildCreateRegExpLiteral(
const interpreter::BytecodeArrayIterator& iterator) {
Handle<String> constant_pattern =
Handle<String>::cast(iterator.GetConstantForIndexOperand(0));
int literal_index = iterator.GetIndexOperand(1);
int literal_flags = iterator.GetImmediateOperand(2);
const Operator* op = javascript()->CreateLiteralRegExp(
constant_pattern, literal_flags, literal_index);
BuildCreateLiteral(op);
}
void BytecodeGraphBuilder::VisitCreateRegExpLiteral( void BytecodeGraphBuilder::VisitCreateRegExpLiteral(
const interpreter::BytecodeArrayIterator& iterator) { const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED(); BuildCreateRegExpLiteral(iterator);
}
void BytecodeGraphBuilder::VisitCreateRegExpLiteralWide(
const interpreter::BytecodeArrayIterator& iterator) {
BuildCreateRegExpLiteral(iterator);
}
void BytecodeGraphBuilder::BuildCreateArrayLiteral(
const interpreter::BytecodeArrayIterator& iterator) {
Handle<FixedArray> constant_elements =
Handle<FixedArray>::cast(iterator.GetConstantForIndexOperand(0));
int literal_index = iterator.GetIndexOperand(1);
int literal_flags = iterator.GetImmediateOperand(2);
const Operator* op = javascript()->CreateLiteralArray(
constant_elements, literal_flags, literal_index);
BuildCreateLiteral(op);
} }
void BytecodeGraphBuilder::VisitCreateArrayLiteral( void BytecodeGraphBuilder::VisitCreateArrayLiteral(
const interpreter::BytecodeArrayIterator& iterator) { const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED(); BuildCreateArrayLiteral(iterator);
}
void BytecodeGraphBuilder::VisitCreateArrayLiteralWide(
const interpreter::BytecodeArrayIterator& iterator) {
BuildCreateArrayLiteral(iterator);
}
void BytecodeGraphBuilder::BuildCreateObjectLiteral(
const interpreter::BytecodeArrayIterator& iterator) {
Handle<FixedArray> constant_properties =
Handle<FixedArray>::cast(iterator.GetConstantForIndexOperand(0));
int literal_index = iterator.GetIndexOperand(1);
int literal_flags = iterator.GetImmediateOperand(2);
const Operator* op = javascript()->CreateLiteralObject(
constant_properties, literal_flags, literal_index);
BuildCreateLiteral(op);
} }
void BytecodeGraphBuilder::VisitCreateObjectLiteral( void BytecodeGraphBuilder::VisitCreateObjectLiteral(
const interpreter::BytecodeArrayIterator& iterator) { const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED(); BuildCreateObjectLiteral(iterator);
}
void BytecodeGraphBuilder::VisitCreateObjectLiteralWide(
const interpreter::BytecodeArrayIterator& iterator) {
BuildCreateObjectLiteral(iterator);
} }
......
...@@ -107,6 +107,13 @@ class BytecodeGraphBuilder { ...@@ -107,6 +107,13 @@ class BytecodeGraphBuilder {
interpreter::Register first_arg, interpreter::Register first_arg,
size_t arity); size_t arity);
void BuildCreateLiteral(const Operator* op);
void BuildCreateRegExpLiteral(
const interpreter::BytecodeArrayIterator& iterator);
void BuildCreateArrayLiteral(
const interpreter::BytecodeArrayIterator& iterator);
void BuildCreateObjectLiteral(
const interpreter::BytecodeArrayIterator& iterator);
void BuildLoadGlobal(const interpreter::BytecodeArrayIterator& iterator, void BuildLoadGlobal(const interpreter::BytecodeArrayIterator& iterator,
TypeofMode typeof_mode); TypeofMode typeof_mode);
void BuildStoreGlobal(const interpreter::BytecodeArrayIterator& iterator); void BuildStoreGlobal(const interpreter::BytecodeArrayIterator& iterator);
......
...@@ -537,11 +537,17 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments( ...@@ -537,11 +537,17 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments(
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral( BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral(
int literal_index, int flags) { Handle<String> pattern, int literal_index, int flags) {
DCHECK(FitsInImm8Operand(flags)); // Flags should fit in 8 bits. DCHECK(FitsInImm8Operand(flags)); // Flags should fit in 8 bits.
if (FitsInIdx8Operand(literal_index)) { size_t pattern_entry = GetConstantPoolEntry(pattern);
Output(Bytecode::kCreateRegExpLiteral, static_cast<uint8_t>(literal_index), if (FitsInIdx8Operand(literal_index) && FitsInIdx8Operand(pattern_entry)) {
static_cast<uint8_t>(flags)); Output(Bytecode::kCreateRegExpLiteral, static_cast<uint8_t>(pattern_entry),
static_cast<uint8_t>(literal_index), static_cast<uint8_t>(flags));
} else if (FitsInIdx16Operand(literal_index) &&
FitsInIdx16Operand(pattern_entry)) {
Output(Bytecode::kCreateRegExpLiteralWide,
static_cast<uint16_t>(pattern_entry),
static_cast<uint16_t>(literal_index), static_cast<uint8_t>(flags));
} else { } else {
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
...@@ -550,11 +556,19 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral( ...@@ -550,11 +556,19 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral(
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral( BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral(
int literal_index, int flags) { Handle<FixedArray> constant_elements, int literal_index, int flags) {
DCHECK(FitsInImm8Operand(flags)); // Flags should fit in 8 bits. DCHECK(FitsInImm8Operand(flags)); // Flags should fit in 8 bits.
if (FitsInIdx8Operand(literal_index)) { size_t constant_elements_entry = GetConstantPoolEntry(constant_elements);
Output(Bytecode::kCreateArrayLiteral, static_cast<uint8_t>(literal_index), if (FitsInIdx8Operand(literal_index) &&
static_cast<uint8_t>(flags)); FitsInIdx8Operand(constant_elements_entry)) {
Output(Bytecode::kCreateArrayLiteral,
static_cast<uint8_t>(constant_elements_entry),
static_cast<uint8_t>(literal_index), static_cast<uint8_t>(flags));
} else if (FitsInIdx16Operand(literal_index) &&
FitsInIdx16Operand(constant_elements_entry)) {
Output(Bytecode::kCreateArrayLiteralWide,
static_cast<uint16_t>(constant_elements_entry),
static_cast<uint16_t>(literal_index), static_cast<uint8_t>(flags));
} else { } else {
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
...@@ -563,11 +577,19 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral( ...@@ -563,11 +577,19 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral(
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral( BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral(
int literal_index, int flags) { Handle<FixedArray> constant_properties, int literal_index, int flags) {
DCHECK(FitsInImm8Operand(flags)); // Flags should fit in 8 bits. DCHECK(FitsInImm8Operand(flags)); // Flags should fit in 8 bits.
if (FitsInIdx8Operand(literal_index)) { size_t constant_properties_entry = GetConstantPoolEntry(constant_properties);
Output(Bytecode::kCreateObjectLiteral, static_cast<uint8_t>(literal_index), if (FitsInIdx8Operand(literal_index) &&
static_cast<uint8_t>(flags)); FitsInIdx8Operand(constant_properties_entry)) {
Output(Bytecode::kCreateObjectLiteral,
static_cast<uint8_t>(constant_properties_entry),
static_cast<uint8_t>(literal_index), static_cast<uint8_t>(flags));
} else if (FitsInIdx16Operand(literal_index) &&
FitsInIdx16Operand(constant_properties_entry)) {
Output(Bytecode::kCreateObjectLiteralWide,
static_cast<uint16_t>(constant_properties_entry),
static_cast<uint16_t>(literal_index), static_cast<uint8_t>(flags));
} else { } else {
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
......
...@@ -125,9 +125,12 @@ class BytecodeArrayBuilder { ...@@ -125,9 +125,12 @@ class BytecodeArrayBuilder {
BytecodeArrayBuilder& CreateArguments(CreateArgumentsType type); BytecodeArrayBuilder& CreateArguments(CreateArgumentsType type);
// Literals creation. Constant elements should be in the accumulator. // Literals creation. Constant elements should be in the accumulator.
BytecodeArrayBuilder& CreateRegExpLiteral(int literal_index, int flags); BytecodeArrayBuilder& CreateRegExpLiteral(Handle<String> pattern,
BytecodeArrayBuilder& CreateArrayLiteral(int literal_index, int flags); int literal_index, int flags);
BytecodeArrayBuilder& CreateObjectLiteral(int literal_index, int flags); BytecodeArrayBuilder& CreateArrayLiteral(Handle<FixedArray> constant_elements,
int literal_index, int flags);
BytecodeArrayBuilder& CreateObjectLiteral(
Handle<FixedArray> constant_properties, int literal_index, int flags);
// Push the context in accumulator as the new context, and store in register // Push the context in accumulator as the new context, and store in register
// |context|. // |context|.
......
...@@ -1040,18 +1040,17 @@ void BytecodeGenerator::VisitLiteral(Literal* expr) { ...@@ -1040,18 +1040,17 @@ void BytecodeGenerator::VisitLiteral(Literal* expr) {
void BytecodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { void BytecodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
// Materialize a regular expression literal. // Materialize a regular expression literal.
TemporaryRegisterScope temporary_register_scope(builder()); TemporaryRegisterScope temporary_register_scope(builder());
builder() builder()->CreateRegExpLiteral(expr->pattern(), expr->literal_index(),
->LoadLiteral(expr->pattern()) expr->flags());
.CreateRegExpLiteral(expr->literal_index(), expr->flags());
execution_result()->SetResultInAccumulator(); execution_result()->SetResultInAccumulator();
} }
void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
// Deep-copy the literal boilerplate. // Deep-copy the literal boilerplate.
builder() builder()->CreateObjectLiteral(expr->constant_properties(),
->LoadLiteral(expr->constant_properties()) expr->literal_index(),
.CreateObjectLiteral(expr->literal_index(), expr->ComputeFlags(true)); expr->ComputeFlags(true));
TemporaryRegisterScope temporary_register_scope(builder()); TemporaryRegisterScope temporary_register_scope(builder());
Register literal; Register literal;
...@@ -1243,9 +1242,9 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -1243,9 +1242,9 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
// Deep-copy the literal boilerplate. // Deep-copy the literal boilerplate.
builder() builder()->CreateArrayLiteral(expr->constant_elements(),
->LoadLiteral(expr->constant_elements()) expr->literal_index(),
.CreateArrayLiteral(expr->literal_index(), expr->ComputeFlags(true)); expr->ComputeFlags(true));
TemporaryRegisterScope temporary_register_scope(builder()); TemporaryRegisterScope temporary_register_scope(builder());
Register index, literal; Register index, literal;
......
...@@ -155,9 +155,18 @@ namespace interpreter { ...@@ -155,9 +155,18 @@ namespace interpreter {
V(ToObject, OperandType::kNone) \ V(ToObject, OperandType::kNone) \
\ \
/* Literals */ \ /* Literals */ \
V(CreateRegExpLiteral, OperandType::kIdx8, OperandType::kImm8) \ V(CreateRegExpLiteral, OperandType::kIdx8, OperandType::kIdx8, \
V(CreateArrayLiteral, OperandType::kIdx8, OperandType::kImm8) \ OperandType::kImm8) \
V(CreateObjectLiteral, OperandType::kIdx8, OperandType::kImm8) \ V(CreateArrayLiteral, OperandType::kIdx8, OperandType::kIdx8, \
OperandType::kImm8) \
V(CreateObjectLiteral, OperandType::kIdx8, OperandType::kIdx8, \
OperandType::kImm8) \
V(CreateRegExpLiteralWide, OperandType::kIdx16, OperandType::kIdx16, \
OperandType::kImm8) \
V(CreateArrayLiteralWide, OperandType::kIdx16, OperandType::kIdx16, \
OperandType::kImm8) \
V(CreateObjectLiteralWide, OperandType::kIdx16, OperandType::kIdx16, \
OperandType::kImm8) \
\ \
/* Closure allocation */ \ /* Closure allocation */ \
V(CreateClosure, OperandType::kIdx8, OperandType::kImm8) \ V(CreateClosure, OperandType::kIdx8, OperandType::kImm8) \
......
...@@ -1305,10 +1305,11 @@ void Interpreter::DoJumpIfUndefinedConstant( ...@@ -1305,10 +1305,11 @@ void Interpreter::DoJumpIfUndefinedConstant(
void Interpreter::DoCreateLiteral(Runtime::FunctionId function_id, void Interpreter::DoCreateLiteral(Runtime::FunctionId function_id,
compiler::InterpreterAssembler* assembler) { compiler::InterpreterAssembler* assembler) {
Node* constant_elements = __ GetAccumulator(); Node* index = __ BytecodeOperandIdx(0);
Node* literal_index_raw = __ BytecodeOperandIdx(0); Node* constant_elements = __ LoadConstantPoolEntry(index);
Node* literal_index_raw = __ BytecodeOperandIdx(1);
Node* literal_index = __ SmiTag(literal_index_raw); Node* literal_index = __ SmiTag(literal_index_raw);
Node* flags_raw = __ BytecodeOperandImm(1); Node* flags_raw = __ BytecodeOperandImm(2);
Node* flags = __ SmiTag(flags_raw); Node* flags = __ SmiTag(flags_raw);
Node* closure = __ LoadRegister(Register::function_closure()); Node* closure = __ LoadRegister(Register::function_closure());
Node* result = __ CallRuntime(function_id, closure, literal_index, Node* result = __ CallRuntime(function_id, closure, literal_index,
...@@ -1318,36 +1319,66 @@ void Interpreter::DoCreateLiteral(Runtime::FunctionId function_id, ...@@ -1318,36 +1319,66 @@ void Interpreter::DoCreateLiteral(Runtime::FunctionId function_id,
} }
// CreateRegExpLiteral <idx> <flags> // CreateRegExpLiteral <pattern_idx> <literal_idx> <flags>
// //
// Creates a regular expression literal for literal index <idx> with <flags> and // Creates a regular expression literal for literal index <literal_idx> with
// the pattern in the accumulator. // <flags> and the pattern in <pattern_idx>.
void Interpreter::DoCreateRegExpLiteral( void Interpreter::DoCreateRegExpLiteral(
compiler::InterpreterAssembler* assembler) { compiler::InterpreterAssembler* assembler) {
DoCreateLiteral(Runtime::kCreateRegExpLiteral, assembler); DoCreateLiteral(Runtime::kCreateRegExpLiteral, assembler);
} }
// CreateArrayLiteral <idx> <flags> // CreateRegExpLiteralWide <pattern_idx> <literal_idx> <flags>
//
// Creates a regular expression literal for literal index <literal_idx> with
// <flags> and the pattern in <pattern_idx>.
void Interpreter::DoCreateRegExpLiteralWide(
compiler::InterpreterAssembler* assembler) {
DoCreateLiteral(Runtime::kCreateRegExpLiteral, assembler);
}
// CreateArrayLiteral <element_idx> <literal_idx> <flags>
// //
// Creates an array literal for literal index <idx> with flags <flags> and // Creates an array literal for literal index <literal_idx> with flags <flags>
// constant elements in the accumulator. // and constant elements in <element_idx>.
void Interpreter::DoCreateArrayLiteral( void Interpreter::DoCreateArrayLiteral(
compiler::InterpreterAssembler* assembler) { compiler::InterpreterAssembler* assembler) {
DoCreateLiteral(Runtime::kCreateArrayLiteral, assembler); DoCreateLiteral(Runtime::kCreateArrayLiteral, assembler);
} }
// CreateObjectLiteral <idx> <flags> // CreateArrayLiteralWide <element_idx> <literal_idx> <flags>
// //
// Creates an object literal for literal index <idx> with flags <flags> and // Creates an array literal for literal index <literal_idx> with flags <flags>
// constant elements in the accumulator. // and constant elements in <element_idx>.
void Interpreter::DoCreateArrayLiteralWide(
compiler::InterpreterAssembler* assembler) {
DoCreateLiteral(Runtime::kCreateArrayLiteral, assembler);
}
// CreateObjectLiteral <element_idx> <literal_idx> <flags>
//
// Creates an object literal for literal index <literal_idx> with flags <flags>
// and constant elements in <element_idx>.
void Interpreter::DoCreateObjectLiteral( void Interpreter::DoCreateObjectLiteral(
compiler::InterpreterAssembler* assembler) { compiler::InterpreterAssembler* assembler) {
DoCreateLiteral(Runtime::kCreateObjectLiteral, assembler); DoCreateLiteral(Runtime::kCreateObjectLiteral, assembler);
} }
// CreateObjectLiteralWide <element_idx> <literal_idx> <flags>
//
// Creates an object literal for literal index <literal_idx> with flags <flags>
// and constant elements in <element_idx>.
void Interpreter::DoCreateObjectLiteralWide(
compiler::InterpreterAssembler* assembler) {
DoCreateLiteral(Runtime::kCreateObjectLiteral, assembler);
}
// CreateClosure <index> <tenured> // CreateClosure <index> <tenured>
// //
// Creates a new closure for SharedFunctionInfo at position |index| in the // Creates a new closure for SharedFunctionInfo at position |index| in the
......
...@@ -1183,6 +1183,150 @@ TEST(BytecodeGraphBuilderLoadContext) { ...@@ -1183,6 +1183,150 @@ TEST(BytecodeGraphBuilderLoadContext) {
} }
} }
TEST(BytecodeGraphBuilderRegExpLiterals) {
HandleAndZoneScope scope;
Isolate* isolate = scope.main_isolate();
Zone* zone = scope.main_zone();
Factory* factory = isolate->factory();
ExpectedSnippet<0> snippets[] = {
{"return /abd/.exec('cccabbdd');", {factory->null_value()}},
{"return /ab+d/.exec('cccabbdd')[0];",
{factory->NewStringFromStaticChars("abbd")}},
{"var a = 3.1414;"
REPEAT_256(SPACE, "a = 3.1414;")
"return /ab+d/.exec('cccabbdd')[0];",
{factory->NewStringFromStaticChars("abbd")}},
{"return /ab+d/.exec('cccabbdd')[1];", {factory->undefined_value()}},
{"return /AbC/i.exec('ssaBC')[0];",
{factory->NewStringFromStaticChars("aBC")}},
{"return 'ssaBC'.match(/AbC/i)[0];",
{factory->NewStringFromStaticChars("aBC")}},
{"return 'ssaBCtAbC'.match(/(AbC)/gi)[1];",
{factory->NewStringFromStaticChars("AbC")}},
};
size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
for (size_t i = 0; i < num_snippets; i++) {
ScopedVector<char> script(4096);
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()));
}
}
TEST(BytecodeGraphBuilderArrayLiterals) {
HandleAndZoneScope scope;
Isolate* isolate = scope.main_isolate();
Zone* zone = scope.main_zone();
Factory* factory = isolate->factory();
ExpectedSnippet<0> snippets[] = {
{"return [][0];", {factory->undefined_value()}},
{"return [1, 3, 2][1];", {factory->NewNumberFromInt(3)}},
{"var a;" REPEAT_256(SPACE, "a = 9.87;") "return [1, 3, 2][1];",
{factory->NewNumberFromInt(3)}},
{"return ['a', 'b', 'c'][2];", {factory->NewStringFromStaticChars("c")}},
{"var a = 100; return [a, a++, a + 2, a + 3][2];",
{factory->NewNumberFromInt(103)}},
{"var a = 100; return [a, ++a, a + 2, a + 3][1];",
{factory->NewNumberFromInt(101)}},
{"var a = 9.2;"
REPEAT_256(SPACE, "a = 9.34;")
"return [a, ++a, a + 2, a + 3][2];",
{factory->NewHeapNumber(12.34)}},
{"return [[1, 2, 3], ['a', 'b', 'c']][1][0];",
{factory->NewStringFromStaticChars("a")}},
{"var t = 't'; return [[t, t + 'est'], [1 + t]][0][1];",
{factory->NewStringFromStaticChars("test")}},
{"var t = 't'; return [[t, t + 'est'], [1 + t]][1][0];",
{factory->NewStringFromStaticChars("1t")}}};
size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
for (size_t i = 0; i < num_snippets; i++) {
ScopedVector<char> script(4096);
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()));
}
}
TEST(BytecodeGraphBuilderObjectLiterals) {
HandleAndZoneScope scope;
Isolate* isolate = scope.main_isolate();
Zone* zone = scope.main_zone();
Factory* factory = isolate->factory();
ExpectedSnippet<0> snippets[] = {
{"return { }.name;", {factory->undefined_value()}},
{"return { name: 'string', val: 9.2 }.name;",
{factory->NewStringFromStaticChars("string")}},
{"var a;\n"
REPEAT_256(SPACE, "a = 1.23;\n")
"return { name: 'string', val: 9.2 }.name;",
{factory->NewStringFromStaticChars("string")}},
{"return { name: 'string', val: 9.2 }['name'];",
{factory->NewStringFromStaticChars("string")}},
{"var a = 15; return { name: 'string', val: a }.val;",
{factory->NewNumberFromInt(15)}},
{"var a;"
REPEAT_256(SPACE, "a = 1.23;")
"return { name: 'string', val: a }.val;",
{factory->NewHeapNumber(1.23)}},
{"var a = 15; var b = 'val'; return { name: 'string', val: a }[b];",
{factory->NewNumberFromInt(15)}},
{"var a = 5; return { val: a, val: a + 1 }.val;",
{factory->NewNumberFromInt(6)}},
{"return { func: function() { return 'test' } }.func();",
{factory->NewStringFromStaticChars("test")}},
{"return { func(a) { return a + 'st'; } }.func('te');",
{factory->NewStringFromStaticChars("test")}},
{"return { get a() { return 22; } }.a;", {factory->NewNumberFromInt(22)}},
{"var a = { get b() { return this.x + 't'; },\n"
" set b(val) { this.x = val + 's' } };\n"
"a.b = 'te';\n"
"return a.b;",
{factory->NewStringFromStaticChars("test")}},
{"var a = 123; return { 1: a }[1];", {factory->NewNumberFromInt(123)}},
{"return Object.getPrototypeOf({ __proto__: null });",
{factory->null_value()}},
{"var a = 'test'; return { [a]: 1 }.test;",
{factory->NewNumberFromInt(1)}},
{"var a = 'test'; return { b: a, [a]: a + 'ing' }['test']",
{factory->NewStringFromStaticChars("testing")}},
{"var a = 'proto_str';\n"
"var b = { [a]: 1, __proto__: { var : a } };\n"
"return Object.getPrototypeOf(b).var",
{factory->NewStringFromStaticChars("proto_str")}},
{"var n = 'name';\n"
"return { [n]: 'val', get a() { return 987 } }['a'];",
{factory->NewNumberFromInt(987)}},
};
size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
for (size_t i = 0; i < num_snippets; i++) {
ScopedVector<char> script(4096);
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()));
}
}
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -104,10 +104,10 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { ...@@ -104,10 +104,10 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
builder.CreateArguments(CreateArgumentsType::kMappedArguments) builder.CreateArguments(CreateArgumentsType::kMappedArguments)
.CreateArguments(CreateArgumentsType::kUnmappedArguments); .CreateArguments(CreateArgumentsType::kUnmappedArguments);
// Emit literal creation operations // Emit literal creation operations.
builder.CreateRegExpLiteral(0, 0) builder.CreateRegExpLiteral(factory->NewStringFromStaticChars("a"), 0, 0)
.CreateArrayLiteral(0, 0) .CreateArrayLiteral(factory->NewFixedArray(1), 0, 0)
.CreateObjectLiteral(0, 0); .CreateObjectLiteral(factory->NewFixedArray(1), 0, 0);
// Call operations. // Call operations.
builder.Call(reg, reg, 0, 0) builder.Call(reg, reg, 0, 0)
...@@ -224,6 +224,12 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { ...@@ -224,6 +224,12 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
false); false);
builder.CreateClosure(shared_info2, NOT_TENURED); builder.CreateClosure(shared_info2, NOT_TENURED);
// Emit wide variant of literal creation operations.
builder.CreateRegExpLiteral(factory->NewStringFromStaticChars("wide_literal"),
0, 0)
.CreateArrayLiteral(factory->NewFixedArray(2), 0, 0)
.CreateObjectLiteral(factory->NewFixedArray(2), 0, 0);
builder.Return(); builder.Return();
// Generate BytecodeArray. // Generate BytecodeArray.
......
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