11b268ca467c924004286c97bac133db489cf43d0Ben Murdoch// Copyright 2015 the V8 project authors. All rights reserved. 21b268ca467c924004286c97bac133db489cf43d0Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 31b268ca467c924004286c97bac133db489cf43d0Ben Murdoch// found in the LICENSE file. 41b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 51b268ca467c924004286c97bac133db489cf43d0Ben Murdoch#include "src/interpreter/interpreter-intrinsics.h" 61b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#include "src/code-factory.h" 821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 91b268ca467c924004286c97bac133db489cf43d0Ben Murdochnamespace v8 { 101b268ca467c924004286c97bac133db489cf43d0Ben Murdochnamespace internal { 111b268ca467c924004286c97bac133db489cf43d0Ben Murdochnamespace interpreter { 121b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 131b268ca467c924004286c97bac133db489cf43d0Ben Murdochusing compiler::Node; 141b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 151b268ca467c924004286c97bac133db489cf43d0Ben Murdoch#define __ assembler_-> 161b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 171b268ca467c924004286c97bac133db489cf43d0Ben MurdochIntrinsicsHelper::IntrinsicsHelper(InterpreterAssembler* assembler) 1821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch : isolate_(assembler->isolate()), 1921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch zone_(assembler->zone()), 2021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch assembler_(assembler) {} 211b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 2221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch// static 231b268ca467c924004286c97bac133db489cf43d0Ben Murdochbool IntrinsicsHelper::IsSupported(Runtime::FunctionId function_id) { 241b268ca467c924004286c97bac133db489cf43d0Ben Murdoch switch (function_id) { 251b268ca467c924004286c97bac133db489cf43d0Ben Murdoch#define SUPPORTED(name, lower_case, count) case Runtime::kInline##name: 261b268ca467c924004286c97bac133db489cf43d0Ben Murdoch INTRINSICS_LIST(SUPPORTED) 271b268ca467c924004286c97bac133db489cf43d0Ben Murdoch return true; 281b268ca467c924004286c97bac133db489cf43d0Ben Murdoch#undef SUPPORTED 291b268ca467c924004286c97bac133db489cf43d0Ben Murdoch default: 301b268ca467c924004286c97bac133db489cf43d0Ben Murdoch return false; 311b268ca467c924004286c97bac133db489cf43d0Ben Murdoch } 321b268ca467c924004286c97bac133db489cf43d0Ben Murdoch} 331b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 3421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch// static 3521efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochIntrinsicsHelper::IntrinsicId IntrinsicsHelper::FromRuntimeId( 3621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Runtime::FunctionId function_id) { 3721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch switch (function_id) { 3821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#define TO_RUNTIME_ID(name, lower_case, count) \ 3921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch case Runtime::kInline##name: \ 4021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return IntrinsicId::k##name; 4121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch INTRINSICS_LIST(TO_RUNTIME_ID) 4221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#undef TO_RUNTIME_ID 4321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch default: 4421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch UNREACHABLE(); 4521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return static_cast<IntrinsicsHelper::IntrinsicId>(-1); 4621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch } 4721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 4821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 4921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch// static 5021efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochRuntime::FunctionId IntrinsicsHelper::ToRuntimeId( 5121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch IntrinsicsHelper::IntrinsicId intrinsic_id) { 5221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch switch (intrinsic_id) { 5321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#define TO_INTRINSIC_ID(name, lower_case, count) \ 5421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch case IntrinsicId::k##name: \ 5521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return Runtime::kInline##name; 5621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch INTRINSICS_LIST(TO_INTRINSIC_ID) 5721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#undef TO_INTRINSIC_ID 5821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch default: 5921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch UNREACHABLE(); 6021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return static_cast<Runtime::FunctionId>(-1); 6121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch } 6221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 6321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 641b268ca467c924004286c97bac133db489cf43d0Ben MurdochNode* IntrinsicsHelper::InvokeIntrinsic(Node* function_id, Node* context, 651b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Node* first_arg_reg, Node* arg_count) { 661b268ca467c924004286c97bac133db489cf43d0Ben Murdoch InterpreterAssembler::Label abort(assembler_), end(assembler_); 671b268ca467c924004286c97bac133db489cf43d0Ben Murdoch InterpreterAssembler::Variable result(assembler_, 681b268ca467c924004286c97bac133db489cf43d0Ben Murdoch MachineRepresentation::kTagged); 691b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 701b268ca467c924004286c97bac133db489cf43d0Ben Murdoch#define MAKE_LABEL(name, lower_case, count) \ 711b268ca467c924004286c97bac133db489cf43d0Ben Murdoch InterpreterAssembler::Label lower_case(assembler_); 721b268ca467c924004286c97bac133db489cf43d0Ben Murdoch INTRINSICS_LIST(MAKE_LABEL) 731b268ca467c924004286c97bac133db489cf43d0Ben Murdoch#undef MAKE_LABEL 741b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 751b268ca467c924004286c97bac133db489cf43d0Ben Murdoch#define LABEL_POINTER(name, lower_case, count) &lower_case, 761b268ca467c924004286c97bac133db489cf43d0Ben Murdoch InterpreterAssembler::Label* labels[] = {INTRINSICS_LIST(LABEL_POINTER)}; 771b268ca467c924004286c97bac133db489cf43d0Ben Murdoch#undef LABEL_POINTER 781b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 791b268ca467c924004286c97bac133db489cf43d0Ben Murdoch#define CASE(name, lower_case, count) \ 8021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch static_cast<int32_t>(IntrinsicId::k##name), 811b268ca467c924004286c97bac133db489cf43d0Ben Murdoch int32_t cases[] = {INTRINSICS_LIST(CASE)}; 821b268ca467c924004286c97bac133db489cf43d0Ben Murdoch#undef CASE 831b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 841b268ca467c924004286c97bac133db489cf43d0Ben Murdoch __ Switch(function_id, &abort, cases, labels, arraysize(cases)); 851b268ca467c924004286c97bac133db489cf43d0Ben Murdoch#define HANDLE_CASE(name, lower_case, expected_arg_count) \ 861b268ca467c924004286c97bac133db489cf43d0Ben Murdoch __ Bind(&lower_case); \ 8721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (FLAG_debug_code && expected_arg_count >= 0) { \ 881b268ca467c924004286c97bac133db489cf43d0Ben Murdoch AbortIfArgCountMismatch(expected_arg_count, arg_count); \ 891b268ca467c924004286c97bac133db489cf43d0Ben Murdoch } \ 9021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch result.Bind(name(first_arg_reg, arg_count, context)); \ 911b268ca467c924004286c97bac133db489cf43d0Ben Murdoch __ Goto(&end); 921b268ca467c924004286c97bac133db489cf43d0Ben Murdoch INTRINSICS_LIST(HANDLE_CASE) 931b268ca467c924004286c97bac133db489cf43d0Ben Murdoch#undef HANDLE_CASE 941b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 951b268ca467c924004286c97bac133db489cf43d0Ben Murdoch __ Bind(&abort); 9621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch { 9721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Abort(BailoutReason::kUnexpectedFunctionIDForInvokeIntrinsic); 9821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch result.Bind(__ UndefinedConstant()); 9921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Goto(&end); 10021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch } 1011b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 1021b268ca467c924004286c97bac133db489cf43d0Ben Murdoch __ Bind(&end); 1031b268ca467c924004286c97bac133db489cf43d0Ben Murdoch return result.value(); 1041b268ca467c924004286c97bac133db489cf43d0Ben Murdoch} 1051b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 1061b268ca467c924004286c97bac133db489cf43d0Ben MurdochNode* IntrinsicsHelper::CompareInstanceType(Node* map, int type, 1071b268ca467c924004286c97bac133db489cf43d0Ben Murdoch InstanceTypeCompareMode mode) { 1081b268ca467c924004286c97bac133db489cf43d0Ben Murdoch InterpreterAssembler::Variable return_value(assembler_, 1091b268ca467c924004286c97bac133db489cf43d0Ben Murdoch MachineRepresentation::kTagged); 1101b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Node* instance_type = __ LoadInstanceType(map); 1111b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 1121b268ca467c924004286c97bac133db489cf43d0Ben Murdoch InterpreterAssembler::Label if_true(assembler_), if_false(assembler_), 1131b268ca467c924004286c97bac133db489cf43d0Ben Murdoch end(assembler_); 1141b268ca467c924004286c97bac133db489cf43d0Ben Murdoch if (mode == kInstanceTypeEqual) { 11521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return __ Word32Equal(instance_type, __ Int32Constant(type)); 1161b268ca467c924004286c97bac133db489cf43d0Ben Murdoch } else { 1171b268ca467c924004286c97bac133db489cf43d0Ben Murdoch DCHECK(mode == kInstanceTypeGreaterThanOrEqual); 11821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return __ Int32GreaterThanOrEqual(instance_type, __ Int32Constant(type)); 1191b268ca467c924004286c97bac133db489cf43d0Ben Murdoch } 12021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 1211b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 12221efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::IsInstanceType(Node* input, int type) { 12321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch InterpreterAssembler::Variable return_value(assembler_, 12421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch MachineRepresentation::kTagged); 12521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch InterpreterAssembler::Label if_not_smi(assembler_), return_true(assembler_), 12621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return_false(assembler_), end(assembler_); 12721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Node* arg = __ LoadRegister(input); 12821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ GotoIf(__ WordIsSmi(arg), &return_false); 1291b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 13021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Node* condition = CompareInstanceType(arg, type, kInstanceTypeEqual); 13121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Branch(condition, &return_true, &return_false); 13221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 13321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Bind(&return_true); 13421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch { 13521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return_value.Bind(__ BooleanConstant(true)); 13621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Goto(&end); 13721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch } 13821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 13921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Bind(&return_false); 14021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch { 14121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return_value.Bind(__ BooleanConstant(false)); 14221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Goto(&end); 14321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch } 1441b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 1451b268ca467c924004286c97bac133db489cf43d0Ben Murdoch __ Bind(&end); 1461b268ca467c924004286c97bac133db489cf43d0Ben Murdoch return return_value.value(); 1471b268ca467c924004286c97bac133db489cf43d0Ben Murdoch} 1481b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 14921efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::IsJSReceiver(Node* input, Node* arg_count, 15021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Node* context) { 1511b268ca467c924004286c97bac133db489cf43d0Ben Murdoch InterpreterAssembler::Variable return_value(assembler_, 1521b268ca467c924004286c97bac133db489cf43d0Ben Murdoch MachineRepresentation::kTagged); 15321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch InterpreterAssembler::Label return_true(assembler_), return_false(assembler_), 1541b268ca467c924004286c97bac133db489cf43d0Ben Murdoch end(assembler_); 1551b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 15621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Node* arg = __ LoadRegister(input); 15721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ GotoIf(__ WordIsSmi(arg), &return_false); 1581b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 1591b268ca467c924004286c97bac133db489cf43d0Ben Murdoch STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); 16021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Node* condition = CompareInstanceType(arg, FIRST_JS_RECEIVER_TYPE, 16121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch kInstanceTypeGreaterThanOrEqual); 16221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Branch(condition, &return_true, &return_false); 16321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 16421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Bind(&return_true); 16521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch { 16621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return_value.Bind(__ BooleanConstant(true)); 16721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Goto(&end); 16821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch } 16921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 17021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Bind(&return_false); 17121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch { 17221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return_value.Bind(__ BooleanConstant(false)); 17321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Goto(&end); 17421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch } 1751b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 1761b268ca467c924004286c97bac133db489cf43d0Ben Murdoch __ Bind(&end); 1771b268ca467c924004286c97bac133db489cf43d0Ben Murdoch return return_value.value(); 1781b268ca467c924004286c97bac133db489cf43d0Ben Murdoch} 1791b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 18021efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::IsArray(Node* input, Node* arg_count, Node* context) { 18121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return IsInstanceType(input, JS_ARRAY_TYPE); 18221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 18321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 18421efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::IsJSProxy(Node* input, Node* arg_count, Node* context) { 18521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return IsInstanceType(input, JS_PROXY_TYPE); 18621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 18721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 18821efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::IsRegExp(Node* input, Node* arg_count, Node* context) { 18921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return IsInstanceType(input, JS_REGEXP_TYPE); 19021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 19121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 19221efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::IsTypedArray(Node* input, Node* arg_count, 19321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Node* context) { 19421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return IsInstanceType(input, JS_TYPED_ARRAY_TYPE); 19521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 19621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 19721efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::IsSmi(Node* input, Node* arg_count, Node* context) { 1981b268ca467c924004286c97bac133db489cf43d0Ben Murdoch InterpreterAssembler::Variable return_value(assembler_, 1991b268ca467c924004286c97bac133db489cf43d0Ben Murdoch MachineRepresentation::kTagged); 2001b268ca467c924004286c97bac133db489cf43d0Ben Murdoch InterpreterAssembler::Label if_smi(assembler_), if_not_smi(assembler_), 2011b268ca467c924004286c97bac133db489cf43d0Ben Murdoch end(assembler_); 20221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 2031b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Node* arg = __ LoadRegister(input); 2041b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 2051b268ca467c924004286c97bac133db489cf43d0Ben Murdoch __ Branch(__ WordIsSmi(arg), &if_smi, &if_not_smi); 2061b268ca467c924004286c97bac133db489cf43d0Ben Murdoch __ Bind(&if_smi); 20721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch { 20821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return_value.Bind(__ BooleanConstant(true)); 20921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Goto(&end); 21021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch } 2111b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 2121b268ca467c924004286c97bac133db489cf43d0Ben Murdoch __ Bind(&if_not_smi); 21321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch { 21421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return_value.Bind(__ BooleanConstant(false)); 21521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Goto(&end); 21621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch } 2171b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 2181b268ca467c924004286c97bac133db489cf43d0Ben Murdoch __ Bind(&end); 2191b268ca467c924004286c97bac133db489cf43d0Ben Murdoch return return_value.value(); 2201b268ca467c924004286c97bac133db489cf43d0Ben Murdoch} 2211b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 22221efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::IntrinsicAsStubCall(Node* args_reg, Node* context, 22321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Callable const& callable) { 22421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch int param_count = callable.descriptor().GetParameterCount(); 22521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Node** args = zone()->NewArray<Node*>(param_count + 1); // 1 for context 22621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch for (int i = 0; i < param_count; i++) { 22721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch args[i] = __ LoadRegister(args_reg); 22821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch args_reg = __ NextRegister(args_reg); 22921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch } 23021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch args[param_count] = context; 23121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 23221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return __ CallStubN(callable, args); 23321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 23421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 23521efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::HasProperty(Node* input, Node* arg_count, 23621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Node* context) { 23721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return IntrinsicAsStubCall(input, context, 23821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch CodeFactory::HasProperty(isolate())); 23921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 24021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 24121efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::MathPow(Node* input, Node* arg_count, Node* context) { 24221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return IntrinsicAsStubCall(input, context, CodeFactory::MathPow(isolate())); 24321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 24421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 24521efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::NewObject(Node* input, Node* arg_count, Node* context) { 24621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return IntrinsicAsStubCall(input, context, 24721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch CodeFactory::FastNewObject(isolate())); 24821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 24921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 25021efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::NumberToString(Node* input, Node* arg_count, 25121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Node* context) { 25221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return IntrinsicAsStubCall(input, context, 25321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch CodeFactory::NumberToString(isolate())); 25421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 25521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 25621efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::RegExpConstructResult(Node* input, Node* arg_count, 25721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Node* context) { 25821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return IntrinsicAsStubCall(input, context, 25921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch CodeFactory::RegExpConstructResult(isolate())); 26021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 26121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 26221efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::RegExpExec(Node* input, Node* arg_count, 26321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Node* context) { 26421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return IntrinsicAsStubCall(input, context, 26521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch CodeFactory::RegExpExec(isolate())); 26621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 26721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 26821efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::SubString(Node* input, Node* arg_count, Node* context) { 26921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return IntrinsicAsStubCall(input, context, CodeFactory::SubString(isolate())); 27021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 27121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 27221efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::ToString(Node* input, Node* arg_count, Node* context) { 27321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return IntrinsicAsStubCall(input, context, CodeFactory::ToString(isolate())); 27421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 27521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 27621efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::ToName(Node* input, Node* arg_count, Node* context) { 27721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return IntrinsicAsStubCall(input, context, CodeFactory::ToName(isolate())); 27821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 27921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 28021efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::ToLength(Node* input, Node* arg_count, Node* context) { 28121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return IntrinsicAsStubCall(input, context, CodeFactory::ToLength(isolate())); 28221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 28321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 28421efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::ToInteger(Node* input, Node* arg_count, Node* context) { 28521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return IntrinsicAsStubCall(input, context, CodeFactory::ToInteger(isolate())); 28621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 28721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 28821efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::ToNumber(Node* input, Node* arg_count, Node* context) { 28921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return IntrinsicAsStubCall(input, context, CodeFactory::ToNumber(isolate())); 29021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 29121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 29221efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::ToObject(Node* input, Node* arg_count, Node* context) { 29321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return IntrinsicAsStubCall(input, context, CodeFactory::ToObject(isolate())); 29421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 29521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 29621efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::Call(Node* args_reg, Node* arg_count, Node* context) { 29721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch // First argument register contains the function target. 29821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Node* function = __ LoadRegister(args_reg); 29921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 30021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch // Receiver is the second runtime call argument. 30121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Node* receiver_reg = __ NextRegister(args_reg); 30221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Node* receiver_arg = __ RegisterLocation(receiver_reg); 30321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 30421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch // Subtract function and receiver from arg count. 30521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Node* function_and_receiver_count = __ Int32Constant(2); 30621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Node* target_args_count = __ Int32Sub(arg_count, function_and_receiver_count); 30721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 30821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (FLAG_debug_code) { 30921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch InterpreterAssembler::Label arg_count_positive(assembler_); 31021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Node* comparison = __ Int32LessThan(target_args_count, __ Int32Constant(0)); 31121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ GotoUnless(comparison, &arg_count_positive); 31221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Abort(kWrongArgumentCountForInvokeIntrinsic); 31321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Goto(&arg_count_positive); 31421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Bind(&arg_count_positive); 31521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch } 31621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 31721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Node* result = __ CallJS(function, context, receiver_arg, target_args_count, 31821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch TailCallMode::kDisallow); 31921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return result; 32021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 32121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 32221efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochNode* IntrinsicsHelper::ValueOf(Node* args_reg, Node* arg_count, 32321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Node* context) { 32421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch InterpreterAssembler::Variable return_value(assembler_, 32521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch MachineRepresentation::kTagged); 32621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch InterpreterAssembler::Label done(assembler_); 32721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 32821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Node* object = __ LoadRegister(args_reg); 32921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return_value.Bind(object); 33021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 33121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch // If the object is a smi return the object. 33221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ GotoIf(__ WordIsSmi(object), &done); 33321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 33421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch // If the object is not a value type, return the object. 33521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Node* condition = 33621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch CompareInstanceType(object, JS_VALUE_TYPE, kInstanceTypeEqual); 33721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ GotoUnless(condition, &done); 33821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 33921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch // If the object is a value type, return the value field. 34021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return_value.Bind(__ LoadObjectField(object, JSValue::kValueOffset)); 34121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Goto(&done); 34221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 34321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Bind(&done); 34421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return return_value.value(); 34521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 34621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 3471b268ca467c924004286c97bac133db489cf43d0Ben Murdochvoid IntrinsicsHelper::AbortIfArgCountMismatch(int expected, Node* actual) { 34821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch InterpreterAssembler::Label match(assembler_); 3491b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Node* comparison = __ Word32Equal(actual, __ Int32Constant(expected)); 35021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ GotoIf(comparison, &match); 3511b268ca467c924004286c97bac133db489cf43d0Ben Murdoch __ Abort(kWrongArgumentCountForInvokeIntrinsic); 35221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Goto(&match); 3531b268ca467c924004286c97bac133db489cf43d0Ben Murdoch __ Bind(&match); 3541b268ca467c924004286c97bac133db489cf43d0Ben Murdoch} 3551b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 3561b268ca467c924004286c97bac133db489cf43d0Ben Murdoch} // namespace interpreter 3571b268ca467c924004286c97bac133db489cf43d0Ben Murdoch} // namespace internal 3581b268ca467c924004286c97bac133db489cf43d0Ben Murdoch} // namespace v8 359