| OLD | NEW |
| (Empty) | |
| 1 var _isolate_helper; |
| 2 (function(_isolate_helper) { |
| 3 'use strict'; |
| 4 // Function _callInIsolate: (_IsolateContext, Function) → dynamic |
| 5 function _callInIsolate(isolate, function) { |
| 6 let result = isolate.eval(function); |
| 7 _isolate_helper._globalState.topEventLoop.run(); |
| 8 return result; |
| 9 } |
| 10 // Function enterJsAsync: () → dynamic |
| 11 function enterJsAsync() { |
| 12 _isolate_helper._globalState.topEventLoop._activeJsAsyncCount++; |
| 13 } |
| 14 // Function leaveJsAsync: () → dynamic |
| 15 function leaveJsAsync() { |
| 16 _isolate_helper._globalState.topEventLoop._activeJsAsyncCount--; |
| 17 dart.assert(_isolate_helper._globalState.topEventLoop._activeJsAsyncCount >=
0); |
| 18 } |
| 19 // Function isWorker: () → bool |
| 20 function isWorker() { |
| 21 return _isolate_helper._globalState.isWorker; |
| 22 } |
| 23 // Function _currentIsolate: () → _IsolateContext |
| 24 function _currentIsolate() { |
| 25 return _isolate_helper._globalState.currentContext; |
| 26 } |
| 27 // Function startRootIsolate: (dynamic, dynamic) → void |
| 28 function startRootIsolate(entry, args) { |
| 29 args = _foreign_helper.JS("", "#", args); |
| 30 if (args === null) |
| 31 args = new List.from([]); |
| 32 if (!dart.is(args, core.List)) { |
| 33 throw new core.ArgumentError(`Arguments to main must be a List: ${args}`); |
| 34 } |
| 35 _isolate_helper._globalState = new _Manager(entry); |
| 36 if (_isolate_helper._globalState.isWorker) |
| 37 return; |
| 38 let rootContext = new _IsolateContext(); |
| 39 _isolate_helper._globalState.rootContext = rootContext; |
| 40 _isolate_helper._globalState.currentContext = rootContext; |
| 41 if (dart.is(entry, _MainFunctionArgs)) { |
| 42 rootContext.eval(() => { |
| 43 dart.dinvokef(entry, args); |
| 44 }); |
| 45 } else if (dart.is(entry, _MainFunctionArgsMessage)) { |
| 46 rootContext.eval(() => { |
| 47 dart.dinvokef(entry, args, null); |
| 48 }); |
| 49 } else { |
| 50 rootContext.eval(dart.as(entry, core.Function)); |
| 51 } |
| 52 _isolate_helper._globalState.topEventLoop.run(); |
| 53 } |
| 54 dart.copyProperties(_isolate_helper, { |
| 55 get _globalState() { |
| 56 return dart.as(_foreign_helper.JS("_Manager", "init.globalState"), _Manage
r); |
| 57 }, |
| 58 set _globalState(val) { |
| 59 _foreign_helper.JS("void", "init.globalState = #", val); |
| 60 } |
| 61 }); |
| 62 class _Manager extends dart.Object { |
| 63 get useWorkers() { |
| 64 return this.supportsWorkers; |
| 65 } |
| 66 _Manager(entry) { |
| 67 this.entry = entry; |
| 68 this.nextIsolateId = 0; |
| 69 this.currentManagerId = 0; |
| 70 this.nextManagerId = 1; |
| 71 this.currentContext = null; |
| 72 this.rootContext = null; |
| 73 this.topEventLoop = null; |
| 74 this.fromCommandLine = null; |
| 75 this.isWorker = null; |
| 76 this.supportsWorkers = null; |
| 77 this.isolates = null; |
| 78 this.mainManager = null; |
| 79 this.managers = null; |
| 80 this._nativeDetectEnvironment(); |
| 81 this.topEventLoop = new _EventLoop(); |
| 82 this.isolates = new core.Map(); |
| 83 this.managers = new core.Map(); |
| 84 if (this.isWorker) { |
| 85 this.mainManager = new _MainManagerStub(); |
| 86 this._nativeInitWorkerMessageHandler(); |
| 87 } |
| 88 } |
| 89 _nativeDetectEnvironment() { |
| 90 let isWindowDefined = _isolate_helper.globalWindow !== null; |
| 91 let isWorkerDefined = _isolate_helper.globalWorker !== null; |
| 92 this.isWorker = dart.notNull(!dart.notNull(isWindowDefined)) && dart.notNu
ll(_isolate_helper.globalPostMessageDefined); |
| 93 this.supportsWorkers = dart.notNull(this.isWorker) || dart.notNull(dart.no
tNull(isWorkerDefined) && dart.notNull(IsolateNatives.thisScript !== null)); |
| 94 this.fromCommandLine = dart.notNull(!dart.notNull(isWindowDefined)) && dar
t.notNull(!dart.notNull(this.isWorker)); |
| 95 } |
| 96 _nativeInitWorkerMessageHandler() { |
| 97 let function = _foreign_helper.JS('', "(function (f, a) { return function
(e) { f(a, e); }})(#, #)", _foreign_helper.DART_CLOSURE_TO_JS(IsolateNatives._pr
ocessWorkerMessage), this.mainManager); |
| 98 _foreign_helper.JS("void", "self.onmessage = #", function); |
| 99 _foreign_helper.JS('', 'self.dartPrint = self.dartPrint || (function(seria
lize) {\n return function (object) {\n if (self.console && self.console.log)
{\n self.console.log(object)\n } else {\n self.postMessage(seriali
ze(object));\n }\n }\n})(#)', _foreign_helper.DART_CLOSURE_TO_JS(_serializeP
rintMessage)); |
| 100 } |
| 101 static _serializePrintMessage(object) { |
| 102 return _serializeMessage(dart.map({command: "print", msg: object})); |
| 103 } |
| 104 maybeCloseWorker() { |
| 105 if (dart.notNull(dart.notNull(this.isWorker) && dart.notNull(this.isolates
.isEmpty)) && dart.notNull(this.topEventLoop._activeJsAsyncCount === 0)) { |
| 106 this.mainManager.postMessage(_serializeMessage(dart.map({command: 'close
'}))); |
| 107 } |
| 108 } |
| 109 } |
| 110 class _IsolateContext extends dart.Object { |
| 111 _IsolateContext() { |
| 112 this.id = _isolate_helper._globalState.nextIsolateId++; |
| 113 this.ports = new core.Map(); |
| 114 this.weakPorts = new core.Set(); |
| 115 this.isolateStatics = _foreign_helper.JS_CREATE_ISOLATE(); |
| 116 this.controlPort = new RawReceivePortImpl._controlPort(); |
| 117 this.pauseCapability = new isolate.Capability(); |
| 118 this.terminateCapability = new isolate.Capability(); |
| 119 this.delayedEvents = dart.as(new List.from([]), core.List$(_IsolateEvent))
; |
| 120 this.pauseTokens = dart.as(new core.Set(), core.Set$(isolate.Capability)); |
| 121 this.errorPorts = dart.as(new core.Set(), core.Set$(isolate.SendPort)); |
| 122 this.initialized = false; |
| 123 this.isPaused = false; |
| 124 this.doneHandlers = null; |
| 125 this._scheduledControlEvents = null; |
| 126 this._isExecutingEvent = false; |
| 127 this.errorsAreFatal = true; |
| 128 this.registerWeak(this.controlPort._id, this.controlPort); |
| 129 } |
| 130 addPause(authentification, resume) { |
| 131 if (!dart.equals(this.pauseCapability, authentification)) |
| 132 return; |
| 133 if (dart.notNull(this.pauseTokens.add(resume)) && dart.notNull(!dart.notNu
ll(this.isPaused))) { |
| 134 this.isPaused = true; |
| 135 } |
| 136 this._updateGlobalState(); |
| 137 } |
| 138 removePause(resume) { |
| 139 if (!dart.notNull(this.isPaused)) |
| 140 return; |
| 141 this.pauseTokens.remove(resume); |
| 142 if (this.pauseTokens.isEmpty) { |
| 143 while (this.delayedEvents.isNotEmpty) { |
| 144 let event = this.delayedEvents.removeLast(); |
| 145 _isolate_helper._globalState.topEventLoop.prequeue(event); |
| 146 } |
| 147 this.isPaused = false; |
| 148 } |
| 149 this._updateGlobalState(); |
| 150 } |
| 151 addDoneListener(responsePort) { |
| 152 if (this.doneHandlers === null) { |
| 153 this.doneHandlers = new List.from([]); |
| 154 } |
| 155 if (dart.dinvoke(this.doneHandlers, 'contains', responsePort)) |
| 156 return; |
| 157 dart.dinvoke(this.doneHandlers, 'add', responsePort); |
| 158 } |
| 159 removeDoneListener(responsePort) { |
| 160 if (this.doneHandlers === null) |
| 161 return; |
| 162 dart.dinvoke(this.doneHandlers, 'remove', responsePort); |
| 163 } |
| 164 setErrorsFatal(authentification, errorsAreFatal) { |
| 165 if (!dart.equals(this.terminateCapability, authentification)) |
| 166 return; |
| 167 this.errorsAreFatal = errorsAreFatal; |
| 168 } |
| 169 handlePing(responsePort, pingType) { |
| 170 if (dart.notNull(pingType === isolate.Isolate.IMMEDIATE) || dart.notNull(d
art.notNull(pingType === isolate.Isolate.BEFORE_NEXT_EVENT) && dart.notNull(!dar
t.notNull(this._isExecutingEvent)))) { |
| 171 responsePort.send(null); |
| 172 return; |
| 173 } |
| 174 // Function respond: () → void |
| 175 function respond() { |
| 176 responsePort.send(null); |
| 177 } |
| 178 if (pingType === isolate.Isolate.AS_EVENT) { |
| 179 _isolate_helper._globalState.topEventLoop.enqueue(this, respond, "ping")
; |
| 180 return; |
| 181 } |
| 182 dart.assert(pingType === isolate.Isolate.BEFORE_NEXT_EVENT); |
| 183 if (this._scheduledControlEvents === null) { |
| 184 this._scheduledControlEvents = new collection.Queue(); |
| 185 } |
| 186 dart.dinvoke(this._scheduledControlEvents, 'addLast', respond); |
| 187 } |
| 188 handleKill(authentification, priority) { |
| 189 if (!dart.equals(this.terminateCapability, authentification)) |
| 190 return; |
| 191 if (dart.notNull(priority === isolate.Isolate.IMMEDIATE) || dart.notNull(d
art.notNull(priority === isolate.Isolate.BEFORE_NEXT_EVENT) && dart.notNull(!dar
t.notNull(this._isExecutingEvent)))) { |
| 192 this.kill(); |
| 193 return; |
| 194 } |
| 195 if (priority === isolate.Isolate.AS_EVENT) { |
| 196 _isolate_helper._globalState.topEventLoop.enqueue(this, this.kill, "kill
"); |
| 197 return; |
| 198 } |
| 199 dart.assert(priority === isolate.Isolate.BEFORE_NEXT_EVENT); |
| 200 if (this._scheduledControlEvents === null) { |
| 201 this._scheduledControlEvents = new collection.Queue(); |
| 202 } |
| 203 dart.dinvoke(this._scheduledControlEvents, 'addLast', this.kill); |
| 204 } |
| 205 addErrorListener(port) { |
| 206 this.errorPorts.add(port); |
| 207 } |
| 208 removeErrorListener(port) { |
| 209 this.errorPorts.remove(port); |
| 210 } |
| 211 handleUncaughtError(error, stackTrace) { |
| 212 if (this.errorPorts.isEmpty) { |
| 213 if (dart.notNull(this.errorsAreFatal) && dart.notNull(core.identical(thi
s, _isolate_helper._globalState.rootContext))) { |
| 214 return; |
| 215 } |
| 216 if (_foreign_helper.JS('bool', 'self.console && self.console.error')) { |
| 217 _foreign_helper.JS('void', 'self.console.error(#, #)', error, stackTra
ce); |
| 218 } else { |
| 219 core.print(error); |
| 220 if (stackTrace !== null) |
| 221 core.print(stackTrace); |
| 222 } |
| 223 return; |
| 224 } |
| 225 let message = new core.List(2); |
| 226 message.set(0, dart.dinvoke(error, 'toString')); |
| 227 message.set(1, stackTrace === null ? null : stackTrace.toString()); |
| 228 for (let port of this.errorPorts) |
| 229 port.send(message); |
| 230 } |
| 231 eval(code) { |
| 232 let old = _isolate_helper._globalState.currentContext; |
| 233 _isolate_helper._globalState.currentContext = this; |
| 234 this._setGlobals(); |
| 235 let result = null; |
| 236 this._isExecutingEvent = true; |
| 237 try { |
| 238 result = dart.dinvokef(code); |
| 239 } catch (e) { |
| 240 let s = dart.stackTrace(e); |
| 241 this.handleUncaughtError(e, s); |
| 242 if (this.errorsAreFatal) { |
| 243 this.kill(); |
| 244 if (core.identical(this, _isolate_helper._globalState.rootContext)) { |
| 245 dart.throw_("Unimplemented RethrowExpression: rethrow"); |
| 246 } |
| 247 } |
| 248 } |
| 249 finally { |
| 250 this._isExecutingEvent = false; |
| 251 _isolate_helper._globalState.currentContext = old; |
| 252 if (old !== null) |
| 253 old._setGlobals(); |
| 254 if (this._scheduledControlEvents !== null) { |
| 255 while (dart.dload(this._scheduledControlEvents, 'isNotEmpty')) { |
| 256 dart.dinvokef(dart.dinvoke(this._scheduledControlEvents, 'removeFirs
t')); |
| 257 } |
| 258 } |
| 259 } |
| 260 return result; |
| 261 } |
| 262 _setGlobals() { |
| 263 _foreign_helper.JS_SET_CURRENT_ISOLATE(this.isolateStatics); |
| 264 } |
| 265 handleControlMessage(message) { |
| 266 switch (dart.dindex(message, 0)) { |
| 267 case "pause": |
| 268 this.addPause(dart.as(dart.dindex(message, 1), isolate.Capability), da
rt.as(dart.dindex(message, 2), isolate.Capability)); |
| 269 break; |
| 270 case "resume": |
| 271 this.removePause(dart.as(dart.dindex(message, 1), isolate.Capability))
; |
| 272 break; |
| 273 case 'add-ondone': |
| 274 this.addDoneListener(dart.as(dart.dindex(message, 1), isolate.SendPort
)); |
| 275 break; |
| 276 case 'remove-ondone': |
| 277 this.removeDoneListener(dart.as(dart.dindex(message, 1), isolate.SendP
ort)); |
| 278 break; |
| 279 case 'set-errors-fatal': |
| 280 this.setErrorsFatal(dart.as(dart.dindex(message, 1), isolate.Capabilit
y), dart.as(dart.dindex(message, 2), core.bool)); |
| 281 break; |
| 282 case "ping": |
| 283 this.handlePing(dart.as(dart.dindex(message, 1), isolate.SendPort), da
rt.as(dart.dindex(message, 2), core.int)); |
| 284 break; |
| 285 case "kill": |
| 286 this.handleKill(dart.as(dart.dindex(message, 1), isolate.Capability),
dart.as(dart.dindex(message, 2), core.int)); |
| 287 break; |
| 288 case "getErrors": |
| 289 this.addErrorListener(dart.as(dart.dindex(message, 1), isolate.SendPor
t)); |
| 290 break; |
| 291 case "stopErrors": |
| 292 this.removeErrorListener(dart.as(dart.dindex(message, 1), isolate.Send
Port)); |
| 293 break; |
| 294 default: |
| 295 } |
| 296 } |
| 297 lookup(portId) { |
| 298 return this.ports.get(portId); |
| 299 } |
| 300 _addRegistration(portId, port) { |
| 301 if (this.ports.containsKey(portId)) { |
| 302 throw new core.Exception("Registry: ports must be registered only once."
); |
| 303 } |
| 304 this.ports.set(portId, port); |
| 305 } |
| 306 register(portId, port) { |
| 307 this._addRegistration(portId, port); |
| 308 this._updateGlobalState(); |
| 309 } |
| 310 registerWeak(portId, port) { |
| 311 this.weakPorts.add(portId); |
| 312 this._addRegistration(portId, port); |
| 313 } |
| 314 _updateGlobalState() { |
| 315 if (dart.notNull(dart.notNull(this.ports.length - this.weakPorts.length >
0) || dart.notNull(this.isPaused)) || dart.notNull(!dart.notNull(this.initialize
d))) { |
| 316 _isolate_helper._globalState.isolates.set(this.id, this); |
| 317 } else { |
| 318 this.kill(); |
| 319 } |
| 320 } |
| 321 kill() { |
| 322 if (this._scheduledControlEvents !== null) { |
| 323 dart.dinvoke(this._scheduledControlEvents, 'clear'); |
| 324 } |
| 325 for (let port of this.ports.values) { |
| 326 dart.dinvoke(port, '_close'); |
| 327 } |
| 328 this.ports.clear(); |
| 329 this.weakPorts.clear(); |
| 330 _isolate_helper._globalState.isolates.remove(this.id); |
| 331 this.errorPorts.clear(); |
| 332 if (this.doneHandlers !== null) { |
| 333 for (let port of this.doneHandlers) { |
| 334 port.send(null); |
| 335 } |
| 336 this.doneHandlers = null; |
| 337 } |
| 338 } |
| 339 unregister(portId) { |
| 340 this.ports.remove(portId); |
| 341 this.weakPorts.remove(portId); |
| 342 this._updateGlobalState(); |
| 343 } |
| 344 } |
| 345 class _EventLoop extends dart.Object { |
| 346 _EventLoop() { |
| 347 this.events = new collection.Queue(); |
| 348 this._activeJsAsyncCount = 0; |
| 349 } |
| 350 enqueue(isolate, fn, msg) { |
| 351 this.events.addLast(new _IsolateEvent(isolate, fn, msg)); |
| 352 } |
| 353 prequeue(event) { |
| 354 this.events.addFirst(event); |
| 355 } |
| 356 dequeue() { |
| 357 if (this.events.isEmpty) |
| 358 return null; |
| 359 return this.events.removeFirst(); |
| 360 } |
| 361 checkOpenReceivePortsFromCommandLine() { |
| 362 if (dart.notNull(dart.notNull(dart.notNull(_isolate_helper._globalState.ro
otContext !== null) && dart.notNull(_isolate_helper._globalState.isolates.contai
nsKey(_isolate_helper._globalState.rootContext.id))) && dart.notNull(_isolate_he
lper._globalState.fromCommandLine)) && dart.notNull(_isolate_helper._globalState
.rootContext.ports.isEmpty)) { |
| 363 throw new core.Exception("Program exited with open ReceivePorts."); |
| 364 } |
| 365 } |
| 366 runIteration() { |
| 367 let event = this.dequeue(); |
| 368 if (event === null) { |
| 369 this.checkOpenReceivePortsFromCommandLine(); |
| 370 _isolate_helper._globalState.maybeCloseWorker(); |
| 371 return false; |
| 372 } |
| 373 event.process(); |
| 374 return true; |
| 375 } |
| 376 _runHelper() { |
| 377 if (_isolate_helper.globalWindow !== null) { |
| 378 // Function next: () → void |
| 379 function next() { |
| 380 if (!dart.notNull(this.runIteration())) |
| 381 return; |
| 382 async.Timer.run(next); |
| 383 } |
| 384 next(); |
| 385 } else { |
| 386 while (this.runIteration()) { |
| 387 } |
| 388 } |
| 389 } |
| 390 run() { |
| 391 if (!dart.notNull(_isolate_helper._globalState.isWorker)) { |
| 392 this._runHelper(); |
| 393 } else { |
| 394 try { |
| 395 this._runHelper(); |
| 396 } catch (e) { |
| 397 let trace = dart.stackTrace(e); |
| 398 _isolate_helper._globalState.mainManager.postMessage(_serializeMessage
(dart.map({command: 'error', msg: `${e}\n${trace}`}))); |
| 399 } |
| 400 |
| 401 } |
| 402 } |
| 403 } |
| 404 class _IsolateEvent extends dart.Object { |
| 405 _IsolateEvent(isolate, fn, message) { |
| 406 this.isolate = isolate; |
| 407 this.fn = fn; |
| 408 this.message = message; |
| 409 } |
| 410 process() { |
| 411 if (this.isolate.isPaused) { |
| 412 this.isolate.delayedEvents.add(this); |
| 413 return; |
| 414 } |
| 415 this.isolate.eval(this.fn); |
| 416 } |
| 417 } |
| 418 class _MainManagerStub extends dart.Object { |
| 419 postMessage(msg) { |
| 420 _js_helper.requiresPreamble(); |
| 421 _foreign_helper.JS("void", "self.postMessage(#)", msg); |
| 422 } |
| 423 } |
| 424 let _SPAWNED_SIGNAL = "spawned"; |
| 425 let _SPAWN_FAILED_SIGNAL = "spawn failed"; |
| 426 dart.copyProperties(_isolate_helper, { |
| 427 get globalWindow() { |
| 428 _js_helper.requiresPreamble(); |
| 429 return _foreign_helper.JS('', "self.window"); |
| 430 }, |
| 431 get globalWorker() { |
| 432 _js_helper.requiresPreamble(); |
| 433 return _foreign_helper.JS('', "self.Worker"); |
| 434 }, |
| 435 get globalPostMessageDefined() { |
| 436 _js_helper.requiresPreamble(); |
| 437 return dart.as(_foreign_helper.JS('bool', "!!self.postMessage"), core.bool
); |
| 438 } |
| 439 }); |
| 440 class IsolateNatives extends dart.Object { |
| 441 static computeThisScript() { |
| 442 let currentScript = _foreign_helper.JS_EMBEDDED_GLOBAL('', dart.as(_js_emb
edded_names.CURRENT_SCRIPT, core.String)); |
| 443 if (currentScript !== null) { |
| 444 return dart.as(_foreign_helper.JS('String', 'String(#.src)', currentScri
pt), core.String); |
| 445 } |
| 446 if (_js_helper.Primitives.isD8) |
| 447 return computeThisScriptD8(); |
| 448 if (_js_helper.Primitives.isJsshell) |
| 449 return computeThisScriptJsshell(); |
| 450 if (_isolate_helper._globalState.isWorker) |
| 451 return computeThisScriptFromTrace(); |
| 452 return null; |
| 453 } |
| 454 static computeThisScriptJsshell() { |
| 455 return dart.as(_foreign_helper.JS('String|Null', 'thisFilename()'), core.S
tring); |
| 456 } |
| 457 static computeThisScriptD8() { |
| 458 return computeThisScriptFromTrace(); |
| 459 } |
| 460 static computeThisScriptFromTrace() { |
| 461 let stack = _foreign_helper.JS('String|Null', 'new Error().stack'); |
| 462 if (stack === null) { |
| 463 stack = _foreign_helper.JS('String|Null', '(function() {' + 'try { throw
new Error() } catch(e) { return e.stack }' + '})()'); |
| 464 if (stack === null) |
| 465 throw new core.UnsupportedError('No stack trace'); |
| 466 } |
| 467 let pattern = null, matches = null; |
| 468 pattern = _foreign_helper.JS('', 'new RegExp("^ *at [^(]*\\\\((.*):[0-9]*:
[0-9]*\\\\)$", "m")'); |
| 469 matches = _foreign_helper.JS('JSExtendableArray|Null', '#.match(#)', stack
, pattern); |
| 470 if (matches !== null) |
| 471 return dart.as(_foreign_helper.JS('String', '#[1]', matches), core.Strin
g); |
| 472 pattern = _foreign_helper.JS('', 'new RegExp("^[^@]*@(.*):[0-9]*$", "m")')
; |
| 473 matches = _foreign_helper.JS('JSExtendableArray|Null', '#.match(#)', stack
, pattern); |
| 474 if (matches !== null) |
| 475 return dart.as(_foreign_helper.JS('String', '#[1]', matches), core.Strin
g); |
| 476 throw new core.UnsupportedError(`Cannot extract URI from "${stack}"`); |
| 477 } |
| 478 static _getEventData(e) { |
| 479 return _foreign_helper.JS("", "#.data", e); |
| 480 } |
| 481 static _processWorkerMessage(sender, e) { |
| 482 let msg = _deserializeMessage(_getEventData(e)); |
| 483 switch (dart.dindex(msg, 'command')) { |
| 484 case 'start': |
| 485 _isolate_helper._globalState.currentManagerId = dart.as(dart.dindex(ms
g, 'id'), core.int); |
| 486 let functionName = dart.as(dart.dindex(msg, 'functionName'), core.Stri
ng); |
| 487 let entryPoint = dart.as(functionName === null ? _isolate_helper._glob
alState.entry : _getJSFunctionFromName(functionName), core.Function); |
| 488 let args = dart.dindex(msg, 'args'); |
| 489 let message = _deserializeMessage(dart.dindex(msg, 'msg')); |
| 490 let isSpawnUri = dart.dindex(msg, 'isSpawnUri'); |
| 491 let startPaused = dart.dindex(msg, 'startPaused'); |
| 492 let replyTo = _deserializeMessage(dart.dindex(msg, 'replyTo')); |
| 493 let context = new _IsolateContext(); |
| 494 _isolate_helper._globalState.topEventLoop.enqueue(context, () => { |
| 495 _startIsolate(entryPoint, dart.as(args, core.List$(core.String)), me
ssage, dart.as(isSpawnUri, core.bool), dart.as(startPaused, core.bool), dart.as(
replyTo, isolate.SendPort)); |
| 496 }, 'worker-start'); |
| 497 _isolate_helper._globalState.currentContext = context; |
| 498 _isolate_helper._globalState.topEventLoop.run(); |
| 499 break; |
| 500 case 'spawn-worker': |
| 501 if (enableSpawnWorker !== null) |
| 502 handleSpawnWorkerRequest(msg); |
| 503 break; |
| 504 case 'message': |
| 505 let port = dart.as(dart.dindex(msg, 'port'), isolate.SendPort); |
| 506 if (port !== null) { |
| 507 dart.dinvoke(dart.dindex(msg, 'port'), 'send', dart.dindex(msg, 'msg
')); |
| 508 } |
| 509 _isolate_helper._globalState.topEventLoop.run(); |
| 510 break; |
| 511 case 'close': |
| 512 _isolate_helper._globalState.managers.remove(workerIds.get(sender)); |
| 513 _foreign_helper.JS('void', '#.terminate()', sender); |
| 514 _isolate_helper._globalState.topEventLoop.run(); |
| 515 break; |
| 516 case 'log': |
| 517 _log(dart.dindex(msg, 'msg')); |
| 518 break; |
| 519 case 'print': |
| 520 if (_isolate_helper._globalState.isWorker) { |
| 521 _isolate_helper._globalState.mainManager.postMessage(_serializeMessa
ge(dart.map({command: 'print', msg: msg}))); |
| 522 } else { |
| 523 core.print(dart.dindex(msg, 'msg')); |
| 524 } |
| 525 break; |
| 526 case 'error': |
| 527 throw dart.dindex(msg, 'msg'); |
| 528 } |
| 529 } |
| 530 static handleSpawnWorkerRequest(msg) { |
| 531 let replyPort = dart.dindex(msg, 'replyPort'); |
| 532 spawn(dart.as(dart.dindex(msg, 'functionName'), core.String), dart.as(dart
.dindex(msg, 'uri'), core.String), dart.as(dart.dindex(msg, 'args'), core.List$(
core.String)), dart.dindex(msg, 'msg'), false, dart.as(dart.dindex(msg, 'isSpawn
Uri'), core.bool), dart.as(dart.dindex(msg, 'startPaused'), core.bool)).then((ms
g) => { |
| 533 dart.dinvoke(replyPort, 'send', msg); |
| 534 }, { |
| 535 onError: (errorMessage) => { |
| 536 dart.dinvoke(replyPort, 'send', new List.from([_SPAWN_FAILED_SIGNAL, e
rrorMessage])); |
| 537 } |
| 538 }); |
| 539 } |
| 540 static _log(msg) { |
| 541 if (_isolate_helper._globalState.isWorker) { |
| 542 _isolate_helper._globalState.mainManager.postMessage(_serializeMessage(d
art.map({command: 'log', msg: msg}))); |
| 543 } else { |
| 544 try { |
| 545 _consoleLog(msg); |
| 546 } catch (e) { |
| 547 let trace = dart.stackTrace(e); |
| 548 throw new core.Exception(trace); |
| 549 } |
| 550 |
| 551 } |
| 552 } |
| 553 static _consoleLog(msg) { |
| 554 _js_helper.requiresPreamble(); |
| 555 _foreign_helper.JS("void", "self.console.log(#)", msg); |
| 556 } |
| 557 static _getJSFunctionFromName(functionName) { |
| 558 let globalFunctionsContainer = _foreign_helper.JS_EMBEDDED_GLOBAL("", dart
.as(_js_embedded_names.GLOBAL_FUNCTIONS, core.String)); |
| 559 return _foreign_helper.JS("", "#[#]()", globalFunctionsContainer, function
Name); |
| 560 } |
| 561 static _getJSFunctionName(f) { |
| 562 return dart.as(dart.is(f, _js_helper.Closure) ? _foreign_helper.JS("String
|Null", '#.$name', f) : null, core.String); |
| 563 } |
| 564 static _allocate(ctor) { |
| 565 return _foreign_helper.JS("", "new #()", ctor); |
| 566 } |
| 567 static spawnFunction(topLevelFunction, message, startPaused) { |
| 568 IsolateNatives.enableSpawnWorker = true; |
| 569 let name = _getJSFunctionName(topLevelFunction); |
| 570 if (name === null) { |
| 571 throw new core.UnsupportedError("only top-level functions can be spawned
."); |
| 572 } |
| 573 let isLight = false; |
| 574 let isSpawnUri = false; |
| 575 return spawn(name, null, null, message, isLight, isSpawnUri, startPaused); |
| 576 } |
| 577 static spawnUri(uri, args, message, startPaused) { |
| 578 IsolateNatives.enableSpawnWorker = true; |
| 579 let isLight = false; |
| 580 let isSpawnUri = true; |
| 581 return spawn(null, uri.toString(), args, message, isLight, isSpawnUri, sta
rtPaused); |
| 582 } |
| 583 static spawn(functionName, uri, args, message, isLight, isSpawnUri, startPau
sed) { |
| 584 if (dart.notNull(uri !== null) && dart.notNull(uri.endsWith(".dart"))) |
| 585 uri = ".js"; |
| 586 let port = new isolate.ReceivePort(); |
| 587 let completer = dart.as(new async.Completer(), async.Completer$(core.List)
); |
| 588 port.first.then(((msg) => { |
| 589 if (dart.equals(dart.dindex(msg, 0), _SPAWNED_SIGNAL)) { |
| 590 completer.complete(msg); |
| 591 } else { |
| 592 dart.assert(dart.equals(dart.dindex(msg, 0), _SPAWN_FAILED_SIGNAL)); |
| 593 completer.completeError(dart.dindex(msg, 1)); |
| 594 } |
| 595 }).bind(this)); |
| 596 let signalReply = port.sendPort; |
| 597 if (dart.notNull(_isolate_helper._globalState.useWorkers) && dart.notNull(
!dart.notNull(isLight))) { |
| 598 _startWorker(functionName, uri, args, message, isSpawnUri, startPaused,
signalReply, ((message) => completer.completeError(message)).bind(this)); |
| 599 } else { |
| 600 _startNonWorker(functionName, uri, args, message, isSpawnUri, startPause
d, signalReply); |
| 601 } |
| 602 return completer.future; |
| 603 } |
| 604 static _startWorker(functionName, uri, args, message, isSpawnUri, startPause
d, replyPort, onError) { |
| 605 if (args !== null) |
| 606 args = new core.List.from(args); |
| 607 if (_isolate_helper._globalState.isWorker) { |
| 608 _isolate_helper._globalState.mainManager.postMessage(_serializeMessage(d
art.map({command: 'spawn-worker', functionName: functionName, args: args, msg: m
essage, uri: uri, isSpawnUri: isSpawnUri, startPaused: startPaused, replyPort: r
eplyPort}))); |
| 609 } else { |
| 610 _spawnWorker(functionName, uri, args, message, isSpawnUri, startPaused,
replyPort, onError); |
| 611 } |
| 612 } |
| 613 static _startNonWorker(functionName, uri, args, message, isSpawnUri, startPa
used, replyPort) { |
| 614 if (uri !== null) { |
| 615 throw new core.UnsupportedError("Currently spawnUri is not supported wit
hout web workers."); |
| 616 } |
| 617 message = _clone(message); |
| 618 if (args !== null) |
| 619 args = new core.List.from(args); |
| 620 _isolate_helper._globalState.topEventLoop.enqueue(new _IsolateContext(), (
) => { |
| 621 let func = _getJSFunctionFromName(functionName); |
| 622 _startIsolate(dart.as(func, core.Function), args, message, isSpawnUri, s
tartPaused, replyPort); |
| 623 }, 'nonworker start'); |
| 624 } |
| 625 static get currentIsolate() { |
| 626 let context = dart.as(_foreign_helper.JS_CURRENT_ISOLATE_CONTEXT(), _Isola
teContext); |
| 627 return new isolate.Isolate(context.controlPort.sendPort, {pauseCapability:
context.pauseCapability, terminateCapability: context.terminateCapability}); |
| 628 } |
| 629 static _startIsolate(topLevel, args, message, isSpawnUri, startPaused, reply
To) { |
| 630 let context = dart.as(_foreign_helper.JS_CURRENT_ISOLATE_CONTEXT(), _Isola
teContext); |
| 631 _js_helper.Primitives.initializeStatics(context.id); |
| 632 replyTo.send(new List.from([_SPAWNED_SIGNAL, context.controlPort.sendPort,
context.pauseCapability, context.terminateCapability])); |
| 633 // Function runStartFunction: () → void |
| 634 function runStartFunction() { |
| 635 context.initialized = true; |
| 636 if (!dart.notNull(isSpawnUri)) { |
| 637 dart.dinvokef(topLevel, message); |
| 638 } else if (dart.is(topLevel, _MainFunctionArgsMessage)) { |
| 639 dart.dinvokef(topLevel, args, message); |
| 640 } else if (dart.is(topLevel, _MainFunctionArgs)) { |
| 641 dart.dinvokef(topLevel, args); |
| 642 } else { |
| 643 dart.dinvokef(topLevel); |
| 644 } |
| 645 } |
| 646 if (startPaused) { |
| 647 context.addPause(context.pauseCapability, context.pauseCapability); |
| 648 _isolate_helper._globalState.topEventLoop.enqueue(context, runStartFunct
ion, 'start isolate'); |
| 649 } else { |
| 650 runStartFunction(); |
| 651 } |
| 652 } |
| 653 static _spawnWorker(functionName, uri, args, message, isSpawnUri, startPause
d, replyPort, onError) { |
| 654 if (uri === null) |
| 655 uri = thisScript; |
| 656 let worker = _foreign_helper.JS('var', 'new Worker(#)', uri); |
| 657 let onerrorTrampoline = _foreign_helper.JS('', '\n(function (f, u, c) {\n
return function(e) {\n return f(e, u, c)\n }\n})(#, #, #)', _foreign_helper
.DART_CLOSURE_TO_JS(workerOnError), uri, onError); |
| 658 _foreign_helper.JS('void', '#.onerror = #', worker, onerrorTrampoline); |
| 659 let processWorkerMessageTrampoline = _foreign_helper.JS('', "\n(function (
f, a) {\n return function (e) {\n // We can stop listening for errors when t
he first message is received as\n // we only listen for messages to determine
if the uri was bad.\n e.onerror = null;\n return f(a, e);\n }\n})(#, #)"
, _foreign_helper.DART_CLOSURE_TO_JS(_processWorkerMessage), worker); |
| 660 _foreign_helper.JS('void', '#.onmessage = #', worker, processWorkerMessage
Trampoline); |
| 661 let workerId = _isolate_helper._globalState.nextManagerId++; |
| 662 workerIds.set(worker, workerId); |
| 663 _isolate_helper._globalState.managers.set(workerId, worker); |
| 664 _foreign_helper.JS('void', '#.postMessage(#)', worker, _serializeMessage(d
art.map({command: 'start', id: workerId, replyTo: _serializeMessage(replyPort),
args: args, msg: _serializeMessage(message), isSpawnUri: isSpawnUri, startPaused
: startPaused, functionName: functionName}))); |
| 665 } |
| 666 static workerOnError(event, uri, onError) { |
| 667 _foreign_helper.JS('void', '#.preventDefault()', event); |
| 668 let message = dart.as(_foreign_helper.JS('String|Null', '#.message', event
), core.String); |
| 669 if (message === null) { |
| 670 message = `Error spawning worker for ${uri}`; |
| 671 } else { |
| 672 message = `Error spawning worker for ${uri} (${message})`; |
| 673 } |
| 674 onError(message); |
| 675 return true; |
| 676 } |
| 677 } |
| 678 IsolateNatives.enableSpawnWorker = null; |
| 679 dart.defineLazyProperties(IsolateNatives, { |
| 680 get thisScript() { |
| 681 return computeThisScript(); |
| 682 }, |
| 683 set thisScript() {}, |
| 684 get workerIds() { |
| 685 return new core.Expando(); |
| 686 } |
| 687 }); |
| 688 class _BaseSendPort extends dart.Object { |
| 689 _BaseSendPort(_isolateId) { |
| 690 this._isolateId = _isolateId; |
| 691 } |
| 692 _checkReplyTo(replyTo) { |
| 693 if (dart.notNull(dart.notNull(replyTo !== null) && dart.notNull(!dart.is(r
eplyTo, _NativeJsSendPort))) && dart.notNull(!dart.is(replyTo, _WorkerSendPort))
) { |
| 694 throw new core.Exception("SendPort.send: Illegal replyTo port type"); |
| 695 } |
| 696 } |
| 697 } |
| 698 class _NativeJsSendPort extends _BaseSendPort { |
| 699 _NativeJsSendPort(_receivePort, isolateId) { |
| 700 this._receivePort = _receivePort; |
| 701 super._BaseSendPort(isolateId); |
| 702 } |
| 703 send(message) { |
| 704 let isolate = _isolate_helper._globalState.isolates.get(this._isolateId); |
| 705 if (isolate === null) |
| 706 return; |
| 707 if (this._receivePort._isClosed) |
| 708 return; |
| 709 let msg = _clone(message); |
| 710 if (dart.equals(isolate.controlPort, this._receivePort)) { |
| 711 isolate.handleControlMessage(msg); |
| 712 return; |
| 713 } |
| 714 _isolate_helper._globalState.topEventLoop.enqueue(isolate, (() => { |
| 715 if (!dart.notNull(this._receivePort._isClosed)) { |
| 716 this._receivePort._add(msg); |
| 717 } |
| 718 }).bind(this), `receive ${message}`); |
| 719 } |
| 720 ['=='](other) { |
| 721 return dart.notNull(dart.is(other, _NativeJsSendPort)) && dart.notNull(dar
t.equals(this._receivePort, dart.dload(other, '_receivePort'))); |
| 722 } |
| 723 get hashCode() { |
| 724 return this._receivePort._id; |
| 725 } |
| 726 } |
| 727 class _WorkerSendPort extends _BaseSendPort { |
| 728 _WorkerSendPort(_workerId, isolateId, _receivePortId) { |
| 729 this._workerId = _workerId; |
| 730 this._receivePortId = _receivePortId; |
| 731 super._BaseSendPort(isolateId); |
| 732 } |
| 733 send(message) { |
| 734 let workerMessage = _serializeMessage(dart.map({command: 'message', port:
this, msg: message})); |
| 735 if (_isolate_helper._globalState.isWorker) { |
| 736 _isolate_helper._globalState.mainManager.postMessage(workerMessage); |
| 737 } else { |
| 738 let manager = _isolate_helper._globalState.managers.get(this._workerId); |
| 739 if (manager !== null) { |
| 740 _foreign_helper.JS('void', '#.postMessage(#)', manager, workerMessage)
; |
| 741 } |
| 742 } |
| 743 } |
| 744 ['=='](other) { |
| 745 return dart.notNull(dart.notNull(dart.notNull(dart.is(other, _WorkerSendPo
rt)) && dart.notNull(this._workerId === dart.dload(other, '_workerId'))) && dart
.notNull(this._isolateId === dart.dload(other, '_isolateId'))) && dart.notNull(t
his._receivePortId === dart.dload(other, '_receivePortId')); |
| 746 } |
| 747 get hashCode() { |
| 748 return this._workerId << 16 ^ this._isolateId << 8 ^ this._receivePortId; |
| 749 } |
| 750 } |
| 751 class RawReceivePortImpl extends dart.Object { |
| 752 RawReceivePortImpl(_handler) { |
| 753 this._handler = _handler; |
| 754 this._id = _nextFreeId++; |
| 755 this._isClosed = false; |
| 756 _isolate_helper._globalState.currentContext.register(this._id, this); |
| 757 } |
| 758 RawReceivePortImpl$weak(_handler) { |
| 759 this._handler = _handler; |
| 760 this._id = _nextFreeId++; |
| 761 this._isClosed = false; |
| 762 _isolate_helper._globalState.currentContext.registerWeak(this._id, this); |
| 763 } |
| 764 RawReceivePortImpl$_controlPort() { |
| 765 this._handler = null; |
| 766 this._id = 0; |
| 767 this._isClosed = false; |
| 768 } |
| 769 set handler(newHandler) { |
| 770 this._handler = newHandler; |
| 771 } |
| 772 _close() { |
| 773 this._isClosed = true; |
| 774 this._handler = null; |
| 775 } |
| 776 close() { |
| 777 if (this._isClosed) |
| 778 return; |
| 779 this._isClosed = true; |
| 780 this._handler = null; |
| 781 _isolate_helper._globalState.currentContext.unregister(this._id); |
| 782 } |
| 783 _add(dataEvent) { |
| 784 if (this._isClosed) |
| 785 return; |
| 786 dart.dinvokef(this._handler, dataEvent); |
| 787 } |
| 788 get sendPort() { |
| 789 return new _NativeJsSendPort(this, _isolate_helper._globalState.currentCon
text.id); |
| 790 } |
| 791 } |
| 792 dart.defineNamedConstructor(RawReceivePortImpl, 'weak'); |
| 793 dart.defineNamedConstructor(RawReceivePortImpl, '_controlPort'); |
| 794 RawReceivePortImpl._nextFreeId = 1; |
| 795 class ReceivePortImpl extends async.Stream { |
| 796 ReceivePortImpl() { |
| 797 this.ReceivePortImpl$fromRawReceivePort(new RawReceivePortImpl(null)); |
| 798 } |
| 799 ReceivePortImpl$weak() { |
| 800 this.ReceivePortImpl$fromRawReceivePort(new RawReceivePortImpl.weak(null))
; |
| 801 } |
| 802 ReceivePortImpl$fromRawReceivePort(_rawPort) { |
| 803 this._rawPort = _rawPort; |
| 804 this._controller = null; |
| 805 super.Stream(); |
| 806 this._controller = new async.StreamController({onCancel: this.close, sync:
true}); |
| 807 this._rawPort.handler = this._controller.add; |
| 808 } |
| 809 listen(onData, opt$) { |
| 810 let onError = opt$.onError === void 0 ? null : opt$.onError; |
| 811 let onDone = opt$.onDone === void 0 ? null : opt$.onDone; |
| 812 let cancelOnError = opt$.cancelOnError === void 0 ? null : opt$.cancelOnEr
ror; |
| 813 return this._controller.stream.listen(onData, {onError: onError, onDone: o
nDone, cancelOnError: cancelOnError}); |
| 814 } |
| 815 close() { |
| 816 this._rawPort.close(); |
| 817 this._controller.close(); |
| 818 } |
| 819 get sendPort() { |
| 820 return this._rawPort.sendPort; |
| 821 } |
| 822 } |
| 823 dart.defineNamedConstructor(ReceivePortImpl, 'weak'); |
| 824 dart.defineNamedConstructor(ReceivePortImpl, 'fromRawReceivePort'); |
| 825 class TimerImpl extends dart.Object { |
| 826 TimerImpl(milliseconds, callback) { |
| 827 this._once = true; |
| 828 this._inEventLoop = false; |
| 829 this._handle = dart.as(null, core.int); |
| 830 if (dart.notNull(milliseconds === 0) && dart.notNull(dart.notNull(!dart.no
tNull(hasTimer())) || dart.notNull(_isolate_helper._globalState.isWorker))) { |
| 831 // Function internalCallback: () → void |
| 832 function internalCallback() { |
| 833 this._handle = dart.as(null, core.int); |
| 834 callback(); |
| 835 } |
| 836 this._handle = 1; |
| 837 _isolate_helper._globalState.topEventLoop.enqueue(_isolate_helper._globa
lState.currentContext, internalCallback, 'timer'); |
| 838 this._inEventLoop = true; |
| 839 } else if (hasTimer()) { |
| 840 // Function internalCallback: () → void |
| 841 function internalCallback() { |
| 842 this._handle = dart.as(null, core.int); |
| 843 leaveJsAsync(); |
| 844 callback(); |
| 845 } |
| 846 enterJsAsync(); |
| 847 this._handle = dart.as(_foreign_helper.JS('int', 'self.setTimeout(#, #)'
, _js_helper.convertDartClosureToJS(internalCallback, 0), milliseconds), core.in
t); |
| 848 } else { |
| 849 dart.assert(milliseconds > 0); |
| 850 throw new core.UnsupportedError("Timer greater than 0."); |
| 851 } |
| 852 } |
| 853 TimerImpl$periodic(milliseconds, callback) { |
| 854 this._once = false; |
| 855 this._inEventLoop = false; |
| 856 this._handle = dart.as(null, core.int); |
| 857 if (hasTimer()) { |
| 858 enterJsAsync(); |
| 859 this._handle = dart.as(_foreign_helper.JS('int', 'self.setInterval(#, #)
', _js_helper.convertDartClosureToJS((() => { |
| 860 callback(this); |
| 861 }).bind(this), 0), milliseconds), core.int); |
| 862 } else { |
| 863 throw new core.UnsupportedError("Periodic timer."); |
| 864 } |
| 865 } |
| 866 cancel() { |
| 867 if (hasTimer()) { |
| 868 if (this._inEventLoop) { |
| 869 throw new core.UnsupportedError("Timer in event loop cannot be cancele
d."); |
| 870 } |
| 871 if (this._handle === null) |
| 872 return; |
| 873 leaveJsAsync(); |
| 874 if (this._once) { |
| 875 _foreign_helper.JS('void', 'self.clearTimeout(#)', this._handle); |
| 876 } else { |
| 877 _foreign_helper.JS('void', 'self.clearInterval(#)', this._handle); |
| 878 } |
| 879 this._handle = dart.as(null, core.int); |
| 880 } else { |
| 881 throw new core.UnsupportedError("Canceling a timer."); |
| 882 } |
| 883 } |
| 884 get isActive() { |
| 885 return this._handle !== null; |
| 886 } |
| 887 } |
| 888 dart.defineNamedConstructor(TimerImpl, 'periodic'); |
| 889 // Function hasTimer: () → bool |
| 890 function hasTimer() { |
| 891 _js_helper.requiresPreamble(); |
| 892 return _foreign_helper.JS('', 'self.setTimeout') !== null; |
| 893 } |
| 894 class CapabilityImpl extends dart.Object { |
| 895 CapabilityImpl() { |
| 896 this.CapabilityImpl$_internal(_js_helper.random64()); |
| 897 } |
| 898 CapabilityImpl$_internal(_id) { |
| 899 this._id = _id; |
| 900 } |
| 901 get hashCode() { |
| 902 let hash = this._id; |
| 903 hash = hash >> 0 ^ (hash / 4294967296).truncate(); |
| 904 hash = ~hash + (hash << 15) & 4294967295; |
| 905 hash = hash >> 12; |
| 906 hash = hash * 5 & 4294967295; |
| 907 hash = hash >> 4; |
| 908 hash = hash * 2057 & 4294967295; |
| 909 hash = hash >> 16; |
| 910 return hash; |
| 911 } |
| 912 ['=='](other) { |
| 913 if (core.identical(other, this)) |
| 914 return true; |
| 915 if (dart.is(other, CapabilityImpl)) { |
| 916 return core.identical(this._id, other._id); |
| 917 } |
| 918 return false; |
| 919 } |
| 920 } |
| 921 dart.defineNamedConstructor(CapabilityImpl, '_internal'); |
| 922 // Function _serializeMessage: (dynamic) → dynamic |
| 923 function _serializeMessage(message) { |
| 924 return new _Serializer().serialize(message); |
| 925 } |
| 926 // Function _deserializeMessage: (dynamic) → dynamic |
| 927 function _deserializeMessage(message) { |
| 928 return new _Deserializer().deserialize(message); |
| 929 } |
| 930 // Function _clone: (dynamic) → dynamic |
| 931 function _clone(message) { |
| 932 let serializer = new _Serializer({serializeSendPorts: false}); |
| 933 let deserializer = new _Deserializer(); |
| 934 return deserializer.deserialize(serializer.serialize(message)); |
| 935 } |
| 936 class _Serializer extends dart.Object { |
| 937 _Serializer(opt$) { |
| 938 let serializeSendPorts = opt$.serializeSendPorts === void 0 ? true : opt$.
serializeSendPorts; |
| 939 this.serializedObjectIds = new core.Map.identity(); |
| 940 this._serializeSendPorts = serializeSendPorts; |
| 941 } |
| 942 serialize(x) { |
| 943 if (this.isPrimitive(x)) |
| 944 return this.serializePrimitive(x); |
| 945 let serializationId = this.serializedObjectIds.get(x); |
| 946 if (serializationId !== null) |
| 947 return this.makeRef(serializationId); |
| 948 serializationId = this.serializedObjectIds.length; |
| 949 this.serializedObjectIds.set(x, serializationId); |
| 950 if (dart.is(x, _native_typed_data.NativeByteBuffer)) |
| 951 return this.serializeByteBuffer(dart.as(x, _native_typed_data.NativeByte
Buffer)); |
| 952 if (dart.is(x, _native_typed_data.NativeTypedData)) |
| 953 return this.serializeTypedData(dart.as(x, _native_typed_data.NativeTyped
Data)); |
| 954 if (dart.is(x, _interceptors.JSIndexable)) |
| 955 return this.serializeJSIndexable(dart.as(x, _interceptors.JSIndexable)); |
| 956 if (dart.is(x, _js_helper.InternalMap)) |
| 957 return this.serializeMap(dart.as(x, core.Map)); |
| 958 if (dart.is(x, _interceptors.JSObject)) |
| 959 return this.serializeJSObject(dart.as(x, _interceptors.JSObject)); |
| 960 if (dart.is(x, _interceptors.Interceptor)) |
| 961 this.unsupported(x); |
| 962 if (dart.is(x, isolate.RawReceivePort)) { |
| 963 this.unsupported(x, "RawReceivePorts can't be transmitted:"); |
| 964 } |
| 965 if (dart.is(x, _NativeJsSendPort)) |
| 966 return this.serializeJsSendPort(dart.as(x, _NativeJsSendPort)); |
| 967 if (dart.is(x, _WorkerSendPort)) |
| 968 return this.serializeWorkerSendPort(dart.as(x, _WorkerSendPort)); |
| 969 if (dart.is(x, _js_helper.Closure)) |
| 970 return this.serializeClosure(dart.as(x, _js_helper.Closure)); |
| 971 return this.serializeDartObject(x); |
| 972 } |
| 973 unsupported(x, message) { |
| 974 if (message === void 0) |
| 975 message = null; |
| 976 if (message === null) |
| 977 message = "Can't transmit:"; |
| 978 throw new core.UnsupportedError(`${message} ${x}`); |
| 979 } |
| 980 makeRef(serializationId) { |
| 981 return new List.from(["ref", serializationId]); |
| 982 } |
| 983 isPrimitive(x) { |
| 984 return dart.notNull(dart.notNull(dart.notNull(x === null) || dart.notNull(
typeof x == string)) || dart.notNull(dart.is(x, core.num))) || dart.notNull(type
of x == boolean); |
| 985 } |
| 986 serializePrimitive(primitive) { |
| 987 return primitive; |
| 988 } |
| 989 serializeByteBuffer(buffer) { |
| 990 return new List.from(["buffer", buffer]); |
| 991 } |
| 992 serializeTypedData(data) { |
| 993 return new List.from(["typed", data]); |
| 994 } |
| 995 serializeJSIndexable(indexable) { |
| 996 dart.assert(!(typeof indexable == string)); |
| 997 let serialized = dart.as(this.serializeArray(dart.as(indexable, _intercept
ors.JSArray)), core.List); |
| 998 if (dart.is(indexable, _interceptors.JSFixedArray)) |
| 999 return new List.from(["fixed", serialized]); |
| 1000 if (dart.is(indexable, _interceptors.JSExtendableArray)) |
| 1001 return new List.from(["extendable", serialized]); |
| 1002 if (dart.is(indexable, _interceptors.JSMutableArray)) |
| 1003 return new List.from(["mutable", serialized]); |
| 1004 if (dart.is(indexable, _interceptors.JSArray)) |
| 1005 return new List.from(["const", serialized]); |
| 1006 this.unsupported(indexable, "Can't serialize indexable: "); |
| 1007 return null; |
| 1008 } |
| 1009 serializeArray(x) { |
| 1010 let serialized = new List.from([]); |
| 1011 serialized.length = x.length; |
| 1012 for (let i = 0; i < x.length; i++) { |
| 1013 serialized.set(i, this.serialize(x.get(i))); |
| 1014 } |
| 1015 return serialized; |
| 1016 } |
| 1017 serializeArrayInPlace(x) { |
| 1018 for (let i = 0; i < x.length; i++) { |
| 1019 x.set(i, this.serialize(x.get(i))); |
| 1020 } |
| 1021 return x; |
| 1022 } |
| 1023 serializeMap(x) { |
| 1024 let serializeTearOff = this.serialize; |
| 1025 return new List.from(['map', x.keys.map(dart.as(serializeTearOff, dart.thr
ow_("Unimplemented type (dynamic) → dynamic"))).toList(), x.values.map(dart.as(s
erializeTearOff, dart.throw_("Unimplemented type (dynamic) → dynamic"))).toList(
)]); |
| 1026 } |
| 1027 serializeJSObject(x) { |
| 1028 if (dart.dbinary(_foreign_helper.JS('bool', '!!(#.constructor)', x), '&&',
_foreign_helper.JS('bool', 'x.constructor !== Object'))) { |
| 1029 this.unsupported(x, "Only plain JS Objects are supported:"); |
| 1030 } |
| 1031 let keys = dart.as(_foreign_helper.JS('JSArray', 'Object.keys(#)', x), cor
e.List); |
| 1032 let values = new List.from([]); |
| 1033 values.length = keys.length; |
| 1034 for (let i = 0; i < keys.length; i++) { |
| 1035 values.set(i, this.serialize(_foreign_helper.JS('', '#[#]', x, keys.get(
i)))); |
| 1036 } |
| 1037 return new List.from(['js-object', keys, values]); |
| 1038 } |
| 1039 serializeWorkerSendPort(x) { |
| 1040 if (this._serializeSendPorts) { |
| 1041 return new List.from(['sendport', x._workerId, x._isolateId, x._receiveP
ortId]); |
| 1042 } |
| 1043 return new List.from(['raw sendport', x]); |
| 1044 } |
| 1045 serializeJsSendPort(x) { |
| 1046 if (this._serializeSendPorts) { |
| 1047 let workerId = _isolate_helper._globalState.currentManagerId; |
| 1048 return new List.from(['sendport', workerId, x._isolateId, x._receivePort
._id]); |
| 1049 } |
| 1050 return new List.from(['raw sendport', x]); |
| 1051 } |
| 1052 serializeCapability(x) { |
| 1053 return new List.from(['capability', x._id]); |
| 1054 } |
| 1055 serializeClosure(x) { |
| 1056 let name = IsolateNatives._getJSFunctionName(x); |
| 1057 if (name === null) { |
| 1058 this.unsupported(x, "Closures can't be transmitted:"); |
| 1059 } |
| 1060 return new List.from(['function', name]); |
| 1061 } |
| 1062 serializeDartObject(x) { |
| 1063 let classExtractor = _foreign_helper.JS_EMBEDDED_GLOBAL('', dart.as(_js_em
bedded_names.CLASS_ID_EXTRACTOR, core.String)); |
| 1064 let fieldsExtractor = _foreign_helper.JS_EMBEDDED_GLOBAL('', dart.as(_js_e
mbedded_names.CLASS_FIELDS_EXTRACTOR, core.String)); |
| 1065 let classId = dart.as(_foreign_helper.JS('String', '#(#)', classExtractor,
x), core.String); |
| 1066 let fields = dart.as(_foreign_helper.JS('JSArray', '#(#)', fieldsExtractor
, x), core.List); |
| 1067 return new List.from(['dart', classId, this.serializeArrayInPlace(dart.as(
fields, _interceptors.JSArray))]); |
| 1068 } |
| 1069 } |
| 1070 class _Deserializer extends dart.Object { |
| 1071 _Deserializer(opt$) { |
| 1072 let adjustSendPorts = opt$.adjustSendPorts === void 0 ? true : opt$.adjust
SendPorts; |
| 1073 this.deserializedObjects = new core.List(); |
| 1074 this._adjustSendPorts = adjustSendPorts; |
| 1075 } |
| 1076 deserialize(x) { |
| 1077 if (this.isPrimitive(x)) |
| 1078 return this.deserializePrimitive(x); |
| 1079 if (!dart.is(x, _interceptors.JSArray)) |
| 1080 throw new core.ArgumentError(`Bad serialized message: ${x}`); |
| 1081 switch (dart.dload(x, 'first')) { |
| 1082 case "ref": |
| 1083 return this.deserializeRef(x); |
| 1084 case "buffer": |
| 1085 return this.deserializeByteBuffer(x); |
| 1086 case "typed": |
| 1087 return this.deserializeTypedData(x); |
| 1088 case "fixed": |
| 1089 return this.deserializeFixed(x); |
| 1090 case "extendable": |
| 1091 return this.deserializeExtendable(x); |
| 1092 case "mutable": |
| 1093 return this.deserializeMutable(x); |
| 1094 case "const": |
| 1095 return this.deserializeConst(x); |
| 1096 case "map": |
| 1097 return this.deserializeMap(x); |
| 1098 case "sendport": |
| 1099 return this.deserializeSendPort(x); |
| 1100 case "raw sendport": |
| 1101 return this.deserializeRawSendPort(x); |
| 1102 case "js-object": |
| 1103 return this.deserializeJSObject(x); |
| 1104 case "function": |
| 1105 return this.deserializeClosure(x); |
| 1106 case "dart": |
| 1107 return this.deserializeDartObject(x); |
| 1108 default: |
| 1109 throw `couldn't deserialize: ${x}`; |
| 1110 } |
| 1111 } |
| 1112 isPrimitive(x) { |
| 1113 return dart.notNull(dart.notNull(dart.notNull(x === null) || dart.notNull(
typeof x == string)) || dart.notNull(dart.is(x, core.num))) || dart.notNull(type
of x == boolean); |
| 1114 } |
| 1115 deserializePrimitive(x) { |
| 1116 return x; |
| 1117 } |
| 1118 deserializeRef(x) { |
| 1119 dart.assert(dart.equals(dart.dindex(x, 0), 'ref')); |
| 1120 let serializationId = dart.as(dart.dindex(x, 1), core.int); |
| 1121 return this.deserializedObjects.get(serializationId); |
| 1122 } |
| 1123 deserializeByteBuffer(x) { |
| 1124 dart.assert(dart.equals(dart.dindex(x, 0), 'buffer')); |
| 1125 let result = dart.as(dart.dindex(x, 1), _native_typed_data.NativeByteBuffe
r); |
| 1126 this.deserializedObjects.add(result); |
| 1127 return result; |
| 1128 } |
| 1129 deserializeTypedData(x) { |
| 1130 dart.assert(dart.equals(dart.dindex(x, 0), 'typed')); |
| 1131 let result = dart.as(dart.dindex(x, 1), _native_typed_data.NativeTypedData
); |
| 1132 this.deserializedObjects.add(result); |
| 1133 return result; |
| 1134 } |
| 1135 deserializeArrayInPlace(x) { |
| 1136 for (let i = 0; i < x.length; i++) { |
| 1137 x.set(i, this.deserialize(x.get(i))); |
| 1138 } |
| 1139 return x; |
| 1140 } |
| 1141 deserializeFixed(x) { |
| 1142 dart.assert(dart.equals(dart.dindex(x, 0), 'fixed')); |
| 1143 let result = dart.as(dart.dindex(x, 1), core.List); |
| 1144 this.deserializedObjects.add(result); |
| 1145 return new _interceptors.JSArray.markFixed(this.deserializeArrayInPlace(da
rt.as(result, _interceptors.JSArray))); |
| 1146 } |
| 1147 deserializeExtendable(x) { |
| 1148 dart.assert(dart.equals(dart.dindex(x, 0), 'extendable')); |
| 1149 let result = dart.as(dart.dindex(x, 1), core.List); |
| 1150 this.deserializedObjects.add(result); |
| 1151 return new _interceptors.JSArray.markGrowable(this.deserializeArrayInPlace
(dart.as(result, _interceptors.JSArray))); |
| 1152 } |
| 1153 deserializeMutable(x) { |
| 1154 dart.assert(dart.equals(dart.dindex(x, 0), 'mutable')); |
| 1155 let result = dart.as(dart.dindex(x, 1), core.List); |
| 1156 this.deserializedObjects.add(result); |
| 1157 return this.deserializeArrayInPlace(dart.as(result, _interceptors.JSArray)
); |
| 1158 } |
| 1159 deserializeConst(x) { |
| 1160 dart.assert(dart.equals(dart.dindex(x, 0), 'const')); |
| 1161 let result = dart.as(dart.dindex(x, 1), core.List); |
| 1162 this.deserializedObjects.add(result); |
| 1163 return new _interceptors.JSArray.markFixed(this.deserializeArrayInPlace(da
rt.as(result, _interceptors.JSArray))); |
| 1164 } |
| 1165 deserializeMap(x) { |
| 1166 dart.assert(dart.equals(dart.dindex(x, 0), 'map')); |
| 1167 let keys = dart.as(dart.dindex(x, 1), core.List); |
| 1168 let values = dart.as(dart.dindex(x, 2), core.List); |
| 1169 let result = dart.map(); |
| 1170 this.deserializedObjects.add(result); |
| 1171 keys = keys.map(this.deserialize).toList(); |
| 1172 for (let i = 0; i < keys.length; i++) { |
| 1173 result.set(keys.get(i), this.deserialize(values.get(i))); |
| 1174 } |
| 1175 return result; |
| 1176 } |
| 1177 deserializeSendPort(x) { |
| 1178 dart.assert(dart.equals(dart.dindex(x, 0), 'sendport')); |
| 1179 let managerId = dart.as(dart.dindex(x, 1), core.int); |
| 1180 let isolateId = dart.as(dart.dindex(x, 2), core.int); |
| 1181 let receivePortId = dart.as(dart.dindex(x, 3), core.int); |
| 1182 let result = null; |
| 1183 if (managerId === _isolate_helper._globalState.currentManagerId) { |
| 1184 let isolate = _isolate_helper._globalState.isolates.get(isolateId); |
| 1185 if (isolate === null) |
| 1186 return null; |
| 1187 let receivePort = isolate.lookup(receivePortId); |
| 1188 if (receivePort === null) |
| 1189 return null; |
| 1190 result = new _NativeJsSendPort(receivePort, isolateId); |
| 1191 } else { |
| 1192 result = new _WorkerSendPort(managerId, isolateId, receivePortId); |
| 1193 } |
| 1194 this.deserializedObjects.add(result); |
| 1195 return result; |
| 1196 } |
| 1197 deserializeRawSendPort(x) { |
| 1198 dart.assert(dart.equals(dart.dindex(x, 0), 'raw sendport')); |
| 1199 let result = dart.as(dart.dindex(x, 1), isolate.SendPort); |
| 1200 this.deserializedObjects.add(result); |
| 1201 return result; |
| 1202 } |
| 1203 deserializeJSObject(x) { |
| 1204 dart.assert(dart.equals(dart.dindex(x, 0), 'js-object')); |
| 1205 let keys = dart.as(dart.dindex(x, 1), core.List); |
| 1206 let values = dart.as(dart.dindex(x, 2), core.List); |
| 1207 let o = _foreign_helper.JS('', '{}'); |
| 1208 this.deserializedObjects.add(o); |
| 1209 for (let i = 0; i < keys.length; i++) { |
| 1210 _foreign_helper.JS('', '#[#]=#', o, keys.get(i), this.deserialize(values
.get(i))); |
| 1211 } |
| 1212 return o; |
| 1213 } |
| 1214 deserializeClosure(x) { |
| 1215 dart.assert(dart.equals(dart.dindex(x, 0), 'function')); |
| 1216 let name = dart.as(dart.dindex(x, 1), core.String); |
| 1217 let result = dart.as(IsolateNatives._getJSFunctionFromName(name), core.Fun
ction); |
| 1218 this.deserializedObjects.add(result); |
| 1219 return result; |
| 1220 } |
| 1221 deserializeDartObject(x) { |
| 1222 dart.assert(dart.equals(dart.dindex(x, 0), 'dart')); |
| 1223 let classId = dart.as(dart.dindex(x, 1), core.String); |
| 1224 let fields = dart.as(dart.dindex(x, 2), core.List); |
| 1225 let instanceFromClassId = _foreign_helper.JS_EMBEDDED_GLOBAL('', dart.as(_
js_embedded_names.INSTANCE_FROM_CLASS_ID, core.String)); |
| 1226 let initializeObject = _foreign_helper.JS_EMBEDDED_GLOBAL('', dart.as(_js_
embedded_names.INITIALIZE_EMPTY_INSTANCE, core.String)); |
| 1227 let emptyInstance = _foreign_helper.JS('', '#(#)', instanceFromClassId, cl
assId); |
| 1228 this.deserializedObjects.add(emptyInstance); |
| 1229 this.deserializeArrayInPlace(dart.as(fields, _interceptors.JSArray)); |
| 1230 return _foreign_helper.JS('', '#(#, #, #)', initializeObject, classId, emp
tyInstance, fields); |
| 1231 } |
| 1232 } |
| 1233 // Exports: |
| 1234 _isolate_helper.enterJsAsync = enterJsAsync; |
| 1235 _isolate_helper.leaveJsAsync = leaveJsAsync; |
| 1236 _isolate_helper.isWorker = isWorker; |
| 1237 _isolate_helper.startRootIsolate = startRootIsolate; |
| 1238 _isolate_helper.globalWindow = globalWindow; |
| 1239 _isolate_helper.globalWorker = globalWorker; |
| 1240 _isolate_helper.globalPostMessageDefined = globalPostMessageDefined; |
| 1241 _isolate_helper.IsolateNatives = IsolateNatives; |
| 1242 _isolate_helper.RawReceivePortImpl = RawReceivePortImpl; |
| 1243 _isolate_helper.ReceivePortImpl = ReceivePortImpl; |
| 1244 _isolate_helper.TimerImpl = TimerImpl; |
| 1245 _isolate_helper.hasTimer = hasTimer; |
| 1246 _isolate_helper.CapabilityImpl = CapabilityImpl; |
| 1247 })(_isolate_helper || (_isolate_helper = {})); |
| OLD | NEW |