OLD | NEW |
---|---|
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/interpreter/interpreter-intrinsics.h" | 5 #include "src/interpreter/interpreter-intrinsics.h" |
6 | 6 |
7 namespace v8 { | 7 namespace v8 { |
8 namespace internal { | 8 namespace internal { |
9 namespace interpreter { | 9 namespace interpreter { |
10 | 10 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
42 #undef LABEL_POINTER | 42 #undef LABEL_POINTER |
43 | 43 |
44 #define CASE(name, lower_case, count) \ | 44 #define CASE(name, lower_case, count) \ |
45 static_cast<int32_t>(Runtime::kInline##name), | 45 static_cast<int32_t>(Runtime::kInline##name), |
46 int32_t cases[] = {INTRINSICS_LIST(CASE)}; | 46 int32_t cases[] = {INTRINSICS_LIST(CASE)}; |
47 #undef CASE | 47 #undef CASE |
48 | 48 |
49 __ Switch(function_id, &abort, cases, labels, arraysize(cases)); | 49 __ Switch(function_id, &abort, cases, labels, arraysize(cases)); |
50 #define HANDLE_CASE(name, lower_case, expected_arg_count) \ | 50 #define HANDLE_CASE(name, lower_case, expected_arg_count) \ |
51 __ Bind(&lower_case); \ | 51 __ Bind(&lower_case); \ |
52 if (FLAG_debug_code) { \ | 52 if (FLAG_debug_code && expected_arg_count >= 0) { \ |
53 AbortIfArgCountMismatch(expected_arg_count, arg_count); \ | 53 AbortIfArgCountMismatch(expected_arg_count, arg_count); \ |
54 } \ | 54 } \ |
55 result.Bind(name(first_arg_reg)); \ | 55 result.Bind(name(first_arg_reg, arg_count, context)); \ |
56 __ Goto(&end); | 56 __ Goto(&end); |
57 INTRINSICS_LIST(HANDLE_CASE) | 57 INTRINSICS_LIST(HANDLE_CASE) |
58 #undef HANDLE_CASE | 58 #undef HANDLE_CASE |
59 | 59 |
60 __ Bind(&abort); | 60 __ Bind(&abort); |
61 __ Abort(BailoutReason::kUnexpectedFunctionIDForInvokeIntrinsic); | 61 __ Abort(BailoutReason::kUnexpectedFunctionIDForInvokeIntrinsic); |
62 result.Bind(__ UndefinedConstant()); | 62 result.Bind(__ UndefinedConstant()); |
63 __ Goto(&end); | 63 __ Goto(&end); |
64 | 64 |
65 __ Bind(&end); | 65 __ Bind(&end); |
(...skipping 23 matching lines...) Expand all Loading... | |
89 __ Goto(&end); | 89 __ Goto(&end); |
90 | 90 |
91 __ Bind(&if_false); | 91 __ Bind(&if_false); |
92 return_value.Bind(__ BooleanConstant(false)); | 92 return_value.Bind(__ BooleanConstant(false)); |
93 __ Goto(&end); | 93 __ Goto(&end); |
94 | 94 |
95 __ Bind(&end); | 95 __ Bind(&end); |
96 return return_value.value(); | 96 return return_value.value(); |
97 } | 97 } |
98 | 98 |
99 Node* IntrinsicsHelper::IsJSReceiver(Node* input) { | 99 Node* IntrinsicsHelper::IsJSReceiver(Node* input, Node* arg_count, |
100 Node* context) { | |
100 InterpreterAssembler::Variable return_value(assembler_, | 101 InterpreterAssembler::Variable return_value(assembler_, |
101 MachineRepresentation::kTagged); | 102 MachineRepresentation::kTagged); |
102 | 103 |
103 InterpreterAssembler::Label if_smi(assembler_), if_not_smi(assembler_), | 104 InterpreterAssembler::Label if_smi(assembler_), if_not_smi(assembler_), |
104 end(assembler_); | 105 end(assembler_); |
105 Node* arg = __ LoadRegister(input); | 106 Node* arg = __ LoadRegister(input); |
106 | 107 |
107 __ Branch(__ WordIsSmi(arg), &if_smi, &if_not_smi); | 108 __ Branch(__ WordIsSmi(arg), &if_smi, &if_not_smi); |
108 __ Bind(&if_smi); | 109 __ Bind(&if_smi); |
109 return_value.Bind(__ BooleanConstant(false)); | 110 return_value.Bind(__ BooleanConstant(false)); |
110 __ Goto(&end); | 111 __ Goto(&end); |
111 | 112 |
112 __ Bind(&if_not_smi); | 113 __ Bind(&if_not_smi); |
113 STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); | 114 STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); |
114 return_value.Bind(CompareInstanceType(arg, FIRST_JS_RECEIVER_TYPE, | 115 return_value.Bind(CompareInstanceType(arg, FIRST_JS_RECEIVER_TYPE, |
115 kInstanceTypeGreaterThanOrEqual)); | 116 kInstanceTypeGreaterThanOrEqual)); |
116 __ Goto(&end); | 117 __ Goto(&end); |
117 | 118 |
118 __ Bind(&end); | 119 __ Bind(&end); |
119 return return_value.value(); | 120 return return_value.value(); |
120 } | 121 } |
121 | 122 |
122 Node* IntrinsicsHelper::IsArray(Node* input) { | 123 Node* IntrinsicsHelper::IsArray(Node* input, Node* arg_count, Node* context) { |
123 InterpreterAssembler::Variable return_value(assembler_, | 124 InterpreterAssembler::Variable return_value(assembler_, |
124 MachineRepresentation::kTagged); | 125 MachineRepresentation::kTagged); |
125 | 126 |
126 InterpreterAssembler::Label if_smi(assembler_), if_not_smi(assembler_), | 127 InterpreterAssembler::Label if_smi(assembler_), if_not_smi(assembler_), |
127 end(assembler_); | 128 end(assembler_); |
128 Node* arg = __ LoadRegister(input); | 129 Node* arg = __ LoadRegister(input); |
129 | 130 |
130 __ Branch(__ WordIsSmi(arg), &if_smi, &if_not_smi); | 131 __ Branch(__ WordIsSmi(arg), &if_smi, &if_not_smi); |
131 __ Bind(&if_smi); | 132 __ Bind(&if_smi); |
132 return_value.Bind(__ BooleanConstant(false)); | 133 return_value.Bind(__ BooleanConstant(false)); |
133 __ Goto(&end); | 134 __ Goto(&end); |
134 | 135 |
135 __ Bind(&if_not_smi); | 136 __ Bind(&if_not_smi); |
136 return_value.Bind( | 137 return_value.Bind( |
137 CompareInstanceType(arg, JS_ARRAY_TYPE, kInstanceTypeEqual)); | 138 CompareInstanceType(arg, JS_ARRAY_TYPE, kInstanceTypeEqual)); |
138 __ Goto(&end); | 139 __ Goto(&end); |
139 | 140 |
140 __ Bind(&end); | 141 __ Bind(&end); |
141 return return_value.value(); | 142 return return_value.value(); |
142 } | 143 } |
143 | 144 |
145 Node* IntrinsicsHelper::Call(Node* args_reg, Node* arg_count, Node* context) { | |
146 // First argument register contains the function target. | |
147 Node* function = __ LoadRegister(args_reg); | |
148 | |
149 // Reciever is the second runtime call argument. | |
oth
2016/05/27 13:11:04
s/Reciever/Receiver/
rmcilroy
2016/05/27 13:37:00
Done.
| |
150 Node* receiver_reg = __ NextRegister(args_reg); | |
151 Node* receiver_arg = __ RegisterLocation(receiver_reg); | |
152 | |
153 // Subtract function and reciever from arg count. | |
oth
2016/05/27 13:11:04
s/reciever/receiver/
rmcilroy
2016/05/27 13:37:00
Done.
| |
154 Node* function_and_receiver_count = __ Int32Constant(2); | |
155 Node* target_args_count = __ Int32Sub(arg_count, function_and_receiver_count); | |
156 | |
157 if (FLAG_debug_code) { | |
158 InterpreterAssembler::Label arg_count_positive(assembler_); | |
159 Node* comparison = __ Int32LessThan(target_args_count, __ Int32Constant(0)); | |
160 __ GotoUnless(comparison, &arg_count_positive); | |
161 __ Abort(kWrongArgumentCountForInvokeIntrinsic); | |
162 __ Goto(&arg_count_positive); | |
163 __ Bind(&arg_count_positive); | |
164 } | |
165 | |
166 Node* result = __ CallJS(function, context, receiver_arg, target_args_count, | |
167 TailCallMode::kDisallow); | |
168 return result; | |
169 } | |
170 | |
144 void IntrinsicsHelper::AbortIfArgCountMismatch(int expected, Node* actual) { | 171 void IntrinsicsHelper::AbortIfArgCountMismatch(int expected, Node* actual) { |
145 InterpreterAssembler::Label match(assembler_), mismatch(assembler_), | 172 InterpreterAssembler::Label match(assembler_); |
146 end(assembler_); | |
147 Node* comparison = __ Word32Equal(actual, __ Int32Constant(expected)); | 173 Node* comparison = __ Word32Equal(actual, __ Int32Constant(expected)); |
148 __ Branch(comparison, &match, &mismatch); | 174 __ GotoIf(comparison, &match); |
149 __ Bind(&mismatch); | |
150 __ Abort(kWrongArgumentCountForInvokeIntrinsic); | 175 __ Abort(kWrongArgumentCountForInvokeIntrinsic); |
151 __ Goto(&end); | 176 __ Goto(&match); |
152 __ Bind(&match); | 177 __ Bind(&match); |
153 __ Goto(&end); | |
154 __ Bind(&end); | |
155 } | 178 } |
156 | 179 |
157 } // namespace interpreter | 180 } // namespace interpreter |
158 } // namespace internal | 181 } // namespace internal |
159 } // namespace v8 | 182 } // namespace v8 |
OLD | NEW |