Commit 4414a14d authored by rmcilroy's avatar rmcilroy Committed by Commit bot

[Interpreter] Add support for strict mode global stores.

Adds the bytecode StaGlobalStrict and replaces StaGlobal with StaGlobalSloppy.

BUG=v8:4280
LOG=N
TBR=bmeurer@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#31339}
parent 4d0c69ad
...@@ -255,7 +255,13 @@ void BytecodeGraphBuilder::VisitLdaGlobal( ...@@ -255,7 +255,13 @@ void BytecodeGraphBuilder::VisitLdaGlobal(
} }
void BytecodeGraphBuilder::VisitStaGlobal( void BytecodeGraphBuilder::VisitStaGlobalSloppy(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
}
void BytecodeGraphBuilder::VisitStaGlobalStrict(
const interpreter::BytecodeArrayIterator& iterator) { const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
......
...@@ -265,12 +265,10 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(int slot_index) { ...@@ -265,12 +265,10 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(int slot_index) {
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal( BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal(
int slot_index, LanguageMode language_mode) { int slot_index, LanguageMode language_mode) {
if (!is_sloppy(language_mode)) {
UNIMPLEMENTED();
}
DCHECK(slot_index >= 0); DCHECK(slot_index >= 0);
Bytecode bytecode = BytecodeForStoreGlobal(language_mode);
if (FitsInIdx8Operand(slot_index)) { if (FitsInIdx8Operand(slot_index)) {
Output(Bytecode::kStaGlobal, static_cast<uint8_t>(slot_index)); Output(bytecode, static_cast<uint8_t>(slot_index));
} else { } else {
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
...@@ -818,6 +816,23 @@ Bytecode BytecodeArrayBuilder::BytecodeForKeyedStoreIC( ...@@ -818,6 +816,23 @@ Bytecode BytecodeArrayBuilder::BytecodeForKeyedStoreIC(
} }
// static
Bytecode BytecodeArrayBuilder::BytecodeForStoreGlobal(
LanguageMode language_mode) {
switch (language_mode) {
case SLOPPY:
return Bytecode::kStaGlobalSloppy;
case STRICT:
return Bytecode::kStaGlobalStrict;
case STRONG:
UNIMPLEMENTED();
default:
UNREACHABLE();
}
return static_cast<Bytecode>(-1);
}
// static // static
bool BytecodeArrayBuilder::FitsInIdx8Operand(int value) { bool BytecodeArrayBuilder::FitsInIdx8Operand(int value) {
return kMinUInt8 <= value && value <= kMaxUInt8; return kMinUInt8 <= value && value <= kMaxUInt8;
......
...@@ -159,6 +159,7 @@ class BytecodeArrayBuilder { ...@@ -159,6 +159,7 @@ class BytecodeArrayBuilder {
static Bytecode BytecodeForKeyedLoadIC(LanguageMode language_mode); static Bytecode BytecodeForKeyedLoadIC(LanguageMode language_mode);
static Bytecode BytecodeForStoreIC(LanguageMode language_mode); static Bytecode BytecodeForStoreIC(LanguageMode language_mode);
static Bytecode BytecodeForKeyedStoreIC(LanguageMode language_mode); static Bytecode BytecodeForKeyedStoreIC(LanguageMode language_mode);
static Bytecode BytecodeForStoreGlobal(LanguageMode language_mode);
static bool FitsInIdx8Operand(int value); static bool FitsInIdx8Operand(int value);
static bool FitsInIdx8Operand(size_t value); static bool FitsInIdx8Operand(size_t value);
......
...@@ -45,7 +45,8 @@ namespace interpreter { ...@@ -45,7 +45,8 @@ namespace interpreter {
\ \
/* Globals */ \ /* Globals */ \
V(LdaGlobal, OperandType::kIdx8) \ V(LdaGlobal, OperandType::kIdx8) \
V(StaGlobal, OperandType::kIdx8) \ V(StaGlobalSloppy, OperandType::kIdx8) \
V(StaGlobalStrict, OperandType::kIdx8) \
\ \
/* Context operations */ \ /* Context operations */ \
V(LdaContextSlot, OperandType::kReg8, OperandType::kIdx8) \ V(LdaContextSlot, OperandType::kReg8, OperandType::kIdx8) \
......
...@@ -196,10 +196,11 @@ void Interpreter::DoLdaGlobal(compiler::InterpreterAssembler* assembler) { ...@@ -196,10 +196,11 @@ void Interpreter::DoLdaGlobal(compiler::InterpreterAssembler* assembler) {
} }
// StaGlobal <slot_index> // StaGlobalSloppy <slot_index>
// //
// Store the global at |slot_index| with the value in the the accumulator. // Store the global at |slot_index| with the value in the the accumulator in
void Interpreter::DoStaGlobal(compiler::InterpreterAssembler* assembler) { // sloppy mode.
void Interpreter::DoStaGlobalSloppy(compiler::InterpreterAssembler* assembler) {
Node* slot_index = __ BytecodeOperandIdx8(0); Node* slot_index = __ BytecodeOperandIdx8(0);
Node* smi_slot_index = __ SmiTag(slot_index); Node* smi_slot_index = __ SmiTag(slot_index);
Node* value = __ GetAccumulator(); Node* value = __ GetAccumulator();
...@@ -208,6 +209,19 @@ void Interpreter::DoStaGlobal(compiler::InterpreterAssembler* assembler) { ...@@ -208,6 +209,19 @@ void Interpreter::DoStaGlobal(compiler::InterpreterAssembler* assembler) {
} }
// StaGlobalStrict <slot_index>
//
// Store the global at |slot_index| with the value in the the accumulator in
// strict mode.
void Interpreter::DoStaGlobalStrict(compiler::InterpreterAssembler* assembler) {
Node* slot_index = __ BytecodeOperandIdx8(0);
Node* smi_slot_index = __ SmiTag(slot_index);
Node* value = __ GetAccumulator();
__ CallRuntime(Runtime::kStoreGlobalViaContext_Strict, smi_slot_index, value);
__ Dispatch();
}
// LdaContextSlot <context> <slot_index> // LdaContextSlot <context> <slot_index>
// //
// Load the object in |slot_index| of |context| into the accumulator. // Load the object in |slot_index| of |context| into the accumulator.
......
...@@ -1073,17 +1073,17 @@ TEST(StoreGlobal) { ...@@ -1073,17 +1073,17 @@ TEST(StoreGlobal) {
InitializedHandleScope handle_scope; InitializedHandleScope handle_scope;
BytecodeGeneratorHelper helper; BytecodeGeneratorHelper helper;
ExpectedSnippet<int> snippets[] = { ExpectedSnippet<InstanceType> snippets[] = {
{ {
"var a = 1;\nfunction f() { a = 2; }\nf()", "var a = 1;\nfunction f() { a = 2; }\nf()",
0, 0,
1, 1,
6, 6,
{ {
B(LdaSmi8), U8(2), // B(LdaSmi8), U8(2), //
B(StaGlobal), _, // B(StaGlobalSloppy), _, //
B(LdaUndefined), // B(LdaUndefined), //
B(Return) // B(Return) //
}, },
}, },
{ {
...@@ -1093,11 +1093,23 @@ TEST(StoreGlobal) { ...@@ -1093,11 +1093,23 @@ TEST(StoreGlobal) {
6, 6,
{ {
B(Ldar), R(helper.kLastParamIndex), // B(Ldar), R(helper.kLastParamIndex), //
B(StaGlobal), _, // B(StaGlobalSloppy), _, //
B(LdaUndefined), // B(LdaUndefined), //
B(Return) // B(Return) //
}, },
}, },
{
"'use strict'; var a = 1;\nfunction f() { a = 2; }\nf()",
0,
1,
6,
{
B(LdaSmi8), U8(2), //
B(StaGlobalStrict), _, //
B(LdaUndefined), //
B(Return) //
},
},
}; };
for (size_t i = 0; i < arraysize(snippets); i++) { for (size_t i = 0; i < arraysize(snippets); i++) {
...@@ -1566,7 +1578,7 @@ TEST(DeclareGlobals) { ...@@ -1566,7 +1578,7 @@ TEST(DeclareGlobals) {
B(CallRuntime), U16(Runtime::kInitializeVarGlobal), R(2), // B(CallRuntime), U16(Runtime::kInitializeVarGlobal), R(2), //
U8(3), // U8(3), //
B(LdaSmi8), U8(2), // B(LdaSmi8), U8(2), //
B(StaGlobal), _, // B(StaGlobalSloppy), _, //
B(Star), R(0), // B(Star), R(0), //
B(Ldar), R(0), // B(Ldar), R(0), //
B(Return) // B(Return) //
......
...@@ -41,8 +41,9 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { ...@@ -41,8 +41,9 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
builder.LoadAccumulatorWithRegister(reg).StoreAccumulatorInRegister(reg); builder.LoadAccumulatorWithRegister(reg).StoreAccumulatorInRegister(reg);
// Emit global load / store operations. // Emit global load / store operations.
builder.LoadGlobal(1); builder.LoadGlobal(1)
builder.StoreGlobal(1, LanguageMode::SLOPPY); .StoreGlobal(1, LanguageMode::SLOPPY)
.StoreGlobal(1, LanguageMode::STRICT);
// Emit context operations. // Emit context operations.
builder.PushContext(reg); builder.PushContext(reg);
......
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