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

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

Issue 1659163007: Rename fletch -> dartino (Closed) Base URL: https://github.com/dartino/sdk.git@master
Patch Set: address comments Created 4 years, 10 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 | « lib/core/string.dart ('k') | lib/dartino_embedded.platform » ('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 Dartino project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dartino 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 library dart.fletch; 5 library dart.dartino;
6 6
7 import 'dart:fletch._system' as fletch; 7 import 'dart:dartino._system' as dartino;
8 8
9 /// Fibers are lightweight co-operative multitask units of execution. They 9 /// Fibers are lightweight co-operative multitask units of execution. They
10 /// are scheduled on top of OS-level threads, but they are cheap to create 10 /// are scheduled on top of OS-level threads, but they are cheap to create
11 /// and block. 11 /// and block.
12 class Fiber { 12 class Fiber {
13 13
14 // We keep track of the top of the coroutine stack and 14 // We keep track of the top of the coroutine stack and
15 // the list of other fibers that are waiting for this 15 // the list of other fibers that are waiting for this
16 // fiber to exit. 16 // fiber to exit.
17 Coroutine _coroutine; 17 Coroutine _coroutine;
(...skipping 15 matching lines...) Expand all
33 static Fiber _idleFibers; 33 static Fiber _idleFibers;
34 34
35 Fiber._initial() { 35 Fiber._initial() {
36 _previous = this; 36 _previous = this;
37 _next = this; 37 _next = this;
38 } 38 }
39 39
40 Fiber._forked(entry) { 40 Fiber._forked(entry) {
41 current; // Force initialization of fiber sub-system. 41 current; // Force initialization of fiber sub-system.
42 _coroutine = new Coroutine((ignore) { 42 _coroutine = new Coroutine((ignore) {
43 fletch.runToEnd(entry); 43 dartino.runToEnd(entry);
44 }); 44 });
45 } 45 }
46 46
47 static Fiber get current { 47 static Fiber get current {
48 var current = _current; 48 var current = _current;
49 if (current != null) return current; 49 if (current != null) return current;
50 return _current = new Fiber._initial(); 50 return _current = new Fiber._initial();
51 } 51 }
52 52
53 static Fiber fork(entry) { 53 static Fiber fork(entry) {
54 Fiber fiber = new Fiber._forked(entry); 54 Fiber fiber = new Fiber._forked(entry);
55 _markReady(fiber); 55 _markReady(fiber);
56 return fiber; 56 return fiber;
57 } 57 }
58 58
59 static void yield() { 59 static void yield() {
60 // Handle messages so that fibers that are blocked on receiving 60 // Handle messages so that fibers that are blocked on receiving
61 // messages can wake up. 61 // messages can wake up.
62 Process._handleMessages(); 62 Process._handleMessages();
63 _current._coroutine = Coroutine._coroutineCurrent(); 63 _current._coroutine = Coroutine._coroutineCurrent();
64 _schedule(_current._next); 64 _schedule(_current._next);
65 } 65 }
66 66
67 static void exit([value]) { 67 static void exit([value]) {
68 // If we never created a fiber, we can just go ahead and halt now. 68 // If we never created a fiber, we can just go ahead and halt now.
69 if (_current == null) fletch.halt(); 69 if (_current == null) dartino.halt();
70 70
71 _current._exit(value); 71 _current._exit(value);
72 } 72 }
73 73
74 join() { 74 join() {
75 // If the fiber is already done, we just return the result. 75 // If the fiber is already done, we just return the result.
76 if (_isDone) return _result; 76 if (_isDone) return _result;
77 77
78 // Add the current fiber to the list of fibers waiting 78 // Add the current fiber to the list of fibers waiting
79 // to join [this] fiber. 79 // to join [this] fiber.
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 if (exiting) { 152 if (exiting) {
153 fiber._next = null; 153 fiber._next = null;
154 fiber._previous = null; 154 fiber._previous = null;
155 } else { 155 } else {
156 _idleFibers = _link(fiber, _idleFibers); 156 _idleFibers = _link(fiber, _idleFibers);
157 } 157 }
158 158
159 if (current != null) return current; 159 if (current != null) return current;
160 160
161 // If we don't have any idle fibers, halt. 161 // If we don't have any idle fibers, halt.
162 if (exiting && _idleFibers == null) fletch.halt(); 162 if (exiting && _idleFibers == null) dartino.halt();
163 163
164 while (true) { 164 while (true) {
165 Process._handleMessages(); 165 Process._handleMessages();
166 // A call to _handleMessages can handle more messages than signaled, so 166 // A call to _handleMessages can handle more messages than signaled, so
167 // we can get a following false-positive wakeup. If no new _current is 167 // we can get a following false-positive wakeup. If no new _current is
168 // set, simply yield again. 168 // set, simply yield again.
169 current = _current; 169 current = _current;
170 if (current != null) return current; 170 if (current != null) return current;
171 fletch.yield(fletch.InterruptKind.yield.index); 171 dartino.yield(dartino.InterruptKind.yield.index);
172 } 172 }
173 } 173 }
174 174
175 static void _yieldTo(Fiber from, Fiber to) { 175 static void _yieldTo(Fiber from, Fiber to) {
176 from._coroutine = Coroutine._coroutineCurrent(); 176 from._coroutine = Coroutine._coroutineCurrent();
177 _schedule(to); 177 _schedule(to);
178 } 178 }
179 179
180 // TODO(kasperl): This is temporary debugging support. We 180 // TODO(kasperl): This is temporary debugging support. We
181 // should probably replace this support for passing in an 181 // should probably replace this support for passing in an
182 // id of some sort when forking a fiber. 182 // id of some sort when forking a fiber.
183 static int _count = 0; 183 static int _count = 0;
184 int _index = _count++; 184 int _index = _count++;
185 toString() => "fiber:$_index"; 185 toString() => "fiber:$_index";
186 186
187 static void _schedule(Fiber to) { 187 static void _schedule(Fiber to) {
188 _current = to; 188 _current = to;
189 fletch.coroutineChange(to._coroutine, null); 189 dartino.coroutineChange(to._coroutine, null);
190 } 190 }
191 } 191 }
192 192
193 class Coroutine { 193 class Coroutine {
194 194
195 // TODO(kasperl): The VM has assumptions about the layout 195 // TODO(kasperl): The VM has assumptions about the layout
196 // of coroutine fields. We should validate that the code 196 // of coroutine fields. We should validate that the code
197 // agrees with those assumptions. 197 // agrees with those assumptions.
198 var _stack; 198 var _stack;
199 var _caller; 199 var _caller;
200 200
201 Coroutine(entry) { 201 Coroutine(entry) {
202 _stack = _coroutineNewStack(this, entry); 202 _stack = _coroutineNewStack(this, entry);
203 } 203 }
204 204
205 bool get isSuspended => identical(_caller, null); 205 bool get isSuspended => identical(_caller, null);
206 bool get isRunning => !isSuspended && !isDone; 206 bool get isRunning => !isSuspended && !isDone;
207 bool get isDone => identical(_caller, this); 207 bool get isDone => identical(_caller, this);
208 208
209 call(argument) { 209 call(argument) {
210 if (!isSuspended) throw "Cannot call non-suspended coroutine"; 210 if (!isSuspended) throw "Cannot call non-suspended coroutine";
211 _caller = _coroutineCurrent(); 211 _caller = _coroutineCurrent();
212 var result = fletch.coroutineChange(this, argument); 212 var result = dartino.coroutineChange(this, argument);
213 213
214 // If the called coroutine is done now, we clear the 214 // If the called coroutine is done now, we clear the
215 // stack reference in it so the memory can be reclaimed. 215 // stack reference in it so the memory can be reclaimed.
216 if (isDone) { 216 if (isDone) {
217 _stack = null; 217 _stack = null;
218 } else { 218 } else {
219 _caller = null; 219 _caller = null;
220 } 220 }
221 return result; 221 return result;
222 } 222 }
223 223
224 static yield(value) { 224 static yield(value) {
225 Coroutine caller = _coroutineCurrent()._caller; 225 Coroutine caller = _coroutineCurrent()._caller;
226 if (caller == null) throw "Cannot yield outside coroutine"; 226 if (caller == null) throw "Cannot yield outside coroutine";
227 return fletch.coroutineChange(caller, value); 227 return dartino.coroutineChange(caller, value);
228 } 228 }
229 229
230 _coroutineStart(entry) { 230 _coroutineStart(entry) {
231 // The first call to changeStack is actually skipped but we need 231 // The first call to changeStack is actually skipped but we need
232 // it to make sure the newly started coroutine is suspended in 232 // it to make sure the newly started coroutine is suspended in
233 // exactly the same way as we do when yielding. 233 // exactly the same way as we do when yielding.
234 var argument = fletch.coroutineChange(0, 0); 234 var argument = dartino.coroutineChange(0, 0);
235 var result = entry(argument); 235 var result = entry(argument);
236 236
237 // Mark this coroutine as done and change back to the caller. 237 // Mark this coroutine as done and change back to the caller.
238 Coroutine caller = _caller; 238 Coroutine caller = _caller;
239 _caller = this; 239 _caller = this;
240 fletch.coroutineChange(caller, result); 240 dartino.coroutineChange(caller, result);
241 } 241 }
242 242
243 @fletch.native external static _coroutineCurrent(); 243 @dartino.native external static _coroutineCurrent();
244 @fletch.native external static _coroutineNewStack(coroutine, entry); 244 @dartino.native external static _coroutineNewStack(coroutine, entry);
245 } 245 }
246 246
247 class ProcessDeath { 247 class ProcessDeath {
248 final Process process; 248 final Process process;
249 final int _reason; 249 final int _reason;
250 250
251 ProcessDeath._(this.process, this._reason); 251 ProcessDeath._(this.process, this._reason);
252 252
253 DeathReason get reason => DeathReason.values[_reason]; 253 DeathReason get reason => DeathReason.values[_reason];
254 } 254 }
(...skipping 12 matching lines...) Expand all
267 final int _nativeProcessHandle; 267 final int _nativeProcessHandle;
268 268
269 bool operator==(other) { 269 bool operator==(other) {
270 return 270 return
271 other is Process && 271 other is Process &&
272 other._nativeProcessHandle == _nativeProcessHandle; 272 other._nativeProcessHandle == _nativeProcessHandle;
273 } 273 }
274 274
275 int get hashCode => _nativeProcessHandle.hashCode; 275 int get hashCode => _nativeProcessHandle.hashCode;
276 276
277 @fletch.native bool link() { 277 @dartino.native bool link() {
278 throw fletch.nativeError; 278 throw dartino.nativeError;
279 } 279 }
280 280
281 @fletch.native void unlink() { 281 @dartino.native void unlink() {
282 switch (fletch.nativeError) { 282 switch (dartino.nativeError) {
283 case fletch.wrongArgumentType: 283 case dartino.wrongArgumentType:
284 throw new StateError("Cannot unlink from parent process."); 284 throw new StateError("Cannot unlink from parent process.");
285 default: 285 default:
286 throw fletch.nativeError; 286 throw dartino.nativeError;
287 } 287 }
288 } 288 }
289 289
290 @fletch.native bool monitor(Port port) { 290 @dartino.native bool monitor(Port port) {
291 switch (fletch.nativeError) { 291 switch (dartino.nativeError) {
292 case fletch.wrongArgumentType: 292 case dartino.wrongArgumentType:
293 throw new StateError("The argument to monitor must be a Port object."); 293 throw new StateError("The argument to monitor must be a Port object.");
294 default: 294 default:
295 throw fletch.nativeError; 295 throw dartino.nativeError;
296 } 296 }
297 } 297 }
298 298
299 @fletch.native void unmonitor(Port port) { 299 @dartino.native void unmonitor(Port port) {
300 switch (fletch.nativeError) { 300 switch (dartino.nativeError) {
301 case fletch.wrongArgumentType: 301 case dartino.wrongArgumentType:
302 throw new StateError( 302 throw new StateError(
303 "The argument to unmonitor must be a Port object."); 303 "The argument to unmonitor must be a Port object.");
304 default: 304 default:
305 throw fletch.nativeError; 305 throw dartino.nativeError;
306 } 306 }
307 } 307 }
308 308
309 @fletch.native void kill() { 309 @dartino.native void kill() {
310 throw fletch.nativeError; 310 throw dartino.nativeError;
311 } 311 }
312 312
313 static Process spawn(Function fn, [argument]) { 313 static Process spawn(Function fn, [argument]) {
314 if (!isImmutable(fn)) { 314 if (!isImmutable(fn)) {
315 throw new ArgumentError( 315 throw new ArgumentError(
316 'The closure passed to Process.spawn() must be immutable.'); 316 'The closure passed to Process.spawn() must be immutable.');
317 } 317 }
318 318
319 if (!isImmutable(argument)) { 319 if (!isImmutable(argument)) {
320 throw new ArgumentError( 320 throw new ArgumentError(
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 388
389 /** 389 /**
390 * Exit the current process. If a non-null [to] port is provided, 390 * Exit the current process. If a non-null [to] port is provided,
391 * the process will send the provided [value] to the [to] port as 391 * the process will send the provided [value] to the [to] port as
392 * its final action. 392 * its final action.
393 */ 393 */
394 static void exit({value, Port to}) { 394 static void exit({value, Port to}) {
395 try { 395 try {
396 if (to != null) to._sendExit(value); 396 if (to != null) to._sendExit(value);
397 } finally { 397 } finally {
398 fletch.yield(fletch.InterruptKind.terminate.index); 398 dartino.yield(dartino.InterruptKind.terminate.index);
399 } 399 }
400 } 400 }
401 401
402 // Low-level entry for spawned processes. 402 // Low-level entry for spawned processes.
403 static void _entry(fn, argument) { 403 static void _entry(fn, argument) {
404 if (argument == null) { 404 if (argument == null) {
405 fletch.runToEnd(fn); 405 dartino.runToEnd(fn);
406 } else { 406 } else {
407 fletch.runToEnd(() => fn(argument)); 407 dartino.runToEnd(() => fn(argument));
408 } 408 }
409 } 409 }
410 410
411 // Low-level helper function for spawning. 411 // Low-level helper function for spawning.
412 @fletch.native static Process _spawn(Function entry, 412 @dartino.native static Process _spawn(Function entry,
413 Function fn, 413 Function fn,
414 argument, 414 argument,
415 bool linkToChild, 415 bool linkToChild,
416 bool linkFromChild, 416 bool linkFromChild,
417 Port monitor) { 417 Port monitor) {
418 throw new ArgumentError(); 418 throw new ArgumentError();
419 } 419 }
420 420
421 static void _handleMessages() { 421 static void _handleMessages() {
422 Channel channel; 422 Channel channel;
423 while ((channel = _queueGetChannel()) != null) { 423 while ((channel = _queueGetChannel()) != null) {
424 var message = _queueGetMessage(); 424 var message = _queueGetMessage();
425 if (message is ProcessDeath) { 425 if (message is ProcessDeath) {
426 message = _queueSetupProcessDeath(message); 426 message = _queueSetupProcessDeath(message);
427 } 427 }
428 channel.send(message); 428 channel.send(message);
429 } 429 }
430 } 430 }
431 431
432 @fletch.native external static Process get current; 432 @dartino.native external static Process get current;
433 @fletch.native external static _queueGetMessage(); 433 @dartino.native external static _queueGetMessage();
434 @fletch.native external static _queueSetupProcessDeath(ProcessDeath message); 434 @dartino.native external static _queueSetupProcessDeath(ProcessDeath message);
435 @fletch.native external static Channel _queueGetChannel(); 435 @dartino.native external static Channel _queueGetChannel();
436 } 436 }
437 437
438 // Ports allow you to send messages to a channel. Ports are 438 // Ports allow you to send messages to a channel. Ports are
439 // are transferable and can be sent between processes. 439 // are transferable and can be sent between processes.
440 class Port { 440 class Port {
441 // A Smi stores the aligned pointer to the C++ port object. 441 // A Smi stores the aligned pointer to the C++ port object.
442 final int _port; 442 final int _port;
443 443
444 factory Port(Channel channel) { 444 factory Port(Channel channel) {
445 return Port._create(channel); 445 return Port._create(channel);
446 } 446 }
447 447
448 // TODO(kasperl): Temporary debugging aid. 448 // TODO(kasperl): Temporary debugging aid.
449 int get id => _port; 449 int get id => _port;
450 450
451 // Send a message to the channel. Not blocking. 451 // Send a message to the channel. Not blocking.
452 @fletch.native void send(message) { 452 @dartino.native void send(message) {
453 switch (fletch.nativeError) { 453 switch (dartino.nativeError) {
454 case fletch.wrongArgumentType: 454 case dartino.wrongArgumentType:
455 throw new ArgumentError(); 455 throw new ArgumentError();
456 case fletch.illegalState: 456 case dartino.illegalState:
457 throw new StateError("Port is closed."); 457 throw new StateError("Port is closed.");
458 default: 458 default:
459 throw fletch.nativeError; 459 throw dartino.nativeError;
460 } 460 }
461 } 461 }
462 462
463 @fletch.native void _sendExit(value) { 463 @dartino.native void _sendExit(value) {
464 throw new StateError("Port is closed."); 464 throw new StateError("Port is closed.");
465 } 465 }
466 466
467 @fletch.native external static Port _create(Channel channel); 467 @dartino.native external static Port _create(Channel channel);
468 } 468 }
469 469
470 class Channel { 470 class Channel {
471 Fiber _receiver; // TODO(kasperl): Should this be a queue too? 471 Fiber _receiver; // TODO(kasperl): Should this be a queue too?
472 472
473 // TODO(kasperl): Maybe make this a bit smarter and store 473 // TODO(kasperl): Maybe make this a bit smarter and store
474 // the elements in a growable list? Consider allowing bounds 474 // the elements in a growable list? Consider allowing bounds
475 // on the queue size. 475 // on the queue size.
476 _ChannelEntry _head; 476 _ChannelEntry _head;
477 _ChannelEntry _tail; 477 _ChannelEntry _tail;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 536
537 class _ChannelEntry { 537 class _ChannelEntry {
538 final message; 538 final message;
539 final Fiber sender; 539 final Fiber sender;
540 _ChannelEntry next; 540 _ChannelEntry next;
541 _ChannelEntry(this.message, this.sender); 541 _ChannelEntry(this.message, this.sender);
542 } 542 }
543 543
544 bool isImmutable(Object object) => _isImmutable(object); 544 bool isImmutable(Object object) => _isImmutable(object);
545 545
546 @fletch.native external bool _isImmutable(String string); 546 @dartino.native external bool _isImmutable(String string);
547 547
548 /// Returns a channel that will receive a message in [milliseconds] 548 /// Returns a channel that will receive a message in [milliseconds]
549 /// milliseconds. 549 /// milliseconds.
550 // TODO(sigurdm): Move this function? 550 // TODO(sigurdm): Move this function?
551 Channel sleep(int milliseconds) { 551 Channel sleep(int milliseconds) {
552 if (milliseconds is! int) throw new ArgumentError(milliseconds); 552 if (milliseconds is! int) throw new ArgumentError(milliseconds);
553 Channel channel = new Channel(); 553 Channel channel = new Channel();
554 Port port = new Port(channel); 554 Port port = new Port(channel);
555 _sleep(milliseconds, port); 555 _sleep(milliseconds, port);
556 return channel; 556 return channel;
557 } 557 }
558 558
559 @fletch.native external void _sleep(int milliseconds, Port port); 559 @dartino.native external void _sleep(int milliseconds, Port port);
OLDNEW
« no previous file with comments | « lib/core/string.dart ('k') | lib/dartino_embedded.platform » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698