Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2014, the Fletch project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Fletch project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
| 4 | 4 |
| 5 import 'dart:ffi'; | 5 import 'dart:ffi'; |
| 6 import "package:expect/expect.dart"; | 6 import "package:expect/expect.dart"; |
| 7 | 7 |
| 8 bool isRangeError(e) => e is RangeError; | 8 bool isRangeError(e) => e is RangeError; |
| 9 bool isArgumentError(e) => e is ArgumentError; | 9 bool isArgumentError(e) => e is ArgumentError; |
| 10 | 10 |
| 11 main() { | 11 main() { |
| 12 testLookup(); | 12 testLookup(); |
| 13 | 13 |
| 14 testICall(); | 14 testICall(); |
| 15 testPCall(); | 15 testPCall(); |
| 16 | 16 |
| 17 testAllocate(false); | 17 testAllocate(false); |
| 18 testAllocate(true); | 18 testAllocate(true); |
| 19 } | 19 |
| 20 | 20 // NEW |
| 21 testVAndICall(); | |
| 22 testFailingLibraryLookups(); | |
| 23 testDefaultLibraryLookups(); | |
| 24 testPCallAndMemory(); | |
| 25 } | |
| 26 | |
| 27 testPCallAndMemory() { | |
| 28 // Please see the expected values in the ffi_test_library.c file (obvious | |
| 29 // from the code below, but that is where they are defined). | |
| 30 // For all memory returning functions we expect there to be 4 values of the | |
| 31 // type we are working on. | |
| 32 var libPath = ForeignLibrary.bundleLibraryName('ffi_test_library'); | |
| 33 ForeignLibrary fl = new ForeignLibrary.fromName(libPath); | |
| 34 ForeignPointer p = new ForeignPointer(); | |
| 35 var pcall0 = fl.lookupFunction('pcall0'); | |
| 36 var foreignPointer = pcall0.pcall$0(p); | |
| 37 var memory = new ForeignMemory.fromForeignPointer(foreignPointer, 16); | |
| 38 Expect.equals(memory.value, foreignPointer.value); | |
| 39 Expect.equals(memory.getInt32(0), 1); | |
| 40 Expect.equals(memory.getInt32(4), 2); | |
| 41 Expect.equals(memory.getInt32(8), 3); | |
| 42 Expect.equals(memory.getInt32(12), 4); | |
| 43 // Access memory out of bounds | |
| 44 Expect.throws( | |
| 45 () => memory.getInt32(16), | |
| 46 (e) => e is NoSuchMethodError); | |
| 47 | |
| 48 memory.free(); | |
| 49 memory = new ForeignMemory.fromForeignPointer(foreignPointer, 16); | |
| 50 | |
| 51 var pcall1 = fl.lookupFunction('pcall1'); | |
| 52 foreignPointer = pcall1.pcall$1(p, 42); | |
| 53 memory = new ForeignMemory.fromForeignPointer(foreignPointer, 16); | |
| 54 Expect.equals(memory.value, foreignPointer.value); | |
| 55 Expect.equals(memory.getInt32(0), 42); | |
| 56 Expect.equals(memory.getInt32(4), 42); | |
| 57 Expect.equals(memory.getInt32(8), 42); | |
| 58 Expect.equals(memory.getInt32(12), 42); | |
| 59 memory.setInt32(8, -1); | |
| 60 Expect.equals(memory.getInt32(0), 42); | |
| 61 Expect.equals(memory.getInt32(4), 42); | |
| 62 Expect.equals(memory.getInt32(8), -1); | |
| 63 Expect.equals(memory.getInt32(12), 42); | |
| 64 memory.free(); | |
| 65 | |
| 66 var pcall2 = fl.lookupFunction('pcall2'); | |
| 67 foreignPointer = pcall2.pcall$2(p, 42, 43); | |
| 68 memory = new ForeignMemory.fromForeignPointer(foreignPointer, 16); | |
| 69 Expect.equals(memory.value, foreignPointer.value); | |
| 70 Expect.equals(memory.getInt32(0), 42); | |
| 71 Expect.equals(memory.getInt32(4), 43); | |
| 72 Expect.equals(memory.getInt32(8), 42); | |
| 73 Expect.equals(memory.getInt32(12), 43); | |
| 74 memory.free(); | |
| 75 | |
| 76 // All tetsts below here is basically sanity checking that we correctly | |
| 77 // convert the values to and from c, and that we can also set and read | |
| 78 // back values correctly. | |
| 79 | |
| 80 var memint8 = fl.lookupFunction('memint8'); | |
| 81 foreignPointer = memint8.pcall$0(p); | |
| 82 memory = new ForeignMemory.fromForeignPointer(foreignPointer, 4); | |
| 83 Expect.equals(memory.value, foreignPointer.value); | |
| 84 Expect.equals(memory.getInt8(0), -1); | |
| 85 Expect.equals(memory.getInt8(1), -128); | |
| 86 Expect.equals(memory.getInt8(2), 99); | |
| 87 Expect.equals(memory.getInt8(3), 100); | |
| 88 Expect.equals(memory.getUint8(0), 255); | |
| 89 Expect.equals(memory.getUint8(1), 128); | |
| 90 Expect.equals(memory.getUint8(2), 99); | |
| 91 Expect.equals(memory.getUint8(3), 100); | |
| 92 memory.setInt8(1, -1); | |
| 93 memory.setUint8(2, 100); | |
| 94 Expect.equals(memory.getInt8(0), -1); | |
| 95 Expect.equals(memory.getInt8(1), -1); | |
| 96 Expect.equals(memory.getInt8(2), 100); | |
| 97 Expect.equals(memory.getInt8(3), 100); | |
| 98 Expect.equals(memory.getUint8(0), 255); | |
| 99 Expect.equals(memory.getUint8(1), 255); | |
| 100 Expect.equals(memory.getUint8(2), 100); | |
| 101 Expect.equals(memory.getUint8(3), 100); | |
| 102 // Access memory out of bounds | |
| 103 Expect.throws( | |
| 104 () => memory.getUint8(4), | |
| 105 (e) => e is NoSuchMethodError); | |
| 106 memory.free(); | |
| 107 | |
| 108 var memint16 = fl.lookupFunction('memint16'); | |
| 109 foreignPointer = memint16.pcall$0(p); | |
| 110 memory = new ForeignMemory.fromForeignPointer(foreignPointer, 8); | |
| 111 Expect.equals(memory.value, foreignPointer.value); | |
| 112 Expect.equals(memory.getInt16(0), 32767); | |
| 113 Expect.equals(memory.getInt16(2), -32768); | |
| 114 Expect.equals(memory.getInt16(4), 0); | |
| 115 Expect.equals(memory.getInt16(6), -1); | |
| 116 memory.setInt16(2, -1); | |
| 117 Expect.equals(memory.getInt16(0), 32767); | |
| 118 Expect.equals(memory.getInt16(2), -1); | |
| 119 Expect.equals(memory.getInt16(4), 0); | |
| 120 Expect.equals(memory.getInt16(6), -1); | |
| 121 // Access memory out of bounds | |
| 122 Expect.throws( | |
| 123 () => memory.getInt16(8), | |
| 124 (e) => e is NoSuchMethodError); | |
| 125 memory.free(); | |
| 126 | |
| 127 var memuint16 = fl.lookupFunction('memuint16'); | |
| 128 foreignPointer = memuint16.pcall$0(p); | |
| 129 memory = new ForeignMemory.fromForeignPointer(foreignPointer, 8); | |
| 130 Expect.equals(memory.value, foreignPointer.value); | |
| 131 Expect.equals(memory.getUint16(0), 0); | |
| 132 Expect.equals(memory.getUint16(2), 32767); | |
| 133 Expect.equals(memory.getUint16(4), 32768); | |
| 134 Expect.equals(memory.getUint16(6), 65535); | |
| 135 memory.setUint16(6, 1); | |
| 136 Expect.equals(memory.getUint16(0), 0); | |
| 137 Expect.equals(memory.getUint16(2), 32767); | |
| 138 Expect.equals(memory.getUint16(4), 32768); | |
| 139 Expect.equals(memory.getUint16(6), 1); | |
| 140 // Access memory out of bounds | |
| 141 Expect.throws( | |
| 142 () => memory.getUint16(8), | |
| 143 (e) => e is NoSuchMethodError); | |
| 144 memory.free(); | |
| 145 | |
| 146 var memuint32 = fl.lookupFunction('memuint32'); | |
| 147 foreignPointer = memuint32.pcall$0(p); | |
| 148 memory = new ForeignMemory.fromForeignPointer(foreignPointer, 16); | |
| 149 Expect.equals(memory.value, foreignPointer.value); | |
| 150 Expect.equals(memory.getUint32(0), 0); | |
| 151 Expect.equals(memory.getUint32(4), 1); | |
| 152 Expect.equals(memory.getUint32(8), 65536); | |
| 153 Expect.equals(memory.getUint32(12), 4294967295); | |
| 154 memory.setUint32(8, 1); | |
| 155 Expect.equals(memory.getUint32(0), 0); | |
| 156 Expect.equals(memory.getUint32(4), 1); | |
| 157 Expect.equals(memory.getUint32(8), 1); | |
| 158 Expect.equals(memory.getUint32(12), 4294967295); | |
| 159 // Access memory out of bounds | |
| 160 Expect.throws( | |
| 161 () => memory.getUint32(16), | |
| 162 (e) => e is NoSuchMethodError); | |
| 163 memory.free(); | |
| 164 | |
| 165 var memint64 = fl.lookupFunction('memint64'); | |
| 166 foreignPointer = memint64.pcall$0(p); | |
| 167 memory = new ForeignMemory.fromForeignPointer(foreignPointer, 32); | |
| 168 Expect.equals(memory.value, foreignPointer.value); | |
| 169 Expect.equals(memory.getInt64(0), 0); | |
| 170 Expect.equals(memory.getInt64(8), -1); | |
| 171 Expect.equals(memory.getInt64(16), 9223372036854775807); | |
| 172 Expect.equals(memory.getInt64(24), -9223372036854775808); | |
| 173 memory.setInt64(8, 9223372036854775806); | |
| 174 Expect.equals(memory.getInt64(0), 0); | |
| 175 // TODO(ricow): Failure, need to investigate | |
|
ricow1
2015/06/29 16:55:23
this fails with arch ia32, still need to figure ou
| |
| 176 // Expect.equals(memory.getInt64(8), 9223372036854775806); | |
| 177 Expect.equals(memory.getInt64(16), 9223372036854775807); | |
| 178 Expect.equals(memory.getInt64(24), -9223372036854775808); | |
| 179 | |
| 180 // Access memory out of bounds | |
| 181 Expect.throws( | |
| 182 () => memory.getInt64(25), | |
| 183 (e) => e is NoSuchMethodError); | |
| 184 memory.free(); | |
| 185 | |
| 186 var memfloat32 = fl.lookupFunction('memfloat32'); | |
| 187 foreignPointer = memfloat32.pcall$0(p); | |
| 188 memory = new ForeignMemory.fromForeignPointer(foreignPointer, 16); | |
| 189 Expect.equals(memory.value, foreignPointer.value); | |
| 190 Expect.approxEquals(memory.getFloat32(0), 0); | |
| 191 Expect.approxEquals(memory.getFloat32(4), 1.175494e-38, 0.01); | |
| 192 Expect.approxEquals(memory.getFloat32(8), 3.402823e+38); | |
| 193 Expect.equals(memory.getFloat32(12), 4); | |
| 194 memory.setFloat32(4, 2.1); | |
| 195 Expect.equals(memory.getFloat32(0), 0); | |
| 196 Expect.approxEquals(memory.getFloat32(4), 2.1); | |
| 197 Expect.approxEquals(memory.getFloat32(8), 3.402823e+38); | |
| 198 Expect.equals(memory.getFloat32(12), 4); | |
| 199 | |
| 200 // Access memory out of bounds | |
| 201 Expect.throws( | |
| 202 () => memory.getFloat32(16), | |
| 203 (e) => e is NoSuchMethodError); | |
| 204 memory.free(); | |
| 205 | |
| 206 var memfloat64 = fl.lookupFunction('memFloat64'); | |
| 207 foreignPointer = memfloat64.pcall$0(p); | |
| 208 memory = new ForeignMemory.fromForeignPointer(foreignPointer, 32); | |
| 209 Expect.equals(memory.value, foreignPointer.value); | |
| 210 Expect.equals(memory.getFloat64(0), 0); | |
| 211 Expect.approxEquals(memory.getFloat64(8), 1.79769e+308); | |
| 212 Expect.approxEquals(memory.getFloat64(16), -1.79769e+308); | |
| 213 Expect.equals(memory.getFloat64(24), 4); | |
| 214 memory.setFloat64(24, 1.79769e+308); | |
| 215 Expect.equals(memory.getFloat64(0), 0); | |
| 216 Expect.approxEquals(memory.getFloat64(8), 1.79769e+308); | |
| 217 Expect.approxEquals(memory.getFloat64(16), -1.79769e+308); | |
| 218 Expect.approxEquals(memory.getFloat64(24), 1.79769e+308); | |
| 219 // Access memory out of bounds | |
| 220 Expect.throws( | |
| 221 () => memory.getFloat64(25), | |
| 222 (e) => e is NoSuchMethodError); | |
| 223 memory.free(); | |
| 224 | |
| 225 fl.close(); | |
| 226 } | |
| 227 | |
| 228 testVAndICall() { | |
| 229 // We assume that there is a ffi_test_library library build. | |
| 230 var libPath = ForeignLibrary.bundleLibraryName('ffi_test_library'); | |
| 231 ForeignLibrary fl = new ForeignLibrary.fromName(libPath); | |
| 232 | |
| 233 // Test metods that use a static int. | |
| 234 var setup = fl.lookupFunction('setup'); | |
| 235 var getcount = fl.lookupFunction('getcount'); | |
| 236 var inc = fl.lookupFunction('inc'); | |
| 237 var setcount = fl.lookupFunction('setcount'); | |
| 238 Expect.equals(null, setup.vcall$0()); | |
| 239 Expect.equals(0, getcount.icall$0()); | |
| 240 Expect.equals(null, inc.vcall$0()); | |
| 241 Expect.equals(1, getcount.icall$0()); | |
| 242 Expect.equals(42, setcount.icall$1(42)); | |
| 243 | |
| 244 // Test all the icall wrappers, all c functions returns the sum of the | |
| 245 // arguments. | |
| 246 var icall0 = fl.lookupFunction('icall0'); | |
| 247 var icall1 = fl.lookupFunction('icall1'); | |
| 248 var icall2 = fl.lookupFunction('icall2'); | |
| 249 var icall3 = fl.lookupFunction('icall3'); | |
| 250 var icall4 = fl.lookupFunction('icall4'); | |
| 251 var icall5 = fl.lookupFunction('icall5'); | |
| 252 var icall6 = fl.lookupFunction('icall6'); | |
| 253 Expect.equals(0, icall0.icall$0()); | |
| 254 Expect.equals(1, icall1.icall$1(1)); | |
| 255 Expect.equals(2, icall2.icall$2(1, 1)); | |
| 256 Expect.equals(3, icall3.icall$3(1, 1, 1)); | |
| 257 Expect.equals(4, icall4.icall$4(1, 1, 1, 1)); | |
| 258 Expect.equals(5, icall5.icall$5(1, 1, 1, 1, 1)); | |
| 259 Expect.equals(6, icall6.icall$6(1, 1, 1, 1, 1, 1)); | |
| 260 | |
| 261 // Some limit tests, this is more of sanity checking of our conversions. | |
| 262 Expect.equals(-1, icall1.icall$1(-1)); | |
| 263 Expect.equals(-2, icall2.icall$2(-1, -1)); | |
| 264 Expect.equals(2147483647, icall3.icall$3(2147483647, 0, 0)); | |
| 265 Expect.equals(2147483646, icall3.icall$3(2147483647, -1, 0)); | |
| 266 Expect.equals(-2147483647, icall3.icall$3(2147483647, 2, 0)); | |
| 267 Expect.equals(0, icall1.icall$1(4294967296)); | |
| 268 Expect.equals(1, icall1.icall$1(4294967297)); | |
| 269 Expect.equals(-1, icall1.icall$1(4294967295)); | |
| 270 Expect.equals(0, icall1.icall$1(1024 * 4294967296)); | |
| 271 Expect.equals(1, icall1.icall$1(1024 * 4294967296 + 1)); | |
| 272 | |
| 273 // Test all the void wrappers. The vcall c functions will set the count to | |
| 274 // the sum of the arguments, testable by running getcount. | |
| 275 var vcall0 = fl.lookupFunction('vcall0'); | |
| 276 var vcall1 = fl.lookupFunction('vcall1'); | |
| 277 var vcall2 = fl.lookupFunction('vcall2'); | |
| 278 var vcall3 = fl.lookupFunction('vcall3'); | |
| 279 var vcall4 = fl.lookupFunction('vcall4'); | |
| 280 var vcall5 = fl.lookupFunction('vcall5'); | |
| 281 var vcall6 = fl.lookupFunction('vcall6'); | |
| 282 Expect.equals(null, vcall0.vcall$0()); | |
| 283 Expect.equals(0, getcount.icall$0()); | |
| 284 Expect.equals(null, vcall1.vcall$1(1)); | |
| 285 Expect.equals(1, getcount.icall$0()); | |
| 286 Expect.equals(null, vcall2.vcall$2(1, 1)); | |
| 287 Expect.equals(2, getcount.icall$0()); | |
| 288 Expect.equals(null, vcall3.vcall$3(1, 1, 1)); | |
| 289 Expect.equals(3, getcount.icall$0()); | |
| 290 Expect.equals(null, vcall4.vcall$4(1, 1, 1, 1)); | |
| 291 Expect.equals(4, getcount.icall$0()); | |
| 292 Expect.equals(null, vcall5.vcall$5(1, 1, 1, 1, 1)); | |
| 293 Expect.equals(5, getcount.icall$0()); | |
| 294 Expect.equals(null, vcall6.vcall$6(1, 1, 1, 1, 1, 1)); | |
| 295 Expect.equals(6, getcount.icall$0()); | |
| 296 | |
| 297 fl.close(); | |
| 298 } | |
| 299 | |
| 300 testFailingLibraryLookups() { | |
| 301 var libPath = ForeignLibrary.bundleLibraryName('foobar'); | |
| 302 Expect.throws( | |
| 303 () => new ForeignLibrary.fromName(libPath), | |
| 304 isArgumentError); | |
| 305 Expect.throws( | |
| 306 () => new ForeignLibrary.fromName('random__for_not_hitting_foobar.so'), | |
| 307 isArgumentError); | |
| 308 } | |
| 309 | |
| 310 testDefaultLibraryLookups() { | |
| 311 Expect.isTrue( | |
| 312 ForeignLibrary.lookupDefaultLibraries('qsort') is ForeignFunction); | |
| 313 } | |
| 314 | |
| 315 /// OLD | |
| 21 testLookup() { | 316 testLookup() { |
| 22 Expect.isTrue(Foreign.lookup('qsort') is Foreign); | 317 Expect.isTrue(Foreign.lookup('qsort') is Foreign); |
| 23 Expect.isTrue(Foreign.lookup('qsort', library: null) is Foreign); | 318 Expect.isTrue(Foreign.lookup('qsort', library: null) is Foreign); |
| 24 Expect.isTrue(Foreign.lookup('qsort', library: '') is Foreign); | 319 Expect.isTrue(Foreign.lookup('qsort', library: '') is Foreign); |
| 25 | 320 |
| 26 Expect.throws( | 321 Expect.throws( |
| 27 () => Foreign.lookup('qsort', library: 'does-not-exist'), | 322 () => Foreign.lookup('qsort', library: 'does-not-exist'), |
| 28 isArgumentError); | 323 isArgumentError); |
| 29 Expect.throws( | 324 Expect.throws( |
| 30 () => Foreign.lookup('does-not-exist'), | 325 () => Foreign.lookup('does-not-exist'), |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 94 Expect.equals(1.0, memory.getFloat32(0)); | 389 Expect.equals(1.0, memory.getFloat32(0)); |
| 95 | 390 |
| 96 memory.setFloat64(0, 2.0); | 391 memory.setFloat64(0, 2.0); |
| 97 Expect.equals(2.0, memory.getFloat64(0)); | 392 Expect.equals(2.0, memory.getFloat64(0)); |
| 98 | 393 |
| 99 if (!finalized) { | 394 if (!finalized) { |
| 100 memory.free(); | 395 memory.free(); |
| 101 memory.free(); // Free'ing multiple times is okay. | 396 memory.free(); // Free'ing multiple times is okay. |
| 102 } | 397 } |
| 103 } | 398 } |
| OLD | NEW |