OLD | NEW |
1 // Copyright 2017 the V8 project authors. All rights reserved. | 1 // Copyright 2017 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/codegen.h" | 5 #include "src/codegen.h" |
6 #include "src/ffi/ffi-compiler.h" | 6 #include "src/ffi/ffi-compiler.h" |
7 #include "test/cctest/cctest.h" | 7 #include "test/cctest/cctest.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 16 matching lines...) Expand all Loading... |
27 reinterpret_cast<uint8_t*>(hello_world)}; | 27 reinterpret_cast<uint8_t*>(hello_world)}; |
28 | 28 |
29 Handle<JSFunction> jsfunc = CompileJSToNativeWrapper(isolate, name, func); | 29 Handle<JSFunction> jsfunc = CompileJSToNativeWrapper(isolate, name, func); |
30 | 30 |
31 Handle<Object> result = | 31 Handle<Object> result = |
32 Execution::Call(isolate, jsfunc, undefined, 0, nullptr).ToHandleChecked(); | 32 Execution::Call(isolate, jsfunc, undefined, 0, nullptr).ToHandleChecked(); |
33 | 33 |
34 CHECK(result->IsUndefined(isolate)); | 34 CHECK(result->IsUndefined(isolate)); |
35 } | 35 } |
36 | 36 |
| 37 static int add2(int x, int y) { return x + y; } |
| 38 |
| 39 TEST(Run_FFI_add2) { |
| 40 Isolate* isolate = CcTest::InitIsolateOnce(); |
| 41 HandleScope scope(isolate); |
| 42 |
| 43 Handle<String> name = isolate->factory()->InternalizeUtf8String("add2"); |
| 44 Handle<Object> undefined = isolate->factory()->undefined_value(); |
| 45 |
| 46 AccountingAllocator allocator; |
| 47 Zone zone(&allocator, ZONE_NAME); |
| 48 FFISignature::Builder sig_builder(&zone, 1, 2); |
| 49 sig_builder.AddReturn(FFIType::kInt32); |
| 50 sig_builder.AddParam(FFIType::kInt32); |
| 51 sig_builder.AddParam(FFIType::kInt32); |
| 52 NativeFunction func = {sig_builder.Build(), reinterpret_cast<uint8_t*>(add2)}; |
| 53 |
| 54 Handle<JSFunction> jsfunc = CompileJSToNativeWrapper(isolate, name, func); |
| 55 |
| 56 // Simple math should work. |
| 57 { |
| 58 Handle<Object> args[] = {isolate->factory()->NewNumber(1.0), |
| 59 isolate->factory()->NewNumber(41.0)}; |
| 60 Handle<Object> result = |
| 61 Execution::Call(isolate, jsfunc, undefined, arraysize(args), args) |
| 62 .ToHandleChecked(); |
| 63 CHECK_EQ(42.0, result->Number()); |
| 64 } |
| 65 |
| 66 // Truncate floating point to integer. |
| 67 { |
| 68 Handle<Object> args[] = {isolate->factory()->NewNumber(1.9), |
| 69 isolate->factory()->NewNumber(41.0)}; |
| 70 Handle<Object> result = |
| 71 Execution::Call(isolate, jsfunc, undefined, arraysize(args), args) |
| 72 .ToHandleChecked(); |
| 73 CHECK_EQ(42.0, result->Number()); |
| 74 } |
| 75 |
| 76 // INT_MAX + 1 should wrap. |
| 77 { |
| 78 Handle<Object> args[] = {isolate->factory()->NewNumber(kMaxInt), |
| 79 isolate->factory()->NewNumber(1)}; |
| 80 Handle<Object> result = |
| 81 Execution::Call(isolate, jsfunc, undefined, arraysize(args), args) |
| 82 .ToHandleChecked(); |
| 83 CHECK_EQ(kMinInt, result->Number()); |
| 84 } |
| 85 |
| 86 // INT_MIN + -1 should wrap. |
| 87 { |
| 88 Handle<Object> args[] = {isolate->factory()->NewNumber(kMinInt), |
| 89 isolate->factory()->NewNumber(-1)}; |
| 90 Handle<Object> result = |
| 91 Execution::Call(isolate, jsfunc, undefined, arraysize(args), args) |
| 92 .ToHandleChecked(); |
| 93 CHECK_EQ(kMaxInt, result->Number()); |
| 94 } |
| 95 |
| 96 // Numbers get truncated to the 32 least significant bits. |
| 97 { |
| 98 Handle<Object> args[] = {isolate->factory()->NewNumber(1ull << 40), |
| 99 isolate->factory()->NewNumber(-1)}; |
| 100 Handle<Object> result = |
| 101 Execution::Call(isolate, jsfunc, undefined, arraysize(args), args) |
| 102 .ToHandleChecked(); |
| 103 CHECK_EQ(-1, result->Number()); |
| 104 } |
| 105 |
| 106 // String '57' converts to 57. |
| 107 { |
| 108 Handle<Object> args[] = { |
| 109 isolate->factory()->NewStringFromAsciiChecked("57"), |
| 110 isolate->factory()->NewNumber(41.0)}; |
| 111 Handle<Object> result = |
| 112 Execution::Call(isolate, jsfunc, undefined, arraysize(args), args) |
| 113 .ToHandleChecked(); |
| 114 CHECK_EQ(98.0, result->Number()); |
| 115 } |
| 116 |
| 117 // String 'foo' converts to 0. |
| 118 { |
| 119 Handle<Object> args[] = { |
| 120 isolate->factory()->NewStringFromAsciiChecked("foo"), |
| 121 isolate->factory()->NewNumber(41.0)}; |
| 122 Handle<Object> result = |
| 123 Execution::Call(isolate, jsfunc, undefined, arraysize(args), args) |
| 124 .ToHandleChecked(); |
| 125 CHECK_EQ(41.0, result->Number()); |
| 126 } |
| 127 |
| 128 // String '58o' converts to 0. |
| 129 { |
| 130 Handle<Object> args[] = { |
| 131 isolate->factory()->NewStringFromAsciiChecked("58o"), |
| 132 isolate->factory()->NewNumber(41.0)}; |
| 133 Handle<Object> result = |
| 134 Execution::Call(isolate, jsfunc, undefined, arraysize(args), args) |
| 135 .ToHandleChecked(); |
| 136 CHECK_EQ(41.0, result->Number()); |
| 137 } |
| 138 |
| 139 // NaN converts to 0. |
| 140 { |
| 141 Handle<Object> args[] = {isolate->factory()->nan_value(), |
| 142 isolate->factory()->NewNumber(41.0)}; |
| 143 Handle<Object> result = |
| 144 Execution::Call(isolate, jsfunc, undefined, arraysize(args), args) |
| 145 .ToHandleChecked(); |
| 146 CHECK_EQ(41.0, result->Number()); |
| 147 } |
| 148 |
| 149 // null converts to 0. |
| 150 { |
| 151 Handle<Object> args[] = {isolate->factory()->null_value(), |
| 152 isolate->factory()->NewNumber(41.0)}; |
| 153 Handle<Object> result = |
| 154 Execution::Call(isolate, jsfunc, undefined, arraysize(args), args) |
| 155 .ToHandleChecked(); |
| 156 CHECK_EQ(41.0, result->Number()); |
| 157 } |
| 158 } |
| 159 |
| 160 static int add6(int a, int b, int c, int d, int e, int f) { |
| 161 return a + b + c + d + e + f; |
| 162 } |
| 163 |
| 164 TEST(Run_FFI_add6) { |
| 165 Isolate* isolate = CcTest::InitIsolateOnce(); |
| 166 HandleScope scope(isolate); |
| 167 |
| 168 Handle<String> name = isolate->factory()->InternalizeUtf8String("add6"); |
| 169 Handle<Object> undefined = isolate->factory()->undefined_value(); |
| 170 |
| 171 AccountingAllocator allocator; |
| 172 Zone zone(&allocator, ZONE_NAME); |
| 173 FFISignature::Builder sig_builder(&zone, 1, 7); |
| 174 sig_builder.AddReturn(FFIType::kInt32); |
| 175 for (int i = 0; i < 7; i++) { |
| 176 sig_builder.AddParam(FFIType::kInt32); |
| 177 } |
| 178 NativeFunction func = {sig_builder.Build(), reinterpret_cast<uint8_t*>(add6)}; |
| 179 |
| 180 Handle<JSFunction> jsfunc = CompileJSToNativeWrapper(isolate, name, func); |
| 181 Handle<Object> args[] = { |
| 182 isolate->factory()->NewNumber(1), isolate->factory()->NewNumber(2), |
| 183 isolate->factory()->NewNumber(3), isolate->factory()->NewNumber(4), |
| 184 isolate->factory()->NewNumber(5), isolate->factory()->NewNumber(6)}; |
| 185 |
| 186 Handle<Object> result = |
| 187 Execution::Call(isolate, jsfunc, undefined, arraysize(args), args) |
| 188 .ToHandleChecked(); |
| 189 |
| 190 CHECK_EQ(21.0, result->Number()); |
| 191 |
| 192 { |
| 193 // Ensure builtin frames are generated |
| 194 FLAG_allow_natives_syntax = true; |
| 195 v8::Local<v8::Value> res = CompileRun( |
| 196 "var o = { valueOf: function() { %DebugTrace(); return 1; } }; o;"); |
| 197 Handle<JSReceiver> param(v8::Utils::OpenHandle(v8::Object::Cast(*res))); |
| 198 Handle<Object> args[] = {param, |
| 199 isolate->factory()->NewNumber(2), |
| 200 isolate->factory()->NewNumber(3), |
| 201 isolate->factory()->NewNumber(4), |
| 202 isolate->factory()->NewNumber(5), |
| 203 isolate->factory()->NewNumber(6), |
| 204 isolate->factory()->NewNumber(21)}; |
| 205 |
| 206 Handle<Object> result = |
| 207 Execution::Call(isolate, jsfunc, undefined, arraysize(args), args) |
| 208 .ToHandleChecked(); |
| 209 CHECK_EQ(21.0, result->Number()); |
| 210 CHECK_EQ( |
| 211 1.0, |
| 212 res->NumberValue( |
| 213 reinterpret_cast<v8::Isolate*>(isolate)->GetCurrentContext()) |
| 214 .ToChecked()); |
| 215 } |
| 216 } |
| 217 |
37 } // namespace ffi | 218 } // namespace ffi |
38 } // namespace internal | 219 } // namespace internal |
39 } // namespace v8 | 220 } // namespace v8 |
OLD | NEW |