Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(502)

Side by Side Diff: lib/ffi/ffi.dart

Issue 1209033003: Work in progres, please take a look and give early feedback if this is the way we want to structure… (Closed) Base URL: git@github.com:dart-lang/fletch.git@master
Patch Set: address comments Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « fletch.gyp ('k') | lib/io/system.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 // The dart:ffi library is a low-level 'foreign function interface' 5 // The dart:ffi library is a low-level 'foreign function interface'
6 // library that allows Dart code to call arbitrary native platform 6 // library that allows Dart code to call arbitrary native platform
7 // code defined outside the VM. 7 // code defined outside the VM.
8 library dart.ffi; 8 library dart.ffi;
9 9
10 import 'dart:_fletch_system' as fletch; 10 import 'dart:_fletch_system' as fletch;
11 11
12 class Foreign { 12 class Foreign {
13 int _value;
14
15 Foreign._(this._value);
16
13 static const int UNKNOWN = 0; 17 static const int UNKNOWN = 0;
14 18
15 static const int LINUX = 1; 19 static const int LINUX = 1;
16 static const int MACOS = 2; 20 static const int MACOS = 2;
17 21
18 static const int IA32 = 1; 22 static const int IA32 = 1;
19 static const int X64 = 2; 23 static const int X64 = 2;
20 static const int ARM = 3; 24 static const int ARM = 3;
21 25
22 static final Foreign NULL = new Foreign();
23
24 int _value;
25 int _length;
26
27 Foreign() : _value = 0, _length = 0;
28
29 Foreign.allocated(this._length) {
30 _value = _allocate(_length);
31 }
32
33 Foreign.allocatedFinalize(this._length) {
34 _value = _allocate(_length);
35 _markForFinalization();
36 }
37
38 Foreign.fromAddress(this._value, this._length);
39
40 Foreign.fromAddressFinalize(this._value, this._length) {
41 _markForFinalization();
42 }
43
44 factory Foreign.fromString(String str) {
45 var foreign = new Foreign.allocated(str.length + 1);
46 for (int i = 0; i < str.length; i++) {
47 foreign.setUint8(i, str.codeUnitAt(i));
48 }
49 return foreign;
50 }
51
52 static Foreign lookup(String name, {String library}) {
53 if (library != null && library.isEmpty) library = null;
54 return new Foreign.fromAddress(_lookup(name, library), 0);
55 }
56
57 // TODO(kasperl): Not quite sure where this fits in. 26 // TODO(kasperl): Not quite sure where this fits in.
58 static final int bitsPerMachineWord = _bitsPerMachineWord(); 27 static final int bitsPerMachineWord = _bitsPerMachineWord();
59 static final int platform = _platform(); 28 static final int platform = _platform();
60 static final int architecture = _architecture(); 29 static final int architecture = _architecture();
61 30
62 int get value => _value; 31 static int get errno => _errno();
63 int get length => _length;
64 32
65 int getInt8(int offset) 33 // Helper for converting the argument to a machine word.
66 => _getInt8(_computeAddress(offset, 1)); 34 int _convert(argument) {
67 int getInt16(int offset) 35 if (argument is Foreign) return argument._value;
68 => _getInt16(_computeAddress(offset, 2)); 36 if (argument is Port) return _convertPort(argument);
69 int getInt32(int offset) 37 if (argument is int) return argument;
70 => _getInt32(_computeAddress(offset, 4)); 38 throw new ArgumentError();
71 int getInt64(int offset)
72 => _getInt64(_computeAddress(offset, 8));
73
74 int setInt8(int offset, int value)
75 => _setInt8(_computeAddress(offset, 1), value);
76 int setInt16(int offset, int value)
77 => _setInt16(_computeAddress(offset, 2), value);
78 int setInt32(int offset, int value)
79 => _setInt32(_computeAddress(offset, 4), value);
80 int setInt64(int offset, int value)
81 => _setInt64(_computeAddress(offset, 8), value);
82
83 int getUint8(int offset)
84 => _getUint8(_computeAddress(offset, 1));
85 int getUint16(int offset)
86 => _getUint16(_computeAddress(offset, 2));
87 int getUint32(int offset)
88 => _getUint32(_computeAddress(offset, 4));
89 int getUint64(int offset)
90 => _getUint64(_computeAddress(offset, 8));
91
92 int setUint8(int offset, int value)
93 => _setUint8(_computeAddress(offset, 1), value);
94 int setUint16(int offset, int value)
95 => _setUint16(_computeAddress(offset, 2), value);
96 int setUint32(int offset, int value)
97 => _setUint32(_computeAddress(offset, 4), value);
98 int setUint64(int offset, int value)
99 => _setUint64(_computeAddress(offset, 8), value);
100
101 double getFloat32(int offset)
102 => _getFloat32(_computeAddress(offset, 4));
103 double getFloat64(int offset)
104 => _getFloat64(_computeAddress(offset, 8));
105
106 double setFloat32(int offset, double value)
107 => _setFloat32(_computeAddress(offset, 4), value);
108 double setFloat64(int offset, double value)
109 => _setFloat64(_computeAddress(offset, 8), value);
110
111 void copyBytesToList(List<int> list, int from, int to, int listOffset) {
112 int length = to - from;
113 for (int i = 0; i < length; i++) {
114 list[listOffset + i] = getUint8(from + i);
115 }
116 } 39 }
117 40
118 void copyBytesFromList(List<int> list, int from, int to, int listOffset) { 41 @fletch.native external static int _bitsPerMachineWord();
119 int length = to - from; 42 @fletch.native external static int _errno();
120 for (int i = 0; i < length; i++) { 43 @fletch.native external static int _platform();
121 setUint8(from + i, list[listOffset + i]); 44 @fletch.native external static int _architecture();
122 } 45 @fletch.native external static int _convertPort(Port port);
123 }
124 46
125 void free() { 47 }
126 if (_length > 0) _free(_value); 48
127 _value = 0; 49 class ForeignFunction extends Foreign {
128 _length = 0; 50 int get address => _value;
129 } 51
52 ForeignFunction.fromAddress(int value) : super._(value);
130 53
131 // Support for calling foreign functions that return 54 // Support for calling foreign functions that return
132 // machine words as immediate integer value. 55 // machine words as immediate integer value.
133 int icall$0() => _icall$0(_value); 56 int icall$0() => _icall$0(_value);
134 int icall$1(a0) => _icall$1(_value, _convert(a0)); 57 int icall$1(a0) => _icall$1(_value, _convert(a0));
135 int icall$2(a0, a1) => _icall$2(_value, _convert(a0), _convert(a1)); 58 int icall$2(a0, a1) => _icall$2(_value, _convert(a0), _convert(a1));
136 int icall$3(a0, a1, a2) { 59 int icall$3(a0, a1, a2) {
137 return _icall$3(_value, _convert(a0), _convert(a1), _convert(a2)); 60 return _icall$3(_value, _convert(a0), _convert(a1), _convert(a2));
138 } 61 }
139 int icall$4(a0, a1, a2, a3) { 62 int icall$4(a0, a1, a2, a3) {
(...skipping 16 matching lines...) Expand all
156 void vcall$1(a0) { 79 void vcall$1(a0) {
157 _vcall$1(_value, _convert(a0)); 80 _vcall$1(_value, _convert(a0));
158 } 81 }
159 void vcall$2(a0, a1) { 82 void vcall$2(a0, a1) {
160 _vcall$2(_value, _convert(a0), _convert(a1)); 83 _vcall$2(_value, _convert(a0), _convert(a1));
161 } 84 }
162 void vcall$3(a0, a1, a2) { 85 void vcall$3(a0, a1, a2) {
163 _vcall$3(_value, _convert(a0), _convert(a1), _convert(a2)); 86 _vcall$3(_value, _convert(a0), _convert(a1), _convert(a2));
164 } 87 }
165 void vcall$4(a0, a1, a2, a3) { 88 void vcall$4(a0, a1, a2, a3) {
166 _vcall$4(_value, _convert(a0), _convert(a1), _convert(a2), _convert(a3)); 89 _vcall$4(_value, _convert(a0), _convert(a1), _convert(a2),_convert(a3));
167 } 90 }
168 void vcall$5(a0, a1, a2, a3, a4) { 91 void vcall$5(a0, a1, a2, a3, a4) {
169 _vcall$5(_value, _convert(a0), _convert(a1), _convert(a2), _convert(a3), 92 _vcall$5(_value, _convert(a0), _convert(a1), _convert(a2), _convert(a3),
170 _convert(a4)); 93 _convert(a4));
171 } 94 }
172 void vcall$6(a0, a1, a2, a3, a4, a5) { 95 void vcall$6(a0, a1, a2, a3, a4, a5) {
173 _vcall$6(_value, _convert(a0), _convert(a1), _convert(a2), _convert(a3), 96 _vcall$6(_value, _convert(a0), _convert(a1), _convert(a2), _convert(a3),
174 _convert(a4), _convert(a5)); 97 _convert(a4), _convert(a5));
175 } 98 }
176 99
100 // TODO(ricow): this is insanely specific and only used for rseek.
177 // Support for calling foreign functions that 101 // Support for calling foreign functions that
178 // - Returns a 64 bit integer value. 102 // - Returns a 64 bit integer value.
179 // - Takes: 103 // - Takes:
180 // * a word, 104 // * a word,
181 // * a 64 bit int 105 // * a 64 bit int
182 // * a word 106 // * a word
183 int Lcall$wLw(a0, a1, a2) { 107 int Lcall$wLw(a0, a1, a2) {
184 return _Lcall$wLw(_value, 108 return _Lcall$wLw(_value,
185 _convert(a0), 109 _convert(a0),
186 _convert(a1), 110 _convert(a1),
187 _convert(a2)); 111 _convert(a2));
188 } 112 }
189 113
190 // Support for calling foreign functions that return 114 // Support for calling foreign functions that return
191 // machine words -- typically pointers -- encapulated in 115 // machine words -- typically pointers -- encapulated in
192 // the given foreign object arguments. 116 // the given foreign object arguments.
193 Foreign pcall$0(Foreign foreign) { 117 ForeignPointer pcall$0(ForeignPointer foreign) {
194 foreign._value = _icall$0(_value); 118 foreign._value = _icall$0(_value);
195 return foreign; 119 return foreign;
196 } 120 }
197 121
198 Foreign pcall$1(Foreign foreign, a0) { 122 ForeignPointer pcall$1(ForeignPointer foreign, a0) {
199 foreign._value = _icall$1(_value, _convert(a0)); 123 foreign._value = _icall$1(_value, _convert(a0));
200 return foreign; 124 return foreign;
201 } 125 }
202 126
203 Foreign pcall$2(Foreign foreign, a0, a1) { 127 ForeignPointer pcall$2(ForeignPointer foreign, a0, a1) {
204 foreign._value = _icall$2(_value, _convert(a0), _convert(a1)); 128 foreign._value = _icall$2(_value, _convert(a0), _convert(a1));
205 return foreign; 129 return foreign;
206 } 130 }
207 131
208 static int get errno => _errno();
209
210 // Helper for checking bounds and computing derived
211 // address for memory address functionality.
212 int _computeAddress(int offset, int n) {
213 if (offset < 0 || offset + n > _length) throw new IndexError(offset, this);
214 return _value + offset;
215 }
216
217 // Helper for converting the argument to a machine word.
218 int _convert(argument) {
219 if (argument is Foreign) return argument._value;
220 if (argument is Port) return _convertPort(argument);
221 if (argument is int) return argument;
222 throw new ArgumentError();
223 }
224
225 // Natives needed for FFI support.
226 @fletch.native static int _lookup(String name, String library) {
227 var error = fletch.nativeError;
228 throw (error != fletch.indexOutOfBounds) ? error : new ArgumentError();
229 }
230
231 @fletch.native external static int _icall$0(int address); 132 @fletch.native external static int _icall$0(int address);
232 @fletch.native external static int _icall$1(int address, a0); 133 @fletch.native external static int _icall$1(int address, a0);
233 @fletch.native external static int _icall$2(int address, a0, a1); 134 @fletch.native external static int _icall$2(int address, a0, a1);
234 @fletch.native external static int _icall$3(int address, a0, a1, a2); 135 @fletch.native external static int _icall$3(int address, a0, a1, a2);
235 @fletch.native external static int _icall$4(int address, a0, a1, a2, a3); 136 @fletch.native external static int _icall$4(int address, a0, a1, a2, a3);
236 @fletch.native external static int _icall$5(int address, a0, a1, a2, a3, a4); 137 @fletch.native external static int _icall$5(int address, a0, a1, a2, a3, a4);
237 @fletch.native external static int _icall$6( 138 @fletch.native external static int _icall$6(
238 int address, a0, a1, a2, a3, a4, a5); 139 int address, a0, a1, a2, a3, a4, a5);
239 140
240 @fletch.native external static int _vcall$0(int address); 141 @fletch.native external static int _vcall$0(int address);
241 @fletch.native external static int _vcall$1(int address, a0); 142 @fletch.native external static int _vcall$1(int address, a0);
242 @fletch.native external static int _vcall$2(int address, a0, a1); 143 @fletch.native external static int _vcall$2(int address, a0, a1);
243 @fletch.native external static int _vcall$3(int address, a0, a1, a2); 144 @fletch.native external static int _vcall$3(int address, a0, a1, a2);
244 @fletch.native external static int _vcall$4(int address, a0, a1, a2, a3); 145 @fletch.native external static int _vcall$4(int address, a0, a1, a2, a3);
245 @fletch.native external static int _vcall$5(int address, a0, a1, a2, a3, a4); 146 @fletch.native external static int _vcall$5(int address, a0, a1, a2, a3, a4);
246 @fletch.native external static int _vcall$6( 147 @fletch.native external static int _vcall$6(
247 int address, a0, a1, a2, a3, a4, a5); 148 int address, a0, a1, a2, a3, a4, a5);
248 149
249 @fletch.native external static int _Lcall$wLw(int address, a0, a1, a2); 150 @fletch.native external static int _Lcall$wLw(int address, a0, a1, a2);
151 }
152
153 class ForeignPointer extends Foreign {
154 int get address => _value;
155 ForeignPointer.fromAddress(int address) : super._(address);
156 ForeignPointer() : super._(0);
157
158 static final ForeignPointer NULL = new ForeignPointer();
159
160 }
161
162 class ForeignLibrary extends ForeignPointer {
163 /// The ForeignLibrary main is used for looking up functions in the libraries
164 /// linked in to the main Fletch binary.
165 static ForeignLibrary main = new ForeignLibrary.fromName(null);
166
167 ForeignLibrary.fromAddress(int address) : super.fromAddress(address);
168
169 factory ForeignLibrary.fromName(String name) {
170 return new ForeignLibrary.fromAddress(_lookupLibrary(name));
171 }
172
173 ForeignFunction lookup(String name) {
174 return new ForeignFunction.fromAddress(_lookupFunction(_value, name));
175 }
176
177 /// Provides a platform specific location for a library relative to the
178 /// location of the Fletch vm. Takes the name without lib in front and
179 /// returns a platform specific path. Example, on linux, foobar_hash
180 /// become PATH_TO_EXECUTABLE/lib/libfoobar_hash.so.
181 @fletch.native external static String bundleLibraryName(String libraryName);
182
183 void close() {
184 _closeLibrary(_value);
185 }
186
187 @fletch.native static int _lookupLibrary(String name) {
188 var error = fletch.nativeError;
189 throw (error != fletch.indexOutOfBounds) ? error : new ArgumentError();
190 }
191
192 @fletch.native static int _lookupFunction(int _value, String name) {
193 var error = fletch.nativeError;
194 throw (error != fletch.indexOutOfBounds) ? error : new ArgumentError();
195 }
196
197 @fletch.native static int _closeLibrary(int _value) {
198 var error = fletch.nativeError;
199 throw (error != fletch.indexOutOfBounds) ? error : new ArgumentError();
200 }
201 }
202
203 class ForeignMemory extends ForeignPointer {
204 int _length;
205 int get length => _length;
206
207 ForeignMemory.fromAddress(int address, this._length) :
208 super.fromAddress(address);
209
210 ForeignMemory.fromForeignPointer(ForeignPointer pointer, this._length) :
211 super.fromAddress(pointer.address);
212
213 ForeignMemory.allocated(this._length) {
214 _value = _allocate(_length);
215 }
216
217 ForeignMemory.allocatedFinalize(this._length) {
218 _value = _allocate(_length);
219 _markForFinalization();
220 }
221
222 factory ForeignMemory.fromString(String str) {
223 var memory = new ForeignMemory.allocated(str.length + 1);
224 for (int i = 0; i < str.length; i++) {
225 memory.setUint8(i, str.codeUnitAt(i));
226 }
227 return memory;
228 }
229
230 int getInt8(int offset)
231 => _getInt8(_computeAddress(offset, 1));
232 int getInt16(int offset)
233 => _getInt16(_computeAddress(offset, 2));
234 int getInt32(int offset)
235 => _getInt32(_computeAddress(offset, 4));
236 int getInt64(int offset)
237 => _getInt64(_computeAddress(offset, 8));
238
239 int setInt8(int offset, int value)
240 => _setInt8(_computeAddress(offset, 1), value);
241 int setInt16(int offset, int value)
242 => _setInt16(_computeAddress(offset, 2), value);
243 int setInt32(int offset, int value)
244 => _setInt32(_computeAddress(offset, 4), value);
245 int setInt64(int offset, int value)
246 => _setInt64(_computeAddress(offset, 8), value);
247
248 int getUint8(int offset)
249 => _getUint8(_computeAddress(offset, 1));
250 int getUint16(int offset)
251 => _getUint16(_computeAddress(offset, 2));
252 int getUint32(int offset)
253 => _getUint32(_computeAddress(offset, 4));
254 int getUint64(int offset)
255 => _getUint64(_computeAddress(offset, 8));
256
257 int setUint8(int offset, int value)
258 => _setUint8(_computeAddress(offset, 1), value);
259 int setUint16(int offset, int value)
260 => _setUint16(_computeAddress(offset, 2), value);
261 int setUint32(int offset, int value)
262 => _setUint32(_computeAddress(offset, 4), value);
263 int setUint64(int offset, int value)
264 => _setUint64(_computeAddress(offset, 8), value);
265
266 double getFloat32(int offset)
267 => _getFloat32(_computeAddress(offset, 4));
268 double getFloat64(int offset)
269 => _getFloat64(_computeAddress(offset, 8));
270
271 double setFloat32(int offset, double value)
272 => _setFloat32(_computeAddress(offset, 4), value);
273 double setFloat64(int offset, double value)
274 => _setFloat64(_computeAddress(offset, 8), value);
275
276 // Helper for checking bounds and computing derived
277 // addresses for memory address functionality.
278 int _computeAddress(int offset, int n) {
279 if (offset < 0 || offset + n > _length) throw new IndexError(offset, this);
280 return _value + offset;
281 }
282
283 void copyBytesToList(List<int> list, int from, int to, int listOffset) {
284 int length = to - from;
285 for (int i = 0; i < length; i++) {
286 list[listOffset + i] = getUint8(from + i);
287 }
288 }
289
290 void copyBytesFromList(List<int> list, int from, int to, int listOffset) {
291 int length = to - from;
292 for (int i = 0; i < length; i++) {
293 setUint8(from + i, list[listOffset + i]);
294 }
295 }
296
297 void free() {
298 if (_length > 0) _free(_value);
299 _value = 0;
300 _length = 0;
301 }
250 302
251 @fletch.native external static int _allocate(int length); 303 @fletch.native external static int _allocate(int length);
252 @fletch.native external static void _free(int address); 304 @fletch.native external static void _free(int address);
253 @fletch.native external void _markForFinalization(); 305 @fletch.native external void _markForFinalization();
254 306
255 @fletch.native external static int _getInt8(int address); 307 @fletch.native external static int _getInt8(int address);
256 @fletch.native external static int _getInt16(int address); 308 @fletch.native external static int _getInt16(int address);
257 @fletch.native external static int _getInt32(int address); 309 @fletch.native external static int _getInt32(int address);
258 @fletch.native external static int _getInt64(int address); 310 @fletch.native external static int _getInt64(int address);
259 311
(...skipping 30 matching lines...) Expand all
290 342
291 @fletch.native external static double _getFloat32(int address); 343 @fletch.native external static double _getFloat32(int address);
292 @fletch.native external static double _getFloat64(int address); 344 @fletch.native external static double _getFloat64(int address);
293 345
294 @fletch.native static double _setFloat32(int address, double value) { 346 @fletch.native static double _setFloat32(int address, double value) {
295 throw new ArgumentError(); 347 throw new ArgumentError();
296 } 348 }
297 @fletch.native static double _setFloat64(int address, double value) { 349 @fletch.native static double _setFloat64(int address, double value) {
298 throw new ArgumentError(); 350 throw new ArgumentError();
299 } 351 }
300
301 @fletch.native external static int _bitsPerMachineWord();
302 @fletch.native external static int _errno();
303 @fletch.native external static int _platform();
304 @fletch.native external static int _architecture();
305 @fletch.native external static int _convertPort(Port port);
306 } 352 }
OLDNEW
« no previous file with comments | « fletch.gyp ('k') | lib/io/system.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698