From a1b2ec60b0d5ab1ee5ba5af362b22bc4b86ebcd6 Mon Sep 17 00:00:00 2001 From: bmeurer Date: Thu, 10 Sep 2015 06:04:15 -0700 Subject: [PATCH] [runtime] Move binary operator fallbacks into the runtime. Replace the ADD, SUB, etc. builtins with proper runtime implementations, and expose them as runtime calls that can be used by the code stubs and the interpreter (for now). Also remove all the support runtime functions for ADD, SUB and friends, namely %NumberAdd, %NumberSub, and so on. R=mstarzinger@chromium.org CQ_INCLUDE_TRYBOTS=tryserver.v8:v8_linux_layout_dbg,v8_linux_nosnap_dbg Review URL: https://codereview.chromium.org/1333843002 Cr-Commit-Position: refs/heads/master@{#30680} --- BUILD.gn | 1 + src/accessors.cc | 2 +- src/api.cc | 5 +- src/compiler/interpreter-assembler.cc | 34 +-- src/compiler/interpreter-assembler.h | 6 +- src/compiler/linkage.cc | 9 +- src/compiler/linkage.h | 2 +- src/compiler/raw-machine-assembler.cc | 29 +- src/compiler/raw-machine-assembler.h | 8 +- src/contexts.h | 58 ++-- src/execution.cc | 6 +- src/hydrogen.cc | 55 +++- src/ic/ic.cc | 123 ++++---- src/ic/ic.h | 2 - src/interpreter/interpreter.cc | 14 +- src/interpreter/interpreter.h | 5 +- src/json-stringifier.h | 4 +- src/objects.cc | 203 ++++++++++++- src/objects.h | 44 ++- src/runtime.js | 254 ---------------- src/runtime/runtime-i18n.cc | 6 +- src/runtime/runtime-numbers.cc | 111 ------- src/runtime/runtime-object.cc | 3 +- src/runtime/runtime-operators.cc | 277 ++++++++++++++++++ src/runtime/runtime.h | 36 ++- test/cctest/compiler/test-run-jscalls.cc | 7 +- test/mjsunit/stack-traces-2.js | 3 - .../interpreter-assembler-unittest.cc | 32 +- .../function-apply-aliased-expected.txt | 2 - test/webkit/function-apply-aliased.js | 13 - tools/gyp/v8.gyp | 1 + 31 files changed, 746 insertions(+), 609 deletions(-) create mode 100644 src/runtime/runtime-operators.cc diff --git a/BUILD.gn b/BUILD.gn index 0191508fd8..6253f54877 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1169,6 +1169,7 @@ source_set("v8_base") { "src/runtime/runtime-numbers.cc", "src/runtime/runtime-object.cc", "src/runtime/runtime-observe.cc", + "src/runtime/runtime-operators.cc", "src/runtime/runtime-proxy.cc", "src/runtime/runtime-regexp.cc", "src/runtime/runtime-scopes.cc", diff --git a/src/accessors.cc b/src/accessors.cc index 4421b43d3f..20dc725d39 100644 --- a/src/accessors.cc +++ b/src/accessors.cc @@ -231,7 +231,7 @@ void Accessors::ArrayLengthSetter( } Handle number_v; - if (!Object::ToNumber(isolate, length_obj).ToHandle(&number_v)) { + if (!Object::ToNumber(length_obj).ToHandle(&number_v)) { isolate->OptionalRescheduleException(false); return; } diff --git a/src/api.cc b/src/api.cc index 4833c313ad..8cceb65a27 100644 --- a/src/api.cc +++ b/src/api.cc @@ -2920,8 +2920,7 @@ MaybeLocal Value::ToNumber(Local context) const { if (obj->IsNumber()) return ToApiHandle(obj); PREPARE_FOR_EXECUTION(context, "ToNumber", Number); Local result; - has_pending_exception = - !ToLocal(i::Object::ToNumber(isolate, obj), &result); + has_pending_exception = !ToLocal(i::Object::ToNumber(obj), &result); RETURN_ON_FAILED_EXECUTION(Number); RETURN_ESCAPED(result); } @@ -3245,7 +3244,7 @@ Maybe Value::NumberValue(Local context) const { if (obj->IsNumber()) return Just(obj->Number()); PREPARE_FOR_EXECUTION_PRIMITIVE(context, "NumberValue", double); i::Handle num; - has_pending_exception = !i::Object::ToNumber(isolate, obj).ToHandle(&num); + has_pending_exception = !i::Object::ToNumber(obj).ToHandle(&num); RETURN_ON_FAILED_EXECUTION_PRIMITIVE(double); return Just(num->Number()); } diff --git a/src/compiler/interpreter-assembler.cc b/src/compiler/interpreter-assembler.cc index 085ce7cdf1..052bcf7c63 100644 --- a/src/compiler/interpreter-assembler.cc +++ b/src/compiler/interpreter-assembler.cc @@ -271,36 +271,10 @@ Node* InterpreterAssembler::CallIC(CallInterfaceDescriptor descriptor, } -Node* InterpreterAssembler::CallJSBuiltin(int context_index, Node* receiver, - Node** js_args, int js_arg_count) { - Node* global_object = LoadContextSlot(Context::GLOBAL_OBJECT_INDEX); - Node* native_context = - LoadObjectField(global_object, GlobalObject::kNativeContextOffset); - Node* function = LoadContextSlot(native_context, context_index); - Node* context = LoadObjectField(function, JSFunction::kContextOffset); - - int index = 0; - Node** args = zone()->NewArray(js_arg_count + 2); - args[index++] = receiver; - for (int i = 0; i < js_arg_count; i++) { - args[index++] = js_args[i]; - } - args[index++] = context; - - CallDescriptor* descriptor = Linkage::GetJSCallDescriptor( - zone(), false, js_arg_count + 1, CallDescriptor::kNoFlags); - return raw_assembler_->CallN(descriptor, function, args); -} - - -Node* InterpreterAssembler::CallJSBuiltin(int context_index, Node* receiver) { - return CallJSBuiltin(context_index, receiver, nullptr, 0); -} - - -Node* InterpreterAssembler::CallJSBuiltin(int context_index, Node* receiver, - Node* arg1) { - return CallJSBuiltin(context_index, receiver, &arg1, 1); +Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, + Node* arg1, Node* arg2) { + return raw_assembler_->CallRuntime2(function_id, arg1, arg2, + ContextTaggedPointer()); } diff --git a/src/compiler/interpreter-assembler.h b/src/compiler/interpreter-assembler.h index d6a75db89f..0949fbb5e6 100644 --- a/src/compiler/interpreter-assembler.h +++ b/src/compiler/interpreter-assembler.h @@ -12,6 +12,7 @@ #include "src/builtins.h" #include "src/frames.h" #include "src/interpreter/bytecodes.h" +#include "src/runtime/runtime.h" namespace v8 { namespace internal { @@ -86,9 +87,8 @@ class InterpreterAssembler { Node* CallIC(CallInterfaceDescriptor descriptor, Node* target, Node* arg1, Node* arg2, Node* arg3, Node* arg4, Node* arg5); - // Call JS builtin. - Node* CallJSBuiltin(int context_index, Node* receiver); - Node* CallJSBuiltin(int context_index, Node* receiver, Node* arg1); + // Call runtime function. + Node* CallRuntime(Runtime::FunctionId function_id, Node* arg1, Node* arg2); // Returns from the function. void Return(); diff --git a/src/compiler/linkage.cc b/src/compiler/linkage.cc index 93f447fc9f..097d3ab92b 100644 --- a/src/compiler/linkage.cc +++ b/src/compiler/linkage.cc @@ -284,7 +284,7 @@ bool CallDescriptor::UsesOnlyRegisters() const { CallDescriptor* Linkage::GetRuntimeCallDescriptor( Zone* zone, Runtime::FunctionId function_id, int js_parameter_count, - Operator::Properties properties) { + Operator::Properties properties, bool needs_frame_state) { const size_t function_count = 1; const size_t num_args_count = 1; const size_t context_count = 1; @@ -327,9 +327,10 @@ CallDescriptor* Linkage::GetRuntimeCallDescriptor( locations.AddParam(regloc(kContextRegister)); types.AddParam(kMachAnyTagged); - CallDescriptor::Flags flags = Linkage::FrameStateInputCount(function_id) > 0 - ? CallDescriptor::kNeedsFrameState - : CallDescriptor::kNoFlags; + CallDescriptor::Flags flags = + needs_frame_state && (Linkage::FrameStateInputCount(function_id) > 0) + ? CallDescriptor::kNeedsFrameState + : CallDescriptor::kNoFlags; // The target for runtime calls is a code object. MachineType target_type = kMachAnyTagged; diff --git a/src/compiler/linkage.h b/src/compiler/linkage.h index 5720362788..b25fe413c9 100644 --- a/src/compiler/linkage.h +++ b/src/compiler/linkage.h @@ -273,7 +273,7 @@ class Linkage : public ZoneObject { CallDescriptor::Flags flags); static CallDescriptor* GetRuntimeCallDescriptor( Zone* zone, Runtime::FunctionId function, int parameter_count, - Operator::Properties properties); + Operator::Properties properties, bool needs_frame_state = true); static CallDescriptor* GetStubCallDescriptor( Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor, diff --git a/src/compiler/raw-machine-assembler.cc b/src/compiler/raw-machine-assembler.cc index 623d5a2ed3..937e3be8b9 100644 --- a/src/compiler/raw-machine-assembler.cc +++ b/src/compiler/raw-machine-assembler.cc @@ -179,19 +179,36 @@ Node* RawMachineAssembler::CallFunctionStub0(Node* function, Node* receiver, Node* RawMachineAssembler::CallRuntime1(Runtime::FunctionId function, - Node* arg0, Node* context, - Node* frame_state) { + Node* arg1, Node* context) { CallDescriptor* descriptor = Linkage::GetRuntimeCallDescriptor( - zone(), function, 1, Operator::kNoProperties); + zone(), function, 1, Operator::kNoProperties, false); Node* centry = HeapConstant(CEntryStub(isolate(), 1).GetCode()); Node* ref = NewNode( common()->ExternalConstant(ExternalReference(function, isolate()))); Node* arity = Int32Constant(1); - Node* call = graph()->NewNode(common()->Call(descriptor), centry, arg0, ref, - arity, context, frame_state, graph()->start(), - graph()->start()); + Node* call = + graph()->NewNode(common()->Call(descriptor), centry, arg1, ref, arity, + context, graph()->start(), graph()->start()); + schedule()->AddNode(CurrentBlock(), call); + return call; +} + + +Node* RawMachineAssembler::CallRuntime2(Runtime::FunctionId function, + Node* arg1, Node* arg2, Node* context) { + CallDescriptor* descriptor = Linkage::GetRuntimeCallDescriptor( + zone(), function, 2, Operator::kNoProperties, false); + + Node* centry = HeapConstant(CEntryStub(isolate(), 1).GetCode()); + Node* ref = NewNode( + common()->ExternalConstant(ExternalReference(function, isolate()))); + Node* arity = Int32Constant(2); + + Node* call = + graph()->NewNode(common()->Call(descriptor), centry, arg1, arg2, ref, + arity, context, graph()->start(), graph()->start()); schedule()->AddNode(CurrentBlock(), call); return call; } diff --git a/src/compiler/raw-machine-assembler.h b/src/compiler/raw-machine-assembler.h index 6e081ccaac..7329af0598 100644 --- a/src/compiler/raw-machine-assembler.h +++ b/src/compiler/raw-machine-assembler.h @@ -485,9 +485,11 @@ class RawMachineAssembler { // Call through CallFunctionStub with lazy deopt and frame-state. Node* CallFunctionStub0(Node* function, Node* receiver, Node* context, Node* frame_state, CallFunctionFlags flags); - // Call to a runtime function with zero arguments. - Node* CallRuntime1(Runtime::FunctionId function, Node* arg0, Node* context, - Node* frame_state); + // Call to a runtime function with one arguments. + Node* CallRuntime1(Runtime::FunctionId function, Node* arg0, Node* context); + // Call to a runtime function with two arguments. + Node* CallRuntime2(Runtime::FunctionId function, Node* arg1, Node* arg2, + Node* context); // Call to a C function with zero arguments. Node* CallCFunction0(MachineType return_type, Node* function); // Call to a C function with one parameter. diff --git a/src/contexts.h b/src/contexts.h index 75cb1513b4..0e37489b06 100644 --- a/src/contexts.h +++ b/src/contexts.h @@ -90,46 +90,24 @@ enum BindingFlags { V(TO_STRING_FUN_INDEX, JSFunction, to_string_fun) -#define NATIVE_CONTEXT_JS_BUILTINS(V) \ - V(ADD_BUILTIN_INDEX, JSFunction, add_builtin) \ - V(ADD_STRONG_BUILTIN_INDEX, JSFunction, add_strong_builtin) \ - V(APPLY_PREPARE_BUILTIN_INDEX, JSFunction, apply_prepare_builtin) \ - V(BIT_AND_BUILTIN_INDEX, JSFunction, bit_and_builtin) \ - V(BIT_AND_STRONG_BUILTIN_INDEX, JSFunction, bit_and_strong_builtin) \ - V(BIT_OR_BUILTIN_INDEX, JSFunction, bit_or_builtin) \ - V(BIT_OR_STRONG_BUILTIN_INDEX, JSFunction, bit_or_strong_builtin) \ - V(BIT_XOR_BUILTIN_INDEX, JSFunction, bit_xor_builtin) \ - V(BIT_XOR_STRONG_BUILTIN_INDEX, JSFunction, bit_xor_strong_builtin) \ - V(CALL_FUNCTION_PROXY_AS_CONSTRUCTOR_BUILTIN_INDEX, JSFunction, \ - call_function_proxy_as_constructor_builtin) \ - V(CALL_NON_FUNCTION_AS_CONSTRUCTOR_BUILTIN_INDEX, JSFunction, \ - call_non_function_as_constructor_builtin) \ - V(COMPARE_BUILTIN_INDEX, JSFunction, compare_builtin) \ - V(COMPARE_STRONG_BUILTIN_INDEX, JSFunction, compare_strong_builtin) \ - V(CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX, JSFunction, \ - concat_iterable_to_array_builtin) \ - V(DIV_BUILTIN_INDEX, JSFunction, div_builtin) \ - V(DIV_STRONG_BUILTIN_INDEX, JSFunction, div_strong_builtin) \ - V(EQUALS_BUILTIN_INDEX, JSFunction, equals_builtin) \ - V(MOD_BUILTIN_INDEX, JSFunction, mod_builtin) \ - V(MOD_STRONG_BUILTIN_INDEX, JSFunction, mod_strong_builtin) \ - V(MUL_BUILTIN_INDEX, JSFunction, mul_builtin) \ - V(MUL_STRONG_BUILTIN_INDEX, JSFunction, mul_strong_builtin) \ - V(REFLECT_APPLY_PREPARE_BUILTIN_INDEX, JSFunction, \ - reflect_apply_prepare_builtin) \ - V(REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX, JSFunction, \ - reflect_construct_prepare_builtin) \ - V(SAR_BUILTIN_INDEX, JSFunction, sar_builtin) \ - V(SAR_STRONG_BUILTIN_INDEX, JSFunction, sar_strong_builtin) \ - V(SHL_BUILTIN_INDEX, JSFunction, shl_builtin) \ - V(SHL_STRONG_BUILTIN_INDEX, JSFunction, shl_strong_builtin) \ - V(SHR_BUILTIN_INDEX, JSFunction, shr_builtin) \ - V(SHR_STRONG_BUILTIN_INDEX, JSFunction, shr_strong_builtin) \ - V(STACK_OVERFLOW_BUILTIN_INDEX, JSFunction, stack_overflow_builtin) \ - V(STRING_ADD_LEFT_BUILTIN_INDEX, JSFunction, string_add_left_builtin) \ - V(STRING_ADD_RIGHT_BUILTIN_INDEX, JSFunction, string_add_right_builtin) \ - V(SUB_BUILTIN_INDEX, JSFunction, sub_builtin) \ - V(SUB_STRONG_BUILTIN_INDEX, JSFunction, sub_strong_builtin) +#define NATIVE_CONTEXT_JS_BUILTINS(V) \ + V(APPLY_PREPARE_BUILTIN_INDEX, JSFunction, apply_prepare_builtin) \ + V(CALL_FUNCTION_PROXY_AS_CONSTRUCTOR_BUILTIN_INDEX, JSFunction, \ + call_function_proxy_as_constructor_builtin) \ + V(CALL_NON_FUNCTION_AS_CONSTRUCTOR_BUILTIN_INDEX, JSFunction, \ + call_non_function_as_constructor_builtin) \ + V(COMPARE_BUILTIN_INDEX, JSFunction, compare_builtin) \ + V(COMPARE_STRONG_BUILTIN_INDEX, JSFunction, compare_strong_builtin) \ + V(CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX, JSFunction, \ + concat_iterable_to_array_builtin) \ + V(EQUALS_BUILTIN_INDEX, JSFunction, equals_builtin) \ + V(REFLECT_APPLY_PREPARE_BUILTIN_INDEX, JSFunction, \ + reflect_apply_prepare_builtin) \ + V(REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX, JSFunction, \ + reflect_construct_prepare_builtin) \ + V(STACK_OVERFLOW_BUILTIN_INDEX, JSFunction, stack_overflow_builtin) \ + V(STRING_ADD_LEFT_BUILTIN_INDEX, JSFunction, string_add_left_builtin) \ + V(STRING_ADD_RIGHT_BUILTIN_INDEX, JSFunction, string_add_right_builtin) #define NATIVE_CONTEXT_IMPORTED_FIELDS(V) \ diff --git a/src/execution.cc b/src/execution.cc index 88511aae29..2496439ca3 100644 --- a/src/execution.cc +++ b/src/execution.cc @@ -557,8 +557,7 @@ MaybeHandle Execution::NewDate(Isolate* isolate, double time) { MaybeHandle Execution::ToInt32(Isolate* isolate, Handle obj) { - ASSIGN_RETURN_ON_EXCEPTION(isolate, obj, Object::ToNumber(isolate, obj), - Object); + ASSIGN_RETURN_ON_EXCEPTION(isolate, obj, Object::ToNumber(obj), Object); return isolate->factory()->NewNumberFromInt(DoubleToInt32(obj->Number())); } @@ -574,8 +573,7 @@ MaybeHandle Execution::ToObject(Isolate* isolate, Handle obj) { MaybeHandle Execution::ToUint32(Isolate* isolate, Handle obj) { - ASSIGN_RETURN_ON_EXCEPTION(isolate, obj, Object::ToNumber(isolate, obj), - Object); + ASSIGN_RETURN_ON_EXCEPTION(isolate, obj, Object::ToNumber(obj), Object); return isolate->factory()->NewNumberFromUint(DoubleToUint32(obj->Number())); } diff --git a/src/hydrogen.cc b/src/hydrogen.cc index d1fca419b0..4152312338 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -11080,10 +11080,57 @@ HValue* HGraphBuilder::BuildBinaryOperation( // inline several instructions (including the two pushes) for every tagged // operation in optimized code, which is more expensive, than a stub call. if (graph()->info()->IsStub() && is_non_primitive) { - HValue* function = - AddLoadJSBuiltin(BinaryOpIC::TokenToContextIndex(op, strength)); + Runtime::FunctionId function_id; + switch (op) { + default: + UNREACHABLE(); + case Token::ADD: + function_id = + is_strong(strength) ? Runtime::kAdd_Strong : Runtime::kAdd; + break; + case Token::SUB: + function_id = is_strong(strength) ? Runtime::kSubtract_Strong + : Runtime::kSubtract; + break; + case Token::MUL: + function_id = is_strong(strength) ? Runtime::kMultiply_Strong + : Runtime::kMultiply; + break; + case Token::DIV: + function_id = + is_strong(strength) ? Runtime::kDivide_Strong : Runtime::kDivide; + break; + case Token::MOD: + function_id = + is_strong(strength) ? Runtime::kModulus_Strong : Runtime::kModulus; + break; + case Token::BIT_OR: + function_id = is_strong(strength) ? Runtime::kBitwiseOr_Strong + : Runtime::kBitwiseOr; + break; + case Token::BIT_AND: + function_id = is_strong(strength) ? Runtime::kBitwiseAnd_Strong + : Runtime::kBitwiseAnd; + break; + case Token::BIT_XOR: + function_id = is_strong(strength) ? Runtime::kBitwiseXor_Strong + : Runtime::kBitwiseXor; + break; + case Token::SAR: + function_id = is_strong(strength) ? Runtime::kShiftRight_Strong + : Runtime::kShiftRight; + break; + case Token::SHR: + function_id = is_strong(strength) ? Runtime::kShiftRightLogical_Strong + : Runtime::kShiftRightLogical; + break; + case Token::SHL: + function_id = is_strong(strength) ? Runtime::kShiftLeft_Strong + : Runtime::kShiftLeft; + break; + } Add(left, right); - instr = AddUncasted(function, 2); + instr = AddUncasted(Runtime::FunctionForId(function_id), 2); } else { if (is_strong(strength) && Token::IsBitOp(op)) { // TODO(conradw): This is not efficient, but is necessary to prevent @@ -11133,7 +11180,7 @@ HValue* HGraphBuilder::BuildBinaryOperation( instr = AddUncasted(op, left, right, strength); break; case Token::BIT_OR: { - HValue* operand, *shift_amount; + HValue *operand, *shift_amount; if (left_type->Is(Type::Signed32()) && right_type->Is(Type::Signed32()) && MatchRotateRight(left, right, &operand, &shift_amount)) { diff --git a/src/ic/ic.cc b/src/ic/ic.cc index e6a3479716..23944028a6 100644 --- a/src/ic/ic.cc +++ b/src/ic/ic.cc @@ -2645,13 +2645,67 @@ MaybeHandle BinaryOpIC::Transition( BinaryOpICState state(isolate(), target()->extra_ic_state()); // Compute the actual result using the builtin for the binary operation. - Object* builtin = isolate()->native_context()->get( - TokenToContextIndex(state.op(), state.strength())); - Handle function = handle(JSFunction::cast(builtin), isolate()); Handle result; - ASSIGN_RETURN_ON_EXCEPTION( - isolate(), result, Execution::Call(isolate(), function, left, 1, &right), - Object); + switch (state.op()) { + default: + UNREACHABLE(); + case Token::ADD: + ASSIGN_RETURN_ON_EXCEPTION( + isolate(), result, + Object::Add(isolate(), left, right, state.strength()), Object); + break; + case Token::SUB: + ASSIGN_RETURN_ON_EXCEPTION( + isolate(), result, + Object::Subtract(isolate(), left, right, state.strength()), Object); + break; + case Token::MUL: + ASSIGN_RETURN_ON_EXCEPTION( + isolate(), result, + Object::Multiply(isolate(), left, right, state.strength()), Object); + break; + case Token::DIV: + ASSIGN_RETURN_ON_EXCEPTION( + isolate(), result, + Object::Divide(isolate(), left, right, state.strength()), Object); + break; + case Token::MOD: + ASSIGN_RETURN_ON_EXCEPTION( + isolate(), result, + Object::Modulus(isolate(), left, right, state.strength()), Object); + break; + case Token::BIT_OR: + ASSIGN_RETURN_ON_EXCEPTION( + isolate(), result, + Object::BitwiseOr(isolate(), left, right, state.strength()), Object); + break; + case Token::BIT_AND: + ASSIGN_RETURN_ON_EXCEPTION( + isolate(), result, + Object::BitwiseAnd(isolate(), left, right, state.strength()), Object); + break; + case Token::BIT_XOR: + ASSIGN_RETURN_ON_EXCEPTION( + isolate(), result, + Object::BitwiseXor(isolate(), left, right, state.strength()), Object); + break; + case Token::SAR: + ASSIGN_RETURN_ON_EXCEPTION( + isolate(), result, + Object::ShiftRight(isolate(), left, right, state.strength()), Object); + break; + case Token::SHR: + ASSIGN_RETURN_ON_EXCEPTION( + isolate(), result, + Object::ShiftRightLogical(isolate(), left, right, state.strength()), + Object); + break; + case Token::SHL: + ASSIGN_RETURN_ON_EXCEPTION( + isolate(), result, + Object::ShiftLeft(isolate(), left, right, state.strength()), Object); + break; + } // Do not try to update the target if the code was marked for lazy // deoptimization. (Since we do not relocate addresses in these @@ -2885,63 +2939,6 @@ RUNTIME_FUNCTION(Runtime_Unreachable) { } -int BinaryOpIC::TokenToContextIndex(Token::Value op, Strength strength) { - if (is_strong(strength)) { - switch (op) { - default: UNREACHABLE(); - case Token::ADD: - return Context::ADD_STRONG_BUILTIN_INDEX; - case Token::SUB: - return Context::SUB_STRONG_BUILTIN_INDEX; - case Token::MUL: - return Context::MUL_STRONG_BUILTIN_INDEX; - case Token::DIV: - return Context::DIV_STRONG_BUILTIN_INDEX; - case Token::MOD: - return Context::MOD_STRONG_BUILTIN_INDEX; - case Token::BIT_OR: - return Context::BIT_OR_STRONG_BUILTIN_INDEX; - case Token::BIT_AND: - return Context::BIT_AND_STRONG_BUILTIN_INDEX; - case Token::BIT_XOR: - return Context::BIT_XOR_STRONG_BUILTIN_INDEX; - case Token::SAR: - return Context::SAR_STRONG_BUILTIN_INDEX; - case Token::SHR: - return Context::SHR_STRONG_BUILTIN_INDEX; - case Token::SHL: - return Context::SHL_STRONG_BUILTIN_INDEX; - } - } else { - switch (op) { - default: UNREACHABLE(); - case Token::ADD: - return Context::ADD_BUILTIN_INDEX; - case Token::SUB: - return Context::SUB_BUILTIN_INDEX; - case Token::MUL: - return Context::MUL_BUILTIN_INDEX; - case Token::DIV: - return Context::DIV_BUILTIN_INDEX; - case Token::MOD: - return Context::MOD_BUILTIN_INDEX; - case Token::BIT_OR: - return Context::BIT_OR_BUILTIN_INDEX; - case Token::BIT_AND: - return Context::BIT_AND_BUILTIN_INDEX; - case Token::BIT_XOR: - return Context::BIT_XOR_BUILTIN_INDEX; - case Token::SAR: - return Context::SAR_BUILTIN_INDEX; - case Token::SHR: - return Context::SHR_BUILTIN_INDEX; - case Token::SHL: - return Context::SHL_BUILTIN_INDEX; - } - } -} - - Handle ToBooleanIC::ToBoolean(Handle object) { ToBooleanStub stub(isolate(), target()->extra_ic_state()); bool to_boolean_value = stub.UpdateStatus(object); diff --git a/src/ic/ic.h b/src/ic/ic.h index 4ae59eaeec..ba606f9ecd 100644 --- a/src/ic/ic.h +++ b/src/ic/ic.h @@ -618,8 +618,6 @@ class BinaryOpIC : public IC { public: explicit BinaryOpIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {} - static int TokenToContextIndex(Token::Value op, Strength strength); - MaybeHandle Transition(Handle allocation_site, Handle left, Handle right) WARN_UNUSED_RESULT; diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc index e7ef203ad9..2029512ea4 100644 --- a/src/interpreter/interpreter.cc +++ b/src/interpreter/interpreter.cc @@ -269,14 +269,14 @@ void Interpreter::DoKeyedStoreIC(compiler::InterpreterAssembler* assembler) { } -void Interpreter::DoBinaryOp(int builtin_context_index, +void Interpreter::DoBinaryOp(Runtime::FunctionId function_id, compiler::InterpreterAssembler* assembler) { // TODO(rmcilroy): Call ICs which back-patch bytecode with type specialized // operations, instead of calling builtins directly. Node* reg_index = __ BytecodeOperandReg(0); Node* lhs = __ LoadRegister(reg_index); Node* rhs = __ GetAccumulator(); - Node* result = __ CallJSBuiltin(builtin_context_index, lhs, rhs); + Node* result = __ CallRuntime(function_id, lhs, rhs); __ SetAccumulator(result); __ Dispatch(); } @@ -286,7 +286,7 @@ void Interpreter::DoBinaryOp(int builtin_context_index, // // Add register to accumulator. void Interpreter::DoAdd(compiler::InterpreterAssembler* assembler) { - DoBinaryOp(Context::ADD_BUILTIN_INDEX, assembler); + DoBinaryOp(Runtime::kAdd, assembler); } @@ -294,7 +294,7 @@ void Interpreter::DoAdd(compiler::InterpreterAssembler* assembler) { // // Subtract register from accumulator. void Interpreter::DoSub(compiler::InterpreterAssembler* assembler) { - DoBinaryOp(Context::SUB_BUILTIN_INDEX, assembler); + DoBinaryOp(Runtime::kSubtract, assembler); } @@ -302,7 +302,7 @@ void Interpreter::DoSub(compiler::InterpreterAssembler* assembler) { // // Multiply accumulator by register . void Interpreter::DoMul(compiler::InterpreterAssembler* assembler) { - DoBinaryOp(Context::MUL_BUILTIN_INDEX, assembler); + DoBinaryOp(Runtime::kMultiply, assembler); } @@ -310,7 +310,7 @@ void Interpreter::DoMul(compiler::InterpreterAssembler* assembler) { // // Divide register by accumulator. void Interpreter::DoDiv(compiler::InterpreterAssembler* assembler) { - DoBinaryOp(Context::DIV_BUILTIN_INDEX, assembler); + DoBinaryOp(Runtime::kDivide, assembler); } @@ -318,7 +318,7 @@ void Interpreter::DoDiv(compiler::InterpreterAssembler* assembler) { // // Modulo register by accumulator. void Interpreter::DoMod(compiler::InterpreterAssembler* assembler) { - DoBinaryOp(Context::MOD_BUILTIN_INDEX, assembler); + DoBinaryOp(Runtime::kModulus, assembler); } diff --git a/src/interpreter/interpreter.h b/src/interpreter/interpreter.h index f4237b3ad2..1e4ca5cdb8 100644 --- a/src/interpreter/interpreter.h +++ b/src/interpreter/interpreter.h @@ -11,6 +11,7 @@ #include "src/base/macros.h" #include "src/builtins.h" #include "src/interpreter/bytecodes.h" +#include "src/runtime/runtime.h" namespace v8 { namespace internal { @@ -48,8 +49,8 @@ class Interpreter { BYTECODE_LIST(DECLARE_BYTECODE_HANDLER_GENERATOR) #undef DECLARE_BYTECODE_HANDLER_GENERATOR - // Generates code to perform the binary operations via |binop_builtin|. - void DoBinaryOp(int builtin_context_index, + // Generates code to perform the binary operations via |function_id|. + void DoBinaryOp(Runtime::FunctionId function_id, compiler::InterpreterAssembler* assembler); // Generates code to perform a property load via |ic|. diff --git a/src/json-stringifier.h b/src/json-stringifier.h index 3744ea78d9..260cade1ff 100644 --- a/src/json-stringifier.h +++ b/src/json-stringifier.h @@ -386,8 +386,8 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSValue( SerializeString(Handle::cast(value)); } else if (class_name == isolate_->heap()->Number_string()) { Handle value; - ASSIGN_RETURN_ON_EXCEPTION_VALUE( - isolate_, value, Object::ToNumber(isolate_, object), EXCEPTION); + ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate_, value, Object::ToNumber(object), + EXCEPTION); if (value->IsSmi()) return SerializeSmi(Smi::cast(*value)); SerializeHeapNumber(Handle::cast(value)); } else if (class_name == isolate_->heap()->Boolean_string()) { diff --git a/src/objects.cc b/src/objects.cc index 2287dd95c0..181c98bbc4 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -93,11 +93,12 @@ MaybeHandle Object::ToObject(Isolate* isolate, // static -MaybeHandle Object::ToNumber(Isolate* isolate, Handle input) { +MaybeHandle Object::ToNumber(Handle input) { while (true) { if (input->IsNumber()) { return input; } + Isolate* const isolate = Handle::cast(input)->GetIsolate(); if (input->IsOddball()) { return handle(Handle::cast(input)->to_number(), isolate); } @@ -193,6 +194,203 @@ Handle Object::TypeOf(Isolate* isolate, Handle object) { } +// static +MaybeHandle Object::Multiply(Isolate* isolate, Handle lhs, + Handle rhs, Strength strength) { + if (!lhs->IsNumber() || !rhs->IsNumber()) { + if (is_strong(strength)) { + THROW_NEW_ERROR(isolate, + NewTypeError(MessageTemplate::kStrongImplicitConversion), + Object); + } + ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object); + ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object); + } + return isolate->factory()->NewNumber(lhs->Number() * rhs->Number()); +} + + +// static +MaybeHandle Object::Divide(Isolate* isolate, Handle lhs, + Handle rhs, Strength strength) { + if (!lhs->IsNumber() || !rhs->IsNumber()) { + if (is_strong(strength)) { + THROW_NEW_ERROR(isolate, + NewTypeError(MessageTemplate::kStrongImplicitConversion), + Object); + } + ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object); + ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object); + } + return isolate->factory()->NewNumber(lhs->Number() / rhs->Number()); +} + + +// static +MaybeHandle Object::Modulus(Isolate* isolate, Handle lhs, + Handle rhs, Strength strength) { + if (!lhs->IsNumber() || !rhs->IsNumber()) { + if (is_strong(strength)) { + THROW_NEW_ERROR(isolate, + NewTypeError(MessageTemplate::kStrongImplicitConversion), + Object); + } + ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object); + ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object); + } + return isolate->factory()->NewNumber(modulo(lhs->Number(), rhs->Number())); +} + + +// static +MaybeHandle Object::Add(Isolate* isolate, Handle lhs, + Handle rhs, Strength strength) { + if (lhs->IsNumber() && rhs->IsNumber()) { + return isolate->factory()->NewNumber(lhs->Number() + rhs->Number()); + } else if (lhs->IsString() && rhs->IsString()) { + return isolate->factory()->NewConsString(Handle::cast(lhs), + Handle::cast(rhs)); + } else if (is_strong(strength)) { + THROW_NEW_ERROR(isolate, + NewTypeError(MessageTemplate::kStrongImplicitConversion), + Object); + } + ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToPrimitive(lhs), Object); + ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToPrimitive(rhs), Object); + if (lhs->IsString() || rhs->IsString()) { + ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToString(isolate, rhs), + Object); + ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToString(isolate, lhs), + Object); + return isolate->factory()->NewConsString(Handle::cast(lhs), + Handle::cast(rhs)); + } + ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object); + ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object); + return isolate->factory()->NewNumber(lhs->Number() + rhs->Number()); +} + + +// static +MaybeHandle Object::Subtract(Isolate* isolate, Handle lhs, + Handle rhs, Strength strength) { + if (!lhs->IsNumber() || !rhs->IsNumber()) { + if (is_strong(strength)) { + THROW_NEW_ERROR(isolate, + NewTypeError(MessageTemplate::kStrongImplicitConversion), + Object); + } + ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object); + ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object); + } + return isolate->factory()->NewNumber(lhs->Number() - rhs->Number()); +} + + +// static +MaybeHandle Object::ShiftLeft(Isolate* isolate, Handle lhs, + Handle rhs, Strength strength) { + if (!lhs->IsNumber() || !rhs->IsNumber()) { + if (is_strong(strength)) { + THROW_NEW_ERROR(isolate, + NewTypeError(MessageTemplate::kStrongImplicitConversion), + Object); + } + ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object); + ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object); + } + return isolate->factory()->NewNumberFromInt(NumberToInt32(*lhs) + << (NumberToUint32(*rhs) & 0x1F)); +} + + +// static +MaybeHandle Object::ShiftRight(Isolate* isolate, Handle lhs, + Handle rhs, Strength strength) { + if (!lhs->IsNumber() || !rhs->IsNumber()) { + if (is_strong(strength)) { + THROW_NEW_ERROR(isolate, + NewTypeError(MessageTemplate::kStrongImplicitConversion), + Object); + } + ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object); + ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object); + } + return isolate->factory()->NewNumberFromInt(NumberToInt32(*lhs) >> + (NumberToUint32(*rhs) & 0x1F)); +} + + +// static +MaybeHandle Object::ShiftRightLogical(Isolate* isolate, + Handle lhs, + Handle rhs, + Strength strength) { + if (!lhs->IsNumber() || !rhs->IsNumber()) { + if (is_strong(strength)) { + THROW_NEW_ERROR(isolate, + NewTypeError(MessageTemplate::kStrongImplicitConversion), + Object); + } + ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object); + ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object); + } + return isolate->factory()->NewNumberFromUint(NumberToUint32(*lhs) >> + (NumberToUint32(*rhs) & 0x1F)); +} + + +// static +MaybeHandle Object::BitwiseAnd(Isolate* isolate, Handle lhs, + Handle rhs, Strength strength) { + if (!lhs->IsNumber() || !rhs->IsNumber()) { + if (is_strong(strength)) { + THROW_NEW_ERROR(isolate, + NewTypeError(MessageTemplate::kStrongImplicitConversion), + Object); + } + ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object); + ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object); + } + return isolate->factory()->NewNumberFromInt(NumberToInt32(*lhs) & + NumberToInt32(*rhs)); +} + + +// static +MaybeHandle Object::BitwiseOr(Isolate* isolate, Handle lhs, + Handle rhs, Strength strength) { + if (!lhs->IsNumber() || !rhs->IsNumber()) { + if (is_strong(strength)) { + THROW_NEW_ERROR(isolate, + NewTypeError(MessageTemplate::kStrongImplicitConversion), + Object); + } + ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object); + ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object); + } + return isolate->factory()->NewNumberFromInt(NumberToInt32(*lhs) | + NumberToInt32(*rhs)); +} + + +// static +MaybeHandle Object::BitwiseXor(Isolate* isolate, Handle lhs, + Handle rhs, Strength strength) { + if (!lhs->IsNumber() || !rhs->IsNumber()) { + if (is_strong(strength)) { + THROW_NEW_ERROR(isolate, + NewTypeError(MessageTemplate::kStrongImplicitConversion), + Object); + } + ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object); + ASSIGN_RETURN_ON_EXCEPTION(isolate, rhs, Object::ToNumber(rhs), Object); + } + return isolate->factory()->NewNumberFromInt(NumberToInt32(*lhs) ^ + NumberToInt32(*rhs)); +} + + bool Object::IsPromise(Handle object) { if (!object->IsJSObject()) return false; auto js_object = Handle::cast(object); @@ -3416,8 +3614,7 @@ MaybeHandle Object::SetDataProperty(LookupIterator* it, if (it->IsElement() && receiver->HasFixedTypedArrayElements()) { if (!value->IsNumber() && !value->IsUndefined()) { ASSIGN_RETURN_ON_EXCEPTION(it->isolate(), to_assign, - Object::ToNumber(it->isolate(), value), - Object); + Object::ToNumber(value), Object); // ToNumber above might modify the receiver, causing the cached // holder_map to mismatch the actual holder->map() after this point. // Reload the map to be in consistent state. Other cached state cannot diff --git a/src/objects.h b/src/objects.h index 113ba3a671..751e3cf345 100644 --- a/src/objects.h +++ b/src/objects.h @@ -1102,8 +1102,7 @@ class Object { Handle input, ToPrimitiveHint hint = ToPrimitiveHint::kDefault); // ES6 section 7.1.3 ToNumber - MUST_USE_RESULT static MaybeHandle ToNumber(Isolate* isolate, - Handle input); + MUST_USE_RESULT static MaybeHandle ToNumber(Handle input); // ES6 section 7.1.12 ToString MUST_USE_RESULT static MaybeHandle ToString(Isolate* isolate, @@ -1116,6 +1115,47 @@ class Object { // ES6 section 12.5.6 The typeof Operator static Handle TypeOf(Isolate* isolate, Handle object); + // ES6 section 12.6 Multiplicative Operators + MUST_USE_RESULT static MaybeHandle Multiply( + Isolate* isolate, Handle lhs, Handle rhs, + Strength strength = Strength::WEAK); + MUST_USE_RESULT static MaybeHandle Divide( + Isolate* isolate, Handle lhs, Handle rhs, + Strength strength = Strength::WEAK); + MUST_USE_RESULT static MaybeHandle Modulus( + Isolate* isolate, Handle lhs, Handle rhs, + Strength strength = Strength::WEAK); + + // ES6 section 12.7 Additive Operators + MUST_USE_RESULT static MaybeHandle Add( + Isolate* isolate, Handle lhs, Handle rhs, + Strength strength = Strength::WEAK); + MUST_USE_RESULT static MaybeHandle Subtract( + Isolate* isolate, Handle lhs, Handle rhs, + Strength strength = Strength::WEAK); + + // ES6 section 12.8 Bitwise Shift Operators + MUST_USE_RESULT static MaybeHandle ShiftLeft( + Isolate* isolate, Handle lhs, Handle rhs, + Strength strength = Strength::WEAK); + MUST_USE_RESULT static MaybeHandle ShiftRight( + Isolate* isolate, Handle lhs, Handle rhs, + Strength strength = Strength::WEAK); + MUST_USE_RESULT static MaybeHandle ShiftRightLogical( + Isolate* isolate, Handle lhs, Handle rhs, + Strength strength = Strength::WEAK); + + // ES6 section 12.11 Binary Bitwise Operators + MUST_USE_RESULT static MaybeHandle BitwiseAnd( + Isolate* isolate, Handle lhs, Handle rhs, + Strength strength = Strength::WEAK); + MUST_USE_RESULT static MaybeHandle BitwiseOr( + Isolate* isolate, Handle lhs, Handle rhs, + Strength strength = Strength::WEAK); + MUST_USE_RESULT static MaybeHandle BitwiseXor( + Isolate* isolate, Handle lhs, Handle rhs, + Strength strength = Strength::WEAK); + MUST_USE_RESULT static MaybeHandle GetProperty( LookupIterator* it, LanguageMode language_mode = SLOPPY); diff --git a/src/runtime.js b/src/runtime.js index e5e306d8cd..098551ad14 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -156,35 +156,6 @@ function COMPARE_STRONG(x, ncr) { ----------------------------------- */ -// ECMA-262, section 11.6.1, page 50. -function ADD(x) { - // Fast case: Check for number operands and do the addition. - if (IS_NUMBER(this) && IS_NUMBER(x)) return %NumberAdd(this, x); - if (IS_STRING(this) && IS_STRING(x)) return %_StringAdd(this, x); - - // Default implementation. - var a = %to_primitive(this, NO_HINT); - var b = %to_primitive(x, NO_HINT); - - if (IS_STRING(a)) { - return %_StringAdd(a, %to_string_fun(b)); - } else if (IS_STRING(b)) { - return %_StringAdd(%non_string_to_string(a), b); - } else { - return %NumberAdd(%to_number_fun(a), %to_number_fun(b)); - } -} - - -// Strong mode ADD throws if an implicit conversion would be performed -function ADD_STRONG(x) { - if (IS_NUMBER(this) && IS_NUMBER(x)) return %NumberAdd(this, x); - if (IS_STRING(this) && IS_STRING(x)) return %_StringAdd(this, x); - - throw %make_type_error(kStrongImplicitConversion); -} - - // Left operand (this) is already a string. function STRING_ADD_LEFT(y) { if (!IS_STRING(y)) { @@ -216,209 +187,6 @@ function STRING_ADD_RIGHT(y) { } -// ECMA-262, section 11.6.2, page 50. -function SUB(y) { - var x = IS_NUMBER(this) ? this : %non_number_to_number(this); - if (!IS_NUMBER(y)) y = %non_number_to_number(y); - return %NumberSub(x, y); -} - - -// Strong mode SUB throws if an implicit conversion would be performed -function SUB_STRONG(y) { - if (IS_NUMBER(this) && IS_NUMBER(y)) { - return %NumberSub(this, y); - } - throw %make_type_error(kStrongImplicitConversion); -} - - -// ECMA-262, section 11.5.1, page 48. -function MUL(y) { - var x = IS_NUMBER(this) ? this : %non_number_to_number(this); - if (!IS_NUMBER(y)) y = %non_number_to_number(y); - return %NumberMul(x, y); -} - - -// Strong mode MUL throws if an implicit conversion would be performed -function MUL_STRONG(y) { - if (IS_NUMBER(this) && IS_NUMBER(y)) { - return %NumberMul(this, y); - } - throw %make_type_error(kStrongImplicitConversion); -} - - -// ECMA-262, section 11.5.2, page 49. -function DIV(y) { - var x = IS_NUMBER(this) ? this : %non_number_to_number(this); - if (!IS_NUMBER(y)) y = %non_number_to_number(y); - return %NumberDiv(x, y); -} - - -// Strong mode DIV throws if an implicit conversion would be performed -function DIV_STRONG(y) { - if (IS_NUMBER(this) && IS_NUMBER(y)) { - return %NumberDiv(this, y); - } - throw %make_type_error(kStrongImplicitConversion); -} - - -// ECMA-262, section 11.5.3, page 49. -function MOD(y) { - var x = IS_NUMBER(this) ? this : %non_number_to_number(this); - if (!IS_NUMBER(y)) y = %non_number_to_number(y); - return %NumberMod(x, y); -} - - -// Strong mode MOD throws if an implicit conversion would be performed -function MOD_STRONG(y) { - if (IS_NUMBER(this) && IS_NUMBER(y)) { - return %NumberMod(this, y); - } - throw %make_type_error(kStrongImplicitConversion); -} - - -/* ------------------------------------------- - - - - B i t o p e r a t i o n s - - - - ------------------------------------------- -*/ - -// ECMA-262, section 11.10, page 57. -function BIT_OR(y) { - var x = IS_NUMBER(this) ? this : %non_number_to_number(this); - if (!IS_NUMBER(y)) y = %non_number_to_number(y); - return %NumberOr(x, y); -} - - -// Strong mode BIT_OR throws if an implicit conversion would be performed -function BIT_OR_STRONG(y) { - if (IS_NUMBER(this) && IS_NUMBER(y)) { - return %NumberOr(this, y); - } - throw %make_type_error(kStrongImplicitConversion); -} - - -// ECMA-262, section 11.10, page 57. -function BIT_AND(y) { - var x; - if (IS_NUMBER(this)) { - x = this; - if (!IS_NUMBER(y)) y = %non_number_to_number(y); - } else { - x = %non_number_to_number(this); - // Make sure to convert the right operand to a number before - // bailing out in the fast case, but after converting the - // left operand. This ensures that valueOf methods on the right - // operand are always executed. - if (!IS_NUMBER(y)) y = %non_number_to_number(y); - // Optimize for the case where we end up AND'ing a value - // that doesn't convert to a number. This is common in - // certain benchmarks. - if (NUMBER_IS_NAN(x)) return 0; - } - return %NumberAnd(x, y); -} - - -// Strong mode BIT_AND throws if an implicit conversion would be performed -function BIT_AND_STRONG(y) { - if (IS_NUMBER(this) && IS_NUMBER(y)) { - return %NumberAnd(this, y); - } - throw %make_type_error(kStrongImplicitConversion); -} - - -// ECMA-262, section 11.10, page 57. -function BIT_XOR(y) { - var x = IS_NUMBER(this) ? this : %non_number_to_number(this); - if (!IS_NUMBER(y)) y = %non_number_to_number(y); - return %NumberXor(x, y); -} - - -// Strong mode BIT_XOR throws if an implicit conversion would be performed -function BIT_XOR_STRONG(y) { - if (IS_NUMBER(this) && IS_NUMBER(y)) { - return %NumberXor(this, y); - } - throw %make_type_error(kStrongImplicitConversion); -} - - -// ECMA-262, section 11.7.1, page 51. -function SHL(y) { - var x = IS_NUMBER(this) ? this : %non_number_to_number(this); - if (!IS_NUMBER(y)) y = %non_number_to_number(y); - return %NumberShl(x, y); -} - - -// Strong mode SHL throws if an implicit conversion would be performed -function SHL_STRONG(y) { - if (IS_NUMBER(this) && IS_NUMBER(y)) { - return %NumberShl(this, y); - } - throw %make_type_error(kStrongImplicitConversion); -} - - -// ECMA-262, section 11.7.2, page 51. -function SAR(y) { - var x; - if (IS_NUMBER(this)) { - x = this; - if (!IS_NUMBER(y)) y = %non_number_to_number(y); - } else { - x = %non_number_to_number(this); - // Make sure to convert the right operand to a number before - // bailing out in the fast case, but after converting the - // left operand. This ensures that valueOf methods on the right - // operand are always executed. - if (!IS_NUMBER(y)) y = %non_number_to_number(y); - // Optimize for the case where we end up shifting a value - // that doesn't convert to a number. This is common in - // certain benchmarks. - if (NUMBER_IS_NAN(x)) return 0; - } - return %NumberSar(x, y); -} - - -// Strong mode SAR throws if an implicit conversion would be performed -function SAR_STRONG(y) { - if (IS_NUMBER(this) && IS_NUMBER(y)) { - return %NumberSar(this, y); - } - throw %make_type_error(kStrongImplicitConversion); -} - - -// ECMA-262, section 11.7.3, page 52. -function SHR(y) { - var x = IS_NUMBER(this) ? this : %non_number_to_number(this); - if (!IS_NUMBER(y)) y = %non_number_to_number(y); - return %NumberShr(x, y); -} - - -// Strong mode SHR throws if an implicit conversion would be performed -function SHR_STRONG(y) { - if (IS_NUMBER(this) && IS_NUMBER(y)) { - return %NumberShr(this, y); - } - throw %make_type_error(kStrongImplicitConversion); -} - - /* ----------------------------- - - - H e l p e r s - - - ----------------------------- @@ -781,40 +549,18 @@ $toPrimitive = ToPrimitive; $toString = ToString; %InstallToContext([ - "add_builtin", ADD, - "add_strong_builtin", ADD_STRONG, "apply_prepare_builtin", APPLY_PREPARE, - "bit_and_builtin", BIT_AND, - "bit_and_strong_builtin", BIT_AND_STRONG, - "bit_or_builtin", BIT_OR, - "bit_or_strong_builtin", BIT_OR_STRONG, - "bit_xor_builtin", BIT_XOR, - "bit_xor_strong_builtin", BIT_XOR_STRONG, "call_function_proxy_as_constructor_builtin", CALL_FUNCTION_PROXY_AS_CONSTRUCTOR, "call_non_function_as_constructor_builtin", CALL_NON_FUNCTION_AS_CONSTRUCTOR, "compare_builtin", COMPARE, "compare_strong_builtin", COMPARE_STRONG, "concat_iterable_to_array_builtin", CONCAT_ITERABLE_TO_ARRAY, - "div_builtin", DIV, - "div_strong_builtin", DIV_STRONG, "equals_builtin", EQUALS, - "mod_builtin", MOD, - "mod_strong_builtin", MOD_STRONG, - "mul_builtin", MUL, - "mul_strong_builtin", MUL_STRONG, "reflect_apply_prepare_builtin", REFLECT_APPLY_PREPARE, "reflect_construct_prepare_builtin", REFLECT_CONSTRUCT_PREPARE, - "sar_builtin", SAR, - "sar_strong_builtin", SAR_STRONG, - "shl_builtin", SHL, - "shl_strong_builtin", SHL_STRONG, - "shr_builtin", SHR, - "shr_strong_builtin", SHR_STRONG, "stack_overflow_builtin", STACK_OVERFLOW, "string_add_left_builtin", STRING_ADD_LEFT, "string_add_right_builtin", STRING_ADD_RIGHT, - "sub_builtin", SUB, - "sub_strong_builtin", SUB_STRONG, ]); %InstallToContext([ diff --git a/src/runtime/runtime-i18n.cc b/src/runtime/runtime-i18n.cc index 8eefca98c8..8b0c98f161 100644 --- a/src/runtime/runtime-i18n.cc +++ b/src/runtime/runtime-i18n.cc @@ -352,8 +352,7 @@ RUNTIME_FUNCTION(Runtime_InternalDateFormat) { CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1); Handle value; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, - Object::ToNumber(isolate, date)); + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, Object::ToNumber(date)); icu::SimpleDateFormat* date_format = DateFormat::UnpackDateFormat(isolate, date_format_holder); @@ -446,8 +445,7 @@ RUNTIME_FUNCTION(Runtime_InternalNumberFormat) { CONVERT_ARG_HANDLE_CHECKED(Object, number, 1); Handle value; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, - Object::ToNumber(isolate, number)); + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, Object::ToNumber(number)); icu::DecimalFormat* number_format = NumberFormat::UnpackNumberFormat(isolate, number_format_holder); diff --git a/src/runtime/runtime-numbers.cc b/src/runtime/runtime-numbers.cc index ac50f0080d..75c8065cdf 100644 --- a/src/runtime/runtime-numbers.cc +++ b/src/runtime/runtime-numbers.cc @@ -220,56 +220,6 @@ RUNTIME_FUNCTION(Runtime_NumberToSmi) { } -RUNTIME_FUNCTION(Runtime_NumberAdd) { - HandleScope scope(isolate); - DCHECK(args.length() == 2); - - CONVERT_DOUBLE_ARG_CHECKED(x, 0); - CONVERT_DOUBLE_ARG_CHECKED(y, 1); - return *isolate->factory()->NewNumber(x + y); -} - - -RUNTIME_FUNCTION(Runtime_NumberSub) { - HandleScope scope(isolate); - DCHECK(args.length() == 2); - - CONVERT_DOUBLE_ARG_CHECKED(x, 0); - CONVERT_DOUBLE_ARG_CHECKED(y, 1); - return *isolate->factory()->NewNumber(x - y); -} - - -RUNTIME_FUNCTION(Runtime_NumberMul) { - HandleScope scope(isolate); - DCHECK(args.length() == 2); - - CONVERT_DOUBLE_ARG_CHECKED(x, 0); - CONVERT_DOUBLE_ARG_CHECKED(y, 1); - return *isolate->factory()->NewNumber(x * y); -} - - -RUNTIME_FUNCTION(Runtime_NumberDiv) { - HandleScope scope(isolate); - DCHECK(args.length() == 2); - - CONVERT_DOUBLE_ARG_CHECKED(x, 0); - CONVERT_DOUBLE_ARG_CHECKED(y, 1); - return *isolate->factory()->NewNumber(x / y); -} - - -RUNTIME_FUNCTION(Runtime_NumberMod) { - HandleScope scope(isolate); - DCHECK(args.length() == 2); - - CONVERT_DOUBLE_ARG_CHECKED(x, 0); - CONVERT_DOUBLE_ARG_CHECKED(y, 1); - return *isolate->factory()->NewNumber(modulo(x, y)); -} - - RUNTIME_FUNCTION(Runtime_NumberImul) { HandleScope scope(isolate); DCHECK(args.length() == 2); @@ -283,67 +233,6 @@ RUNTIME_FUNCTION(Runtime_NumberImul) { } -RUNTIME_FUNCTION(Runtime_NumberOr) { - HandleScope scope(isolate); - DCHECK(args.length() == 2); - - CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); - CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); - return *isolate->factory()->NewNumberFromInt(x | y); -} - - -RUNTIME_FUNCTION(Runtime_NumberAnd) { - HandleScope scope(isolate); - DCHECK(args.length() == 2); - - CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); - CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); - return *isolate->factory()->NewNumberFromInt(x & y); -} - - -RUNTIME_FUNCTION(Runtime_NumberXor) { - HandleScope scope(isolate); - DCHECK(args.length() == 2); - - CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); - CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); - return *isolate->factory()->NewNumberFromInt(x ^ y); -} - - -RUNTIME_FUNCTION(Runtime_NumberShl) { - HandleScope scope(isolate); - DCHECK(args.length() == 2); - - CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); - CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); - return *isolate->factory()->NewNumberFromInt(x << (y & 0x1f)); -} - - -RUNTIME_FUNCTION(Runtime_NumberShr) { - HandleScope scope(isolate); - DCHECK(args.length() == 2); - - CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]); - CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); - return *isolate->factory()->NewNumberFromUint(x >> (y & 0x1f)); -} - - -RUNTIME_FUNCTION(Runtime_NumberSar) { - HandleScope scope(isolate); - DCHECK(args.length() == 2); - - CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); - CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); - return *isolate->factory()->NewNumberFromInt( - ArithmeticShiftRight(x, y & 0x1f)); -} - - RUNTIME_FUNCTION(Runtime_NumberEquals) { SealHandleScope shs(isolate); DCHECK(args.length() == 2); diff --git a/src/runtime/runtime-object.cc b/src/runtime/runtime-object.cc index 9ffb2500ef..6e138adfbe 100644 --- a/src/runtime/runtime-object.cc +++ b/src/runtime/runtime-object.cc @@ -1459,8 +1459,7 @@ RUNTIME_FUNCTION(Runtime_ToNumber) { DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, input, 0); Handle result; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, - Object::ToNumber(isolate, input)); + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::ToNumber(input)); return *result; } diff --git a/src/runtime/runtime-operators.cc b/src/runtime/runtime-operators.cc new file mode 100644 index 0000000000..b5e92af8f6 --- /dev/null +++ b/src/runtime/runtime-operators.cc @@ -0,0 +1,277 @@ +// Copyright 2014 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. + +#include "src/arguments.h" +#include "src/isolate-inl.h" +#include "src/runtime/runtime-utils.h" + +namespace v8 { +namespace internal { + +RUNTIME_FUNCTION(Runtime_Multiply) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, + Object::Multiply(isolate, lhs, rhs)); + return *result; +} + + +RUNTIME_FUNCTION(Runtime_Multiply_Strong) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, Object::Multiply(isolate, lhs, rhs, Strength::STRONG)); + return *result; +} + + +RUNTIME_FUNCTION(Runtime_Divide) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, + Object::Divide(isolate, lhs, rhs)); + return *result; +} + + +RUNTIME_FUNCTION(Runtime_Divide_Strong) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, Object::Divide(isolate, lhs, rhs, Strength::STRONG)); + return *result; +} + + +RUNTIME_FUNCTION(Runtime_Modulus) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, + Object::Modulus(isolate, lhs, rhs)); + return *result; +} + + +RUNTIME_FUNCTION(Runtime_Modulus_Strong) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, Object::Modulus(isolate, lhs, rhs, Strength::STRONG)); + return *result; +} + + +RUNTIME_FUNCTION(Runtime_Add) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, + Object::Add(isolate, lhs, rhs)); + return *result; +} + + +RUNTIME_FUNCTION(Runtime_Add_Strong) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, Object::Add(isolate, lhs, rhs, Strength::STRONG)); + return *result; +} + + +RUNTIME_FUNCTION(Runtime_Subtract) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, + Object::Subtract(isolate, lhs, rhs)); + return *result; +} + + +RUNTIME_FUNCTION(Runtime_Subtract_Strong) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, Object::Subtract(isolate, lhs, rhs, Strength::STRONG)); + return *result; +} + + +RUNTIME_FUNCTION(Runtime_ShiftLeft) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, + Object::ShiftLeft(isolate, lhs, rhs)); + return *result; +} + + +RUNTIME_FUNCTION(Runtime_ShiftLeft_Strong) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, Object::ShiftLeft(isolate, lhs, rhs, Strength::STRONG)); + return *result; +} + + +RUNTIME_FUNCTION(Runtime_ShiftRight) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, + Object::ShiftRight(isolate, lhs, rhs)); + return *result; +} + + +RUNTIME_FUNCTION(Runtime_ShiftRight_Strong) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, Object::ShiftRight(isolate, lhs, rhs, Strength::STRONG)); + return *result; +} + + +RUNTIME_FUNCTION(Runtime_ShiftRightLogical) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, Object::ShiftRightLogical(isolate, lhs, rhs)); + return *result; +} + + +RUNTIME_FUNCTION(Runtime_ShiftRightLogical_Strong) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, + Object::ShiftRightLogical(isolate, lhs, rhs, Strength::STRONG)); + return *result; +} + + +RUNTIME_FUNCTION(Runtime_BitwiseAnd) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, + Object::BitwiseAnd(isolate, lhs, rhs)); + return *result; +} + + +RUNTIME_FUNCTION(Runtime_BitwiseAnd_Strong) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, Object::BitwiseAnd(isolate, lhs, rhs, Strength::STRONG)); + return *result; +} + + +RUNTIME_FUNCTION(Runtime_BitwiseOr) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, + Object::BitwiseOr(isolate, lhs, rhs)); + return *result; +} + + +RUNTIME_FUNCTION(Runtime_BitwiseOr_Strong) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, Object::BitwiseOr(isolate, lhs, rhs, Strength::STRONG)); + return *result; +} + + +RUNTIME_FUNCTION(Runtime_BitwiseXor) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, + Object::BitwiseXor(isolate, lhs, rhs)); + return *result; +} + + +RUNTIME_FUNCTION(Runtime_BitwiseXor_Strong) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); + Handle result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, Object::BitwiseXor(isolate, lhs, rhs, Strength::STRONG)); + return *result; +} + +} // namespace internal +} // namespace v8 diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index f626893a90..e4893c0dff 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -405,18 +405,7 @@ namespace internal { F(NumberToInteger, 1, 1) \ F(NumberToIntegerMapMinusZero, 1, 1) \ F(NumberToSmi, 1, 1) \ - F(NumberAdd, 2, 1) \ - F(NumberSub, 2, 1) \ - F(NumberMul, 2, 1) \ - F(NumberDiv, 2, 1) \ - F(NumberMod, 2, 1) \ F(NumberImul, 2, 1) \ - F(NumberOr, 2, 1) \ - F(NumberAnd, 2, 1) \ - F(NumberXor, 2, 1) \ - F(NumberShl, 2, 1) \ - F(NumberShr, 2, 1) \ - F(NumberSar, 2, 1) \ F(NumberEquals, 2, 1) \ F(NumberCompare, 3, 1) \ F(SmiLexicographicCompare, 2, 1) \ @@ -511,6 +500,30 @@ namespace internal { F(GetObjectContextNotifierPerformChange, 1, 1) +#define FOR_EACH_INTRINSIC_OPERATORS(F) \ + F(Multiply, 2, 1) \ + F(Multiply_Strong, 2, 1) \ + F(Divide, 2, 1) \ + F(Divide_Strong, 2, 1) \ + F(Modulus, 2, 1) \ + F(Modulus_Strong, 2, 1) \ + F(Add, 2, 1) \ + F(Add_Strong, 2, 1) \ + F(Subtract, 2, 1) \ + F(Subtract_Strong, 2, 1) \ + F(ShiftLeft, 2, 1) \ + F(ShiftLeft_Strong, 2, 1) \ + F(ShiftRight, 2, 1) \ + F(ShiftRight_Strong, 2, 1) \ + F(ShiftRightLogical, 2, 1) \ + F(ShiftRightLogical_Strong, 2, 1) \ + F(BitwiseAnd, 2, 1) \ + F(BitwiseAnd_Strong, 2, 1) \ + F(BitwiseOr, 2, 1) \ + F(BitwiseOr_Strong, 2, 1) \ + F(BitwiseXor, 2, 1) \ + F(BitwiseXor_Strong, 2, 1) + #define FOR_EACH_INTRINSIC_PROXY(F) \ F(CreateJSProxy, 2, 1) \ F(CreateJSFunctionProxy, 4, 1) \ @@ -1065,6 +1078,7 @@ namespace internal { FOR_EACH_INTRINSIC_NUMBERS(F) \ FOR_EACH_INTRINSIC_OBJECT(F) \ FOR_EACH_INTRINSIC_OBSERVE(F) \ + FOR_EACH_INTRINSIC_OPERATORS(F) \ FOR_EACH_INTRINSIC_PROXY(F) \ FOR_EACH_INTRINSIC_REGEXP(F) \ FOR_EACH_INTRINSIC_SCOPES(F) \ diff --git a/test/cctest/compiler/test-run-jscalls.cc b/test/cctest/compiler/test-run-jscalls.cc index ed3a0b412a..63c12bfc08 100644 --- a/test/cctest/compiler/test-run-jscalls.cc +++ b/test/cctest/compiler/test-run-jscalls.cc @@ -134,11 +134,10 @@ TEST(ConstructorCall) { // TODO(titzer): factor these out into test-runtime-calls.cc TEST(RuntimeCallCPP2) { FLAG_allow_natives_syntax = true; - FunctionTester T("(function(a,b) { return %NumberAdd(a, b); })"); + FunctionTester T("(function(a,b) { return %NumberImul(a, b); })"); - T.CheckCall(T.Val(65), T.Val(42), T.Val(23)); - T.CheckCall(T.Val(19), T.Val(42), T.Val(-23)); - T.CheckCall(T.Val(6.5), T.Val(4.2), T.Val(2.3)); + T.CheckCall(T.Val(2730), T.Val(42), T.Val(65)); + T.CheckCall(T.Val(798), T.Val(42), T.Val(19)); } diff --git a/test/mjsunit/stack-traces-2.js b/test/mjsunit/stack-traces-2.js index 3bec963701..a54bb45ff5 100644 --- a/test/mjsunit/stack-traces-2.js +++ b/test/mjsunit/stack-traces-2.js @@ -82,6 +82,3 @@ testTraceNativeConstructor(Date); // Does ToNumber on argument. testNotOmittedBuiltin(function(){ [thrower, 2].sort(function (a,b) { (b < a) - (a < b); }); }, "QuickSort"); - -// Not omitted even though ADD from runtime.js is a non-native builtin. -testNotOmittedBuiltin(function(){ thrower + 2; }, "ADD"); diff --git a/test/unittests/compiler/interpreter-assembler-unittest.cc b/test/unittests/compiler/interpreter-assembler-unittest.cc index 9e6eff36da..1dfaf58ba0 100644 --- a/test/unittests/compiler/interpreter-assembler-unittest.cc +++ b/test/unittests/compiler/interpreter-assembler-unittest.cc @@ -328,33 +328,15 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadObjectField) { } -TARGET_TEST_F(InterpreterAssemblerTest, CallJSBuiltin) { +TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { InterpreterAssemblerForTest m(this, bytecode); - Node* receiver = m.IntPtrConstant(1234); - Node* call_js_builtin_0 = - m.CallJSBuiltin(Context::SUB_BUILTIN_INDEX, receiver); - - Matcher load_globals_matcher = m.IsLoad( - kMachAnyTagged, IsParameter(Linkage::kInterpreterContextParameter), - IsIntPtrConstant(Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); - Matcher load_native_context_matcher = m.IsLoad( - kMachAnyTagged, load_globals_matcher, - IsIntPtrConstant(GlobalObject::kNativeContextOffset - kHeapObjectTag)); - Matcher function_matcher = m.IsLoad( - kMachAnyTagged, load_native_context_matcher, - IsIntPtrConstant(Context::SlotOffset(Context::SUB_BUILTIN_INDEX))); - Matcher context_matcher = - m.IsLoad(kMachAnyTagged, function_matcher, - IsIntPtrConstant(JSFunction::kContextOffset - kHeapObjectTag)); - EXPECT_THAT(call_js_builtin_0, - m.IsCall(_, function_matcher, receiver, context_matcher)); - - Node* arg1 = m.Int32Constant(0xabcd); - Node* call_js_builtin_1 = - m.CallJSBuiltin(Context::SUB_BUILTIN_INDEX, receiver, arg1); - EXPECT_THAT(call_js_builtin_1, - m.IsCall(_, function_matcher, receiver, arg1, context_matcher)); + Node* arg1 = m.Int32Constant(2); + Node* arg2 = m.Int32Constant(3); + Node* call_runtime = m.CallRuntime(Runtime::kAdd, arg1, arg2); + EXPECT_THAT(call_runtime, + m.IsCall(_, _, arg1, arg2, _, IsInt32Constant(2), + IsParameter(Linkage::kInterpreterContextParameter))); } } diff --git a/test/webkit/function-apply-aliased-expected.txt b/test/webkit/function-apply-aliased-expected.txt index 8007e1a546..01962d341c 100644 --- a/test/webkit/function-apply-aliased-expected.txt +++ b/test/webkit/function-apply-aliased-expected.txt @@ -45,8 +45,6 @@ PASS myFunctionWithApply.aliasedApply(myObject, ['arg1']) is [myObject, "myFunct PASS myFunctionWithApply.apply(myObject, arg1Array) is [myFunctionWithApply, "myFunctionWithApply.apply", myObject] PASS forwarder(myFunctionWithApply, myObject, arg1Array) is [myFunctionWithApply, "myFunctionWithApply.apply", myObject] PASS myFunctionWithApply.aliasedApply(myObject, arg1Array) is [myObject, "myFunctionWithApply", "arg1"] -PASS myFunction.apply(null, new Array(500000)) threw exception RangeError: Maximum call stack size exceeded. -PASS myFunction.apply(null, new Array(1 << 30)) threw exception RangeError: Maximum call stack size exceeded. PASS recurseArguments.apply(null, new Array(50000)) threw exception RangeError: Maximum call stack size exceeded. PASS successfullyParsed is true diff --git a/test/webkit/function-apply-aliased.js b/test/webkit/function-apply-aliased.js index a6a7ff4533..4c46c6c66a 100644 --- a/test/webkit/function-apply-aliased.js +++ b/test/webkit/function-apply-aliased.js @@ -68,18 +68,5 @@ shouldBe("myFunctionWithApply.apply(myObject, arg1Array)", '[myFunctionWithApply shouldBe("forwarder(myFunctionWithApply, myObject, arg1Array)", '[myFunctionWithApply, "myFunctionWithApply.apply", myObject]'); shouldBe("myFunctionWithApply.aliasedApply(myObject, arg1Array)", '[myObject, "myFunctionWithApply", "arg1"]'); -function stackOverflowTest() { - try { - var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z; - stackOverflowTest(); - } catch(e) { - // Blow the stack with a sparse array - shouldThrow("myFunction.apply(null, new Array(500000))"); - // Blow the stack with a sparse array that is sufficiently large to cause int overflow - shouldThrow("myFunction.apply(null, new Array(1 << 30))"); - } -} -stackOverflowTest(); - // Blow the stack recursing with arguments shouldThrow("recurseArguments.apply(null, new Array(50000))"); diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp index 808098e2b1..ef56b91ea5 100644 --- a/tools/gyp/v8.gyp +++ b/tools/gyp/v8.gyp @@ -911,6 +911,7 @@ '../../src/runtime/runtime-numbers.cc', '../../src/runtime/runtime-object.cc', '../../src/runtime/runtime-observe.cc', + '../../src/runtime/runtime-operators.cc', '../../src/runtime/runtime-proxy.cc', '../../src/runtime/runtime-regexp.cc', '../../src/runtime/runtime-scopes.cc',