[interpreter] Bytecode for StaDataPropertyInLiteral.

Add bytecode for defining data properties, which initially just calls the runtime function.

BUG=v8:5624

Review-Url: https://codereview.chromium.org/2510743002
Cr-Commit-Position: refs/heads/master@{#41101}
This commit is contained in:
franzih 2016-11-18 04:13:30 -08:00 committed by Commit bot
parent 572b643b47
commit f7795cbf6e
11 changed files with 120 additions and 69 deletions

View File

@ -792,6 +792,23 @@ void BytecodeGraphBuilder::VisitStaGlobalStrict() {
BuildStoreGlobal(LanguageMode::STRICT);
}
void BytecodeGraphBuilder::VisitStaDataPropertyInLiteral() {
Node* object =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Node* name =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
Node* value =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
Node* attrs =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(3));
Node* set_function_name = environment()->LookupAccumulator();
const Operator* op =
javascript()->CallRuntime(Runtime::kDefineDataPropertyInLiteral);
Node* store = NewNode(op, object, name, value, attrs, set_function_name);
environment()->RecordAfterState(store, Environment::kAttachFrameState);
}
void BytecodeGraphBuilder::VisitLdaContextSlot() {
// TODO(mythria): immutable flag is also set to false. This information is not
// available in bytecode array. update this code when the implementation

View File

@ -87,6 +87,12 @@ class BytecodeGraphBuilder {
return MakeNode(op, arraysize(buffer), buffer, false);
}
Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
Node* n5) {
Node* buffer[] = {n1, n2, n3, n4, n5};
return MakeNode(op, arraysize(buffer), buffer, false);
}
// Helpers to create new control nodes.
Node* NewIfTrue() { return NewNode(common()->IfTrue()); }
Node* NewIfFalse() { return NewNode(common()->IfFalse()); }

View File

