| 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/execution.h" | 7 #include "src/execution.h" |
| 8 #include "src/handles.h" | 8 #include "src/handles.h" |
| 9 #include "src/interpreter/bytecode-array-builder.h" | 9 #include "src/interpreter/bytecode-array-builder.h" |
| 10 #include "src/interpreter/interpreter.h" | 10 #include "src/interpreter/interpreter.h" |
| 11 #include "test/cctest/cctest.h" | 11 #include "test/cctest/cctest.h" |
| 12 | 12 |
| 13 namespace v8 { | 13 namespace v8 { |
| 14 namespace internal { | 14 namespace internal { |
| 15 namespace interpreter { | 15 namespace interpreter { |
| 16 | 16 |
| 17 |
| 18 static MaybeHandle<Object> CallInterpreter(Isolate* isolate, |
| 19 Handle<JSFunction> function) { |
| 20 return Execution::Call(isolate, function, |
| 21 isolate->factory()->undefined_value(), 0, nullptr, |
| 22 false); |
| 23 } |
| 24 |
| 25 |
| 26 template <class... A> |
| 27 static MaybeHandle<Object> CallInterpreter(Isolate* isolate, |
| 28 Handle<JSFunction> function, |
| 29 A... args) { |
| 30 Handle<Object> argv[] = { args... }; |
| 31 return Execution::Call(isolate, function, |
| 32 isolate->factory()->undefined_value(), sizeof...(args), |
| 33 argv, false); |
| 34 } |
| 35 |
| 36 |
| 37 template <class... A> |
| 17 class InterpreterCallable { | 38 class InterpreterCallable { |
| 18 public: | 39 public: |
| 19 InterpreterCallable(Isolate* isolate, Handle<JSFunction> function) | 40 InterpreterCallable(Isolate* isolate, Handle<JSFunction> function) |
| 20 : isolate_(isolate), function_(function) {} | 41 : isolate_(isolate), function_(function) {} |
| 21 virtual ~InterpreterCallable() {} | 42 virtual ~InterpreterCallable() {} |
| 22 | 43 |
| 23 MaybeHandle<Object> operator()() { | 44 MaybeHandle<Object> operator()(A... args) { |
| 24 return Execution::Call(isolate_, function_, | 45 return CallInterpreter(isolate_, function_, args...); |
| 25 isolate_->factory()->undefined_value(), 0, nullptr, | |
| 26 false); | |
| 27 } | 46 } |
| 28 | 47 |
| 29 private: | 48 private: |
| 30 Isolate* isolate_; | 49 Isolate* isolate_; |
| 31 Handle<JSFunction> function_; | 50 Handle<JSFunction> function_; |
| 32 }; | 51 }; |
| 33 | 52 |
| 53 |
| 34 class InterpreterTester { | 54 class InterpreterTester { |
| 35 public: | 55 public: |
| 36 InterpreterTester(Isolate* isolate, Handle<BytecodeArray> bytecode) | 56 InterpreterTester(Isolate* isolate, Handle<BytecodeArray> bytecode) |
| 37 : isolate_(isolate), function_(GetBytecodeFunction(isolate, bytecode)) { | 57 : isolate_(isolate), bytecode_(bytecode) { |
| 38 i::FLAG_ignition = true; | 58 i::FLAG_ignition = true; |
| 39 // Ensure handler table is generated. | 59 // Ensure handler table is generated. |
| 40 isolate->interpreter()->Initialize(); | 60 isolate->interpreter()->Initialize(); |
| 41 } | 61 } |
| 42 virtual ~InterpreterTester() {} | 62 virtual ~InterpreterTester() {} |
| 43 | 63 |
| 44 InterpreterCallable GetCallable() { | 64 template <class... A> |
| 45 return InterpreterCallable(isolate_, function_); | 65 InterpreterCallable<A...> GetCallable() { |
| 66 return InterpreterCallable<A...>(isolate_, GetBytecodeFunction<A...>()); |
| 46 } | 67 } |
| 47 | 68 |
| 48 private: | 69 private: |
| 49 Isolate* isolate_; | 70 Isolate* isolate_; |
| 50 Handle<JSFunction> function_; | 71 Handle<BytecodeArray> bytecode_; |
| 51 | 72 |
| 52 static Handle<JSFunction> GetBytecodeFunction( | 73 template <class... A> |
| 53 Isolate* isolate, Handle<BytecodeArray> bytecode_array) { | 74 Handle<JSFunction> GetBytecodeFunction() { |
| 75 int arg_count = sizeof...(A); |
| 76 std::string function_text("(function("); |
| 77 for (int i = 0; i < arg_count; i++) { |
| 78 function_text += i == 0 ? "a" : ", a"; |
| 79 } |
| 80 function_text += "){})"; |
| 81 |
| 54 Handle<JSFunction> function = v8::Utils::OpenHandle( | 82 Handle<JSFunction> function = v8::Utils::OpenHandle( |
| 55 *v8::Handle<v8::Function>::Cast(CompileRun("(function(){})"))); | 83 *v8::Handle<v8::Function>::Cast(CompileRun(function_text.c_str()))); |
| 56 function->ReplaceCode(*isolate->builtins()->InterpreterEntryTrampoline()); | 84 function->ReplaceCode(*isolate_->builtins()->InterpreterEntryTrampoline()); |
| 57 function->shared()->set_function_data(*bytecode_array); | 85 function->shared()->set_function_data(*bytecode_); |
| 58 return function; | 86 return function; |
| 59 } | 87 } |
| 60 | 88 |
| 61 DISALLOW_COPY_AND_ASSIGN(InterpreterTester); | 89 DISALLOW_COPY_AND_ASSIGN(InterpreterTester); |
| 62 }; | 90 }; |
| 63 | 91 |
| 64 } // namespace interpreter | 92 } // namespace interpreter |
| 65 } // namespace internal | 93 } // namespace internal |
| 66 } // namespace v8 | 94 } // namespace v8 |
| 67 | 95 |
| 68 using v8::internal::BytecodeArray; | 96 using v8::internal::BytecodeArray; |
| 69 using v8::internal::Handle; | 97 using v8::internal::Handle; |
| 70 using v8::internal::Object; | 98 using v8::internal::Object; |
| 71 using v8::internal::Smi; | 99 using v8::internal::Smi; |
| 72 using v8::internal::Token; | 100 using v8::internal::Token; |
| 73 using namespace v8::internal::interpreter; | 101 using namespace v8::internal::interpreter; |
| 74 | 102 |
| 75 TEST(TestInterpreterReturn) { | 103 TEST(InterpreterReturn) { |
| 76 InitializedHandleScope handles; | 104 InitializedHandleScope handles; |
| 77 Handle<Object> undefined_value = | 105 Handle<Object> undefined_value = |
| 78 handles.main_isolate()->factory()->undefined_value(); | 106 handles.main_isolate()->factory()->undefined_value(); |
| 79 | 107 |
| 80 BytecodeArrayBuilder builder(handles.main_isolate()); | 108 BytecodeArrayBuilder builder(handles.main_isolate()); |
| 81 builder.set_locals_count(0); | 109 builder.set_locals_count(0); |
| 110 builder.set_parameter_count(1); |
| 82 builder.Return(); | 111 builder.Return(); |
| 83 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 112 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 84 | 113 |
| 85 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 114 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 86 InterpreterCallable callable(tester.GetCallable()); | 115 auto callable = tester.GetCallable<>(); |
| 87 Handle<Object> return_val = callable().ToHandleChecked(); | 116 Handle<Object> return_val = callable().ToHandleChecked(); |
| 88 CHECK(return_val.is_identical_to(undefined_value)); | 117 CHECK(return_val.is_identical_to(undefined_value)); |
| 89 } | 118 } |
| 90 | 119 |
| 91 | 120 |
| 92 TEST(TestInterpreterLoadUndefined) { | 121 TEST(InterpreterLoadUndefined) { |
| 93 InitializedHandleScope handles; | 122 InitializedHandleScope handles; |
| 94 Handle<Object> undefined_value = | 123 Handle<Object> undefined_value = |
| 95 handles.main_isolate()->factory()->undefined_value(); | 124 handles.main_isolate()->factory()->undefined_value(); |
| 96 | 125 |
| 97 BytecodeArrayBuilder builder(handles.main_isolate()); | 126 BytecodeArrayBuilder builder(handles.main_isolate()); |
| 98 builder.set_locals_count(0); | 127 builder.set_locals_count(0); |
| 128 builder.set_parameter_count(1); |
| 99 builder.LoadUndefined().Return(); | 129 builder.LoadUndefined().Return(); |
| 100 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 130 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 101 | 131 |
| 102 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 132 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 103 InterpreterCallable callable(tester.GetCallable()); | 133 auto callable = tester.GetCallable<>(); |
| 104 Handle<Object> return_val = callable().ToHandleChecked(); | 134 Handle<Object> return_val = callable().ToHandleChecked(); |
| 105 CHECK(return_val.is_identical_to(undefined_value)); | 135 CHECK(return_val.is_identical_to(undefined_value)); |
| 106 } | 136 } |
| 107 | 137 |
| 108 | 138 |
| 109 TEST(TestInterpreterLoadNull) { | 139 TEST(InterpreterLoadNull) { |
| 110 InitializedHandleScope handles; | 140 InitializedHandleScope handles; |
| 111 Handle<Object> null_value = handles.main_isolate()->factory()->null_value(); | 141 Handle<Object> null_value = handles.main_isolate()->factory()->null_value(); |
| 112 | 142 |
| 113 BytecodeArrayBuilder builder(handles.main_isolate()); | 143 BytecodeArrayBuilder builder(handles.main_isolate()); |
| 114 builder.set_locals_count(0); | 144 builder.set_locals_count(0); |
| 145 builder.set_parameter_count(1); |
| 115 builder.LoadNull().Return(); | 146 builder.LoadNull().Return(); |
| 116 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 147 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 117 | 148 |
| 118 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 149 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 119 InterpreterCallable callable(tester.GetCallable()); | 150 auto callable = tester.GetCallable<>(); |
| 120 Handle<Object> return_val = callable().ToHandleChecked(); | 151 Handle<Object> return_val = callable().ToHandleChecked(); |
| 121 CHECK(return_val.is_identical_to(null_value)); | 152 CHECK(return_val.is_identical_to(null_value)); |
| 122 } | 153 } |
| 123 | 154 |
| 124 | 155 |
| 125 TEST(TestInterpreterLoadTheHole) { | 156 TEST(InterpreterLoadTheHole) { |
| 126 InitializedHandleScope handles; | 157 InitializedHandleScope handles; |
| 127 Handle<Object> the_hole_value = | 158 Handle<Object> the_hole_value = |
| 128 handles.main_isolate()->factory()->the_hole_value(); | 159 handles.main_isolate()->factory()->the_hole_value(); |
| 129 | 160 |
| 130 BytecodeArrayBuilder builder(handles.main_isolate()); | 161 BytecodeArrayBuilder builder(handles.main_isolate()); |
| 131 builder.set_locals_count(0); | 162 builder.set_locals_count(0); |
| 163 builder.set_parameter_count(1); |
| 132 builder.LoadTheHole().Return(); | 164 builder.LoadTheHole().Return(); |
| 133 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 165 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 134 | 166 |
| 135 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 167 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 136 InterpreterCallable callable(tester.GetCallable()); | 168 auto callable = tester.GetCallable<>(); |
| 137 Handle<Object> return_val = callable().ToHandleChecked(); | 169 Handle<Object> return_val = callable().ToHandleChecked(); |
| 138 CHECK(return_val.is_identical_to(the_hole_value)); | 170 CHECK(return_val.is_identical_to(the_hole_value)); |
| 139 } | 171 } |
| 140 | 172 |
| 141 | 173 |
| 142 TEST(TestInterpreterLoadTrue) { | 174 TEST(InterpreterLoadTrue) { |
| 143 InitializedHandleScope handles; | 175 InitializedHandleScope handles; |
| 144 Handle<Object> true_value = handles.main_isolate()->factory()->true_value(); | 176 Handle<Object> true_value = handles.main_isolate()->factory()->true_value(); |
| 145 | 177 |
| 146 BytecodeArrayBuilder builder(handles.main_isolate()); | 178 BytecodeArrayBuilder builder(handles.main_isolate()); |
| 147 builder.set_locals_count(0); | 179 builder.set_locals_count(0); |
| 180 builder.set_parameter_count(1); |
| 148 builder.LoadTrue().Return(); | 181 builder.LoadTrue().Return(); |
| 149 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 182 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 150 | 183 |
| 151 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 184 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 152 InterpreterCallable callable(tester.GetCallable()); | 185 auto callable = tester.GetCallable<>(); |
| 153 Handle<Object> return_val = callable().ToHandleChecked(); | 186 Handle<Object> return_val = callable().ToHandleChecked(); |
| 154 CHECK(return_val.is_identical_to(true_value)); | 187 CHECK(return_val.is_identical_to(true_value)); |
| 155 } | 188 } |
| 156 | 189 |
| 157 | 190 |
| 158 TEST(TestInterpreterLoadFalse) { | 191 TEST(InterpreterLoadFalse) { |
| 159 InitializedHandleScope handles; | 192 InitializedHandleScope handles; |
| 160 Handle<Object> false_value = handles.main_isolate()->factory()->false_value(); | 193 Handle<Object> false_value = handles.main_isolate()->factory()->false_value(); |
| 161 | 194 |
| 162 BytecodeArrayBuilder builder(handles.main_isolate()); | 195 BytecodeArrayBuilder builder(handles.main_isolate()); |
| 163 builder.set_locals_count(0); | 196 builder.set_locals_count(0); |
| 197 builder.set_parameter_count(1); |
| 164 builder.LoadFalse().Return(); | 198 builder.LoadFalse().Return(); |
| 165 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 199 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 166 | 200 |
| 167 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 201 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 168 InterpreterCallable callable(tester.GetCallable()); | 202 auto callable = tester.GetCallable<>(); |
| 169 Handle<Object> return_val = callable().ToHandleChecked(); | 203 Handle<Object> return_val = callable().ToHandleChecked(); |
| 170 CHECK(return_val.is_identical_to(false_value)); | 204 CHECK(return_val.is_identical_to(false_value)); |
| 171 } | 205 } |
| 172 | 206 |
| 173 | 207 |
| 174 TEST(TestInterpreterLoadLiteral) { | 208 TEST(InterpreterLoadLiteral) { |
| 175 InitializedHandleScope handles; | 209 InitializedHandleScope handles; |
| 176 for (int i = -128; i < 128; i++) { | 210 for (int i = -128; i < 128; i++) { |
| 177 BytecodeArrayBuilder builder(handles.main_isolate()); | 211 BytecodeArrayBuilder builder(handles.main_isolate()); |
| 178 builder.set_locals_count(0); | 212 builder.set_locals_count(0); |
| 213 builder.set_parameter_count(1); |
| 179 builder.LoadLiteral(Smi::FromInt(i)).Return(); | 214 builder.LoadLiteral(Smi::FromInt(i)).Return(); |
| 180 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 215 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 181 | 216 |
| 182 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 217 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 183 InterpreterCallable callable(tester.GetCallable()); | 218 auto callable = tester.GetCallable<>(); |
| 184 Handle<Object> return_val = callable().ToHandleChecked(); | 219 Handle<Object> return_val = callable().ToHandleChecked(); |
| 185 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(i)); | 220 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(i)); |
| 186 } | 221 } |
| 187 } | 222 } |
| 188 | 223 |
| 189 | 224 |
| 190 TEST(TestInterpreterLoadStoreRegisters) { | 225 TEST(InterpreterLoadStoreRegisters) { |
| 191 InitializedHandleScope handles; | 226 InitializedHandleScope handles; |
| 192 Handle<Object> true_value = handles.main_isolate()->factory()->true_value(); | 227 Handle<Object> true_value = handles.main_isolate()->factory()->true_value(); |
| 193 for (int i = 0; i <= Register::kMaxRegisterIndex; i++) { | 228 for (int i = 0; i <= Register::kMaxRegisterIndex; i++) { |
| 194 BytecodeArrayBuilder builder(handles.main_isolate()); | 229 BytecodeArrayBuilder builder(handles.main_isolate()); |
| 195 builder.set_locals_count(i + 1); | 230 builder.set_locals_count(i + 1); |
| 231 builder.set_parameter_count(1); |
| 196 Register reg(i); | 232 Register reg(i); |
| 197 builder.LoadTrue() | 233 builder.LoadTrue() |
| 198 .StoreAccumulatorInRegister(reg) | 234 .StoreAccumulatorInRegister(reg) |
| 199 .LoadFalse() | 235 .LoadFalse() |
| 200 .LoadAccumulatorWithRegister(reg) | 236 .LoadAccumulatorWithRegister(reg) |
| 201 .Return(); | 237 .Return(); |
| 202 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 238 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 203 | 239 |
| 204 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 240 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 205 InterpreterCallable callable(tester.GetCallable()); | 241 auto callable = tester.GetCallable<>(); |
| 206 Handle<Object> return_val = callable().ToHandleChecked(); | 242 Handle<Object> return_val = callable().ToHandleChecked(); |
| 207 CHECK(return_val.is_identical_to(true_value)); | 243 CHECK(return_val.is_identical_to(true_value)); |
| 208 } | 244 } |
| 209 } | 245 } |
| 210 | 246 |
| 211 | 247 |
| 212 TEST(TestInterpreterAdd) { | 248 TEST(InterpreterAdd) { |
| 213 InitializedHandleScope handles; | 249 InitializedHandleScope handles; |
| 214 // TODO(rmcilroy): Do add tests for heap numbers and strings once we support | 250 // TODO(rmcilroy): Do add tests for heap numbers and strings once we support |
| 215 // them. | 251 // them. |
| 216 BytecodeArrayBuilder builder(handles.main_isolate()); | 252 BytecodeArrayBuilder builder(handles.main_isolate()); |
| 217 builder.set_locals_count(1); | 253 builder.set_locals_count(1); |
| 254 builder.set_parameter_count(1); |
| 218 Register reg(0); | 255 Register reg(0); |
| 219 builder.LoadLiteral(Smi::FromInt(1)) | 256 builder.LoadLiteral(Smi::FromInt(1)) |
| 220 .StoreAccumulatorInRegister(reg) | 257 .StoreAccumulatorInRegister(reg) |
| 221 .LoadLiteral(Smi::FromInt(2)) | 258 .LoadLiteral(Smi::FromInt(2)) |
| 222 .BinaryOperation(Token::Value::ADD, reg) | 259 .BinaryOperation(Token::Value::ADD, reg) |
| 223 .Return(); | 260 .Return(); |
| 224 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 261 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 225 | 262 |
| 226 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 263 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 227 InterpreterCallable callable(tester.GetCallable()); | 264 auto callable = tester.GetCallable<>(); |
| 228 Handle<Object> return_val = callable().ToHandleChecked(); | 265 Handle<Object> return_val = callable().ToHandleChecked(); |
| 229 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(3)); | 266 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(3)); |
| 230 } | 267 } |
| 231 | 268 |
| 232 | 269 |
| 233 TEST(TestInterpreterSub) { | 270 TEST(InterpreterSub) { |
| 234 InitializedHandleScope handles; | 271 InitializedHandleScope handles; |
| 235 // TODO(rmcilroy): Do add tests for heap numbers once we support them. | 272 // TODO(rmcilroy): Do add tests for heap numbers once we support them. |
| 236 BytecodeArrayBuilder builder(handles.main_isolate()); | 273 BytecodeArrayBuilder builder(handles.main_isolate()); |
| 237 builder.set_locals_count(1); | 274 builder.set_locals_count(1); |
| 275 builder.set_parameter_count(1); |
| 238 Register reg(0); | 276 Register reg(0); |
| 239 builder.LoadLiteral(Smi::FromInt(5)) | 277 builder.LoadLiteral(Smi::FromInt(5)) |
| 240 .StoreAccumulatorInRegister(reg) | 278 .StoreAccumulatorInRegister(reg) |
| 241 .LoadLiteral(Smi::FromInt(31)) | 279 .LoadLiteral(Smi::FromInt(31)) |
| 242 .BinaryOperation(Token::Value::SUB, reg) | 280 .BinaryOperation(Token::Value::SUB, reg) |
| 243 .Return(); | 281 .Return(); |
| 244 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 282 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 245 | 283 |
| 246 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 284 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 247 InterpreterCallable callable(tester.GetCallable()); | 285 auto callable = tester.GetCallable<>(); |
| 248 Handle<Object> return_val = callable().ToHandleChecked(); | 286 Handle<Object> return_val = callable().ToHandleChecked(); |
| 249 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(-26)); | 287 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(-26)); |
| 250 } | 288 } |
| 251 | 289 |
| 252 | 290 |
| 253 TEST(TestInterpreterMul) { | 291 TEST(InterpreterMul) { |
| 254 InitializedHandleScope handles; | 292 InitializedHandleScope handles; |
| 255 // TODO(rmcilroy): Do add tests for heap numbers once we support them. | 293 // TODO(rmcilroy): Do add tests for heap numbers once we support them. |
| 256 BytecodeArrayBuilder builder(handles.main_isolate()); | 294 BytecodeArrayBuilder builder(handles.main_isolate()); |
| 257 builder.set_locals_count(1); | 295 builder.set_locals_count(1); |
| 296 builder.set_parameter_count(1); |
| 258 Register reg(0); | 297 Register reg(0); |
| 259 builder.LoadLiteral(Smi::FromInt(111)) | 298 builder.LoadLiteral(Smi::FromInt(111)) |
| 260 .StoreAccumulatorInRegister(reg) | 299 .StoreAccumulatorInRegister(reg) |
| 261 .LoadLiteral(Smi::FromInt(6)) | 300 .LoadLiteral(Smi::FromInt(6)) |
| 262 .BinaryOperation(Token::Value::MUL, reg) | 301 .BinaryOperation(Token::Value::MUL, reg) |
| 263 .Return(); | 302 .Return(); |
| 264 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 303 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 265 | 304 |
| 266 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 305 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 267 InterpreterCallable callable(tester.GetCallable()); | 306 auto callable = tester.GetCallable<>(); |
| 268 Handle<Object> return_val = callable().ToHandleChecked(); | 307 Handle<Object> return_val = callable().ToHandleChecked(); |
| 269 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(666)); | 308 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(666)); |
| 270 } | 309 } |
| 271 | 310 |
| 272 | 311 |
| 273 TEST(TestInterpreterDiv) { | 312 TEST(InterpreterDiv) { |
| 274 InitializedHandleScope handles; | 313 InitializedHandleScope handles; |
| 275 // TODO(rmcilroy): Do add tests for heap numbers once we support them. | 314 // TODO(rmcilroy): Do add tests for heap numbers once we support them. |
| 276 BytecodeArrayBuilder builder(handles.main_isolate()); | 315 BytecodeArrayBuilder builder(handles.main_isolate()); |
| 277 builder.set_locals_count(1); | 316 builder.set_locals_count(1); |
| 317 builder.set_parameter_count(1); |
| 278 Register reg(0); | 318 Register reg(0); |
| 279 builder.LoadLiteral(Smi::FromInt(-20)) | 319 builder.LoadLiteral(Smi::FromInt(-20)) |
| 280 .StoreAccumulatorInRegister(reg) | 320 .StoreAccumulatorInRegister(reg) |
| 281 .LoadLiteral(Smi::FromInt(5)) | 321 .LoadLiteral(Smi::FromInt(5)) |
| 282 .BinaryOperation(Token::Value::DIV, reg) | 322 .BinaryOperation(Token::Value::DIV, reg) |
| 283 .Return(); | 323 .Return(); |
| 284 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 324 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 285 | 325 |
| 286 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 326 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 287 InterpreterCallable callable(tester.GetCallable()); | 327 auto callable = tester.GetCallable<>(); |
| 288 Handle<Object> return_val = callable().ToHandleChecked(); | 328 Handle<Object> return_val = callable().ToHandleChecked(); |
| 289 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(-4)); | 329 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(-4)); |
| 290 } | 330 } |
| 291 | 331 |
| 292 | 332 |
| 293 TEST(TestInterpreterMod) { | 333 TEST(InterpreterMod) { |
| 294 InitializedHandleScope handles; | 334 InitializedHandleScope handles; |
| 295 // TODO(rmcilroy): Do add tests for heap numbers once we support them. | 335 // TODO(rmcilroy): Do add tests for heap numbers once we support them. |
| 296 BytecodeArrayBuilder builder(handles.main_isolate()); | 336 BytecodeArrayBuilder builder(handles.main_isolate()); |
| 297 builder.set_locals_count(1); | 337 builder.set_locals_count(1); |
| 338 builder.set_parameter_count(1); |
| 298 Register reg(0); | 339 Register reg(0); |
| 299 builder.LoadLiteral(Smi::FromInt(121)) | 340 builder.LoadLiteral(Smi::FromInt(121)) |
| 300 .StoreAccumulatorInRegister(reg) | 341 .StoreAccumulatorInRegister(reg) |
| 301 .LoadLiteral(Smi::FromInt(100)) | 342 .LoadLiteral(Smi::FromInt(100)) |
| 302 .BinaryOperation(Token::Value::MOD, reg) | 343 .BinaryOperation(Token::Value::MOD, reg) |
| 303 .Return(); | 344 .Return(); |
| 304 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 345 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 305 | 346 |
| 306 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 347 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 307 InterpreterCallable callable(tester.GetCallable()); | 348 auto callable = tester.GetCallable<>(); |
| 308 Handle<Object> return_val = callable().ToHandleChecked(); | 349 Handle<Object> return_val = callable().ToHandleChecked(); |
| 309 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(21)); | 350 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(21)); |
| 310 } | 351 } |
| 352 |
| 353 |
| 354 TEST(InterpreterParameter1) { |
| 355 InitializedHandleScope handles; |
| 356 BytecodeArrayBuilder builder(handles.main_isolate()); |
| 357 builder.set_locals_count(1); |
| 358 builder.set_parameter_count(1); |
| 359 builder.LoadAccumulatorWithRegister(builder.Parameter(0)).Return(); |
| 360 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 361 |
| 362 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 363 auto callable = tester.GetCallable<Handle<Object>>(); |
| 364 |
| 365 // Check for heap objects. |
| 366 Handle<Object> true_value = handles.main_isolate()->factory()->true_value(); |
| 367 Handle<Object> return_val = callable(true_value).ToHandleChecked(); |
| 368 CHECK(return_val.is_identical_to(true_value)); |
| 369 |
| 370 // Check for Smis. |
| 371 return_val = callable(Handle<Smi>(Smi::FromInt(3), handles.main_isolate())) |
| 372 .ToHandleChecked(); |
| 373 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(3)); |
| 374 } |
| 375 |
| 376 |
| 377 TEST(InterpreterParameter8) { |
| 378 InitializedHandleScope handles; |
| 379 BytecodeArrayBuilder builder(handles.main_isolate()); |
| 380 builder.set_locals_count(1); |
| 381 builder.set_parameter_count(8); |
| 382 builder.LoadAccumulatorWithRegister(builder.Parameter(0)) |
| 383 .BinaryOperation(Token::Value::ADD, builder.Parameter(1)) |
| 384 .BinaryOperation(Token::Value::ADD, builder.Parameter(2)) |
| 385 .BinaryOperation(Token::Value::ADD, builder.Parameter(3)) |
| 386 .BinaryOperation(Token::Value::ADD, builder.Parameter(4)) |
| 387 .BinaryOperation(Token::Value::ADD, builder.Parameter(5)) |
| 388 .BinaryOperation(Token::Value::ADD, builder.Parameter(6)) |
| 389 .BinaryOperation(Token::Value::ADD, builder.Parameter(7)) |
| 390 .Return(); |
| 391 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 392 |
| 393 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 394 typedef Handle<Object> H; |
| 395 auto callable = tester.GetCallable<H, H, H, H, H, H, H, H>(); |
| 396 |
| 397 Handle<Smi> arg1 = Handle<Smi>(Smi::FromInt(1), handles.main_isolate()); |
| 398 Handle<Smi> arg2 = Handle<Smi>(Smi::FromInt(2), handles.main_isolate()); |
| 399 Handle<Smi> arg3 = Handle<Smi>(Smi::FromInt(3), handles.main_isolate()); |
| 400 Handle<Smi> arg4 = Handle<Smi>(Smi::FromInt(4), handles.main_isolate()); |
| 401 Handle<Smi> arg5 = Handle<Smi>(Smi::FromInt(5), handles.main_isolate()); |
| 402 Handle<Smi> arg6 = Handle<Smi>(Smi::FromInt(6), handles.main_isolate()); |
| 403 Handle<Smi> arg7 = Handle<Smi>(Smi::FromInt(7), handles.main_isolate()); |
| 404 Handle<Smi> arg8 = Handle<Smi>(Smi::FromInt(8), handles.main_isolate()); |
| 405 // Check for Smis. |
| 406 Handle<Object> return_val = |
| 407 callable(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) |
| 408 .ToHandleChecked(); |
| 409 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(36)); |
| 410 } |
| OLD | NEW |