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