| Index: lib/ffi/ffi.dart
|
| diff --git a/lib/ffi/ffi.dart b/lib/ffi/ffi.dart
|
| index 7b2fcc2d5fa3aabf4381f35100a1cbff3dc38923..4d25b9eba37ee01f8353c383d8e1888d0cbfdb55 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;
|
| +
|
| + Foreign._(this._value);
|
| +
|
| static const int UNKNOWN = 0;
|
|
|
| static const int LINUX = 1;
|
| @@ -19,114 +23,33 @@ 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();
|
|
|
| - 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 +86,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 +97,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 +114,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 +148,157 @@ class Foreign {
|
| int address, a0, a1, a2, a3, a4, a5);
|
|
|
| @fletch.native external static int _Lcall$wLw(int address, a0, a1, a2);
|
| +}
|
| +
|
| +class ForeignPointer extends Foreign {
|
| + int get address => _value;
|
| + ForeignPointer.fromAddress(int address) : super._(address);
|
| + ForeignPointer() : super._(0);
|
| +
|
| + static final ForeignPointer NULL = new ForeignPointer();
|
| +
|
| +}
|
| +
|
| +class ForeignLibrary extends ForeignPointer {
|
| + /// The ForeignLibrary main is used for looking up functions in the libraries
|
| + /// linked in to the main Fletch binary.
|
| + static ForeignLibrary main = new ForeignLibrary.fromName(null);
|
| +
|
| + 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));
|
| + }
|
| +
|
| + /// Provides a platform specific location for a library relative to the
|
| + /// location of the Fletch vm. Takes the name without lib in front and
|
| + /// 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 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) {
|
| + _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 +349,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);
|
| }
|
|
|