Chromium Code Reviews| Index: lib/ffi/ffi.dart |
| diff --git a/lib/ffi/ffi.dart b/lib/ffi/ffi.dart |
| index 7b2fcc2d5fa3aabf4381f35100a1cbff3dc38923..531a94c97d0e30b35615c1dda82bb15f1db09d11 100644 |
| --- a/lib/ffi/ffi.dart |
| +++ b/lib/ffi/ffi.dart |
| @@ -10,6 +10,10 @@ library dart.ffi; |
| import 'dart:_fletch_system' as fletch; |
| class Foreign { |
| + int _value; |
| + int get value => _value; |
|
kasperl
2015/07/03 07:49:54
I'd move the getter below the constructor. Do we n
ricow1
2015/07/03 08:57:24
removed
|
| + Foreign._(this._value); |
| + |
| static const int UNKNOWN = 0; |
| static const int LINUX = 1; |
| @@ -19,114 +23,34 @@ class Foreign { |
| static const int X64 = 2; |
| static const int ARM = 3; |
| - static final Foreign NULL = new Foreign(); |
| - |
| - int _value; |
| - int _length; |
| - |
| - Foreign() : _value = 0, _length = 0; |
| - |
| - Foreign.allocated(this._length) { |
| - _value = _allocate(_length); |
| - } |
| - |
| - Foreign.allocatedFinalize(this._length) { |
| - _value = _allocate(_length); |
| - _markForFinalization(); |
| - } |
| - |
| - Foreign.fromAddress(this._value, this._length); |
| - |
| - Foreign.fromAddressFinalize(this._value, this._length) { |
| - _markForFinalization(); |
| - } |
| - |
| - factory Foreign.fromString(String str) { |
| - var foreign = new Foreign.allocated(str.length + 1); |
| - for (int i = 0; i < str.length; i++) { |
| - foreign.setUint8(i, str.codeUnitAt(i)); |
| - } |
| - return foreign; |
| - } |
| - |
| - static Foreign lookup(String name, {String library}) { |
| - if (library != null && library.isEmpty) library = null; |
| - return new Foreign.fromAddress(_lookup(name, library), 0); |
| - } |
| - |
| // TODO(kasperl): Not quite sure where this fits in. |
| static final int bitsPerMachineWord = _bitsPerMachineWord(); |
| static final int platform = _platform(); |
| static final int architecture = _architecture(); |
| + static final Foreign NULL = new Foreign._(0); |
|
kasperl
2015/07/03 07:49:54
Where do you use this? Should it be a ForeignPoint
ricow1
2015/07/03 08:57:24
Done.
|
| - int get value => _value; |
| - int get length => _length; |
| - |
| - int getInt8(int offset) |
| - => _getInt8(_computeAddress(offset, 1)); |
| - int getInt16(int offset) |
| - => _getInt16(_computeAddress(offset, 2)); |
| - int getInt32(int offset) |
| - => _getInt32(_computeAddress(offset, 4)); |
| - int getInt64(int offset) |
| - => _getInt64(_computeAddress(offset, 8)); |
| - |
| - int setInt8(int offset, int value) |
| - => _setInt8(_computeAddress(offset, 1), value); |
| - int setInt16(int offset, int value) |
| - => _setInt16(_computeAddress(offset, 2), value); |
| - int setInt32(int offset, int value) |
| - => _setInt32(_computeAddress(offset, 4), value); |
| - int setInt64(int offset, int value) |
| - => _setInt64(_computeAddress(offset, 8), value); |
| - |
| - int getUint8(int offset) |
| - => _getUint8(_computeAddress(offset, 1)); |
| - int getUint16(int offset) |
| - => _getUint16(_computeAddress(offset, 2)); |
| - int getUint32(int offset) |
| - => _getUint32(_computeAddress(offset, 4)); |
| - int getUint64(int offset) |
| - => _getUint64(_computeAddress(offset, 8)); |
| - |
| - int setUint8(int offset, int value) |
| - => _setUint8(_computeAddress(offset, 1), value); |
| - int setUint16(int offset, int value) |
| - => _setUint16(_computeAddress(offset, 2), value); |
| - int setUint32(int offset, int value) |
| - => _setUint32(_computeAddress(offset, 4), value); |
| - int setUint64(int offset, int value) |
| - => _setUint64(_computeAddress(offset, 8), value); |
| + static int get errno => _errno(); |
| - double getFloat32(int offset) |
| - => _getFloat32(_computeAddress(offset, 4)); |
| - double getFloat64(int offset) |
| - => _getFloat64(_computeAddress(offset, 8)); |
| + // Helper for converting the argument to a machine word. |
| + int _convert(argument) { |
| + if (argument is Foreign) return argument._value; |
| + if (argument is Port) return _convertPort(argument); |
| + if (argument is int) return argument; |
| + throw new ArgumentError(); |
| + } |
| - double setFloat32(int offset, double value) |
| - => _setFloat32(_computeAddress(offset, 4), value); |
| - double setFloat64(int offset, double value) |
| - => _setFloat64(_computeAddress(offset, 8), value); |
| + @fletch.native external static int _bitsPerMachineWord(); |
| + @fletch.native external static int _errno(); |
| + @fletch.native external static int _platform(); |
| + @fletch.native external static int _architecture(); |
| + @fletch.native external static int _convertPort(Port port); |
| - void copyBytesToList(List<int> list, int from, int to, int listOffset) { |
| - int length = to - from; |
| - for (int i = 0; i < length; i++) { |
| - list[listOffset + i] = getUint8(from + i); |
| - } |
| - } |
| +} |
| - void copyBytesFromList(List<int> list, int from, int to, int listOffset) { |
| - int length = to - from; |
| - for (int i = 0; i < length; i++) { |
| - setUint8(from + i, list[listOffset + i]); |
| - } |
| - } |
| +class ForeignFunction extends Foreign { |
| + int get address => _value; |
| - void free() { |
| - if (_length > 0) _free(_value); |
| - _value = 0; |
| - _length = 0; |
| - } |
| + ForeignFunction.fromAddress(int value) : super._(value); |
| // Support for calling foreign functions that return |
| // machine words as immediate integer value. |
| @@ -163,7 +87,7 @@ class Foreign { |
| _vcall$3(_value, _convert(a0), _convert(a1), _convert(a2)); |
| } |
| void vcall$4(a0, a1, a2, a3) { |
| - _vcall$4(_value, _convert(a0), _convert(a1), _convert(a2), _convert(a3)); |
| + _vcall$4(_value, _convert(a0), _convert(a1), _convert(a2),_convert(a3)); |
| } |
| void vcall$5(a0, a1, a2, a3, a4) { |
| _vcall$5(_value, _convert(a0), _convert(a1), _convert(a2), _convert(a3), |
| @@ -174,6 +98,7 @@ class Foreign { |
| _convert(a4), _convert(a5)); |
| } |
| + // TODO(ricow): this is insanely specific and only used for rseek. |
| // Support for calling foreign functions that |
| // - Returns a 64 bit integer value. |
| // - Takes: |
| @@ -190,44 +115,21 @@ class Foreign { |
| // Support for calling foreign functions that return |
| // machine words -- typically pointers -- encapulated in |
| // the given foreign object arguments. |
| - Foreign pcall$0(Foreign foreign) { |
| + ForeignPointer pcall$0(ForeignPointer foreign) { |
| foreign._value = _icall$0(_value); |
| return foreign; |
| } |
| - Foreign pcall$1(Foreign foreign, a0) { |
| + ForeignPointer pcall$1(ForeignPointer foreign, a0) { |
| foreign._value = _icall$1(_value, _convert(a0)); |
| return foreign; |
| } |
| - Foreign pcall$2(Foreign foreign, a0, a1) { |
| + ForeignPointer pcall$2(ForeignPointer foreign, a0, a1) { |
| foreign._value = _icall$2(_value, _convert(a0), _convert(a1)); |
| return foreign; |
| } |
| - static int get errno => _errno(); |
| - |
| - // Helper for checking bounds and computing derived |
| - // address for memory address functionality. |
| - int _computeAddress(int offset, int n) { |
| - if (offset < 0 || offset + n > _length) throw new IndexError(offset, this); |
| - return _value + offset; |
| - } |
| - |
| - // Helper for converting the argument to a machine word. |
| - int _convert(argument) { |
| - if (argument is Foreign) return argument._value; |
| - if (argument is Port) return _convertPort(argument); |
| - if (argument is int) return argument; |
| - throw new ArgumentError(); |
| - } |
| - |
| - // Natives needed for FFI support. |
| - @fletch.native static int _lookup(String name, String library) { |
| - var error = fletch.nativeError; |
| - throw (error != fletch.indexOutOfBounds) ? error : new ArgumentError(); |
| - } |
| - |
| @fletch.native external static int _icall$0(int address); |
| @fletch.native external static int _icall$1(int address, a0); |
| @fletch.native external static int _icall$2(int address, a0, a1); |
| @@ -247,6 +149,153 @@ class Foreign { |
| int address, a0, a1, a2, a3, a4, a5); |
| @fletch.native external static int _Lcall$wLw(int address, a0, a1, a2); |
| +} |
| + |
| +class ForeignLibrary extends ForeignPointer { |
| + /// ForeignLibrary used for looking up functions in the linked in libraries. |
|
kasperl
2015/07/03 07:49:53
This sentence no verb.
ricow1
2015/07/03 08:57:25
Done.
|
| + static ForeignLibrary standard = new ForeignLibrary.fromName(null); |
|
kasperl
2015/07/03 07:49:53
final? Maybe rename to main or builtin? The dlopen
ricow1
2015/07/03 08:57:24
Renamed to main
|
| + |
| + ForeignLibrary.fromAddress(int address) : super.fromAddress(address); |
| + |
| + factory ForeignLibrary.fromName(String name) { |
| + return new ForeignLibrary.fromAddress(_lookupLibrary(name)); |
| + } |
| + |
| + ForeignFunction lookup(String name) { |
| + return new ForeignFunction.fromAddress(_lookupFunction(_value, name)); |
| + } |
| + |
| + /// Provide a platform specific location for a library relative to the |
|
kasperl
2015/07/03 07:49:54
Provides
ricow1
2015/07/03 08:57:25
Done.
|
| + /// location of the fletch vm. Takes the name without lib in front and |
|
kasperl
2015/07/03 07:49:54
fletch -> Fletch
ricow1
2015/07/03 08:57:25
Done.
|
| + /// returns a platform specific path. Example, on linux, foobar_hash |
| + /// become PATH_TO_EXECUTABLE/lib/libfoobar_hash.so. |
| + @fletch.native external static String bundleLibraryName(String libraryName); |
| + |
| + void close() { |
| + _closeLibrary(_value); |
| + } |
| + |
| + @fletch.native static int _lookupLibrary(String name) { |
| + var error = fletch.nativeError; |
| + throw (error != fletch.indexOutOfBounds) ? error : new ArgumentError(); |
| + } |
| + |
| + @fletch.native static int _lookupFunction(int _value, String name) { |
| + var error = fletch.nativeError; |
| + throw (error != fletch.indexOutOfBounds) ? error : new ArgumentError(); |
| + } |
| + |
| + @fletch.native static int _closeLibrary(int _value) { |
| + var error = fletch.nativeError; |
| + throw (error != fletch.indexOutOfBounds) ? error : new ArgumentError(); |
| + } |
| +} |
| + |
| +class ForeignPointer extends Foreign { |
|
kasperl
2015/07/03 07:49:54
Move this up above the definition of ForeignLibrar
ricow1
2015/07/03 08:57:25
Done.
|
| + int get address => _value; |
| + ForeignPointer.fromAddress(int address) : super._(address); |
| + ForeignPointer() : super._(0); |
| +} |
| + |
| +class ForeignMemory extends ForeignPointer { |
| + int _length; |
| + int get length => _length; |
| + |
| + ForeignMemory.fromAddress(int address, this._length) : |
| + super.fromAddress(address); |
| + |
| + ForeignMemory.fromForeignPointer(ForeignPointer pointer, this._length) : |
| + super.fromAddress(pointer.address); |
| + |
| + ForeignMemory.allocated(this._length) { |
| + _value = _allocate(_length); |
| + } |
| + |
| + ForeignMemory.allocatedFinalize(this._length) { |
|
kasperl
2015/07/03 07:49:53
Not sure I like the name of this named constructor
ricow1
2015/07/03 08:57:25
allocatedAutoFree?
|
| + _value = _allocate(_length); |
| + _markForFinalization(); |
| + } |
| + |
| + factory ForeignMemory.fromString(String str) { |
| + var memory = new ForeignMemory.allocated(str.length + 1); |
| + for (int i = 0; i < str.length; i++) { |
| + memory.setUint8(i, str.codeUnitAt(i)); |
| + } |
| + return memory; |
| + } |
| + |
| + int getInt8(int offset) |
| + => _getInt8(_computeAddress(offset, 1)); |
| + int getInt16(int offset) |
| + => _getInt16(_computeAddress(offset, 2)); |
| + int getInt32(int offset) |
| + => _getInt32(_computeAddress(offset, 4)); |
| + int getInt64(int offset) |
| + => _getInt64(_computeAddress(offset, 8)); |
| + |
| + int setInt8(int offset, int value) |
| + => _setInt8(_computeAddress(offset, 1), value); |
| + int setInt16(int offset, int value) |
| + => _setInt16(_computeAddress(offset, 2), value); |
| + int setInt32(int offset, int value) |
| + => _setInt32(_computeAddress(offset, 4), value); |
| + int setInt64(int offset, int value) |
| + => _setInt64(_computeAddress(offset, 8), value); |
| + |
| + int getUint8(int offset) |
| + => _getUint8(_computeAddress(offset, 1)); |
| + int getUint16(int offset) |
| + => _getUint16(_computeAddress(offset, 2)); |
| + int getUint32(int offset) |
| + => _getUint32(_computeAddress(offset, 4)); |
| + int getUint64(int offset) |
| + => _getUint64(_computeAddress(offset, 8)); |
| + |
| + int setUint8(int offset, int value) |
| + => _setUint8(_computeAddress(offset, 1), value); |
| + int setUint16(int offset, int value) |
| + => _setUint16(_computeAddress(offset, 2), value); |
| + int setUint32(int offset, int value) |
| + => _setUint32(_computeAddress(offset, 4), value); |
| + int setUint64(int offset, int value) |
| + => _setUint64(_computeAddress(offset, 8), value); |
| + |
| + double getFloat32(int offset) |
| + => _getFloat32(_computeAddress(offset, 4)); |
| + double getFloat64(int offset) |
| + => _getFloat64(_computeAddress(offset, 8)); |
| + |
| + double setFloat32(int offset, double value) |
| + => _setFloat32(_computeAddress(offset, 4), value); |
| + double setFloat64(int offset, double value) |
| + => _setFloat64(_computeAddress(offset, 8), value); |
| + |
| + // Helper for checking bounds and computing derived |
| + // addresses for memory address functionality. |
| + int _computeAddress(int offset, int n) { |
| + if (offset < 0 || offset + n > _length) throw new IndexError(offset, this); |
| + return _value + offset; |
| + } |
| + |
| + void copyBytesToList(List<int> list, int from, int to, int listOffset) { |
| + int length = to - from; |
| + for (int i = 0; i < length; i++) { |
| + list[listOffset + i] = getUint8(from + i); |
| + } |
| + } |
| + |
| + void copyBytesFromList(List<int> list, int from, int to, int listOffset) { |
| + int length = to - from; |
| + for (int i = 0; i < length; i++) { |
| + setUint8(from + i, list[listOffset + i]); |
| + } |
| + } |
| + |
| + void free() { |
| + if (_length > 0) _free(_value); |
| + _value = 0; |
| + _length = 0; |
| + } |
| @fletch.native external static int _allocate(int length); |
| @fletch.native external static void _free(int address); |
| @@ -297,10 +346,4 @@ class Foreign { |
| @fletch.native static double _setFloat64(int address, double value) { |
| throw new ArgumentError(); |
| } |
| - |
| - @fletch.native external static int _bitsPerMachineWord(); |
| - @fletch.native external static int _errno(); |
| - @fletch.native external static int _platform(); |
| - @fletch.native external static int _architecture(); |
| - @fletch.native external static int _convertPort(Port port); |
| } |