Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 isolates in JavaScript. Without this we would have | 10 * implement the semantics of isolates in JavaScript. Without this we would have |
| 11 * been forced to implement more code (including the top-level event loop) in | 11 * been forced to implement more code (including the top-level event loop) in |
| 12 * JavaScript itself. | 12 * JavaScript itself. |
| 13 */ | 13 */ |
| 14 _GlobalState get _globalState() native "return \$globalState;"; | 14 _GlobalState get _globalState() native "return \$globalState;"; |
| 15 set _globalState(_GlobalState val) native "\$globalState = val;"; | 15 set _globalState(_GlobalState val) native "\$globalState = val;"; |
| 16 | 16 |
| 17 void _fillStatics(context) native @""" | 17 void _fillStatics(context) native @""" |
| 18 $globals = context.isolateStatics; | 18 $globals = context.isolateStatics; |
| 19 $static_init(); | 19 $static_init(); |
| 20 """; | 20 """; |
| 21 | 21 |
| 22 ReceivePort _port; | |
|
ngeoffray
2012/03/11 15:43:54
I moved this code here because it can be shared be
| |
| 23 | |
| 24 SendPort _spawnFunction(void topLevelFunction()) { | |
| 25 final name = _IsolateNatives._getJSFunctionName(topLevelFunction); | |
| 26 if (name == null) { | |
| 27 throw new UnsupportedOperationException( | |
| 28 "only top-level functions can be spawned."); | |
| 29 } | |
| 30 return _IsolateNatives._spawn2(name, null, false); | |
| 31 } | |
| 32 | |
| 33 SendPort _spawnUri(String uri) { | |
| 34 return _IsolateNatives._spawn2(null, uri, false); | |
| 35 } | |
| 36 | |
| 22 /** Global state associated with the current worker. See [globalState]. */ | 37 /** Global state associated with the current worker. See [globalState]. */ |
| 23 // TODO(sigmund): split in multiple classes: global, thread, main-worker states? | 38 // TODO(sigmund): split in multiple classes: global, thread, main-worker states? |
| 24 class _GlobalState { | 39 class _GlobalState { |
| 25 | 40 |
| 26 /** Next available isolate id. */ | 41 /** Next available isolate id. */ |
| 27 int nextIsolateId = 0; | 42 int nextIsolateId = 0; |
| 28 | 43 |
| 29 /** Worker id associated with this worker. */ | 44 /** Worker id associated with this worker. */ |
| 30 int currentWorkerId = 0; | 45 int currentWorkerId = 0; |
| 31 | 46 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 132 /** Holds isolate globals (statics and top-level properties). */ | 147 /** Holds isolate globals (statics and top-level properties). */ |
| 133 var isolateStatics; // native object containing all globals of an isolate. | 148 var isolateStatics; // native object containing all globals of an isolate. |
| 134 | 149 |
| 135 _IsolateContext() { | 150 _IsolateContext() { |
| 136 id = _globalState.nextIsolateId++; | 151 id = _globalState.nextIsolateId++; |
| 137 ports = {}; | 152 ports = {}; |
| 138 initGlobals(); | 153 initGlobals(); |
| 139 } | 154 } |
| 140 | 155 |
| 141 // these are filled lazily the first time the isolate starts running. | 156 // these are filled lazily the first time the isolate starts running. |
| 142 void initGlobals() native 'this.isolateStatics = {};'; | 157 void initGlobals() native @'$initGlobals(this);'; |
|
ngeoffray
2012/03/11 15:43:54
Leg and Frog currently differ in where they put gl
| |
| 143 | 158 |
| 144 /** | 159 /** |
| 145 * Run [code] in the context of the isolate represented by [this]. Note this | 160 * Run [code] in the context of the isolate represented by [this]. Note this |
| 146 * is called from JavaScript (see $wrap_call in corejs.dart). | 161 * is called from JavaScript (see $wrap_call in corejs.dart). |
| 147 */ | 162 */ |
| 148 void eval(Function code) { | 163 void eval(Function code) { |
| 149 var old = _globalState.currentContext; | 164 var old = _globalState.currentContext; |
| 150 _globalState.currentContext = this; | 165 _globalState.currentContext = this; |
| 151 this._setGlobals(); | 166 this._setGlobals(); |
| 152 var result = null; | 167 var result = null; |
| 153 try { | 168 try { |
| 154 result = code(); | 169 result = code(); |
| 155 } finally { | 170 } finally { |
| 156 _globalState.currentContext = old; | 171 _globalState.currentContext = old; |
| 157 if (old != null) old._setGlobals(); | 172 if (old != null) old._setGlobals(); |
| 158 } | 173 } |
| 159 return result; | 174 return result; |
| 160 } | 175 } |
| 161 | 176 |
| 162 void _setGlobals() native @'$globals = this.isolateStatics;'; | 177 void _setGlobals() native @'$setGlobals(this);'; |
|
ngeoffray
2012/03/11 15:43:54
Ditto.
| |
| 163 | 178 |
| 164 /** Lookup a port registered for this isolate. */ | 179 /** Lookup a port registered for this isolate. */ |
| 165 ReceivePort lookup(int id) => ports[id]; | 180 ReceivePort lookup(int id) => ports[id]; |
| 166 | 181 |
| 167 /** Register a port on this isolate. */ | 182 /** Register a port on this isolate. */ |
| 168 void register(int portId, ReceivePort port) { | 183 void register(int portId, ReceivePort port) { |
| 169 if (ports.containsKey(portId)) { | 184 if (ports.containsKey(portId)) { |
| 170 throw new Exception("Registry: ports must be registered only once."); | 185 throw new Exception("Registry: ports must be registered only once."); |
| 171 } | 186 } |
| 172 ports[portId] = port; | 187 ports[portId] = port; |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 331 _thisScriptCache = _computeThisScript(); | 346 _thisScriptCache = _computeThisScript(); |
| 332 } | 347 } |
| 333 return _thisScriptCache; | 348 return _thisScriptCache; |
| 334 } | 349 } |
| 335 | 350 |
| 336 static String _thisScriptCache; | 351 static String _thisScriptCache; |
| 337 | 352 |
| 338 // TODO(sigmund): fix - this code should be run synchronously when loading the | 353 // TODO(sigmund): fix - this code should be run synchronously when loading the |
| 339 // script. Running lazily on DOMContentLoaded will yield incorrect results. | 354 // script. Running lazily on DOMContentLoaded will yield incorrect results. |
| 340 static String _computeThisScript() native @""" | 355 static String _computeThisScript() native @""" |
| 341 if (!$globalState.supportsWorkers || $globalState.isWorker) return null; | 356 if (!$globalState.supportsWorkers || $globalState.isWorker) return (void 0); |
|
ngeoffray
2012/03/11 15:43:54
Currently leg recognizes JS undefined as Dart null
| |
| 342 | 357 |
| 343 // TODO(5334778): Find a cross-platform non-brittle way of getting the | 358 // TODO(5334778): Find a cross-platform non-brittle way of getting the |
| 344 // currently running script. | 359 // currently running script. |
| 345 var scripts = document.getElementsByTagName('script'); | 360 var scripts = document.getElementsByTagName('script'); |
| 346 // The scripts variable only contains the scripts that have already been | 361 // The scripts variable only contains the scripts that have already been |
| 347 // executed. The last one is the currently running script. | 362 // executed. The last one is the currently running script. |
| 348 var script = scripts[scripts.length - 1]; | 363 var script = scripts[scripts.length - 1]; |
| 349 var src = script && script.src; | 364 var src = script && script.src; |
| 350 if (!src) { | 365 if (!src) { |
| 351 // TODO() | 366 // TODO() |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 500 // When there is a match, our capture is element 1 of the results list. | 515 // When there is a match, our capture is element 1 of the results list. |
| 501 // If there is no match, match() returns null; we || this to a list | 516 // If there is no match, match() returns null; we || this to a list |
| 502 // whose element 1 is null so everything lines up without error. | 517 // whose element 1 is null so everything lines up without error. |
| 503 // | 518 // |
| 504 // TODO(eub): remove the toString workaround by attaching names to | 519 // TODO(eub): remove the toString workaround by attaching names to |
| 505 // functions where they could be needed. For a simple | 520 // functions where they could be needed. For a simple |
| 506 // conservative approximation of "needed", see Siggi's option (c) | 521 // conservative approximation of "needed", see Siggi's option (c) |
| 507 // in discussion on the CL, 9416119. | 522 // in discussion on the CL, 9416119. |
| 508 native @""" | 523 native @""" |
| 509 if (typeof(f.name) === 'undefined') { | 524 if (typeof(f.name) === 'undefined') { |
| 510 return (f.toString().match(/function (.+)\(/) || [, null])[1]; | 525 return (f.toString().match(/function (.+)\(/) || [, (void 0)])[1]; |
| 511 } else { | 526 } else { |
| 512 return f.name || null; | 527 return f.name || (void 0); |
| 513 } | 528 } |
| 514 """; | 529 """; |
| 515 | 530 |
| 516 /** Create a new JavaScript object instance given its constructor. */ | 531 /** Create a new JavaScript object instance given its constructor. */ |
| 517 static var _allocate(var ctor) native "return new ctor();"; | 532 static var _allocate(var ctor) native "return new ctor();"; |
| 518 | 533 |
| 519 /** Starts a non-worker isolate. */ | 534 /** Starts a non-worker isolate. */ |
| 520 static SendPort _startNonWorker(Isolate runnable, SendPort replyTo) { | 535 static SendPort _startNonWorker(Isolate runnable, SendPort replyTo) { |
| 521 // Spawn a new isolate and create the receive port in it. | 536 // Spawn a new isolate and create the receive port in it. |
| 522 final spawned = new _IsolateContext(); | 537 final spawned = new _IsolateContext(); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 614 'command': 'start2', | 629 'command': 'start2', |
| 615 'id': workerId, | 630 'id': workerId, |
| 616 // Note: we serialize replyPort twice because the child worker needs to | 631 // Note: we serialize replyPort twice because the child worker needs to |
| 617 // first deserialize the worker id, before it can correctly deserialize | 632 // first deserialize the worker id, before it can correctly deserialize |
| 618 // the port (port deserialization is sensitive to what is the current | 633 // the port (port deserialization is sensitive to what is the current |
| 619 // workerId). | 634 // workerId). |
| 620 'replyTo': _serializeMessage(replyPort), | 635 'replyTo': _serializeMessage(replyPort), |
| 621 'functionName': functionName })); | 636 'functionName': functionName })); |
| 622 } | 637 } |
| 623 } | 638 } |
| OLD | NEW |