@ -542,6 +542,12 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty(
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreDataPropertyInLiteral(
Register object, Register name, Register value, Register attrs) {
OutputStaDataPropertyInLiteral(object, name, value, attrs);
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
Register object, const Handle<Name> name, int feedback_slot,
LanguageMode language_mode) {

View File

@ -122,6 +122,13 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final
// Keyed load property. The key should be in the accumulator.
BytecodeArrayBuilder& LoadKeyedProperty(Register object, int feedback_slot);
// Store properties. Flag for NeedsSetFunctionName() should
// be in the accumulator.
BytecodeArrayBuilder& StoreDataPropertyInLiteral(Register object,
Register name,
Register value,
Register attrs);
// Store properties. The value to be stored should be in the accumulator.
BytecodeArrayBuilder& StoreNamedProperty(Register object,
const Handle<Name> name,

View File

@ -1431,9 +1431,8 @@ void BytecodeGenerator::VisitClassLiteralProperties(ClassLiteral* expr,
Register literal,
Register prototype) {
RegisterAllocationScope register_scope(this);
RegisterList args = register_allocator()->NewRegisterList(5);
Register receiver = args[0], key = args[1], value = args[2], attr = args[3],
set_function_name = args[4];
RegisterList args = register_allocator()->NewRegisterList(4);
Register receiver = args[0], key = args[1], value = args[2], attr = args[3];
bool attr_assigned = false;
Register old_receiver = Register::invalid_value();
@ -1480,18 +1479,15 @@ void BytecodeGenerator::VisitClassLiteralProperties(ClassLiteral* expr,
case ClassLiteral::Property::METHOD: {
builder()
->LoadLiteral(Smi::FromInt(property->NeedsSetFunctionName()))
.StoreAccumulatorInRegister(set_function_name)
.CallRuntime(Runtime::kDefineDataPropertyInLiteral, args);
.StoreDataPropertyInLiteral(receiver, key, value, attr);
break;
}
case ClassLiteral::Property::GETTER: {
builder()->CallRuntime(Runtime::kDefineGetterPropertyUnchecked,
args.Truncate(4));
builder()->CallRuntime(Runtime::kDefineGetterPropertyUnchecked, args);
break;
}
case ClassLiteral::Property::SETTER: {
builder()->CallRuntime(Runtime::kDefineSetterPropertyUnchecked,
args.Truncate(4));
builder()->CallRuntime(Runtime::kDefineSetterPropertyUnchecked, args);
break;
}
case ClassLiteral::Property::FIELD: {
@ -1699,18 +1695,20 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::CONSTANT:
case ObjectLiteral::Property::COMPUTED:
case ObjectLiteral::Property::MATERIALIZED_LITERAL: {
RegisterList args = register_allocator()->NewRegisterList(5);
builder()->MoveRegister(literal, args[0]);
Register key = register_allocator()->NewRegister();
VisitForAccumulatorValue(property->key());
builder()->ConvertAccumulatorToName(args[1]);
VisitForRegisterValue(property->value(), args[2]);
VisitSetHomeObject(args[2], literal, property);
builder()->ConvertAccumulatorToName(key);
Register value = VisitForRegisterValue(property->value());
VisitSetHomeObject(value, literal, property);
Register attr = register_allocator()->NewRegister();
builder()
->LoadLiteral(Smi::FromInt(NONE))
.StoreAccumulatorInRegister(args[3])
.StoreAccumulatorInRegister(attr)
.LoadLiteral(Smi::FromInt(property->NeedsSetFunctionName()))
.StoreAccumulatorInRegister(args[4]);
builder()->CallRuntime(Runtime::kDefineDataPropertyInLiteral, args);
.StoreDataPropertyInLiteral(literal, key, value, attr);
break;
}
case ObjectLiteral::Property::GETTER:

View File

@ -98,6 +98,8 @@ namespace interpreter {
OperandType::kReg, OperandType::kIdx) \
V(StaKeyedPropertyStrict, AccumulatorUse::kRead, OperandType::kReg, \
OperandType::kReg, OperandType::kIdx) \
V(StaDataPropertyInLiteral, AccumulatorUse::kRead, OperandType::kReg, \
OperandType::kReg, OperandType::kReg, OperandType::kReg) \
\
/* Binary Operators */ \
V(Add, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx) \

View File

@ -846,6 +846,33 @@ void Interpreter::DoStaKeyedPropertyStrict(InterpreterAssembler* assembler) {
DoKeyedStoreIC(ic, assembler);
}
// StaDataPropertyInLiteral <object> <name> <value> <attrs>
//
// Define a property <name> with value <value> in <object>. Use property
// attributes <attrs> in the definition and set the name property of <value>
// according to the flag in the accumulator.
//
// This definition is not observable and is used only for definitions
// in object or class literals.
void Interpreter::DoStaDataPropertyInLiteral(InterpreterAssembler* assembler) {
Node* object_reg_index = __ BytecodeOperandReg(0);
Node* object = __ LoadRegister(object_reg_index);
Node* name_reg_index = __ BytecodeOperandReg(1);
Node* name = __ LoadRegister(name_reg_index);
Node* value_reg_index = __ BytecodeOperandReg(2);
Node* value = __ LoadRegister(value_reg_index);
Node* attrs_reg_index = __ BytecodeOperandReg(3);
Node* attrs = __ LoadRegister(attrs_reg_index);
Node* set_function_name = __ GetAccumulator();
Node* context = __ GetContext();
__ CallRuntime(Runtime::kDefineDataPropertyInLiteral, context, object, name,
value, attrs, set_function_name);
__ Dispatch();
}
// LdaModuleVariable <cell_index> <depth>
//
// Load the contents of a module variable into the accumulator. The variable is

View File

@ -12,9 +12,9 @@ snippet: "
speak() { console.log(this.name + ' is speaking.'); }
}
"
frame size: 10
frame size: 9
parameter count: 1
bytecode array length: 75
bytecode array length: 70
bytecodes: [
B(LdaTheHole),
B(Star), R(2),
@ -40,9 +40,7 @@ bytecodes: [
B(LdaSmi), U8(2),
B(Star), R(8),
B(LdaZero),
B(Star), R(9),
B(Mov), R(4), R(5),
B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(5), U8(5),
B(StaDataPropertyInLiteral), R(4), R(6), R(7), R(8),
B(CallRuntime), U16(Runtime::kToFastProperties), R(3), U8(1),
B(Star), R(0),
B(Star), R(1),
@ -66,9 +64,9 @@ snippet: "
speak() { console.log(this.name + ' is speaking.'); }
}
"
frame size: 10
frame size: 9
parameter count: 1
bytecode array length: 75
bytecode array length: 70
bytecodes: [
B(LdaTheHole),
B(Star), R(2),
@ -94,9 +92,7 @@ bytecodes: [
B(LdaSmi), U8(2),
B(Star), R(8),
B(LdaZero),
B(Star), R(9),
B(Mov), R(4), R(5),
B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(5), U8(5),
B(StaDataPropertyInLiteral), R(4), R(6), R(7), R(8),
B(CallRuntime), U16(Runtime::kToFastProperties), R(3), U8(1),
B(Star), R(0),
B(Star), R(1),
@ -122,9 +118,9 @@ snippet: "
static [n1]() { return n1; }
}
"
frame size: 11
frame size: 10
parameter count: 1
bytecode array length: 121
bytecode array length: 114
bytecodes: [
B(CreateFunctionContext), U8(2),
B(PushContext), R(3),
@ -156,9 +152,7 @@ bytecodes: [
B(LdaSmi), U8(2),
B(Star), R(9),
B(LdaSmi), U8(1),
B(Star), R(10),
B(Mov), R(5), R(6),
B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(6), U8(5),
B(StaDataPropertyInLiteral), R(5), R(7), R(8), R(9),
B(LdaCurrentContextSlot), U8(5),
/* 106 E> */ B(ToName), R(7),
B(LdaConstant), U8(3),
@ -169,8 +163,7 @@ bytecodes: [
B(CreateClosure), U8(5), U8(2),
B(Star), R(8),
B(LdaSmi), U8(1),
B(Star), R(10),
B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(6), U8(5),
B(StaDataPropertyInLiteral), R(6), R(7), R(8), R(9),
B(CallRuntime), U16(Runtime::kToFastProperties), R(4), U8(1),
B(Star), R(0),
B(Star), R(1),

View File

@ -285,24 +285,22 @@ handlers: [
snippet: "
var a = 'test'; return { [a]: 1 };
"
frame size: 7
frame size: 5
parameter count: 1
bytecode array length: 33
bytecode array length: 28
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
B(Star), R(0),
/* 50 S> */ B(CreateObjectLiteral), U8(1), U8(0), U8(35), R(1),
/* 60 E> */ B(ToName), R(3),
/* 60 E> */ B(ToName), R(2),
B(LdaSmi), U8(1),
B(Star), R(3),
B(LdaZero),
B(Star), R(4),
B(LdaZero),
B(Star), R(5),
B(LdaZero),
B(Star), R(6),
B(Mov), R(1), R(2),
B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(2), U8(5),
B(Ldar), R(2),
B(StaDataPropertyInLiteral), R(1), R(2), R(3), R(4),
B(Ldar), R(1),
/* 69 S> */ B(Return),
]
constant pool: [
@ -316,25 +314,23 @@ handlers: [
snippet: "
var a = 'test'; return { val: a, [a]: 1 };
"
frame size: 7
frame size: 5
parameter count: 1
bytecode array length: 37
bytecode array length: 32
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
B(Star), R(0),
/* 50 S> */ B(CreateObjectLiteral), U8(1), U8(0), U8(1), R(1),
/* 64 E> */ B(StaNamedPropertySloppy), R(1), U8(2), U8(2),
/* 68 E> */ B(ToName), R(3),
/* 68 E> */ B(ToName), R(2),
B(LdaSmi), U8(1),
B(Star), R(3),
B(LdaZero),
B(Star), R(4),
B(LdaZero),
B(Star), R(5),
B(LdaZero),
B(Star), R(6),
B(Mov), R(1), R(2),
B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(2), U8(5),
B(Ldar), R(2),
B(StaDataPropertyInLiteral), R(1), R(2), R(3), R(4),
B(Ldar), R(1),
/* 77 S> */ B(Return),
]
constant pool: [
@ -349,24 +345,23 @@ handlers: [
snippet: "
var a = 'test'; return { [a]: 1, __proto__: {} };
"
frame size: 7
frame size: 5
parameter count: 1
bytecode array length: 46
bytecode array length: 44
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
B(Star), R(0),
/* 50 S> */ B(CreateObjectLiteral), U8(1), U8(1), U8(35), R(1),
/* 60 E> */ B(ToName), R(3),
/* 60 E> */ B(ToName), R(2),
B(LdaSmi), U8(1),
B(Star), R(3),
B(LdaZero),
B(Star), R(4),
B(LdaZero),
B(Star), R(5),
B(LdaZero),
B(Star), R(6),
B(Mov), R(1), R(2),
B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(2), U8(5),
B(StaDataPropertyInLiteral), R(1), R(2), R(3), R(4),
B(CreateObjectLiteral), U8(1), U8(0), U8(35), R(4),
B(Mov), R(1), R(2),
B(Mov), R(4), R(3),
B(CallRuntime), U16(Runtime::kInternalSetPrototype), R(2), U8(2),
B(Ldar), R(2),
@ -383,29 +378,28 @@ handlers: [
snippet: "
var n = 'name'; return { [n]: 'val', get a() { }, set a(b) {} };
"
frame size: 7
frame size: 6
parameter count: 1
bytecode array length: 67
bytecode array length: 65
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
B(Star), R(0),
/* 50 S> */ B(CreateObjectLiteral), U8(1), U8(0), U8(35), R(1),
/* 60 E> */ B(ToName), R(3),
/* 60 E> */ B(ToName), R(2),
B(LdaConstant), U8(2),
B(Star), R(3),
B(LdaZero),
B(Star), R(4),
B(LdaZero),
B(Star), R(5),
B(LdaZero),
B(Star), R(6),
B(Mov), R(1), R(2),
B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(2), U8(5),
B(StaDataPropertyInLiteral), R(1), R(2), R(3), R(4),
B(LdaConstant), U8(3),
B(ToName), R(3),
B(CreateClosure), U8(4), U8(2),
B(Star), R(4),
B(LdaZero),
B(Star), R(5),
B(Mov), R(1), R(2),
B(CallRuntime), U16(Runtime::kDefineGetterPropertyUnchecked), R(2), U8(4),
B(LdaConstant), U8(3),
B(ToName), R(3),

View File

@ -261,7 +261,6 @@ TestNumericNamesSetter(['1.2', '1.3'], {
set 1.30(_) {; }
});
(function TestPrototypeInObjectLiteral() {
// The prototype chain should not be used if the definition
// happens in the object literal.

View File

@ -302,6 +302,8 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.StoreNamedProperty(reg, wide_name, 0, LanguageMode::STRICT)
.StoreKeyedProperty(reg, reg, 2056, LanguageMode::STRICT);
builder.StoreDataPropertyInLiteral(reg, reg, reg, reg);
// Emit wide context operations.
builder.LoadContextSlot(reg, 1024, 0).StoreContextSlot(reg, 1024, 0);