13b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// Copyright 2015 the V8 project authors. All rights reserved. 23b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 33b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// found in the LICENSE file. 43b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 53b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#include "src/interpreter/interpreter-intrinsics.h" 63b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/code-factory.h" 862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects-inl.h" 913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochnamespace v8 { 113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochnamespace internal { 123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochnamespace interpreter { 133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochusing compiler::Node; 153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#define __ assembler_-> 173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochIntrinsicsHelper::IntrinsicsHelper(InterpreterAssembler* assembler) 1913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch : isolate_(assembler->isolate()), 2013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch zone_(assembler->zone()), 2113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch assembler_(assembler) {} 223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 2313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// static 243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochbool IntrinsicsHelper::IsSupported(Runtime::FunctionId function_id) { 253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch switch (function_id) { 263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#define SUPPORTED(name, lower_case, count) case Runtime::kInline##name: 273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch INTRINSICS_LIST(SUPPORTED) 283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return true; 293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#undef SUPPORTED 303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch default: 313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return false; 323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 3513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// static 3613e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochIntrinsicsHelper::IntrinsicId IntrinsicsHelper::FromRuntimeId( 3713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Runtime::FunctionId function_id) { 3813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch switch (function_id) { 3913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#define TO_RUNTIME_ID(name, lower_case, count) \ 4013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case Runtime::kInline##name: \ 4113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return IntrinsicId::k##name; 4213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch INTRINSICS_LIST(TO_RUNTIME_ID) 4313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#undef TO_RUNTIME_ID 4413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch default: 4513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch UNREACHABLE(); 4613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return static_cast<IntrinsicsHelper::IntrinsicId>(-1); 4713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 4813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 4913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 5013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// static 5113e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochRuntime::FunctionId IntrinsicsHelper::ToRuntimeId( 5213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch IntrinsicsHelper::IntrinsicId intrinsic_id) { 5313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch switch (intrinsic_id) { 5413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#define TO_INTRINSIC_ID(name, lower_case, count) \ 5513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case IntrinsicId::k##name: \ 5613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return Runtime::kInline##name; 5713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch INTRINSICS_LIST(TO_INTRINSIC_ID) 5813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#undef TO_INTRINSIC_ID 5913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch default: 6013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch UNREACHABLE(); 6113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return static_cast<Runtime::FunctionId>(-1); 6213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 6313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 6413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochNode* IntrinsicsHelper::InvokeIntrinsic(Node* function_id, Node* context, 663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* first_arg_reg, Node* arg_count) { 673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch InterpreterAssembler::Label abort(assembler_), end(assembler_); 683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch InterpreterAssembler::Variable result(assembler_, 693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch MachineRepresentation::kTagged); 703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#define MAKE_LABEL(name, lower_case, count) \ 723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch InterpreterAssembler::Label lower_case(assembler_); 733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch INTRINSICS_LIST(MAKE_LABEL) 743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#undef MAKE_LABEL 753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#define LABEL_POINTER(name, lower_case, count) &lower_case, 773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch InterpreterAssembler::Label* labels[] = {INTRINSICS_LIST(LABEL_POINTER)}; 783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#undef LABEL_POINTER 793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#define CASE(name, lower_case, count) \ 8113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static_cast<int32_t>(IntrinsicId::k##name), 823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int32_t cases[] = {INTRINSICS_LIST(CASE)}; 833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#undef CASE 843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Switch(function_id, &abort, cases, labels, arraysize(cases)); 863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#define HANDLE_CASE(name, lower_case, expected_arg_count) \ 873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Bind(&lower_case); \ 8813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (FLAG_debug_code && expected_arg_count >= 0) { \ 893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch AbortIfArgCountMismatch(expected_arg_count, arg_count); \ 903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } \ 9113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch result.Bind(name(first_arg_reg, arg_count, context)); \ 923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Goto(&end); 933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch INTRINSICS_LIST(HANDLE_CASE) 943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#undef HANDLE_CASE 953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Bind(&abort); 9713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch { 9813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Abort(BailoutReason::kUnexpectedFunctionIDForInvokeIntrinsic); 9913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch result.Bind(__ UndefinedConstant()); 10013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Goto(&end); 10113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 1023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Bind(&end); 1043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return result.value(); 1053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 1063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 107f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochNode* IntrinsicsHelper::CompareInstanceType(Node* object, int type, 1083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch InstanceTypeCompareMode mode) { 109f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* instance_type = __ LoadInstanceType(object); 1103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (mode == kInstanceTypeEqual) { 11213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return __ Word32Equal(instance_type, __ Int32Constant(type)); 1133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 1143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(mode == kInstanceTypeGreaterThanOrEqual); 11513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return __ Int32GreaterThanOrEqual(instance_type, __ Int32Constant(type)); 1163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 11713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 1183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 11913e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* IntrinsicsHelper::IsInstanceType(Node* input, int type) { 12013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch InterpreterAssembler::Variable return_value(assembler_, 12113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch MachineRepresentation::kTagged); 12262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // TODO(ishell): Use Select here. 12313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch InterpreterAssembler::Label if_not_smi(assembler_), return_true(assembler_), 12413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return_false(assembler_), end(assembler_); 12513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* arg = __ LoadRegister(input); 126c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ GotoIf(__ TaggedIsSmi(arg), &return_false); 1273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 12813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* condition = CompareInstanceType(arg, type, kInstanceTypeEqual); 12913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Branch(condition, &return_true, &return_false); 13013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 13113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Bind(&return_true); 13213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch { 13313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return_value.Bind(__ BooleanConstant(true)); 13413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Goto(&end); 13513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 13613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 13713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Bind(&return_false); 13813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch { 13913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return_value.Bind(__ BooleanConstant(false)); 14013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Goto(&end); 14113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 1423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Bind(&end); 1443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return return_value.value(); 1453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 1463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 14713e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* IntrinsicsHelper::IsJSReceiver(Node* input, Node* arg_count, 14813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* context) { 14962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // TODO(ishell): Use Select here. 15062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // TODO(ishell): Use CSA::IsJSReceiverInstanceType here. 1513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch InterpreterAssembler::Variable return_value(assembler_, 1523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch MachineRepresentation::kTagged); 15313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch InterpreterAssembler::Label return_true(assembler_), return_false(assembler_), 1543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch end(assembler_); 1553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 15613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* arg = __ LoadRegister(input); 157c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ GotoIf(__ TaggedIsSmi(arg), &return_false); 1583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); 16013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* condition = CompareInstanceType(arg, FIRST_JS_RECEIVER_TYPE, 16113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch kInstanceTypeGreaterThanOrEqual); 16213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Branch(condition, &return_true, &return_false); 16313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 16413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Bind(&return_true); 16513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch { 16613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return_value.Bind(__ BooleanConstant(true)); 16713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Goto(&end); 16813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 16913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 17013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Bind(&return_false); 17113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch { 17213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return_value.Bind(__ BooleanConstant(false)); 17313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Goto(&end); 17413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 1753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Bind(&end); 1773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return return_value.value(); 1783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 1793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 18013e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* IntrinsicsHelper::IsArray(Node* input, Node* arg_count, Node* context) { 18113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return IsInstanceType(input, JS_ARRAY_TYPE); 18213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 18313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 18413e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* IntrinsicsHelper::IsJSProxy(Node* input, Node* arg_count, Node* context) { 18513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return IsInstanceType(input, JS_PROXY_TYPE); 18613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 18713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 18813e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* IntrinsicsHelper::IsTypedArray(Node* input, Node* arg_count, 18913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* context) { 19013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return IsInstanceType(input, JS_TYPED_ARRAY_TYPE); 19113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 19213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 19313e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* IntrinsicsHelper::IsSmi(Node* input, Node* arg_count, Node* context) { 19462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // TODO(ishell): Use SelectBooleanConstant here. 1953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch InterpreterAssembler::Variable return_value(assembler_, 1963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch MachineRepresentation::kTagged); 1973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch InterpreterAssembler::Label if_smi(assembler_), if_not_smi(assembler_), 1983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch end(assembler_); 19913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 2003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* arg = __ LoadRegister(input); 2013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 202c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ Branch(__ TaggedIsSmi(arg), &if_smi, &if_not_smi); 2033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Bind(&if_smi); 20413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch { 20513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return_value.Bind(__ BooleanConstant(true)); 20613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Goto(&end); 20713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 2083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 2093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Bind(&if_not_smi); 21013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch { 21113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return_value.Bind(__ BooleanConstant(false)); 21213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Goto(&end); 21313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 2143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 2153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Bind(&end); 2163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return return_value.value(); 2173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 2183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 21913e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* IntrinsicsHelper::IntrinsicAsStubCall(Node* args_reg, Node* context, 22013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Callable const& callable) { 22113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch int param_count = callable.descriptor().GetParameterCount(); 22262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int input_count = param_count + 2; // +2 for target and context 22362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node** args = zone()->NewArray<Node*>(input_count); 22462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int index = 0; 22562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch args[index++] = __ HeapConstant(callable.code()); 22613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch for (int i = 0; i < param_count; i++) { 22762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch args[index++] = __ LoadRegister(args_reg); 22813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch args_reg = __ NextRegister(args_reg); 22913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 23062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch args[index++] = context; 23162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return __ CallStubN(callable.descriptor(), 1, input_count, args); 23262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 23313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 23462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* IntrinsicsHelper::CreateIterResultObject(Node* input, Node* arg_count, 23562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* context) { 23662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return IntrinsicAsStubCall(input, context, 23762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CodeFactory::CreateIterResultObject(isolate())); 23813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 23913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 24013e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* IntrinsicsHelper::HasProperty(Node* input, Node* arg_count, 24113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* context) { 24213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return IntrinsicAsStubCall(input, context, 24313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch CodeFactory::HasProperty(isolate())); 24413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 24513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 24613e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* IntrinsicsHelper::SubString(Node* input, Node* arg_count, Node* context) { 24713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return IntrinsicAsStubCall(input, context, CodeFactory::SubString(isolate())); 24813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 24913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 25013e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* IntrinsicsHelper::ToString(Node* input, Node* arg_count, Node* context) { 25113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return IntrinsicAsStubCall(input, context, CodeFactory::ToString(isolate())); 25213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 25313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 25413e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* IntrinsicsHelper::ToLength(Node* input, Node* arg_count, Node* context) { 25513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return IntrinsicAsStubCall(input, context, CodeFactory::ToLength(isolate())); 25613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 25713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 25813e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* IntrinsicsHelper::ToInteger(Node* input, Node* arg_count, Node* context) { 25913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return IntrinsicAsStubCall(input, context, CodeFactory::ToInteger(isolate())); 26013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 26113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 26213e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* IntrinsicsHelper::ToNumber(Node* input, Node* arg_count, Node* context) { 26313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return IntrinsicAsStubCall(input, context, CodeFactory::ToNumber(isolate())); 26413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 26513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 26613e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* IntrinsicsHelper::ToObject(Node* input, Node* arg_count, Node* context) { 26713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return IntrinsicAsStubCall(input, context, CodeFactory::ToObject(isolate())); 26813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 26913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 27013e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* IntrinsicsHelper::Call(Node* args_reg, Node* arg_count, Node* context) { 27113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // First argument register contains the function target. 27213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* function = __ LoadRegister(args_reg); 27313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 27413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Receiver is the second runtime call argument. 27513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* receiver_reg = __ NextRegister(args_reg); 27613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* receiver_arg = __ RegisterLocation(receiver_reg); 27713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 27813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Subtract function and receiver from arg count. 27913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* function_and_receiver_count = __ Int32Constant(2); 28013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* target_args_count = __ Int32Sub(arg_count, function_and_receiver_count); 28113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 28213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (FLAG_debug_code) { 28313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch InterpreterAssembler::Label arg_count_positive(assembler_); 28413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* comparison = __ Int32LessThan(target_args_count, __ Int32Constant(0)); 28562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ GotoIfNot(comparison, &arg_count_positive); 28613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Abort(kWrongArgumentCountForInvokeIntrinsic); 28713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Goto(&arg_count_positive); 28813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Bind(&arg_count_positive); 28913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 29013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 29113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* result = __ CallJS(function, context, receiver_arg, target_args_count, 29213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch TailCallMode::kDisallow); 29313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return result; 29413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 29513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 29662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* IntrinsicsHelper::ClassOf(Node* args_reg, Node* arg_count, 29713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* context) { 29862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* value = __ LoadRegister(args_reg); 29962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return __ ClassOf(value); 30062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 30162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 30262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* IntrinsicsHelper::CreateAsyncFromSyncIterator(Node* args_reg, 30362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* arg_count, 30462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* context) { 30562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InterpreterAssembler::Label not_receiver( 30662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch assembler_, InterpreterAssembler::Label::kDeferred); 30762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InterpreterAssembler::Label done(assembler_); 30813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch InterpreterAssembler::Variable return_value(assembler_, 30913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch MachineRepresentation::kTagged); 31013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 31162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* sync_iterator = __ LoadRegister(args_reg); 31213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 31362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ GotoIf(__ TaggedIsSmi(sync_iterator), ¬_receiver); 31462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ GotoIfNot(__ IsJSReceiver(sync_iterator), ¬_receiver); 31513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 31662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* const native_context = __ LoadNativeContext(context); 31762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* const map = __ LoadContextElement( 31862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch native_context, Context::ASYNC_FROM_SYNC_ITERATOR_MAP_INDEX); 31962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* const iterator = __ AllocateJSObjectFromMap(map); 32013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 32162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ StoreObjectFieldNoWriteBarrier( 32262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch iterator, JSAsyncFromSyncIterator::kSyncIteratorOffset, sync_iterator); 32313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 32462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return_value.Bind(iterator); 325f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Goto(&done); 326f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 32762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ Bind(¬_receiver); 328f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 32962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return_value.Bind( 33062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ CallRuntime(Runtime::kThrowSymbolIteratorInvalid, context)); 331f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 33262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Unreachable due to the Throw in runtime call. 333f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Goto(&done); 334f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 335f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 336f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Bind(&done); 337f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return return_value.value(); 338f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 339f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 3403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid IntrinsicsHelper::AbortIfArgCountMismatch(int expected, Node* actual) { 34113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch InterpreterAssembler::Label match(assembler_); 3423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* comparison = __ Word32Equal(actual, __ Int32Constant(expected)); 34313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ GotoIf(comparison, &match); 3443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Abort(kWrongArgumentCountForInvokeIntrinsic); 34513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Goto(&match); 3463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Bind(&match); 3473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 3483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 3493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} // namespace interpreter 3503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} // namespace internal 3513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} // namespace v8 352