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

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

Powered by Google App Engine
This is Rietveld 408576698