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