| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart 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 file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * A native object that is shared across isolates. This object is visible to all | 6 * A native object that is shared across isolates. This object is visible to all |
| 7 * isolates running on the same worker (either UI or background web worker). | 7 * isolates running on the same worker (either UI or background web worker). |
| 8 * | 8 * |
| 9 * This is code that is intended to 'escape' the isolate boundaries in order to | 9 * This is code that is intended to 'escape' the isolate boundaries in order to |
| 10 * implement the semantics of friendly isolates in JavaScript. Without this we | 10 * implement the semantics of friendly isolates in JavaScript. Without this we |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 } else { | 159 } else { |
| 160 // Nothing more to do. | 160 // Nothing more to do. |
| 161 return message; | 161 return message; |
| 162 } | 162 } |
| 163 } | 163 } |
| 164 | 164 |
| 165 /** Default worker. */ | 165 /** Default worker. */ |
| 166 class MainWorker { | 166 class MainWorker { |
| 167 int id = 0; | 167 int id = 0; |
| 168 void postMessage(msg) native "return \$globalThis.postMessage(msg);"; | 168 void postMessage(msg) native "return \$globalThis.postMessage(msg);"; |
| 169 void onmessage(f) native "\$globalThis.onmessage = f;"; | 169 void set onmessage(f) native "\$globalThis.onmessage = f;"; |
| 170 void terminate() {} | 170 void terminate() {} |
| 171 } | 171 } |
| 172 | 172 |
| 173 /** |
| 174 * A web worker. This type is also defined in 'dart:dom', but we define it here |
| 175 * to avoid introducing a dependency from corelib to dom. This definition uses a |
| 176 * 'hidden' type (* prefix on the native name) to enforce that the type is |
| 177 * defined dynamically only when web workers are actually available. |
| 178 */ |
| 179 class _Worker native "*Worker" { |
| 180 get id() native "return this.id;"; |
| 181 void set id(i) native "this.id = i;"; |
| 182 void set onmessage(f) native "this.onmessage = f;"; |
| 183 void postMessage(msg) native "return this.postMessage(msg);"; |
| 184 } |
| 185 |
| 173 /** Context information tracked for each isolate. */ | 186 /** Context information tracked for each isolate. */ |
| 174 class IsolateContext { | 187 class IsolateContext { |
| 175 /** Current isolate id. */ | 188 /** Current isolate id. */ |
| 176 int id; | 189 int id; |
| 177 | 190 |
| 178 /** Registry of receive ports currently active on this isolate. */ | 191 /** Registry of receive ports currently active on this isolate. */ |
| 179 Map<int, ReceivePort> ports; | 192 Map<int, ReceivePort> ports; |
| 180 | 193 |
| 181 /** Holds isolate globals (statics and top-level properties). */ | 194 /** Holds isolate globals (statics and top-level properties). */ |
| 182 var isolateStatics; // native object containing all globals of an isolate. | 195 var isolateStatics; // native object containing all globals of an isolate. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 196 */ | 209 */ |
| 197 void eval(Function code) { | 210 void eval(Function code) { |
| 198 var old = _globalState.currentContext; | 211 var old = _globalState.currentContext; |
| 199 _globalState.currentContext = this; | 212 _globalState.currentContext = this; |
| 200 this._setGlobals(); | 213 this._setGlobals(); |
| 201 var result = null; | 214 var result = null; |
| 202 try { | 215 try { |
| 203 result = code(); | 216 result = code(); |
| 204 } finally { | 217 } finally { |
| 205 _globalState.currentContext = old; | 218 _globalState.currentContext = old; |
| 206 old._setGlobals(); | 219 if (old != null) old._setGlobals(); |
| 207 } | 220 } |
| 208 return result; | 221 return result; |
| 209 } | 222 } |
| 210 | 223 |
| 211 void _setGlobals() native @'$globals = this.isolateStatics;'; | 224 void _setGlobals() native @'$globals = this.isolateStatics;'; |
| 212 | 225 |
| 213 /** Lookup a port registered for this isolate. */ | 226 /** Lookup a port registered for this isolate. */ |
| 214 ReceivePort lookup(int id) => ports[id]; | 227 ReceivePort lookup(int id) => ports[id]; |
| 215 | 228 |
| 216 /** Register a port on this isolate. */ | 229 /** Register a port on this isolate. */ |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 /** | 298 /** |
| 286 * Call [_runHelper] but ensure that worker exceptions are propragated. Note | 299 * Call [_runHelper] but ensure that worker exceptions are propragated. Note |
| 287 * this is called from JavaScript (see $wrap_call in corejs.dart). | 300 * this is called from JavaScript (see $wrap_call in corejs.dart). |
| 288 */ | 301 */ |
| 289 void run() { | 302 void run() { |
| 290 if (!_globalState.isWorker) { | 303 if (!_globalState.isWorker) { |
| 291 _runHelper(); | 304 _runHelper(); |
| 292 } else { | 305 } else { |
| 293 try { | 306 try { |
| 294 _runHelper(); | 307 _runHelper(); |
| 295 } catch(e) { | 308 } catch(var e, var trace) { |
| 296 // TODO(floitsch): try to send stack-trace to the other side. | |
| 297 _globalState.mainWorker.postMessage(_serializeMessage( | 309 _globalState.mainWorker.postMessage(_serializeMessage( |
| 298 {'command': 'error', 'msg': "" + e })); | 310 {'command': 'error', 'msg': '$e\n$trace' })); |
| 299 } | 311 } |
| 300 } | 312 } |
| 301 } | 313 } |
| 302 } | 314 } |
| 303 | 315 |
| 304 /** An event in the top-level event queue. */ | 316 /** An event in the top-level event queue. */ |
| 305 class IsolateEvent { | 317 class IsolateEvent { |
| 306 IsolateContext isolate; | 318 IsolateContext isolate; |
| 307 Function fn; | 319 Function fn; |
| 308 String message; | 320 String message; |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 if (!src) { | 495 if (!src) { |
| 484 // TODO() | 496 // TODO() |
| 485 src = "FIXME:5407062" + "_" + Math.random().toString(); | 497 src = "FIXME:5407062" + "_" + Math.random().toString(); |
| 486 if (script) script.src = src; | 498 if (script) script.src = src; |
| 487 } | 499 } |
| 488 IsolateNatives._thisScriptCache = src; | 500 IsolateNatives._thisScriptCache = src; |
| 489 return src; | 501 return src; |
| 490 """; | 502 """; |
| 491 | 503 |
| 492 /** Starts a new worker with the given URL. */ | 504 /** Starts a new worker with the given URL. */ |
| 493 static _newWorker(url) native "return new Worker(url)"; | 505 static _Worker _newWorker(url) native "return new Worker(url);"; |
| 494 | 506 |
| 495 /** | 507 /** |
| 496 * Spawns an isolate in a worker. [factoryName] is the Javascript constructor | 508 * Spawns an isolate in a worker. [factoryName] is the Javascript constructor |
| 497 * name for the isolate entry point class. | 509 * name for the isolate entry point class. |
| 498 */ | 510 */ |
| 499 static void _spawnWorker(factoryName, serializedReplyPort) { | 511 static void _spawnWorker(factoryName, serializedReplyPort) { |
| 500 var worker = _newWorker(_thisScript); | 512 final worker = _newWorker(_thisScript); |
| 501 // TODO(sigmund): make this work. | 513 worker.onmessage = (e) { _processWorkerMessage(worker, e); }; |
| 502 worker.onmessage = function(e) { | |
| 503 _processWorkerMessage(worker, e); | |
| 504 }; | |
| 505 var workerId = _globalState.nextWorkerId++; | 514 var workerId = _globalState.nextWorkerId++; |
| 506 // We also store the id on the worker itself so that we can unregister it. | 515 // We also store the id on the worker itself so that we can unregister it. |
| 507 worker.id = workerId; | 516 worker.id = workerId; |
| 508 _globalState.workers[workerId] = worker; | 517 _globalState.workers[workerId] = worker; |
| 509 worker.postMessage(_serializeMessage({ | 518 worker.postMessage(_serializeMessage({ |
| 510 'command': 'start', | 519 'command': 'start', |
| 511 'id': workerId, | 520 'id': workerId, |
| 512 'replyTo': serializedReplyPort, | 521 'replyTo': serializedReplyPort, |
| 513 'factoryName': factoryName })); | 522 'factoryName': factoryName })); |
| 514 } | 523 } |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 656 worker.postMessage(_serializeMessage({ | 665 worker.postMessage(_serializeMessage({ |
| 657 'command': 'message', | 666 'command': 'message', |
| 658 'workerId': workerId, | 667 'workerId': workerId, |
| 659 'isolateId': isolateId, | 668 'isolateId': isolateId, |
| 660 'portId': receivePortId, | 669 'portId': receivePortId, |
| 661 'msg': message, | 670 'msg': message, |
| 662 'replyTo': replyTo })); | 671 'replyTo': replyTo })); |
| 663 } | 672 } |
| 664 } | 673 } |
| 665 } | 674 } |
| OLD | NEW |