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

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: indentation 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
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 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
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();
30 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.
61 31
62 int get value => _value; 32 static int get errno => _errno();
63 int get length => _length;
64 33
65 int getInt8(int offset) 34 // Helper for converting the argument to a machine word.
66 => _getInt8(_computeAddress(offset, 1)); 35 int _convert(argument) {
67 int getInt16(int offset) 36 if (argument is Foreign) return argument._value;
68 => _getInt16(_computeAddress(offset, 2)); 37 if (argument is Port) return _convertPort(argument);
69 int getInt32(int offset) 38 if (argument is int) return argument;
70 => _getInt32(_computeAddress(offset, 4)); 39 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 } 40 }
117 41
118 void copyBytesFromList(List<int> list, int from, int to, int listOffset) { 42 @fletch.native external static int _bitsPerMachineWord();
119 int length = to - from; 43 @fletch.native external static int _errno();
120 for (int i = 0; i < length; i++) { 44 @fletch.native external static int _platform();
121 setUint8(from + i, list[listOffset + i]); 45 @fletch.native external static int _architecture();
122 } 46 @fletch.native external static int _convertPort(Port port);
123 }
124 47
125 void free() { 48 }
126 if (_length > 0) _free(_value); 49
127 _value = 0; 50 class ForeignFunction extends Foreign {
128 _length = 0; 51 int get address => _value;
129 } 52
53 ForeignFunction.fromAddress(int value) : super._(value);
130 54
131 // Support for calling foreign functions that return 55 // Support for calling foreign functions that return
132 // machine words as immediate integer value. 56 // machine words as immediate integer value.
133 int icall$0() => _icall$0(_value); 57 int icall$0() => _icall$0(_value);
134 int icall$1(a0) => _icall$1(_value, _convert(a0)); 58 int icall$1(a0) => _icall$1(_value, _convert(a0));
135 int icall$2(a0, a1) => _icall$2(_value, _convert(a0), _convert(a1)); 59 int icall$2(a0, a1) => _icall$2(_value, _convert(a0), _convert(a1));
136 int icall$3(a0, a1, a2) { 60 int icall$3(a0, a1, a2) {
137 return _icall$3(_value, _convert(a0), _convert(a1), _convert(a2)); 61 return _icall$3(_value, _convert(a0), _convert(a1), _convert(a2));
138 } 62 }
139 int icall$4(a0, a1, a2, a3) { 63 int icall$4(a0, a1, a2, a3) {
(...skipping 16 matching lines...) Expand all
156 void vcall$1(a0) { 80 void vcall$1(a0) {
157 _vcall$1(_value, _convert(a0)); 81 _vcall$1(_value, _convert(a0));
158 } 82 }
159 void vcall$2(a0, a1) { 83 void vcall$2(a0, a1) {
160 _vcall$2(_value, _convert(a0), _convert(a1)); 84 _vcall$2(_value, _convert(a0), _convert(a1));
161 } 85 }
162 void vcall$3(a0, a1, a2) { 86 void vcall$3(a0, a1, a2) {
163 _vcall$3(_value, _convert(a0), _convert(a1), _convert(a2)); 87 _vcall$3(_value, _convert(a0), _convert(a1), _convert(a2));
164 } 88 }
165 void vcall$4(a0, a1, a2, a3) { 89 void vcall$4(a0, a1, a2, a3) {
166 _vcall$4(_value, _convert(a0), _convert(a1), _convert(a2), _convert(a3)); 90 _vcall$4(_value, _convert(a0), _convert(a1), _convert(a2),_convert(a3));
167 } 91 }
168 void vcall$5(a0, a1, a2, a3, a4) { 92 void vcall$5(a0, a1, a2, a3, a4) {
169 _vcall$5(_value, _convert(a0), _convert(a1), _convert(a2), _convert(a3), 93 _vcall$5(_value, _convert(a0), _convert(a1), _convert(a2), _convert(a3),
170 _convert(a4)); 94 _convert(a4));
171 } 95 }
172 void vcall$6(a0, a1, a2, a3, a4, a5) { 96 void vcall$6(a0, a1, a2, a3, a4, a5) {
173 _vcall$6(_value, _convert(a0), _convert(a1), _convert(a2), _convert(a3), 97 _vcall$6(_value, _convert(a0), _convert(a1), _convert(a2), _convert(a3),
174 _convert(a4), _convert(a5)); 98 _convert(a4), _convert(a5));
175 } 99 }
176 100
101 // TODO(ricow): this is insanely specific and only used for rseek.
177 // Support for calling foreign functions that 102 // Support for calling foreign functions that
178 // - Returns a 64 bit integer value. 103 // - Returns a 64 bit integer value.
179 // - Takes: 104 // - Takes:
180 // * a word, 105 // * a word,
181 // * a 64 bit int 106 // * a 64 bit int
182 // * a word 107 // * a word
183 int Lcall$wLw(a0, a1, a2) { 108 int Lcall$wLw(a0, a1, a2) {
184 return _Lcall$wLw(_value, 109 return _Lcall$wLw(_value,
185 _convert(a0), 110 _convert(a0),
186 _convert(a1), 111 _convert(a1),
187 _convert(a2)); 112 _convert(a2));
188 } 113 }
189 114
190 // Support for calling foreign functions that return 115 // Support for calling foreign functions that return
191 // machine words -- typically pointers -- encapulated in 116 // machine words -- typically pointers -- encapulated in
192 // the given foreign object arguments. 117 // the given foreign object arguments.
193 Foreign pcall$0(Foreign foreign) { 118 ForeignPointer pcall$0(ForeignPointer foreign) {
194 foreign._value = _icall$0(_value); 119 foreign._value = _icall$0(_value);
195 return foreign; 120 return foreign;
196 } 121 }
197 122
198 Foreign pcall$1(Foreign foreign, a0) { 123 ForeignPointer pcall$1(ForeignPointer foreign, a0) {
199 foreign._value = _icall$1(_value, _convert(a0)); 124 foreign._value = _icall$1(_value, _convert(a0));
200 return foreign; 125 return foreign;
201 } 126 }
202 127
203 Foreign pcall$2(Foreign foreign, a0, a1) { 128 ForeignPointer pcall$2(ForeignPointer foreign, a0, a1) {
204 foreign._value = _icall$2(_value, _convert(a0), _convert(a1)); 129 foreign._value = _icall$2(_value, _convert(a0), _convert(a1));
205 return foreign; 130 return foreign;
206 } 131 }
207 132
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); 133 @fletch.native external static int _icall$0(int address);
232 @fletch.native external static int _icall$1(int address, a0); 134 @fletch.native external static int _icall$1(int address, a0);
233 @fletch.native external static int _icall$2(int address, a0, a1); 135 @fletch.native external static int _icall$2(int address, a0, a1);
234 @fletch.native external static int _icall$3(int address, a0, a1, a2); 136 @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); 137 @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); 138 @fletch.native external static int _icall$5(int address, a0, a1, a2, a3, a4);
237 @fletch.native external static int _icall$6( 139 @fletch.native external static int _icall$6(
238 int address, a0, a1, a2, a3, a4, a5); 140 int address, a0, a1, a2, a3, a4, a5);
239 141
240 @fletch.native external static int _vcall$0(int address); 142 @fletch.native external static int _vcall$0(int address);
241 @fletch.native external static int _vcall$1(int address, a0); 143 @fletch.native external static int _vcall$1(int address, a0);
242 @fletch.native external static int _vcall$2(int address, a0, a1); 144 @fletch.native external static int _vcall$2(int address, a0, a1);
243 @fletch.native external static int _vcall$3(int address, a0, a1, a2); 145 @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); 146 @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); 147 @fletch.native external static int _vcall$5(int address, a0, a1, a2, a3, a4);
246 @fletch.native external static int _vcall$6( 148 @fletch.native external static int _vcall$6(
247 int address, a0, a1, a2, a3, a4, a5); 149 int address, a0, a1, a2, a3, a4, a5);
248 150
249 @fletch.native external static int _Lcall$wLw(int address, a0, a1, a2); 151 @fletch.native external static int _Lcall$wLw(int address, a0, a1, a2);
152 }
153
154 class ForeignLibrary extends ForeignPointer {
155 /// 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.
156 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
157
158 ForeignLibrary.fromAddress(int address) : super.fromAddress(address);
159
160 factory ForeignLibrary.fromName(String name) {
161 return new ForeignLibrary.fromAddress(_lookupLibrary(name));
162 }
163
164 ForeignFunction lookup(String name) {
165 return new ForeignFunction.fromAddress(_lookupFunction(_value, name));
166 }
167
168 /// 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.
169 /// 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.
170 /// returns a platform specific path. Example, on linux, foobar_hash
171 /// become PATH_TO_EXECUTABLE/lib/libfoobar_hash.so.
172 @fletch.native external static String bundleLibraryName(String libraryName);
173
174 void close() {
175 _closeLibrary(_value);
176 }
177
178 @fletch.native static int _lookupLibrary(String name) {
179 var error = fletch.nativeError;
180 throw (error != fletch.indexOutOfBounds) ? error : new ArgumentError();
181 }
182
183 @fletch.native static int _lookupFunction(int _value, String name) {
184 var error = fletch.nativeError;
185 throw (error != fletch.indexOutOfBounds) ? error : new ArgumentError();
186 }
187
188 @fletch.native static int _closeLibrary(int _value) {
189 var error = fletch.nativeError;
190 throw (error != fletch.indexOutOfBounds) ? error : new ArgumentError();
191 }
192 }
193
194 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.
195 int get address => _value;
196 ForeignPointer.fromAddress(int address) : super._(address);
197 ForeignPointer() : super._(0);
198 }
199
200 class ForeignMemory extends ForeignPointer {
201 int _length;
202 int get length => _length;
203
204 ForeignMemory.fromAddress(int address, this._length) :
205 super.fromAddress(address);
206
207 ForeignMemory.fromForeignPointer(ForeignPointer pointer, this._length) :
208 super.fromAddress(pointer.address);
209
210 ForeignMemory.allocated(this._length) {
211 _value = _allocate(_length);
212 }
213
214 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?
215 _value = _allocate(_length);
216 _markForFinalization();
217 }
218
219 factory ForeignMemory.fromString(String str) {
220 var memory = new ForeignMemory.allocated(str.length + 1);
221 for (int i = 0; i < str.length; i++) {
222 memory.setUint8(i, str.codeUnitAt(i));
223 }
224 return memory;
225 }
226
227 int getInt8(int offset)
228 => _getInt8(_computeAddress(offset, 1));
229 int getInt16(int offset)
230 => _getInt16(_computeAddress(offset, 2));
231 int getInt32(int offset)
232 => _getInt32(_computeAddress(offset, 4));
233 int getInt64(int offset)
234 => _getInt64(_computeAddress(offset, 8));
235
236 int setInt8(int offset, int value)
237 => _setInt8(_computeAddress(offset, 1), value);
238 int setInt16(int offset, int value)
239 => _setInt16(_computeAddress(offset, 2), value);
240 int setInt32(int offset, int value)
241 => _setInt32(_computeAddress(offset, 4), value);
242 int setInt64(int offset, int value)
243 => _setInt64(_computeAddress(offset, 8), value);
244
245 int getUint8(int offset)
246 => _getUint8(_computeAddress(offset, 1));
247 int getUint16(int offset)
248 => _getUint16(_computeAddress(offset, 2));
249 int getUint32(int offset)
250 => _getUint32(_computeAddress(offset, 4));
251 int getUint64(int offset)
252 => _getUint64(_computeAddress(offset, 8));
253
254 int setUint8(int offset, int value)
255 => _setUint8(_computeAddress(offset, 1), value);
256 int setUint16(int offset, int value)
257 => _setUint16(_computeAddress(offset, 2), value);
258 int setUint32(int offset, int value)
259 => _setUint32(_computeAddress(offset, 4), value);
260 int setUint64(int offset, int value)
261 => _setUint64(_computeAddress(offset, 8), value);
262
263 double getFloat32(int offset)
264 => _getFloat32(_computeAddress(offset, 4));
265 double getFloat64(int offset)
266 => _getFloat64(_computeAddress(offset, 8));
267
268 double setFloat32(int offset, double value)
269 => _setFloat32(_computeAddress(offset, 4), value);
270 double setFloat64(int offset, double value)
271 => _setFloat64(_computeAddress(offset, 8), value);
272
273 // Helper for checking bounds and computing derived
274 // addresses for memory address functionality.
275 int _computeAddress(int offset, int n) {
276 if (offset < 0 || offset + n > _length) throw new IndexError(offset, this);
277 return _value + offset;
278 }
279
280 void copyBytesToList(List<int> list, int from, int to, int listOffset) {
281 int length = to - from;
282 for (int i = 0; i < length; i++) {
283 list[listOffset + i] = getUint8(from + i);
284 }
285 }
286
287 void copyBytesFromList(List<int> list, int from, int to, int listOffset) {
288 int length = to - from;
289 for (int i = 0; i < length; i++) {
290 setUint8(from + i, list[listOffset + i]);
291 }
292 }
293
294 void free() {
295 if (_length > 0) _free(_value);
296 _value = 0;
297 _length = 0;
298 }
250 299
251 @fletch.native external static int _allocate(int length); 300 @fletch.native external static int _allocate(int length);
252 @fletch.native external static void _free(int address); 301 @fletch.native external static void _free(int address);
253 @fletch.native external void _markForFinalization(); 302 @fletch.native external void _markForFinalization();
254 303
255 @fletch.native external static int _getInt8(int address); 304 @fletch.native external static int _getInt8(int address);
256 @fletch.native external static int _getInt16(int address); 305 @fletch.native external static int _getInt16(int address);
257 @fletch.native external static int _getInt32(int address); 306 @fletch.native external static int _getInt32(int address);
258 @fletch.native external static int _getInt64(int address); 307 @fletch.native external static int _getInt64(int address);
259 308
(...skipping 30 matching lines...) Expand all
290 339
291 @fletch.native external static double _getFloat32(int address); 340 @fletch.native external static double _getFloat32(int address);
292 @fletch.native external static double _getFloat64(int address); 341 @fletch.native external static double _getFloat64(int address);
293 342
294 @fletch.native static double _setFloat32(int address, double value) { 343 @fletch.native static double _setFloat32(int address, double value) {
295 throw new ArgumentError(); 344 throw new ArgumentError();
296 } 345 }
297 @fletch.native static double _setFloat64(int address, double value) { 346 @fletch.native static double _setFloat64(int address, double value) {
298 throw new ArgumentError(); 347 throw new ArgumentError();
299 } 348 }
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 } 349 }
OLDNEW
« no previous file with comments | « fletch.gyp ('k') | lib/io/system.dart » ('j') | lib/io/system_posix.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698