diff --git a/BUILD.gn b/BUILD.gn index bb95fc1136..ac8b31078a 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1022,6 +1022,7 @@ v8_source_set("v8_initializers") { "src/builtins/builtins-iterator-gen.cc", "src/builtins/builtins-iterator-gen.h", "src/builtins/builtins-math-gen.cc", + "src/builtins/builtins-math-gen.h", "src/builtins/builtins-number-gen.cc", "src/builtins/builtins-object-gen.cc", "src/builtins/builtins-promise-gen.cc", diff --git a/src/builtins/builtins-definitions.h b/src/builtins/builtins-definitions.h index 2705f29336..63b849f3a1 100644 --- a/src/builtins/builtins-definitions.h +++ b/src/builtins/builtins-definitions.h @@ -688,6 +688,7 @@ namespace internal { TFC(Multiply, BinaryOp, 1) \ TFC(Divide, BinaryOp, 1) \ TFC(Modulus, BinaryOp, 1) \ + TFC(Exponentiate, BinaryOp, 1) \ TFC(BitwiseAnd, BinaryOp, 1) \ TFC(BitwiseOr, BinaryOp, 1) \ TFC(BitwiseXor, BinaryOp, 1) \ diff --git a/src/builtins/builtins-math-gen.cc b/src/builtins/builtins-math-gen.cc index f270a42ee7..706fa4f3a8 100644 --- a/src/builtins/builtins-math-gen.cc +++ b/src/builtins/builtins-math-gen.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "src/builtins/builtins-math-gen.h" + #include "src/builtins/builtins-utils-gen.h" #include "src/builtins/builtins.h" #include "src/code-factory.h" @@ -14,24 +16,6 @@ namespace internal { // ----------------------------------------------------------------------------- // ES6 section 20.2.2 Function Properties of the Math Object -class MathBuiltinsAssembler : public CodeStubAssembler { - public: - explicit MathBuiltinsAssembler(compiler::CodeAssemblerState* state) - : CodeStubAssembler(state) {} - - protected: - void MathRoundingOperation( - Node* context, Node* x, - TNode (CodeStubAssembler::*float64op)(SloppyTNode)); - void MathUnaryOperation( - Node* context, Node* x, - TNode (CodeStubAssembler::*float64op)(SloppyTNode)); - void MathMaxMin(Node* context, Node* argc, - TNode (CodeStubAssembler::*float64op)( - SloppyTNode, SloppyTNode), - double default_val); -}; - // ES6 #sec-math.abs TF_BUILTIN(MathAbs, CodeStubAssembler) { Node* context = Parameter(Descriptor::kContext); @@ -405,16 +389,19 @@ TF_BUILTIN(MathLog2, MathBuiltinsAssembler) { MathUnaryOperation(context, x, &CodeStubAssembler::Float64Log2); } +CodeStubAssembler::Node* MathBuiltinsAssembler::MathPow(Node* context, + Node* base, + Node* exponent) { + Node* base_value = TruncateTaggedToFloat64(context, base); + Node* exponent_value = TruncateTaggedToFloat64(context, exponent); + Node* value = Float64Pow(base_value, exponent_value); + return ChangeFloat64ToTagged(value); +} + // ES6 #sec-math.pow -TF_BUILTIN(MathPow, CodeStubAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* x = Parameter(Descriptor::kBase); - Node* y = Parameter(Descriptor::kExponent); - Node* x_value = TruncateTaggedToFloat64(context, x); - Node* y_value = TruncateTaggedToFloat64(context, y); - Node* value = Float64Pow(x_value, y_value); - Node* result = ChangeFloat64ToTagged(value); - Return(result); +TF_BUILTIN(MathPow, MathBuiltinsAssembler) { + Return(MathPow(Parameter(Descriptor::kContext), Parameter(Descriptor::kBase), + Parameter(Descriptor::kExponent))); } // ES6 #sec-math.random diff --git a/src/builtins/builtins-math-gen.h b/src/builtins/builtins-math-gen.h new file mode 100644 index 0000000000..7b9079b6e9 --- /dev/null +++ b/src/builtins/builtins-math-gen.h @@ -0,0 +1,36 @@ +// Copyright 2017 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_BUILTINS_BUILTINS_MATH_GEN_H_ +#define V8_BUILTINS_BUILTINS_MATH_GEN_H_ + +#include "src/code-stub-assembler.h" + +namespace v8 { +namespace internal { + +class MathBuiltinsAssembler : public CodeStubAssembler { + public: + explicit MathBuiltinsAssembler(compiler::CodeAssemblerState* state) + : CodeStubAssembler(state) {} + + Node* MathPow(Node* context, Node* base, Node* exponent); + + protected: + void MathRoundingOperation( + Node* context, Node* x, + TNode (CodeStubAssembler::*float64op)(SloppyTNode)); + void MathUnaryOperation( + Node* context, Node* x, + TNode (CodeStubAssembler::*float64op)(SloppyTNode)); + void MathMaxMin(Node* context, Node* argc, + TNode (CodeStubAssembler::*float64op)( + SloppyTNode, SloppyTNode), + double default_val); +}; + +} // namespace internal +} // namespace v8 + +#endif // V8_BUILTINS_BUILTINS_MATH_GEN_H_ diff --git a/src/builtins/builtins-number-gen.cc b/src/builtins/builtins-number-gen.cc index 23dc0f813a..821dac9cc0 100644 --- a/src/builtins/builtins-number-gen.cc +++ b/src/builtins/builtins-number-gen.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "src/builtins/builtins-math-gen.h" #include "src/builtins/builtins-utils-gen.h" #include "src/builtins/builtins.h" #include "src/code-stub-assembler.h" @@ -636,8 +637,11 @@ void NumberBuiltinsAssembler::BinaryOp(Label* smis, Variable* var_left, Label* bigints) { DCHECK_EQ(var_left->rep(), MachineRepresentation::kTagged); DCHECK_EQ(var_right->rep(), MachineRepresentation::kTagged); - DCHECK_EQ(var_left_double->rep(), MachineRepresentation::kFloat64); - DCHECK_EQ(var_right_double->rep(), MachineRepresentation::kFloat64); + DCHECK_IMPLIES(var_left_double != nullptr, + var_left_double->rep() == MachineRepresentation::kFloat64); + DCHECK_IMPLIES(var_right_double != nullptr, + var_right_double->rep() == MachineRepresentation::kFloat64); + DCHECK_EQ(var_left_double == nullptr, var_right_double == nullptr); Node* context = Parameter(Descriptor::kContext); var_left->Bind(Parameter(Descriptor::kLeft)); @@ -655,8 +659,10 @@ void NumberBuiltinsAssembler::BinaryOp(Label* smis, Variable* var_left, // At this point, var_left is a Smi but var_right is not. GotoIfNot(IsHeapNumber(var_right->value()), &right_not_number); - var_left_double->Bind(SmiToFloat64(var_left->value())); - var_right_double->Bind(LoadHeapNumberValue(var_right->value())); + if (var_left_double != nullptr) { + var_left_double->Bind(SmiToFloat64(var_left->value())); + var_right_double->Bind(LoadHeapNumberValue(var_right->value())); + } Goto(doubles); BIND(&left_not_smi); @@ -665,16 +671,20 @@ void NumberBuiltinsAssembler::BinaryOp(Label* smis, Variable* var_left, GotoIfNot(TaggedIsSmi(var_right->value()), &right_not_smi); // At this point, var_left is a HeapNumber and var_right is a Smi. - var_left_double->Bind(LoadHeapNumberValue(var_left->value())); - var_right_double->Bind(SmiToFloat64(var_right->value())); + if (var_left_double != nullptr) { + var_left_double->Bind(LoadHeapNumberValue(var_left->value())); + var_right_double->Bind(SmiToFloat64(var_right->value())); + } Goto(doubles); } BIND(&right_not_smi); { GotoIfNot(IsHeapNumber(var_right->value()), &right_not_number); - var_left_double->Bind(LoadHeapNumberValue(var_left->value())); - var_right_double->Bind(LoadHeapNumberValue(var_right->value())); + if (var_left_double != nullptr) { + var_left_double->Bind(LoadHeapNumberValue(var_left->value())); + var_right_double->Bind(LoadHeapNumberValue(var_right->value())); + } Goto(doubles); } @@ -970,6 +980,26 @@ TF_BUILTIN(Modulus, NumberBuiltinsAssembler) { } } +TF_BUILTIN(Exponentiate, NumberBuiltinsAssembler) { + VARIABLE(var_left, MachineRepresentation::kTagged); + VARIABLE(var_right, MachineRepresentation::kTagged); + Label do_number_exp(this), do_bigint_exp(this); + Node* context = Parameter(Descriptor::kContext); + + BinaryOp(&do_number_exp, &var_left, &var_right, &do_number_exp, + nullptr, nullptr, &do_bigint_exp); + + BIND(&do_number_exp); + { + MathBuiltinsAssembler math_asm(state()); + Return(math_asm.MathPow(context, var_left.value(), var_right.value())); + } + + BIND(&do_bigint_exp); + Return(CallRuntime(Runtime::kBigIntBinaryOp, context, var_left.value(), + var_right.value(), SmiConstant(Operation::kExponentiate))); +} + TF_BUILTIN(ShiftLeft, NumberBuiltinsAssembler) { EmitBitwiseOp(Operation::kShiftLeft); } diff --git a/src/compiler/bytecode-graph-builder.cc b/src/compiler/bytecode-graph-builder.cc index 7a4d6363bb..7e1fbfddb3 100644 --- a/src/compiler/bytecode-graph-builder.cc +++ b/src/compiler/bytecode-graph-builder.cc @@ -2139,6 +2139,10 @@ void BytecodeGraphBuilder::VisitMod() { BuildBinaryOp(javascript()->Modulus()); } +void BytecodeGraphBuilder::VisitExp() { + BuildBinaryOp(javascript()->Exponentiate()); +} + void BytecodeGraphBuilder::VisitBitwiseOr() { BuildBinaryOp(javascript()->BitwiseOr()); } @@ -2205,6 +2209,10 @@ void BytecodeGraphBuilder::VisitModSmi() { BuildBinaryOpWithImmediate(javascript()->Modulus()); } +void BytecodeGraphBuilder::VisitExpSmi() { + BuildBinaryOpWithImmediate(javascript()->Exponentiate()); +} + void BytecodeGraphBuilder::VisitBitwiseOrSmi() { BuildBinaryOpWithImmediate(javascript()->BitwiseOr()); } diff --git a/src/compiler/js-generic-lowering.cc b/src/compiler/js-generic-lowering.cc index e89ea28bbd..d06717717d 100644 --- a/src/compiler/js-generic-lowering.cc +++ b/src/compiler/js-generic-lowering.cc @@ -60,6 +60,7 @@ REPLACE_STUB_CALL(Subtract) REPLACE_STUB_CALL(Multiply) REPLACE_STUB_CALL(Divide) REPLACE_STUB_CALL(Modulus) +REPLACE_STUB_CALL(Exponentiate) REPLACE_STUB_CALL(BitwiseAnd) REPLACE_STUB_CALL(BitwiseOr) REPLACE_STUB_CALL(BitwiseXor) diff --git a/src/compiler/js-operator.cc b/src/compiler/js-operator.cc index d53dd52e59..5b5e6589d2 100644 --- a/src/compiler/js-operator.cc +++ b/src/compiler/js-operator.cc @@ -577,6 +577,7 @@ CompareOperationHint CompareOperationHintOf(const Operator* op) { V(Multiply, Operator::kNoProperties, 2, 1) \ V(Divide, Operator::kNoProperties, 2, 1) \ V(Modulus, Operator::kNoProperties, 2, 1) \ + V(Exponentiate, Operator::kNoProperties, 2, 1) \ V(BitwiseNot, Operator::kNoProperties, 1, 1) \ V(Decrement, Operator::kNoProperties, 1, 1) \ V(Increment, Operator::kNoProperties, 1, 1) \ diff --git a/src/compiler/js-operator.h b/src/compiler/js-operator.h index 97eeac598c..94a9b1fdb6 100644 --- a/src/compiler/js-operator.h +++ b/src/compiler/js-operator.h @@ -651,6 +651,7 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final const Operator* Multiply(); const Operator* Divide(); const Operator* Modulus(); + const Operator* Exponentiate(); const Operator* BitwiseNot(); const Operator* Decrement(); diff --git a/src/compiler/js-type-hint-lowering.cc b/src/compiler/js-type-hint-lowering.cc index 9318612f16..a7ce12cdb4 100644 --- a/src/compiler/js-type-hint-lowering.cc +++ b/src/compiler/js-type-hint-lowering.cc @@ -344,6 +344,10 @@ JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceBinaryOperation( } break; } + case IrOpcode::kJSExponentiate: { + // TODO(neis): Introduce a SpeculativeNumberPow operator? + break; + } default: UNREACHABLE(); break; diff --git a/src/compiler/js-typed-lowering.cc b/src/compiler/js-typed-lowering.cc index f159ead960..7bc2d8b733 100644 --- a/src/compiler/js-typed-lowering.cc +++ b/src/compiler/js-typed-lowering.cc @@ -279,6 +279,8 @@ class JSBinopReduction final { return simplified()->NumberDivide(); case IrOpcode::kJSModulus: return simplified()->NumberModulus(); + case IrOpcode::kJSExponentiate: + return simplified()->NumberPow(); case IrOpcode::kJSBitwiseAnd: return simplified()->NumberBitwiseAnd(); case IrOpcode::kJSBitwiseOr: @@ -2123,6 +2125,7 @@ Reduction JSTypedLowering::Reduce(Node* node) { case IrOpcode::kJSMultiply: case IrOpcode::kJSDivide: case IrOpcode::kJSModulus: + case IrOpcode::kJSExponentiate: return ReduceNumberBinop(node); case IrOpcode::kJSBitwiseNot: return ReduceJSBitwiseNot(node); diff --git a/src/compiler/opcodes.h b/src/compiler/opcodes.h index 0827ca12b1..886ea6fa1a 100644 --- a/src/compiler/opcodes.h +++ b/src/compiler/opcodes.h @@ -105,7 +105,8 @@ V(JSSubtract) \ V(JSMultiply) \ V(JSDivide) \ - V(JSModulus) + V(JSModulus) \ + V(JSExponentiate) #define JS_SIMPLE_BINOP_LIST(V) \ JS_COMPARE_BINOP_LIST(V) \ diff --git a/src/compiler/operator-properties.cc b/src/compiler/operator-properties.cc index b6e8841393..d786bb3ee5 100644 --- a/src/compiler/operator-properties.cc +++ b/src/compiler/operator-properties.cc @@ -44,6 +44,7 @@ bool OperatorProperties::HasFrameStateInput(const Operator* op) { case IrOpcode::kJSMultiply: case IrOpcode::kJSDivide: case IrOpcode::kJSModulus: + case IrOpcode::kJSExponentiate: // Bitwise operations case IrOpcode::kJSBitwiseOr: diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc index 12b0090ee1..bc3a78e526 100644 --- a/src/compiler/typer.cc +++ b/src/compiler/typer.cc @@ -1103,6 +1103,12 @@ Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { return NumberModulus(ToNumber(lhs, t), ToNumber(rhs, t), t); } +// TODO(neis): Adapt all these for bigints. Why does this even work in the +// bigint tests? + +Type* Typer::Visitor::JSExponentiateTyper(Type* lhs, Type* rhs, Typer* t) { + return Type::Number(); +} // JS unary operators. diff --git a/src/compiler/verifier.cc b/src/compiler/verifier.cc index 6d856fd5ce..c604a681b8 100644 --- a/src/compiler/verifier.cc +++ b/src/compiler/verifier.cc @@ -608,7 +608,9 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) { case IrOpcode::kJSMultiply: case IrOpcode::kJSDivide: case IrOpcode::kJSModulus: + case IrOpcode::kJSExponentiate: // Type is Number. + // TODO(neis): Adapt for bigints. CheckTypeIs(node, Type::Number()); break; diff --git a/src/debug/debug-evaluate.cc b/src/debug/debug-evaluate.cc index 1be8d4b8d1..afad8e2f68 100644 --- a/src/debug/debug-evaluate.cc +++ b/src/debug/debug-evaluate.cc @@ -382,6 +382,8 @@ bool BytecodeHasNoSideEffect(interpreter::Bytecode bytecode) { case Bytecode::kDivSmi: case Bytecode::kMod: case Bytecode::kModSmi: + case Bytecode::kExp: + case Bytecode::kExpSmi: case Bytecode::kNegate: case Bytecode::kBitwiseAnd: case Bytecode::kBitwiseAndSmi: diff --git a/src/globals.h b/src/globals.h index d8a6d96587..8f5253016f 100644 --- a/src/globals.h +++ b/src/globals.h @@ -1305,6 +1305,7 @@ enum class Operation { kMultiply, kDivide, kModulus, + kExponentiate, kBitwiseAnd, kBitwiseOr, kBitwiseXor, diff --git a/src/ic/binary-op-assembler.cc b/src/ic/binary-op-assembler.cc index 9cf030cbec..717c38e356 100644 --- a/src/ic/binary-op-assembler.cc +++ b/src/ic/binary-op-assembler.cc @@ -529,5 +529,14 @@ Node* BinaryOpAssembler::Generate_ModulusWithFeedback( floatFunction, Operation::kModulus, rhs_is_smi); } +Node* BinaryOpAssembler::Generate_ExponentiateWithFeedback( + Node* context, Node* base, Node* exponent, Node* slot_id, + Node* feedback_vector, bool rhs_is_smi) { + // We currently don't optimize exponentiation based on feedback. + Node* dummy_feedback = SmiConstant(BinaryOperationFeedback::kAny); + UpdateFeedback(dummy_feedback, feedback_vector, slot_id); + return CallBuiltin(Builtins::kExponentiate, context, base, exponent); +} + } // namespace internal } // namespace v8 diff --git a/src/ic/binary-op-assembler.h b/src/ic/binary-op-assembler.h index 9cafe29656..d7afd7b655 100644 --- a/src/ic/binary-op-assembler.h +++ b/src/ic/binary-op-assembler.h @@ -42,6 +42,11 @@ class BinaryOpAssembler : public CodeStubAssembler { Node* divisor, Node* slot_id, Node* feedback_vector, bool rhs_is_smi); + Node* Generate_ExponentiateWithFeedback(Node* context, Node* dividend, + Node* divisor, Node* slot_id, + Node* feedback_vector, + bool rhs_is_smi); + private: typedef std::function SmiOperation; typedef std::function FloatOperation; diff --git a/src/interpreter/bytecode-array-builder.cc b/src/interpreter/bytecode-array-builder.cc index 2cdc22fdc5..5be818eb2d 100644 --- a/src/interpreter/bytecode-array-builder.cc +++ b/src/interpreter/bytecode-array-builder.cc @@ -362,6 +362,9 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, case Token::Value::MOD: OutputMod(reg, feedback_slot); break; + case Token::Value::EXP: + OutputExp(reg, feedback_slot); + break; case Token::Value::BIT_OR: OutputBitwiseOr(reg, feedback_slot); break; @@ -404,6 +407,9 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperationSmiLiteral( case Token::Value::MOD: OutputModSmi(literal->value(), feedback_slot); break; + case Token::Value::EXP: + OutputExpSmi(literal->value(), feedback_slot); + break; case Token::Value::BIT_OR: OutputBitwiseOrSmi(literal->value(), feedback_slot); break; diff --git a/src/interpreter/bytecodes.h b/src/interpreter/bytecodes.h index 5962863185..2d3fc2c96e 100644 --- a/src/interpreter/bytecodes.h +++ b/src/interpreter/bytecodes.h @@ -110,6 +110,7 @@ namespace interpreter { V(Mul, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx) \ V(Div, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx) \ V(Mod, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx) \ + V(Exp, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx) \ V(BitwiseOr, AccumulatorUse::kReadWrite, OperandType::kReg, \ OperandType::kIdx) \ V(BitwiseXor, AccumulatorUse::kReadWrite, OperandType::kReg, \ @@ -129,6 +130,7 @@ namespace interpreter { V(MulSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx) \ V(DivSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx) \ V(ModSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx) \ + V(ExpSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx) \ V(BitwiseOrSmi, AccumulatorUse::kReadWrite, OperandType::kImm, \ OperandType::kIdx) \ V(BitwiseXorSmi, AccumulatorUse::kReadWrite, OperandType::kImm, \ diff --git a/src/interpreter/interpreter-generator.cc b/src/interpreter/interpreter-generator.cc index 2b27980690..1665aff29b 100644 --- a/src/interpreter/interpreter-generator.cc +++ b/src/interpreter/interpreter-generator.cc @@ -910,6 +910,13 @@ IGNITION_HANDLER(Mod, InterpreterBinaryOpAssembler) { BinaryOpWithFeedback(&BinaryOpAssembler::Generate_ModulusWithFeedback); } +// Exp +// +// Exponentiate register (base) with accumulator (exponent). +IGNITION_HANDLER(Exp, InterpreterBinaryOpAssembler) { + BinaryOpWithFeedback(&BinaryOpAssembler::Generate_ExponentiateWithFeedback); +} + // AddSmi // // Adds an immediate value to the value in the accumulator. @@ -945,6 +952,14 @@ IGNITION_HANDLER(ModSmi, InterpreterBinaryOpAssembler) { BinaryOpSmiWithFeedback(&BinaryOpAssembler::Generate_ModulusWithFeedback); } +// ExpSmi +// +// Exponentiate accumulator (base) with immediate value (exponent). +IGNITION_HANDLER(ExpSmi, InterpreterBinaryOpAssembler) { + BinaryOpSmiWithFeedback( + &BinaryOpAssembler::Generate_ExponentiateWithFeedback); +} + class InterpreterBitwiseBinaryOpAssembler : public InterpreterAssembler { public: InterpreterBitwiseBinaryOpAssembler(CodeAssemblerState* state, diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h index da48324957..c393bc5ec2 100644 --- a/src/parsing/parser-base.h +++ b/src/parsing/parser-base.h @@ -2973,15 +2973,11 @@ ParserBase::ParseAssignmentExpression(bool accept_IN, bool* ok) { impl()->SetFunctionNameFromIdentifierRef(right, expression); } - if (op == Token::ASSIGN_EXP) { - DCHECK(!is_destructuring_assignment); - return impl()->RewriteAssignExponentiation(expression, right, pos); - } - DCHECK_NE(op, Token::INIT); ExpressionT result = factory()->NewAssignment(op, expression, right, pos); if (is_destructuring_assignment) { + DCHECK_NE(op, Token::ASSIGN_EXP); auto rewritable = factory()->NewRewritableExpression(result, scope()); impl()->QueueDestructuringAssignmentForRewriting(rewritable); result = rewritable; @@ -3131,8 +3127,6 @@ typename ParserBase::ExpressionT ParserBase::ParseBinaryExpression( // The comparison was negated - add a NOT. x = factory()->NewUnaryOperation(Token::NOT, x, pos); } - } else if (op == Token::EXP) { - x = impl()->RewriteExponentiation(x, y, pos); } else if (impl()->CollapseNaryExpression(&x, y, op, pos, right_range)) { continue; } else { diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc index 5a823c939d..4d291a741e 100644 --- a/src/parsing/parser.cc +++ b/src/parsing/parser.cc @@ -3845,58 +3845,6 @@ void Parser::RewriteDestructuringAssignments() { } } -Expression* Parser::RewriteExponentiation(Expression* left, Expression* right, - int pos) { - ZoneList* args = new (zone()) ZoneList(2, zone()); - args->Add(left, zone()); - args->Add(right, zone()); - return factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos); -} - -Expression* Parser::RewriteAssignExponentiation(Expression* left, - Expression* right, int pos) { - ZoneList* args = new (zone()) ZoneList(2, zone()); - if (left->IsVariableProxy()) { - VariableProxy* lhs = left->AsVariableProxy(); - - Expression* result; - DCHECK_NOT_NULL(lhs->raw_name()); - result = ExpressionFromIdentifier(lhs->raw_name(), lhs->position()); - args->Add(left, zone()); - args->Add(right, zone()); - Expression* call = - factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos); - return factory()->NewAssignment(Token::ASSIGN, result, call, pos); - } else if (left->IsProperty()) { - Property* prop = left->AsProperty(); - auto temp_obj = NewTemporary(ast_value_factory()->empty_string()); - auto temp_key = NewTemporary(ast_value_factory()->empty_string()); - Expression* assign_obj = factory()->NewAssignment( - Token::ASSIGN, factory()->NewVariableProxy(temp_obj), prop->obj(), - kNoSourcePosition); - Expression* assign_key = factory()->NewAssignment( - Token::ASSIGN, factory()->NewVariableProxy(temp_key), prop->key(), - kNoSourcePosition); - args->Add(factory()->NewProperty(factory()->NewVariableProxy(temp_obj), - factory()->NewVariableProxy(temp_key), - left->position()), - zone()); - args->Add(right, zone()); - Expression* call = - factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos); - Expression* target = factory()->NewProperty( - factory()->NewVariableProxy(temp_obj), - factory()->NewVariableProxy(temp_key), kNoSourcePosition); - Expression* assign = - factory()->NewAssignment(Token::ASSIGN, target, call, pos); - return factory()->NewBinaryOperation( - Token::COMMA, assign_obj, - factory()->NewBinaryOperation(Token::COMMA, assign_key, assign, pos), - pos); - } - UNREACHABLE(); -} - Expression* Parser::RewriteSpreads(ArrayLiteral* lit) { // Array literals containing spreads are rewritten using do expressions, e.g. // [1, 2, 3, ...x, 4, ...y, 5] diff --git a/src/parsing/parser.h b/src/parsing/parser.h index 985856b84e..aa800dafc5 100644 --- a/src/parsing/parser.h +++ b/src/parsing/parser.h @@ -551,11 +551,6 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase) { // Rewrite all DestructuringAssignments in the current FunctionState. V8_INLINE void RewriteDestructuringAssignments(); - V8_INLINE Expression* RewriteExponentiation(Expression* left, - Expression* right, int pos); - V8_INLINE Expression* RewriteAssignExponentiation(Expression* left, - Expression* right, int pos); - Expression* RewriteSpreads(ArrayLiteral* lit); // Rewrite expressions that are not used as patterns diff --git a/src/parsing/preparser.h b/src/parsing/preparser.h index 49069e02e3..8c1d183fd6 100644 --- a/src/parsing/preparser.h +++ b/src/parsing/preparser.h @@ -995,17 +995,6 @@ class PreParser : public ParserBase { V8_INLINE void RewriteDestructuringAssignments() {} - V8_INLINE PreParserExpression - RewriteExponentiation(const PreParserExpression& left, - const PreParserExpression& right, int pos) { - return left; - } - V8_INLINE PreParserExpression - RewriteAssignExponentiation(const PreParserExpression& left, - const PreParserExpression& right, int pos) { - return left; - } - V8_INLINE void PrepareGeneratorVariables() {} V8_INLINE void RewriteAsyncFunctionBody( PreParserStatementList body, PreParserStatement block, diff --git a/src/parsing/token.h b/src/parsing/token.h index 261f8cd291..e4a4a5e587 100644 --- a/src/parsing/token.h +++ b/src/parsing/token.h @@ -284,6 +284,8 @@ class Token { return Token::DIV; case Token::ASSIGN_MOD: return Token::MOD; + case Token::ASSIGN_EXP: + return Token::EXP; default: UNREACHABLE(); } diff --git a/src/runtime/runtime-bigint.cc b/src/runtime/runtime-bigint.cc index b59f2c9a6d..ce513d2f92 100644 --- a/src/runtime/runtime-bigint.cc +++ b/src/runtime/runtime-bigint.cc @@ -107,6 +107,9 @@ RUNTIME_FUNCTION(Runtime_BigIntBinaryOp) { case Operation::kModulus: result = BigInt::Remainder(left, right); break; + case Operation::kExponentiate: + UNIMPLEMENTED(); + break; case Operation::kBitwiseAnd: result = BigInt::BitwiseAnd(left, right); break; diff --git a/src/v8.gyp b/src/v8.gyp index 4aa494e4f2..a6f72c9f1e 100644 --- a/src/v8.gyp +++ b/src/v8.gyp @@ -200,6 +200,7 @@ 'builtins/builtins-iterator-gen.h', 'builtins/builtins-iterator-gen.cc', 'builtins/builtins-math-gen.cc', + 'builtins/builtins-math-gen.h', 'builtins/builtins-number-gen.cc', 'builtins/builtins-object-gen.cc', 'builtins/builtins-promise-gen.cc', diff --git a/test/unittests/interpreter/bytecode-array-builder-unittest.cc b/test/unittests/interpreter/bytecode-array-builder-unittest.cc index 0c0b886cac..bbc9e565c9 100644 --- a/test/unittests/interpreter/bytecode-array-builder-unittest.cc +++ b/test/unittests/interpreter/bytecode-array-builder-unittest.cc @@ -199,7 +199,8 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { .BinaryOperation(Token::Value::SUB, reg, 2) .BinaryOperation(Token::Value::MUL, reg, 3) .BinaryOperation(Token::Value::DIV, reg, 4) - .BinaryOperation(Token::Value::MOD, reg, 5); + .BinaryOperation(Token::Value::MOD, reg, 5) + .BinaryOperation(Token::Value::EXP, reg, 6); // Emit bitwise operator invocations builder.BinaryOperation(Token::Value::BIT_OR, reg, 6) @@ -217,6 +218,7 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { .BinaryOperationSmiLiteral(Token::Value::MUL, Smi::FromInt(42), 2) .BinaryOperationSmiLiteral(Token::Value::DIV, Smi::FromInt(42), 2) .BinaryOperationSmiLiteral(Token::Value::MOD, Smi::FromInt(42), 2) + .BinaryOperationSmiLiteral(Token::Value::EXP, Smi::FromInt(42), 2) .BinaryOperationSmiLiteral(Token::Value::BIT_OR, Smi::FromInt(42), 2) .BinaryOperationSmiLiteral(Token::Value::BIT_XOR, Smi::FromInt(42), 2) .BinaryOperationSmiLiteral(Token::Value::BIT_AND, Smi::FromInt(42), 2)