Commit 90721a51 authored by mythria's avatar mythria Committed by Commit bot

[Interpreter] Adds support for const/let variables to interpreter.

Adds implementation and tests to support const/let variables in the
interpreter.

BUG=v8:4280,v8:4679
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#33819}
parent e708dd54
......@@ -1510,6 +1510,20 @@ void BytecodeGraphBuilder::VisitJumpIfUndefinedConstantWide() {
BuildJumpIfEqual(jsgraph()->UndefinedConstant());
}
void BytecodeGraphBuilder::VisitJumpIfHole() {
BuildJumpIfEqual(jsgraph()->TheHoleConstant());
}
void BytecodeGraphBuilder::VisitJumpIfNotHole() {
Node* accumulator = environment()->LookupAccumulator();
Node* condition = NewNode(javascript()->StrictEqual(), accumulator,
jsgraph()->TheHoleConstant());
Node* node =
NewNode(common()->Select(MachineRepresentation::kTagged), condition,
jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
BuildConditionalJump(node);
}
void BytecodeGraphBuilder::VisitStackCheck() {
FrameStateBeforeAndAfter states(this);
Node* node = NewNode(javascript()->StackCheck());
......
......@@ -661,9 +661,8 @@ Node* InterpreterAssembler::Advance(Node* delta) {
void InterpreterAssembler::Jump(Node* delta) { DispatchTo(Advance(delta)); }
void InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) {
void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) {
RawMachineLabel match, no_match;
Node* condition = raw_assembler_->WordEqual(lhs, rhs);
raw_assembler_->Branch(condition, &match, &no_match);
raw_assembler_->Bind(&match);
DispatchTo(Advance(delta));
......@@ -671,6 +670,14 @@ void InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) {
Dispatch();
}
void InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) {
JumpConditional(raw_assembler_->WordEqual(lhs, rhs), delta);
}
void InterpreterAssembler::JumpIfWordNotEqual(Node* lhs, Node* rhs,
Node* delta) {
JumpConditional(raw_assembler_->WordNotEqual(lhs, rhs), delta);
}
void InterpreterAssembler::Dispatch() {
DispatchTo(Advance(interpreter::Bytecodes::Size(bytecode_)));
......
......@@ -147,10 +147,19 @@ class InterpreterAssembler {
// Jump relative to the current bytecode by |jump_offset|.
void Jump(Node* jump_offset);
// Jump relative to the current bytecode by |jump_offset| if the
// |condition| is true. Helper function for JumpIfWordEqual and
// JumpIfWordNotEqual.
void JumpConditional(Node* condition, Node* jump_offset);
// Jump relative to the current bytecode by |jump_offset| if the
// word values |lhs| and |rhs| are equal.
void JumpIfWordEqual(Node* lhs, Node* rhs, Node* jump_offset);
// Jump relative to the current bytecode by |jump_offset| if the
// word values |lhs| and |rhs| are not equal.
void JumpIfWordNotEqual(Node* lhs, Node* rhs, Node* jump_offset);
// Perform a stack guard check.
void StackCheck();
......
......@@ -807,6 +807,8 @@ Bytecode BytecodeArrayBuilder::GetJumpWithToBoolean(Bytecode jump_bytecode) {
case Bytecode::kJump:
case Bytecode::kJumpIfNull:
case Bytecode::kJumpIfUndefined:
case Bytecode::kJumpIfHole:
case Bytecode::kJumpIfNotHole:
return jump_bytecode;
case Bytecode::kJumpIfTrue:
return Bytecode::kJumpIfToBooleanTrue;
......@@ -972,6 +974,15 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck() {
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfHole(BytecodeLabel* label) {
return OutputJump(Bytecode::kJumpIfHole, label);
}
BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole(
BytecodeLabel* label) {
return OutputJump(Bytecode::kJumpIfNotHole, label);
}
BytecodeArrayBuilder& BytecodeArrayBuilder::Throw() {
Output(Bytecode::kThrow);
exit_seen_in_block_ = true;
......
......@@ -231,6 +231,8 @@ class BytecodeArrayBuilder final : public ZoneObject, private RegisterMover {
BytecodeArrayBuilder& JumpIfFalse(BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfNull(BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfUndefined(BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfHole(BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfNotHole(BytecodeLabel* label);
BytecodeArrayBuilder& StackCheck();
......
This diff is collapsed.
......@@ -76,7 +76,13 @@ class BytecodeGenerator final : public AstVisitor {
MUST_USE_RESULT Register
VisitVariableLoadForRegisterValue(Variable* variable, FeedbackVectorSlot slot,
TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
void VisitVariableAssignment(Variable* variable, FeedbackVectorSlot slot);
void VisitVariableAssignment(Variable* variable, Token::Value op,
FeedbackVectorSlot slot);
void BuildThrowIfHole(Handle<String> name);
void BuildThrowIfNotHole(Handle<String> name);
void BuildThrowReassignConstant(Handle<String> name);
void BuildHoleCheckForVariableLoad(VariableMode mode, Handle<String> name);
void BuildHoleCheckForVariableAssignment(Variable* variable, Token::Value op);
void VisitArgumentsObject(Variable* variable);
void VisitRestArgumentsArray(Variable* rest);
......
......@@ -196,7 +196,9 @@ bool Bytecodes::IsConditionalJumpImmediate(Bytecode bytecode) {
bytecode == Bytecode::kJumpIfToBooleanTrue ||
bytecode == Bytecode::kJumpIfToBooleanFalse ||
bytecode == Bytecode::kJumpIfNull ||
bytecode == Bytecode::kJumpIfUndefined;
bytecode == Bytecode::kJumpIfUndefined ||
bytecode == Bytecode::kJumpIfHole ||
bytecode == Bytecode::kJumpIfNotHole;
}
......
......@@ -252,6 +252,9 @@ namespace interpreter {
V(JumpIfUndefined, OperandType::kImm8) \
V(JumpIfUndefinedConstant, OperandType::kIdx8) \
V(JumpIfUndefinedConstantWide, OperandType::kIdx16) \
/* TODO(mythria): Replace with opcodes that throw on a hole */ \
V(JumpIfHole, OperandType::kImm8) \
V(JumpIfNotHole, OperandType::kImm8) \
\
/* Complex flow control For..in */ \
V(ForInPrepare, OperandType::kRegOutTriple8) \
......
......@@ -1605,8 +1605,7 @@ void Interpreter::DoJumpIfNullConstantWide(
DoJumpIfNullConstant(assembler);
}
// jumpifundefined <imm8>
// JumpIfUndefined <imm8>
//
// Jump by number of bytes represented by an immediate operand if the object
// referenced by the accumulator is the undefined constant.
......@@ -1644,6 +1643,27 @@ void Interpreter::DoJumpIfUndefinedConstantWide(
DoJumpIfUndefinedConstant(assembler);
}
// JumpIfHole <imm8>
//
// Jump by number of bytes represented by an immediate operand if the object
// referenced by the accumulator is the hole.
void Interpreter::DoJumpIfHole(compiler::InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator();
Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value());
Node* relative_jump = __ BytecodeOperandImm(0);
__ JumpIfWordEqual(accumulator, the_hole_value, relative_jump);
}
// JumpIfNotHole <imm8>
//
// Jump by number of bytes represented by an immediate operand if the object
// referenced by the accumulator is not the hole.
void Interpreter::DoJumpIfNotHole(compiler::InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator();
Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value());
Node* relative_jump = __ BytecodeOperandImm(0);
__ JumpIfWordNotEqual(accumulator, the_hole_value, relative_jump);
}
void Interpreter::DoCreateLiteral(Runtime::FunctionId function_id,
compiler::InterpreterAssembler* assembler) {
......
......@@ -575,14 +575,6 @@
'test-api/InterceptorShouldThrowOnError': [FAIL],
'test-api/StrongModeAccessCheckAllowed': [FAIL],
# TODO(rmcilroy,4680): FunctionTester SameValue check fails.
'test-run-variables/StackInitializeVariables': [FAIL],
'test-run-variables/ContextInitializeVariables': [FAIL],
'test-run-variables/ContextStoreVariables': [FAIL],
'test-run-variables/StackStoreVariables': [FAIL],
'test-run-variables/ContextLoadVariables': [FAIL],
'test-run-variables/StackLoadVariables': [FAIL],
# TODO(rmcilroy,4680): The function_data field should be a BytecodeArray on interpreter entry
'test-api/SetFunctionEntryHook': [FAIL],
......@@ -640,7 +632,6 @@
'test-heap/CompilationCacheCachingBehavior': [FAIL],
'test-heap/CellsInOptimizedCodeAreWeak': [FAIL],
'test-run-inlining/InlineTwice': [FAIL],
'test-decls/Regress425510': [FAIL],
# TODO(rmcilroy,4680): Fail on some bot configurations.
'test-heap/CanonicalSharedFunctionInfo': [PASS, FAIL],
......
This diff is collapsed.
......@@ -747,7 +747,6 @@
}], # 'arch == ppc and simulator_run == True'
['ignition == True', {
'const*': [SKIP],
'debug-*': [SKIP],
'es6/*': [SKIP],
'es7/*': [SKIP],
......@@ -771,20 +770,14 @@
'compiler/deopt-tonumber-compare': [SKIP],
'compiler/expression-trees': [SKIP],
'compiler/regress-446647': [SKIP],
'compiler/regress-447567': [SKIP],
'compiler/regress-96989': [SKIP],
'compiler/regress-const': [SKIP],
'compiler/regress-funarguments': [SKIP],
'compiler/regress-stacktrace-methods': [SKIP],
'compiler/strict-recompile': [SKIP],
'cyclic-array-to-string': [SKIP],
'd8-worker-sharedarraybuffer': [SKIP],
'declare-locally': [SKIP],
'deserialize-optimize-inner': [SKIP],
'eval-enclosing-function-name': [SKIP],
'eval-stack-trace': [SKIP],
'field-type-tracking': [SKIP],
'global-const-var-conflicts': [SKIP],
'global-hash': [SKIP],
'messages': [SKIP],
'property-load-across-eval': [SKIP],
......@@ -796,7 +789,6 @@
'regress/regress-109195': [SKIP],
'regress/regress-1114040': [SKIP],
'regress/regress-1170187': [SKIP],
'regress/regress-1178598': [SKIP],
'regress/regress-119609': [SKIP],
'regress/regress-1199637': [SKIP],
'regress/regress-1200351': [SKIP],
......@@ -812,7 +804,6 @@
'regress/regress-1639': [SKIP],
'regress/regress-1790': [SKIP],
'regress/regress-1853': [SKIP],
'regress/regress-186': [SKIP],
'regress/regress-1980': [SKIP],
'regress/regress-2318': [SKIP],
'regress/regress-2618': [SKIP],
......@@ -822,7 +813,6 @@
'regress/regress-2825': [SKIP],
'regress/regress-353551': [SKIP],
'regress/regress-354357': [SKIP],
'regress/regress-3926': [SKIP],
'regress/regress-3960': [SKIP],
'regress/regress-3969': [SKIP],
'regress/regress-3985': [SKIP],
......@@ -837,7 +827,6 @@
'regress/regress-4309-3': [SKIP],
'regress/regress-4320': [SKIP],
'regress/regress-4374': [SKIP],
'regress/regress-4388': [SKIP],
'regress/regress-446389': [SKIP],
'regress/regress-447756': [SKIP],
'regress/regress-4509-Class-constructor-typeerror-realm' : [SKIP],
......@@ -854,7 +843,6 @@
'regress/regress-544991': [SKIP],
'regress/regress-572589': [SKIP],
'regress/regress-799761': [SKIP],
'regress/regress-88591': [SKIP],
'regress/regress-94873': [SKIP],
'regress/regress-97116b': [SKIP],
'regress/regress-97116': [SKIP],
......
......@@ -564,7 +564,6 @@
'language/expressions/object/method-definition/generator*': [SKIP],
'language/expressions/yield/*': [SKIP],
'language/statements/class/*': [SKIP],
'language/statements/const/*': [SKIP],
'language/statements/generators/*': [SKIP],
'built-ins/Array/prototype/concat/Array.prototype.concat_non-array': [SKIP],
......@@ -602,15 +601,12 @@
'language/computed-property-names/object/method/super': [SKIP],
'language/default-parameters/class-definitions': [SKIP],
'language/default-parameters/generators': [SKIP],
'language/default-parameters/param-ref-uninitialized': [SKIP],
'language/expressions/object/method-definition/name-prop-name-yield-expr': [SKIP],
'language/expressions/object/method-definition/name-super-prop-param': [SKIP],
'language/expressions/object/method-definition/name-super-prop-body': [SKIP],
'language/expressions/tagged-template/call-expression-context-no-strict': [SKIP],
'language/expressions/tagged-template/call-expression-context-strict': [SKIP],
'language/expressions/template-literal/evaluation-order': [SKIP],
'language/statements/for-in/const-bound-names-fordecl-tdz-for-in': [SKIP],
'language/statements/for-in/let-bound-names-fordecl-tdz-for-in': [SKIP],
'language/statements/for-of/body-dstr-assign': [SKIP],
'language/statements/for-of/break': [SKIP],
'language/statements/for-of/break-from-catch': [SKIP],
......@@ -620,7 +616,6 @@
'language/statements/for-of/break-label-from-catch': [SKIP],
'language/statements/for-of/break-label-from-finally': [SKIP],
'language/statements/for-of/break-label-from-try': [SKIP],
'language/statements/for-of/const-bound-names-fordecl-tdz-for-of': [SKIP],
'language/statements/for-of/continue': [SKIP],
'language/statements/for-of/continue-from-catch': [SKIP],
'language/statements/for-of/continue-from-finally': [SKIP],
......@@ -631,7 +626,6 @@
'language/statements/for-of/continue-label-from-try': [SKIP],
'language/statements/for-of/generator': [SKIP],
'language/statements/for-of/generator-next-error': [SKIP],
'language/statements/for-of/let-bound-names-fordecl-tdz-for-of': [SKIP],
'language/statements/for-of/nested': [SKIP],
'language/statements/for-of/return': [SKIP],
'language/statements/for-of/return-from-catch': [SKIP],
......@@ -654,18 +648,6 @@
'language/object-literal/setter': [SKIP],
'language/rest-parameters/with-new-target': [SKIP],
'language/statements/do-while/S12.6.1_A4_T5': [SKIP],
'language/statements/let/block-local-closure-get-before-initialization': [SKIP],
'language/statements/let/block-local-closure-set-before-initialization': [SKIP],
'language/statements/let/block-local-use-before-initialization-in-declaration-statement': [SKIP],
'language/statements/let/block-local-use-before-initialization-in-prior-statement': [SKIP],
'language/statements/let/function-local-closure-get-before-initialization': [SKIP],
'language/statements/let/function-local-closure-set-before-initialization': [SKIP],
'language/statements/let/function-local-use-before-initialization-in-declaration-statement': [SKIP],
'language/statements/let/function-local-use-before-initialization-in-prior-statement': [SKIP],
'language/statements/let/global-closure-get-before-initialization': [SKIP],
'language/statements/let/global-closure-set-before-initialization': [SKIP],
'language/statements/let/global-use-before-initialization-in-declaration-statement': [SKIP],
'language/statements/let/global-use-before-initialization-in-prior-statement': [SKIP],
'language/statements/while/S12.6.2_A4_T5': [SKIP],
}], # ignition == True
......
......@@ -165,7 +165,11 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
BytecodeLabel start;
builder.Bind(&start);
// Short jumps with Imm8 operands
builder.Jump(&start).JumpIfNull(&start).JumpIfUndefined(&start);
builder.Jump(&start)
.JumpIfNull(&start)
.JumpIfUndefined(&start)
.JumpIfHole(&start)
.JumpIfNotHole(&start);
// Perform an operation that returns boolean value to
// generate JumpIfTrue/False
builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
......
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