@swf2es/player-hosts 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (405) hide show
  1. package/LICENSE +202 -0
  2. package/LICENSE.third-party +759 -0
  3. package/README.md +43 -2
  4. package/dist/indexeddb.d.ts +27 -0
  5. package/dist/indexeddb.d.ts.map +1 -0
  6. package/dist/indexeddb.js +170 -0
  7. package/dist/indexeddb.js.map +1 -0
  8. package/dist/node-worker.d.ts +2 -0
  9. package/dist/node-worker.d.ts.map +1 -0
  10. package/dist/node-worker.js +12 -0
  11. package/dist/node-worker.js.map +1 -0
  12. package/dist/node.d.ts +8 -0
  13. package/dist/node.d.ts.map +1 -0
  14. package/dist/node.js +43 -0
  15. package/dist/node.js.map +1 -0
  16. package/dist/precompiled.d.ts +31 -0
  17. package/dist/precompiled.d.ts.map +1 -0
  18. package/dist/precompiled.js +125 -0
  19. package/dist/precompiled.js.map +1 -0
  20. package/dist/stage3d.d.ts +13 -0
  21. package/dist/stage3d.d.ts.map +1 -0
  22. package/dist/stage3d.js +61 -0
  23. package/dist/stage3d.js.map +1 -0
  24. package/dist/thread/codegen/codegen.js +308 -0
  25. package/dist/thread/codegen/index.js +405 -0
  26. package/dist/thread/format/abc-names.js +126 -0
  27. package/dist/thread/format/actions.js +222 -0
  28. package/dist/thread/format/air-descriptor.js +63 -0
  29. package/dist/thread/format/api-versions.js +22 -0
  30. package/dist/thread/format/bitmap.js +199 -0
  31. package/dist/thread/format/button.js +60 -0
  32. package/dist/thread/format/compression.js +200 -0
  33. package/dist/thread/format/display.js +305 -0
  34. package/dist/thread/format/filters.js +136 -0
  35. package/dist/thread/format/font.js +168 -0
  36. package/dist/thread/format/index.js +26 -0
  37. package/dist/thread/format/pbj.js +484 -0
  38. package/dist/thread/format/shape.js +411 -0
  39. package/dist/thread/format/sound.js +91 -0
  40. package/dist/thread/format/swf.js +163 -0
  41. package/dist/thread/format/tags.js +58 -0
  42. package/dist/thread/format/text.js +135 -0
  43. package/dist/thread/format/zip.js +91 -0
  44. package/dist/thread/native/audio/binary.js +3 -0
  45. package/dist/thread/native/audio/index.js +72 -0
  46. package/dist/thread/native/base64.js +9 -0
  47. package/dist/thread/native/compress/binary.js +3 -0
  48. package/dist/thread/native/compress/index.js +145 -0
  49. package/dist/thread/native/instance.js +49 -0
  50. package/dist/thread/native/mp3/binary.js +3 -0
  51. package/dist/thread/native/mp3/index.js +48 -0
  52. package/dist/thread/native/render/binary.js +3 -0
  53. package/dist/thread/native/render/bitmap-kernel.js +591 -0
  54. package/dist/thread/native/render/draw-kernel.js +204 -0
  55. package/dist/thread/native/render/dxt-encoder.js +94 -0
  56. package/dist/thread/native/render/index.js +10 -0
  57. package/dist/thread/native/render/lines.js +122 -0
  58. package/dist/thread/native/render/module.js +26 -0
  59. package/dist/thread/native/render/pixel-ops.js +235 -0
  60. package/dist/thread/native/render/tessellator.js +250 -0
  61. package/dist/thread/player/avm1/amf.js +507 -0
  62. package/dist/thread/player/avm1/avm1.js +1304 -0
  63. package/dist/thread/player/avm1/bindings.js +214 -0
  64. package/dist/thread/player/avm1/classes.js +75 -0
  65. package/dist/thread/player/avm1/clips.js +229 -0
  66. package/dist/thread/player/avm1/compile.js +140 -0
  67. package/dist/thread/player/avm1/external.js +79 -0
  68. package/dist/thread/player/avm1/focus.js +278 -0
  69. package/dist/thread/player/avm1/globals/BitmapData.js +542 -0
  70. package/dist/thread/player/avm1/globals/Button.js +31 -0
  71. package/dist/thread/player/avm1/globals/Color.js +115 -0
  72. package/dist/thread/player/avm1/globals/ExternalInterface.js +310 -0
  73. package/dist/thread/player/avm1/globals/FileReference.js +217 -0
  74. package/dist/thread/player/avm1/globals/Key.js +60 -0
  75. package/dist/thread/player/avm1/globals/LoadVars.js +208 -0
  76. package/dist/thread/player/avm1/globals/LocalConnection.js +92 -0
  77. package/dist/thread/player/avm1/globals/MovieClip.js +1070 -0
  78. package/dist/thread/player/avm1/globals/MovieClipLoader.js +90 -0
  79. package/dist/thread/player/avm1/globals/NetConnection.js +261 -0
  80. package/dist/thread/player/avm1/globals/PrintJob.js +37 -0
  81. package/dist/thread/player/avm1/globals/Selection.js +62 -0
  82. package/dist/thread/player/avm1/globals/SharedObject.js +245 -0
  83. package/dist/thread/player/avm1/globals/Sound.js +238 -0
  84. package/dist/thread/player/avm1/globals/Stage.js +12 -0
  85. package/dist/thread/player/avm1/globals/StyleSheet.js +205 -0
  86. package/dist/thread/player/avm1/globals/TextField.js +396 -0
  87. package/dist/thread/player/avm1/globals/TextFormat.js +194 -0
  88. package/dist/thread/player/avm1/globals/TextSnapshot.js +88 -0
  89. package/dist/thread/player/avm1/globals/XML.js +396 -0
  90. package/dist/thread/player/avm1/globals/XMLNode.js +413 -0
  91. package/dist/thread/player/avm1/globals/XMLSocket.js +205 -0
  92. package/dist/thread/player/avm1/globals/drawing.js +202 -0
  93. package/dist/thread/player/avm1/globals/filters.js +635 -0
  94. package/dist/thread/player/avm1/globals/geom.js +600 -0
  95. package/dist/thread/player/avm1/input.js +483 -0
  96. package/dist/thread/player/avm1/keyboard.js +113 -0
  97. package/dist/thread/player/avm1/loads.js +352 -0
  98. package/dist/thread/player/avm1/net.js +219 -0
  99. package/dist/thread/player/avm1/paths.js +104 -0
  100. package/dist/thread/player/avm1/pointer.js +512 -0
  101. package/dist/thread/player/avm1/queue.js +303 -0
  102. package/dist/thread/player/avm1/sound.js +106 -0
  103. package/dist/thread/player/avm1/swf.js +141 -0
  104. package/dist/thread/player/avm1/timers.js +113 -0
  105. package/dist/thread/player/bitmap/bitmap.js +627 -0
  106. package/dist/thread/player/bitmap/draw.js +68 -0
  107. package/dist/thread/player/bitmap/dxt.js +11 -0
  108. package/dist/thread/player/bitmap/filters.js +656 -0
  109. package/dist/thread/player/bitmap/images.js +240 -0
  110. package/dist/thread/player/bitmap/kernel.js +65 -0
  111. package/dist/thread/player/bitmap/ops.js +1239 -0
  112. package/dist/thread/player/bitmap/pixel-bender.js +911 -0
  113. package/dist/thread/player/bitmap/png.js +139 -0
  114. package/dist/thread/player/bitmap/turbulence.js +89 -0
  115. package/dist/thread/player/clock.js +182 -0
  116. package/dist/thread/player/display/bitmapobject.js +25 -0
  117. package/dist/thread/player/display/bounds.js +520 -0
  118. package/dist/thread/player/display/buttonobject.js +305 -0
  119. package/dist/thread/player/display/color.js +40 -0
  120. package/dist/thread/player/display/container.js +150 -0
  121. package/dist/thread/player/display/display.js +14 -0
  122. package/dist/thread/player/display/displayobject.js +664 -0
  123. package/dist/thread/player/display/drawing.js +613 -0
  124. package/dist/thread/player/display/filters.js +285 -0
  125. package/dist/thread/player/display/geometry.js +189 -0
  126. package/dist/thread/player/display/gradients.js +117 -0
  127. package/dist/thread/player/display/graphicsdata.js +592 -0
  128. package/dist/thread/player/display/instantiate.js +71 -0
  129. package/dist/thread/player/display/matrix3d.js +373 -0
  130. package/dist/thread/player/display/morph.js +226 -0
  131. package/dist/thread/player/display/movieclip.js +680 -0
  132. package/dist/thread/player/display/perspective.js +193 -0
  133. package/dist/thread/player/display/scale9.js +236 -0
  134. package/dist/thread/player/display/shapeobject.js +131 -0
  135. package/dist/thread/player/display/shapes.js +407 -0
  136. package/dist/thread/player/display/textobjects.js +222 -0
  137. package/dist/thread/player/display/timeline.js +471 -0
  138. package/dist/thread/player/display/value-lists.js +40 -0
  139. package/dist/thread/player/display/videoobject.js +6 -0
  140. package/dist/thread/player/display/walk.js +127 -0
  141. package/dist/thread/player/files.js +334 -0
  142. package/dist/thread/player/hosts.js +207 -0
  143. package/dist/thread/player/input/avm1.js +82 -0
  144. package/dist/thread/player/input/context-menu.js +63 -0
  145. package/dist/thread/player/input/keyboard.js +458 -0
  146. package/dist/thread/player/input/pointer.js +863 -0
  147. package/dist/thread/player/input/text-editor.js +319 -0
  148. package/dist/thread/player/input/touch.js +209 -0
  149. package/dist/thread/player/localconnection.js +90 -0
  150. package/dist/thread/player/media/audio.js +376 -0
  151. package/dist/thread/player/media/dynamic-sound.js +90 -0
  152. package/dist/thread/player/media/extract.js +135 -0
  153. package/dist/thread/player/media/mp3.js +152 -0
  154. package/dist/thread/player/media/sounds.js +507 -0
  155. package/dist/thread/player/media/streaming-audio.js +133 -0
  156. package/dist/thread/player/player.js +616 -0
  157. package/dist/thread/player/playerglobal/air/net/WebSocket.js +250 -0
  158. package/dist/thread/player/playerglobal/air-library.js +8 -0
  159. package/dist/thread/player/playerglobal/flash/accessibility/Accessibility.js +21 -0
  160. package/dist/thread/player/playerglobal/flash/crypto/generateRandomBytes.js +32 -0
  161. package/dist/thread/player/playerglobal/flash/data/EncryptedLocalStore.js +61 -0
  162. package/dist/thread/player/playerglobal/flash/desktop/Clipboard.js +173 -0
  163. package/dist/thread/player/playerglobal/flash/desktop/NativeApplication.js +179 -0
  164. package/dist/thread/player/playerglobal/flash/display/AVM1Movie.js +19 -0
  165. package/dist/thread/player/playerglobal/flash/display/Bitmap.js +58 -0
  166. package/dist/thread/player/playerglobal/flash/display/BitmapData.js +633 -0
  167. package/dist/thread/player/playerglobal/flash/display/DisplayObject.js +614 -0
  168. package/dist/thread/player/playerglobal/flash/display/DisplayObjectContainer.js +224 -0
  169. package/dist/thread/player/playerglobal/flash/display/Graphics.js +345 -0
  170. package/dist/thread/player/playerglobal/flash/display/InteractiveObject.js +87 -0
  171. package/dist/thread/player/playerglobal/flash/display/Loader.js +79 -0
  172. package/dist/thread/player/playerglobal/flash/display/LoaderInfo.js +128 -0
  173. package/dist/thread/player/playerglobal/flash/display/MovieClip.js +194 -0
  174. package/dist/thread/player/playerglobal/flash/display/NativeWindow.js +245 -0
  175. package/dist/thread/player/playerglobal/flash/display/Shader.js +26 -0
  176. package/dist/thread/player/playerglobal/flash/display/ShaderData.js +85 -0
  177. package/dist/thread/player/playerglobal/flash/display/ShaderInput.js +64 -0
  178. package/dist/thread/player/playerglobal/flash/display/ShaderJob.js +181 -0
  179. package/dist/thread/player/playerglobal/flash/display/ShaderParameter.js +23 -0
  180. package/dist/thread/player/playerglobal/flash/display/Shape.js +13 -0
  181. package/dist/thread/player/playerglobal/flash/display/SimpleButton.js +103 -0
  182. package/dist/thread/player/playerglobal/flash/display/Sprite.js +84 -0
  183. package/dist/thread/player/playerglobal/flash/display/Stage.js +231 -0
  184. package/dist/thread/player/playerglobal/flash/display/Stage3D.js +54 -0
  185. package/dist/thread/player/playerglobal/flash/display/shaders.js +228 -0
  186. package/dist/thread/player/playerglobal/flash/events/Event.js +58 -0
  187. package/dist/thread/player/playerglobal/flash/events/EventDispatcher.js +103 -0
  188. package/dist/thread/player/playerglobal/flash/events/GestureEvent.js +34 -0
  189. package/dist/thread/player/playerglobal/flash/events/HTTPStatusEvent.js +8 -0
  190. package/dist/thread/player/playerglobal/flash/events/KeyboardEvent.js +51 -0
  191. package/dist/thread/player/playerglobal/flash/events/MouseEvent.js +59 -0
  192. package/dist/thread/player/playerglobal/flash/events/PressAndTapGestureEvent.js +30 -0
  193. package/dist/thread/player/playerglobal/flash/events/TimerEvent.js +16 -0
  194. package/dist/thread/player/playerglobal/flash/events/TouchEvent.js +45 -0
  195. package/dist/thread/player/playerglobal/flash/external/ExternalInterface.js +73 -0
  196. package/dist/thread/player/playerglobal/flash/filesystem/File.js +340 -0
  197. package/dist/thread/player/playerglobal/flash/filesystem/FileStream.js +453 -0
  198. package/dist/thread/player/playerglobal/flash/filesystem/paths.js +156 -0
  199. package/dist/thread/player/playerglobal/flash/filesystem/writes.js +143 -0
  200. package/dist/thread/player/playerglobal/flash/filters/BevelFilter.js +4 -0
  201. package/dist/thread/player/playerglobal/flash/filters/BitmapFilter.js +205 -0
  202. package/dist/thread/player/playerglobal/flash/filters/BlurFilter.js +4 -0
  203. package/dist/thread/player/playerglobal/flash/filters/ColorMatrixFilter.js +11 -0
  204. package/dist/thread/player/playerglobal/flash/filters/ConvolutionFilter.js +26 -0
  205. package/dist/thread/player/playerglobal/flash/filters/DisplacementMapFilter.js +51 -0
  206. package/dist/thread/player/playerglobal/flash/filters/DropShadowFilter.js +4 -0
  207. package/dist/thread/player/playerglobal/flash/filters/GlowFilter.js +4 -0
  208. package/dist/thread/player/playerglobal/flash/filters/GradientBevelFilter.js +4 -0
  209. package/dist/thread/player/playerglobal/flash/filters/GradientGlowFilter.js +4 -0
  210. package/dist/thread/player/playerglobal/flash/filters/ShaderFilter.js +53 -0
  211. package/dist/thread/player/playerglobal/flash/geom/Matrix3D.js +361 -0
  212. package/dist/thread/player/playerglobal/flash/geom/PerspectiveProjection.js +122 -0
  213. package/dist/thread/player/playerglobal/flash/geom/Transform.js +245 -0
  214. package/dist/thread/player/playerglobal/flash/geom/Utils3D.js +85 -0
  215. package/dist/thread/player/playerglobal/flash/globalization/Collator.js +149 -0
  216. package/dist/thread/player/playerglobal/flash/globalization/CurrencyFormatter.js +272 -0
  217. package/dist/thread/player/playerglobal/flash/globalization/CurrencyParseResult.js +21 -0
  218. package/dist/thread/player/playerglobal/flash/globalization/DateTimeFormatter.js +463 -0
  219. package/dist/thread/player/playerglobal/flash/globalization/LocaleID.js +144 -0
  220. package/dist/thread/player/playerglobal/flash/globalization/NumberFormatter.js +444 -0
  221. package/dist/thread/player/playerglobal/flash/globalization/NumberParseResult.js +22 -0
  222. package/dist/thread/player/playerglobal/flash/globalization/StringTools.js +59 -0
  223. package/dist/thread/player/playerglobal/flash/globalization/locale.js +190 -0
  224. package/dist/thread/player/playerglobal/flash/media/Camera.js +89 -0
  225. package/dist/thread/player/playerglobal/flash/media/Microphone.js +126 -0
  226. package/dist/thread/player/playerglobal/flash/media/Sound.js +543 -0
  227. package/dist/thread/player/playerglobal/flash/media/SoundMixer.js +74 -0
  228. package/dist/thread/player/playerglobal/flash/media/SoundTransform.js +40 -0
  229. package/dist/thread/player/playerglobal/flash/media/Video.js +43 -0
  230. package/dist/thread/player/playerglobal/flash/net/FileFilter.js +27 -0
  231. package/dist/thread/player/playerglobal/flash/net/FileReference.js +197 -0
  232. package/dist/thread/player/playerglobal/flash/net/LocalConnection.js +167 -0
  233. package/dist/thread/player/playerglobal/flash/net/NetConnection.js +155 -0
  234. package/dist/thread/player/playerglobal/flash/net/SharedObject.js +299 -0
  235. package/dist/thread/player/playerglobal/flash/net/Socket.js +282 -0
  236. package/dist/thread/player/playerglobal/flash/net/URLRequest.js +93 -0
  237. package/dist/thread/player/playerglobal/flash/net/URLStream.js +146 -0
  238. package/dist/thread/player/playerglobal/flash/net/XMLSocket.js +14 -0
  239. package/dist/thread/player/playerglobal/flash/net/local-modern.js +142 -0
  240. package/dist/thread/player/playerglobal/flash/net/local-values.js +217 -0
  241. package/dist/thread/player/playerglobal/flash/net/navigateToURL.js +29 -0
  242. package/dist/thread/player/playerglobal/flash/profiler/Telemetry.js +25 -0
  243. package/dist/thread/player/playerglobal/flash/sensors/Accelerometer.js +12 -0
  244. package/dist/thread/player/playerglobal/flash/system/ApplicationDomain.js +69 -0
  245. package/dist/thread/player/playerglobal/flash/system/Capabilities.js +163 -0
  246. package/dist/thread/player/playerglobal/flash/system/FSCommandHost.js +17 -0
  247. package/dist/thread/player/playerglobal/flash/system/Security.js +46 -0
  248. package/dist/thread/player/playerglobal/flash/system/SecurityDomain.js +21 -0
  249. package/dist/thread/player/playerglobal/flash/system/System.js +73 -0
  250. package/dist/thread/player/playerglobal/flash/system/Worker.js +112 -0
  251. package/dist/thread/player/playerglobal/flash/text/Font.js +95 -0
  252. package/dist/thread/player/playerglobal/flash/text/StaticText.js +16 -0
  253. package/dist/thread/player/playerglobal/flash/text/StyleSheet.js +65 -0
  254. package/dist/thread/player/playerglobal/flash/text/TextField.js +707 -0
  255. package/dist/thread/player/playerglobal/flash/text/TextRenderer.js +77 -0
  256. package/dist/thread/player/playerglobal/flash/text/engine/FontDescription.js +141 -0
  257. package/dist/thread/player/playerglobal/flash/text/engine/TabStop.js +46 -0
  258. package/dist/thread/player/playerglobal/flash/trace/Trace.js +17 -0
  259. package/dist/thread/player/playerglobal/flash/ui/ContextMenu.js +17 -0
  260. package/dist/thread/player/playerglobal/flash/ui/GameInput.js +19 -0
  261. package/dist/thread/player/playerglobal/flash/ui/Keyboard.js +27 -0
  262. package/dist/thread/player/playerglobal/flash/ui/Mouse.js +127 -0
  263. package/dist/thread/player/playerglobal/flash/ui/Multitouch.js +46 -0
  264. package/dist/thread/player/playerglobal/flash/utils/ByteArray.js +155 -0
  265. package/dist/thread/player/playerglobal/flash/utils/Timer.js +25 -0
  266. package/dist/thread/player/playerglobal/flash/xml/XMLDocument.js +74 -0
  267. package/dist/thread/player/playerglobal/index.js +224 -0
  268. package/dist/thread/player/playerglobal/libraries.js +10 -0
  269. package/dist/thread/player/playerglobal/playerglobal-library.js +22 -0
  270. package/dist/thread/player/playerglobal/toplevel.js +122 -0
  271. package/dist/thread/player/scripting/clipboard.js +146 -0
  272. package/dist/thread/player/scripting/code.js +900 -0
  273. package/dist/thread/player/scripting/evaluate.js +144 -0
  274. package/dist/thread/player/scripting/events.js +172 -0
  275. package/dist/thread/player/scripting/handover.js +182 -0
  276. package/dist/thread/player/scripting/lazy.js +38 -0
  277. package/dist/thread/player/scripting/lifecycle.js +272 -0
  278. package/dist/thread/player/scripting/loads.js +860 -0
  279. package/dist/thread/player/scripting/sha256.js +95 -0
  280. package/dist/thread/player/scripting/symbols.js +348 -0
  281. package/dist/thread/player/scripting/timers.js +434 -0
  282. package/dist/thread/player/scripting/workers.js +923 -0
  283. package/dist/thread/player/scripting.js +1018 -0
  284. package/dist/thread/player/stage.js +4 -0
  285. package/dist/thread/player/text/csm.js +113 -0
  286. package/dist/thread/player/text/css.js +167 -0
  287. package/dist/thread/player/text/fonts.js +97 -0
  288. package/dist/thread/player/text/layout.js +393 -0
  289. package/dist/thread/player/text/static.js +109 -0
  290. package/dist/thread/player/text/text.js +431 -0
  291. package/dist/thread/player/workers/thread.js +159 -0
  292. package/dist/thread/player/workers/wire.js +198 -0
  293. package/dist/thread/player-hosts/web-worker.js +19 -0
  294. package/dist/thread/runtime/avm1/activation.js +89 -0
  295. package/dist/thread/runtime/avm1/case.js +249 -0
  296. package/dist/thread/runtime/avm1/clips.js +334 -0
  297. package/dist/thread/runtime/avm1/control.js +280 -0
  298. package/dist/thread/runtime/avm1/errors.js +50 -0
  299. package/dist/thread/runtime/avm1/functions.js +249 -0
  300. package/dist/thread/runtime/avm1/globals/array.js +549 -0
  301. package/dist/thread/runtime/avm1/globals/broadcaster.js +131 -0
  302. package/dist/thread/runtime/avm1/globals/date.js +436 -0
  303. package/dist/thread/runtime/avm1/globals/global.js +344 -0
  304. package/dist/thread/runtime/avm1/globals/math.js +139 -0
  305. package/dist/thread/runtime/avm1/globals/number.js +93 -0
  306. package/dist/thread/runtime/avm1/globals/string.js +201 -0
  307. package/dist/thread/runtime/avm1/globals/timers.js +129 -0
  308. package/dist/thread/runtime/avm1/host.js +5 -0
  309. package/dist/thread/runtime/avm1/index.js +14 -0
  310. package/dist/thread/runtime/avm1/inheritance.js +132 -0
  311. package/dist/thread/runtime/avm1/numbers.js +298 -0
  312. package/dist/thread/runtime/avm1/objects.js +896 -0
  313. package/dist/thread/runtime/avm1/operators.js +170 -0
  314. package/dist/thread/runtime/avm1/realm.js +529 -0
  315. package/dist/thread/runtime/avm1/runtime.js +882 -0
  316. package/dist/thread/runtime/avm1/scope.js +385 -0
  317. package/dist/thread/runtime/avm1/urls.js +180 -0
  318. package/dist/thread/runtime/avm1/values.js +97 -0
  319. package/dist/thread/runtime/avm2/amf-classes.js +66 -0
  320. package/dist/thread/runtime/avm2/amf.js +801 -0
  321. package/dist/thread/runtime/avm2/array-conversion.js +100 -0
  322. package/dist/thread/runtime/avm2/builtin-library.js +21 -0
  323. package/dist/thread/runtime/avm2/cache-fill.js +86 -0
  324. package/dist/thread/runtime/avm2/classes.js +211 -0
  325. package/dist/thread/runtime/avm2/definitions.js +69 -0
  326. package/dist/thread/runtime/avm2/descriptors.js +5 -0
  327. package/dist/thread/runtime/avm2/dictionary-keys.js +295 -0
  328. package/dist/thread/runtime/avm2/domain-memory.js +75 -0
  329. package/dist/thread/runtime/avm2/domain.js +280 -0
  330. package/dist/thread/runtime/avm2/dynamic-properties.js +182 -0
  331. package/dist/thread/runtime/avm2/enumeration.js +393 -0
  332. package/dist/thread/runtime/avm2/errors.js +45 -0
  333. package/dist/thread/runtime/avm2/float-library.js +66 -0
  334. package/dist/thread/runtime/avm2/float.js +26 -0
  335. package/dist/thread/runtime/avm2/hooks.js +19 -0
  336. package/dist/thread/runtime/avm2/index.js +38 -0
  337. package/dist/thread/runtime/avm2/messages.js +177 -0
  338. package/dist/thread/runtime/avm2/method-factories.js +95 -0
  339. package/dist/thread/runtime/avm2/modules.js +105 -0
  340. package/dist/thread/runtime/avm2/names.js +248 -0
  341. package/dist/thread/runtime/avm2/natives/aliases.js +47 -0
  342. package/dist/thread/runtime/avm2/natives/array.js +390 -0
  343. package/dist/thread/runtime/avm2/natives/bytearray.js +1227 -0
  344. package/dist/thread/runtime/avm2/natives/case.js +88 -0
  345. package/dist/thread/runtime/avm2/natives/concurrent.js +199 -0
  346. package/dist/thread/runtime/avm2/natives/date.js +581 -0
  347. package/dist/thread/runtime/avm2/natives/define.js +130 -0
  348. package/dist/thread/runtime/avm2/natives/describe.js +351 -0
  349. package/dist/thread/runtime/avm2/natives/dictionary.js +12 -0
  350. package/dist/thread/runtime/avm2/natives/float-vector.js +81 -0
  351. package/dist/thread/runtime/avm2/natives/float.js +96 -0
  352. package/dist/thread/runtime/avm2/natives/index.js +64 -0
  353. package/dist/thread/runtime/avm2/natives/json.js +514 -0
  354. package/dist/thread/runtime/avm2/natives/number.js +162 -0
  355. package/dist/thread/runtime/avm2/natives/object.js +237 -0
  356. package/dist/thread/runtime/avm2/natives/proxy.js +75 -0
  357. package/dist/thread/runtime/avm2/natives/regexp.js +485 -0
  358. package/dist/thread/runtime/avm2/natives/shell-workers.js +404 -0
  359. package/dist/thread/runtime/avm2/natives/shell.js +557 -0
  360. package/dist/thread/runtime/avm2/natives/sort.js +377 -0
  361. package/dist/thread/runtime/avm2/natives/string.js +132 -0
  362. package/dist/thread/runtime/avm2/natives/sync.js +821 -0
  363. package/dist/thread/runtime/avm2/natives/toplevel.js +139 -0
  364. package/dist/thread/runtime/avm2/natives/vector-elements.js +46 -0
  365. package/dist/thread/runtime/avm2/natives/vector.js +406 -0
  366. package/dist/thread/runtime/avm2/natives/xml/access.js +633 -0
  367. package/dist/thread/runtime/avm2/natives/xml/build.js +291 -0
  368. package/dist/thread/runtime/avm2/natives/xml/chars.js +112 -0
  369. package/dist/thread/runtime/avm2/natives/xml/escape.js +38 -0
  370. package/dist/thread/runtime/avm2/natives/xml/names.js +204 -0
  371. package/dist/thread/runtime/avm2/natives/xml/node.js +272 -0
  372. package/dist/thread/runtime/avm2/natives/xml/operators.js +69 -0
  373. package/dist/thread/runtime/avm2/natives/xml/parser.js +356 -0
  374. package/dist/thread/runtime/avm2/natives/xml/strings.js +191 -0
  375. package/dist/thread/runtime/avm2/natives/xml/values.js +122 -0
  376. package/dist/thread/runtime/avm2/natives/xml/xml.js +645 -0
  377. package/dist/thread/runtime/avm2/number-strings.js +110 -0
  378. package/dist/thread/runtime/avm2/numbers.js +558 -0
  379. package/dist/thread/runtime/avm2/options.js +16 -0
  380. package/dist/thread/runtime/avm2/player-messages.js +550 -0
  381. package/dist/thread/runtime/avm2/property-cache.js +135 -0
  382. package/dist/thread/runtime/avm2/runtime.js +2644 -0
  383. package/dist/thread/runtime/avm2/traits.js +509 -0
  384. package/dist/thread/runtime/index.js +7 -0
  385. package/dist/web-worker.d.ts +2 -0
  386. package/dist/web-worker.d.ts.map +1 -0
  387. package/dist/web-worker.js +20 -0
  388. package/dist/web-worker.js.map +1 -0
  389. package/dist/websocket.d.ts +4 -0
  390. package/dist/websocket.d.ts.map +1 -0
  391. package/dist/websocket.js +27 -0
  392. package/dist/websocket.js.map +1 -0
  393. package/dist/workers.d.ts +35 -0
  394. package/dist/workers.d.ts.map +1 -0
  395. package/dist/workers.js +171 -0
  396. package/dist/workers.js.map +1 -0
  397. package/package.json +62 -3
  398. package/src/indexeddb.ts +227 -0
  399. package/src/node-worker.ts +13 -0
  400. package/src/node.ts +49 -0
  401. package/src/precompiled.ts +166 -0
  402. package/src/stage3d.ts +76 -0
  403. package/src/web-worker.ts +24 -0
  404. package/src/websocket.ts +32 -0
  405. package/src/workers.ts +255 -0
@@ -0,0 +1,821 @@
1
+ // What flash.concurrent's Mutex and Condition, and the player's message
2
+ // queues, share between workers (docs/workers.md): one heap of int32
3
+ // words that every thread of a primordial's sees, a SharedArrayBuffer
4
+ // where memory can be shared, so that a Mutex or a queue crosses to another
5
+ // worker as an address and is there at once, with no memory to post after
6
+ // it. A thread blocks with Atomics.wait where it can; a browser's main
7
+ // thread cannot, and spins instead, up to Flash's script timeout.
8
+ //
9
+ // A worker may be stopped anywhere, so nothing here waits for ever on a
10
+ // worker that has ended: a lock held by one is taken over by the next
11
+ // thread that wants it, as avmplus lets go of the Mutexes a terminated
12
+ // worker held, and a notify passes over the waiters that have ended. A
13
+ // terminated worker's thread is stopped some time after it is terminated,
14
+ // and may run on meanwhile, so terminating it (stop) only makes this memory
15
+ // refuse it anything more, and notifies pass over it; its locks are taken
16
+ // over only once its thread has stopped (end), which the thread that
17
+ // stops it learns from its host, or the worker says itself as its code
18
+ // ends.
19
+ /** Flash's script timeout, which a primordial that blocks too long hits. */
20
+ export const SCRIPT_TIMEOUT = 15000;
21
+ // The heap's header: its lock, the next free word, and a free list for
22
+ // each block size, 2^k words.
23
+ const HEAP_LOCK = 0;
24
+ const HEAP_NEXT = 1;
25
+ const BINS = 2;
26
+ const MAX_CLASS = 28;
27
+ /** The next worker's number, for workers any thread makes. */
28
+ const NEXT_THREAD = BINS + MAX_CLASS + 1;
29
+ /** The address of the queue of requests for the primordial, which it takes even while it waits. */
30
+ const REQUESTS = NEXT_THREAD + 1;
31
+ // A table every thread reads, the player's workers' shared properties: its
32
+ // lock, the block that holds its bytes (their length, then them), its
33
+ // version, and the last token given out.
34
+ const TABLE_LOCK = REQUESTS + 1;
35
+ const TABLE = TABLE_LOCK + 1;
36
+ const TABLE_VERSION = TABLE + 1;
37
+ const TABLE_TOKEN = TABLE_VERSION + 1;
38
+ const HEADER = TABLE_TOKEN + 1;
39
+ /** A block's own words before what it holds: its size class. */
40
+ const BLOCK_HEAD = 2;
41
+ const HEAP_MAX = 1 << 30;
42
+ const THREADS_MAX = 1 << 20;
43
+ /**
44
+ * A thread's state in its table: 0 before it runs, then RUNNING; STOPPING
45
+ * once it is terminated, while its thread may still run, and ENDED once
46
+ * its thread has stopped, or it has ended its own code.
47
+ */
48
+ const RUNNING = 2;
49
+ const ENDED = 1;
50
+ const STOPPING = 3;
51
+ /** How long a blocked thread sleeps before it looks again whether a lock's holder has ended. */
52
+ const CHUNK = 50;
53
+ // A thread's record: its park word, its next in a condition's queue, its
54
+ // worker's number, and its next in a mutex's queue. The park word is
55
+ // WAITING in a condition's wait, until a notify picks it or it times out.
56
+ const PARK = 0;
57
+ const C_NEXT = 1;
58
+ const OWNER = 2;
59
+ const M_NEXT = 3;
60
+ const WAITING = 0;
61
+ const NOTIFIED = 1;
62
+ const TIMED_OUT = 2;
63
+ // A mutex: its holder plus one (0 when free), how many times it holds it,
64
+ // the queue of the threads waiting for it, first and last, and the
65
+ // queue's lock.
66
+ const HOLDER = 0;
67
+ const COUNT = 1;
68
+ const M_HEAD = 2;
69
+ const M_TAIL = 3;
70
+ const M_LOCK = 4;
71
+ // A condition: its mutex, and its queue of waiting threads' records.
72
+ const MUTEX = 0;
73
+ const HEAD = 1;
74
+ const TAIL = 2;
75
+ // A queue: its lock, how many entries it holds, its first and last, and
76
+ // whether it was closed. An entry: the next, its length in bytes, its bytes.
77
+ const Q_LOCK = 0;
78
+ const Q_COUNT = 1;
79
+ const Q_HEAD = 2;
80
+ const Q_TAIL = 3;
81
+ const Q_CLOSED = 4;
82
+ /** Growable memory, shared where it can be, as much as the host reserves up to `max`. */
83
+ function growable(length, max, shared) {
84
+ const ctor = (shared ? SharedArrayBuffer : ArrayBuffer);
85
+ for (;;) {
86
+ try {
87
+ return new ctor(length, { maxByteLength: max });
88
+ }
89
+ catch (e) {
90
+ if (max <= length * 2) {
91
+ throw e;
92
+ }
93
+ max /= 2;
94
+ }
95
+ }
96
+ }
97
+ /** `buffer` made at least `length` bytes; false where it cannot grow so far. */
98
+ function grow(buffer, length) {
99
+ const b = buffer;
100
+ while (b.byteLength < length) {
101
+ try {
102
+ if (b.grow) {
103
+ b.grow(length);
104
+ }
105
+ else {
106
+ b.resize?.(length);
107
+ }
108
+ }
109
+ catch {
110
+ // Another thread grew it meanwhile, to as much or more, or it cannot grow.
111
+ return b.byteLength >= length;
112
+ }
113
+ }
114
+ return true;
115
+ }
116
+ /** Whether this thread can share memory: SharedArrayBuffer is there, and a page is cross-origin isolated. */
117
+ function canShare() {
118
+ const g = globalThis;
119
+ return typeof SharedArrayBuffer === "function" && g.crossOriginIsolated !== false;
120
+ }
121
+ /** New memory for a primordial's workers: shared where it can be, else this thread's alone. */
122
+ export function newSyncMemory() {
123
+ const shared = canShare();
124
+ const heap = growable(1 << 16, HEAP_MAX, shared);
125
+ const words = new Int32Array(heap);
126
+ words[HEAP_NEXT] = HEADER;
127
+ words[NEXT_THREAD] = 1;
128
+ return { heap, threads: growable(64, THREADS_MAX, shared) };
129
+ }
130
+ let threadCanWait = null;
131
+ /** Whether this thread may Atomics.wait: a browser's main thread may not. */
132
+ function canWaitHere() {
133
+ if (threadCanWait === null) {
134
+ try {
135
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 1, 0);
136
+ threadCanWait = true;
137
+ }
138
+ catch {
139
+ threadCanWait = false;
140
+ }
141
+ }
142
+ return threadCanWait;
143
+ }
144
+ /**
145
+ * What a terminated worker's thread gets for anything it asks of the shared
146
+ * memory while it still runs: it changes nothing there any more, and its
147
+ * code stops, as avmplus interrupts a terminated worker.
148
+ */
149
+ export class SyncTerminated extends Error {
150
+ constructor() {
151
+ super("swf2es: the worker was terminated");
152
+ }
153
+ }
154
+ /** The shared heap has no room for a block, or a block would be larger than it. */
155
+ export class SyncFull extends RangeError {
156
+ constructor() {
157
+ super("swf2es: the memory the workers share is full");
158
+ }
159
+ }
160
+ /** A lock or wait that spun for longer than the script timeout. */
161
+ export class SyncTimeout extends Error {
162
+ constructor() {
163
+ super("swf2es: a lock or wait took longer than the script timeout");
164
+ }
165
+ }
166
+ /** The shared heap as one thread sees it. */
167
+ export class Sync {
168
+ memory;
169
+ thread;
170
+ words;
171
+ bytes;
172
+ threads;
173
+ /** Whether other threads see this memory: else nothing else can take a lock or notify. */
174
+ shared;
175
+ /** Whether this thread blocks in Atomics.wait, or spins. */
176
+ waits;
177
+ timeout;
178
+ record = 0;
179
+ /** See spinningSince. */
180
+ spinning = null;
181
+ /**
182
+ * What this thread does whenever it waits, between waits of no more
183
+ * than a few milliseconds: the primordial takes its requests then, as
184
+ * a background worker that asks for a worker may be what it waits for.
185
+ */
186
+ poll = null;
187
+ /** Whether a refused thread's code has ended with it (see refuse). */
188
+ selfEnds;
189
+ constructor(memory, thread, options = {}) {
190
+ this.memory = memory;
191
+ this.thread = thread;
192
+ this.selfEnds = options.selfEnds ?? false;
193
+ this.words = new Int32Array(memory.heap);
194
+ this.bytes = new Uint8Array(memory.heap);
195
+ this.threads = new Int32Array(memory.threads);
196
+ this.shared =
197
+ typeof SharedArrayBuffer === "function" && memory.heap instanceof SharedArrayBuffer;
198
+ this.waits = this.shared && !options.spin && canWaitHere();
199
+ this.timeout = options.timeout ?? SCRIPT_TIMEOUT;
200
+ this.addThread(thread);
201
+ }
202
+ /** A number for a new worker, unique among the primordial's whichever thread makes it, with room in the threads' table. */
203
+ newThread() {
204
+ const id = Atomics.add(this.words, NEXT_THREAD, 1);
205
+ this.addThread(id);
206
+ return id;
207
+ }
208
+ /** The shared table's version, which every change moves on. */
209
+ tableVersion() {
210
+ return Atomics.load(this.words, TABLE_VERSION);
211
+ }
212
+ /** The shared table's bytes, and their version. */
213
+ readTable() {
214
+ this.acquire(TABLE_LOCK, Date.now());
215
+ try {
216
+ return { version: this.tableVersion(), bytes: this.tableBytes() };
217
+ }
218
+ finally {
219
+ this.release(TABLE_LOCK);
220
+ }
221
+ }
222
+ /** Replace the shared table's bytes with what `f` makes of them, in one step every thread sees. */
223
+ updateTable(f) {
224
+ this.acquire(TABLE_LOCK, Date.now());
225
+ try {
226
+ const bytes = f(this.tableBytes());
227
+ const block = this.alloc(1 + Math.ceil(bytes.length / 4));
228
+ this.words[block] = bytes.length;
229
+ this.bytes.set(bytes, (block + 1) * 4);
230
+ const old = Atomics.exchange(this.words, TABLE, block);
231
+ Atomics.add(this.words, TABLE_VERSION, 1);
232
+ if (old !== 0) {
233
+ this.free(old);
234
+ }
235
+ }
236
+ finally {
237
+ this.release(TABLE_LOCK);
238
+ }
239
+ }
240
+ /** A number never given out before, for an entry of the table. */
241
+ nextToken() {
242
+ return Atomics.add(this.words, TABLE_TOKEN, 1) + 1;
243
+ }
244
+ tableBytes() {
245
+ const block = Atomics.load(this.words, TABLE);
246
+ if (block === 0) {
247
+ return new Uint8Array(0);
248
+ }
249
+ const at = (block + 1) * 4;
250
+ return this.bytes.slice(at, at + this.words[block]);
251
+ }
252
+ /** The primordial's queue of requests, once it has made it; 0 before. */
253
+ get requests() {
254
+ return Atomics.load(this.words, REQUESTS);
255
+ }
256
+ set requests(q) {
257
+ Atomics.store(this.words, REQUESTS, q);
258
+ }
259
+ /** Make room for worker `id` in the threads' table, before it starts. */
260
+ addThread(id) {
261
+ grow(this.memory.threads, (id + 1) * 8);
262
+ }
263
+ stateOf(id) {
264
+ return 2 * id + 1 < this.threads.length ? Atomics.load(this.threads, 2 * id + 1) : 0;
265
+ }
266
+ /** Whether worker `id` is neither terminated nor ended: a notify may pick it, a queue waits for it. */
267
+ alive(id) {
268
+ if (id < 0) {
269
+ return false;
270
+ }
271
+ const state = this.stateOf(id);
272
+ return state !== ENDED && state !== STOPPING;
273
+ }
274
+ /**
275
+ * Whether worker `id`'s thread has stopped, or ended its code: a lock it
276
+ * holds is free to take. A worker terminated while its thread may still
277
+ * run is not, as it may still be writing what the lock guards.
278
+ */
279
+ stopped(id) {
280
+ return this.stateOf(id) === ENDED;
281
+ }
282
+ /** Whether worker `id` has started and not ended, as its own thread says. */
283
+ running(id) {
284
+ return 2 * id + 1 < this.threads.length && Atomics.load(this.threads, 2 * id + 1) === RUNNING;
285
+ }
286
+ /** Worker `id`, this thread's, runs; unless it has ended already. */
287
+ start(id) {
288
+ this.addThread(id);
289
+ Atomics.compareExchange(this.threads, 2 * id + 1, 0, RUNNING);
290
+ }
291
+ /**
292
+ * Worker `id` was terminated: no notify picks it, no queue waits for it,
293
+ * and its thread, while it still runs, gets SyncTerminated for anything
294
+ * it asks of this memory. The locks it holds stay held until end.
295
+ */
296
+ stop(id) {
297
+ this.addThread(id);
298
+ if (Atomics.compareExchange(this.threads, 2 * id + 1, 0, STOPPING) !== 0) {
299
+ Atomics.compareExchange(this.threads, 2 * id + 1, RUNNING, STOPPING);
300
+ }
301
+ }
302
+ /**
303
+ * Worker `id`'s thread has stopped, or the worker has ended its own code:
304
+ * the locks it held are free to take. Only the thread itself, or one that
305
+ * knows it has stopped, may say so.
306
+ */
307
+ end(id) {
308
+ this.addThread(id);
309
+ Atomics.store(this.threads, 2 * id + 1, ENDED);
310
+ Atomics.notify(this.threads, 2 * id + 1);
311
+ }
312
+ /**
313
+ * Refuse anything more of a thread whose worker was terminated: the
314
+ * script that asked stops here, as avmplus interrupts a terminated worker
315
+ * that waits (the runtime lets no script catch the error). Where that
316
+ * ends all of the worker's code, as an avmshell worker's (`selfEnds`),
317
+ * the locks it holds are free to take from now on, as avmplus lets go of
318
+ * them when the worker goes; a player's worker plays on to the end of its
319
+ * frame, and says it has stopped itself (end) once no code of it can run.
320
+ */
321
+ refuse() {
322
+ if (this.thread !== 0) {
323
+ const state = this.stateOf(this.thread);
324
+ if (state === STOPPING || state === ENDED) {
325
+ if (this.selfEnds) {
326
+ this.end(this.thread);
327
+ }
328
+ throw new SyncTerminated();
329
+ }
330
+ }
331
+ }
332
+ /** Whether this thread's worker was terminated, which the next thing it asks of this memory says too. */
333
+ get terminated() {
334
+ const state = this.thread === 0 ? 0 : this.stateOf(this.thread);
335
+ return state === STOPPING || state === ENDED;
336
+ }
337
+ /** Wait until worker `id`'s thread says it has stopped, up to `ms`; whether it has. */
338
+ waitStopped(id, ms) {
339
+ const end = Date.now() + ms;
340
+ for (;;) {
341
+ const state = this.stateOf(id);
342
+ if (state === ENDED) {
343
+ return true;
344
+ }
345
+ const left = end - Date.now();
346
+ if (left <= 0 || !this.waits) {
347
+ return false;
348
+ }
349
+ Atomics.wait(this.threads, 2 * id + 1, state, Math.min(left, 5));
350
+ }
351
+ }
352
+ /** A block of at least `n` words, zeroed: the address of its first. */
353
+ alloc(n) {
354
+ let k = 2;
355
+ while (1 << k < n + BLOCK_HEAD) {
356
+ k++;
357
+ }
358
+ if (k > MAX_CLASS) {
359
+ throw new SyncFull();
360
+ }
361
+ const words = this.words;
362
+ this.acquire(HEAP_LOCK, Date.now());
363
+ let block;
364
+ try {
365
+ block = Atomics.load(words, BINS + k);
366
+ if (block !== 0) {
367
+ Atomics.store(words, BINS + k, Atomics.load(words, block + 1));
368
+ }
369
+ else {
370
+ block = Atomics.load(words, HEAP_NEXT);
371
+ if (!grow(this.memory.heap, (block + (1 << k)) * 4)) {
372
+ throw new SyncFull();
373
+ }
374
+ Atomics.store(words, HEAP_NEXT, block + (1 << k));
375
+ }
376
+ }
377
+ finally {
378
+ this.release(HEAP_LOCK);
379
+ }
380
+ words.fill(0, block, block + (1 << k));
381
+ words[block] = k;
382
+ return block + BLOCK_HEAD;
383
+ }
384
+ free(address) {
385
+ const block = address - BLOCK_HEAD;
386
+ const k = this.words[block];
387
+ this.acquire(HEAP_LOCK, Date.now());
388
+ try {
389
+ Atomics.store(this.words, block + 1, Atomics.load(this.words, BINS + k));
390
+ Atomics.store(this.words, BINS + k, block);
391
+ }
392
+ finally {
393
+ this.release(HEAP_LOCK);
394
+ }
395
+ }
396
+ /**
397
+ * Take the lock in word `index`, which holds its holder's number plus
398
+ * one; from a holder whose thread has stopped, at once. `start` is when the
399
+ * operation began, for the script timeout of a thread that spins.
400
+ */
401
+ acquire(index, start) {
402
+ const me = this.thread + 1;
403
+ for (;;) {
404
+ this.refuse();
405
+ const holder = Atomics.compareExchange(this.words, index, 0, me);
406
+ if (holder === 0) {
407
+ return;
408
+ }
409
+ if (this.stopped(holder - 1) &&
410
+ Atomics.compareExchange(this.words, index, holder, me) === holder) {
411
+ return;
412
+ }
413
+ this.park(index, holder, CHUNK, start);
414
+ }
415
+ }
416
+ /** Take the lock in word `index` if it is free, or its holder's thread has stopped. */
417
+ tryAcquire(index) {
418
+ this.refuse();
419
+ const me = this.thread + 1;
420
+ const holder = Atomics.compareExchange(this.words, index, 0, me);
421
+ return (holder === 0 ||
422
+ (this.stopped(holder - 1) &&
423
+ Atomics.compareExchange(this.words, index, holder, me) === holder));
424
+ }
425
+ /** Let go of the lock in word `index`, unless another thread has taken it over meanwhile. */
426
+ release(index) {
427
+ if (Atomics.compareExchange(this.words, index, this.thread + 1, 0) === this.thread + 1) {
428
+ Atomics.notify(this.words, index, 1);
429
+ }
430
+ }
431
+ /**
432
+ * Wait up to `ms` while word `index` holds `value`: Atomics.wait where
433
+ * this thread can, else spinning on it with a backoff that never sleeps,
434
+ * failing with SyncTimeout once this thread has spun for longer than the
435
+ * script timeout without returning to its event loop, as Flash times a
436
+ * script out: content that waits a millisecond at a time in a loop, as
437
+ * Crossbridge's startup does, is stopped too. Where there is no event
438
+ * loop to tell, from `start`, when the operation began.
439
+ */
440
+ park(index, value, ms, start) {
441
+ this.refuse();
442
+ this.poll?.();
443
+ Atomics.store(this.threads, 2 * this.thread, 1);
444
+ try {
445
+ this.spinOrWait(index, value, ms, start);
446
+ }
447
+ finally {
448
+ Atomics.store(this.threads, 2 * this.thread, 0);
449
+ }
450
+ }
451
+ /** Whether worker `id` is blocked in a lock or a wait now. */
452
+ blocked(id) {
453
+ return 2 * id < this.threads.length && Atomics.load(this.threads, 2 * id) !== 0;
454
+ }
455
+ spinOrWait(index, value, ms, start) {
456
+ if (this.waits) {
457
+ Atomics.wait(this.words, index, value, ms);
458
+ return;
459
+ }
460
+ const since = this.spinningSince(start);
461
+ const end = Date.now() + ms;
462
+ let spins = 1;
463
+ for (;;) {
464
+ if (Atomics.load(this.words, index) !== value) {
465
+ return;
466
+ }
467
+ const now = Date.now();
468
+ if (now - since > this.timeout) {
469
+ throw new SyncTimeout();
470
+ }
471
+ if (now >= end) {
472
+ return;
473
+ }
474
+ for (let i = 0; i < spins; i++) {
475
+ // A pause between loads, longer each time, up to a few microseconds.
476
+ }
477
+ spins = Math.min(spins * 2, 4096);
478
+ }
479
+ }
480
+ /** When this thread began to spin since it last returned to its event loop. */
481
+ spinningSince(start) {
482
+ if (this.spinning === null) {
483
+ const later = globalThis
484
+ .setTimeout;
485
+ if (!later) {
486
+ return start;
487
+ }
488
+ this.spinning = Date.now();
489
+ // A task of its own, which runs only once the thread is back in its event loop.
490
+ later(() => {
491
+ this.spinning = null;
492
+ }, 0);
493
+ }
494
+ return this.spinning;
495
+ }
496
+ newMutex() {
497
+ return this.alloc(5);
498
+ }
499
+ /** Whether this thread holds the mutex at `m`. */
500
+ holds(m) {
501
+ return Atomics.load(this.words, m + HOLDER) === this.thread + 1;
502
+ }
503
+ /**
504
+ * As avmplus' MutexObject::lock: held again by its holder, or taken in
505
+ * the order the threads came for it. A thread that ended leaves the
506
+ * queue to the next, and the mutex if it held it.
507
+ */
508
+ lock(m) {
509
+ if (this.holds(m)) {
510
+ this.words[m + COUNT]++;
511
+ return;
512
+ }
513
+ const start = Date.now();
514
+ if (Atomics.load(this.words, m + M_HEAD) !== 0 || !this.tryAcquire(m + HOLDER)) {
515
+ this.enqueue(m, this.ownRecord());
516
+ this.timed(() => this.takeTurn(m, start));
517
+ }
518
+ this.words[m + COUNT] = 1;
519
+ }
520
+ /** As MutexObject::tryLock: never while another thread waits for it, as avmplus' hasWaiters. */
521
+ tryLock(m) {
522
+ if (this.waiter(m) !== 0) {
523
+ return false;
524
+ }
525
+ if (this.holds(m)) {
526
+ this.words[m + COUNT]++;
527
+ return true;
528
+ }
529
+ if (!this.tryAcquire(m + HOLDER)) {
530
+ return false;
531
+ }
532
+ this.words[m + COUNT] = 1;
533
+ return true;
534
+ }
535
+ /** Whether this thread held it, once less now. */
536
+ unlock(m) {
537
+ if (!this.holds(m)) {
538
+ return false;
539
+ }
540
+ if (--this.words[m + COUNT] === 0) {
541
+ Atomics.compareExchange(this.words, m + HOLDER, this.thread + 1, 0);
542
+ // The first in its queue takes it; the others look again whether they are first.
543
+ Atomics.notify(this.words, m + HOLDER);
544
+ }
545
+ return true;
546
+ }
547
+ /** Add record `r` at the end of the queue of the threads waiting for mutex `m`. */
548
+ enqueue(m, r) {
549
+ const words = this.words;
550
+ Atomics.store(words, r + M_NEXT, 0);
551
+ this.acquire(m + M_LOCK, Date.now());
552
+ try {
553
+ const tail = Atomics.load(words, m + M_TAIL);
554
+ if (tail === 0) {
555
+ Atomics.store(words, m + M_HEAD, r);
556
+ }
557
+ else {
558
+ Atomics.store(words, tail + M_NEXT, r);
559
+ }
560
+ Atomics.store(words, m + M_TAIL, r);
561
+ }
562
+ finally {
563
+ this.release(m + M_LOCK);
564
+ }
565
+ }
566
+ /** The first thread waiting for mutex `m` that has not ended, those that ended taken out; 0 for none. */
567
+ waiter(m) {
568
+ const words = this.words;
569
+ for (;;) {
570
+ const head = Atomics.load(words, m + M_HEAD);
571
+ if (head === 0 || this.alive(Atomics.load(words, head + OWNER))) {
572
+ return head;
573
+ }
574
+ this.dequeue(m, head);
575
+ }
576
+ }
577
+ /** Take record `r` from the head of mutex `m`'s queue, if it is still there. */
578
+ dequeue(m, r) {
579
+ const words = this.words;
580
+ this.acquire(m + M_LOCK, Date.now());
581
+ try {
582
+ if (Atomics.load(words, m + M_HEAD) !== r) {
583
+ return;
584
+ }
585
+ const next = Atomics.load(words, r + M_NEXT);
586
+ Atomics.store(words, m + M_HEAD, next);
587
+ if (next === 0) {
588
+ Atomics.store(words, m + M_TAIL, 0);
589
+ }
590
+ }
591
+ finally {
592
+ this.release(m + M_LOCK);
593
+ }
594
+ }
595
+ /** Wait, this thread's record in mutex `m`'s queue, until it is first and takes the mutex. */
596
+ takeTurn(m, start) {
597
+ const r = this.record;
598
+ for (;;) {
599
+ if (this.waiter(m) === r && this.tryAcquire(m + HOLDER)) {
600
+ this.dequeue(m, r);
601
+ return;
602
+ }
603
+ const holder = Atomics.load(this.words, m + HOLDER);
604
+ this.park(m + HOLDER, holder, holder === 0 ? 1 : CHUNK, start);
605
+ }
606
+ }
607
+ newCondition(m) {
608
+ const c = this.alloc(3);
609
+ Atomics.store(this.words, c + MUTEX, m);
610
+ return c;
611
+ }
612
+ conditionMutex(c) {
613
+ return Atomics.load(this.words, c + MUTEX);
614
+ }
615
+ /**
616
+ * As avmplus' ConditionObject::wait, its mutex held by this thread: the
617
+ * mutex let go, however many times it was held, until a notify picks
618
+ * this thread or `ms` have passed (never, for -1), then held again as
619
+ * it was. A notify picks the waiters in the order they came, and they
620
+ * take the mutex again in that order. Whether the time ran out.
621
+ */
622
+ wait(c, ms) {
623
+ this.refuse();
624
+ const words = this.words;
625
+ const m = this.conditionMutex(c);
626
+ const r = this.ownRecord();
627
+ const start = Date.now();
628
+ Atomics.store(words, r + PARK, WAITING);
629
+ Atomics.store(words, r + C_NEXT, 0);
630
+ const tail = Atomics.load(words, c + TAIL);
631
+ if (tail === 0) {
632
+ Atomics.store(words, c + HEAD, r);
633
+ }
634
+ else {
635
+ Atomics.store(words, tail + C_NEXT, r);
636
+ }
637
+ Atomics.store(words, c + TAIL, r);
638
+ const count = words[m + COUNT];
639
+ words[m + COUNT] = 1;
640
+ // As often as it was held, once now.
641
+ this.unlock(m);
642
+ const end = ms < 0 ? Number.POSITIVE_INFINITY : start + ms;
643
+ let timedOut = false;
644
+ this.timed(() => {
645
+ for (;;) {
646
+ if (Atomics.load(words, r + PARK) === NOTIFIED) {
647
+ break;
648
+ }
649
+ const left = end - Date.now();
650
+ if (left <= 0 && Atomics.compareExchange(words, r + PARK, WAITING, TIMED_OUT) === WAITING) {
651
+ // Left in the condition's queue, which a notify passes over, until
652
+ // this thread holds the mutex again and takes it out.
653
+ timedOut = true;
654
+ this.enqueue(m, r);
655
+ break;
656
+ }
657
+ this.park(r + PARK, WAITING, Math.max(Math.min(left, CHUNK), 0), start);
658
+ }
659
+ // A notify put the record in the mutex's queue, in the order it picked it.
660
+ this.takeTurn(m, start);
661
+ });
662
+ words[m + COUNT] = count;
663
+ if (timedOut) {
664
+ this.unqueue(c, r);
665
+ }
666
+ return timedOut;
667
+ }
668
+ /**
669
+ * Pick the first waiter that has not ended or timed out, or all of them,
670
+ * the mutex held by this thread: each moves to the mutex's queue, to take
671
+ * it in turn once this thread lets go of it.
672
+ */
673
+ notify(c, all) {
674
+ // Before it changes anything: a notify half done would lose a waiter.
675
+ this.refuse();
676
+ const words = this.words;
677
+ const m = this.conditionMutex(c);
678
+ for (;;) {
679
+ const r = Atomics.load(words, c + HEAD);
680
+ if (r === 0) {
681
+ return;
682
+ }
683
+ const next = Atomics.load(words, r + C_NEXT);
684
+ Atomics.store(words, c + HEAD, next);
685
+ if (next === 0) {
686
+ Atomics.store(words, c + TAIL, 0);
687
+ }
688
+ // One whose wait timed out meanwhile has queued itself for the mutex.
689
+ if (this.alive(Atomics.load(words, r + OWNER)) &&
690
+ Atomics.compareExchange(words, r + PARK, WAITING, NOTIFIED) === WAITING) {
691
+ this.enqueue(m, r);
692
+ Atomics.notify(words, r + PARK);
693
+ if (!all) {
694
+ return;
695
+ }
696
+ }
697
+ }
698
+ }
699
+ /**
700
+ * Run `f`, which may leave this thread's record in a queue: one it
701
+ * leaves for the script timeout is given up, its owner none, so that
702
+ * the queue passes over it, and the next wait or lock makes another.
703
+ */
704
+ timed(f) {
705
+ try {
706
+ f();
707
+ }
708
+ catch (e) {
709
+ if (e instanceof SyncTimeout && this.record !== 0) {
710
+ Atomics.store(this.words, this.record + OWNER, -1);
711
+ this.record = 0;
712
+ }
713
+ throw e;
714
+ }
715
+ }
716
+ /** This thread's record, made once, and again after a timeout gave it up. */
717
+ ownRecord() {
718
+ if (this.record === 0) {
719
+ this.record = this.alloc(4);
720
+ Atomics.store(this.words, this.record + OWNER, this.thread);
721
+ }
722
+ return this.record;
723
+ }
724
+ /** Take record `r`, whose wait timed out, from the queue of `c`, if a notify has not passed over it. */
725
+ unqueue(c, r) {
726
+ const words = this.words;
727
+ let previous = 0;
728
+ let at = Atomics.load(words, c + HEAD);
729
+ while (at !== 0 && at !== r) {
730
+ previous = at;
731
+ at = Atomics.load(words, at + C_NEXT);
732
+ }
733
+ if (at === 0) {
734
+ return;
735
+ }
736
+ const next = Atomics.load(words, r + C_NEXT);
737
+ if (previous === 0) {
738
+ Atomics.store(words, c + HEAD, next);
739
+ }
740
+ else {
741
+ Atomics.store(words, previous + C_NEXT, next);
742
+ }
743
+ if (Atomics.load(words, c + TAIL) === r) {
744
+ Atomics.store(words, c + TAIL, previous);
745
+ }
746
+ }
747
+ newQueue() {
748
+ return this.alloc(5);
749
+ }
750
+ /** How many entries queue `q` holds. */
751
+ queued(q) {
752
+ return Atomics.load(this.words, q + Q_COUNT);
753
+ }
754
+ closed(q) {
755
+ return Atomics.load(this.words, q + Q_CLOSED) !== 0;
756
+ }
757
+ /** Add `bytes` at the end of queue `q`, waking a thread that waits on it. */
758
+ push(q, bytes) {
759
+ const words = this.words;
760
+ const entry = this.alloc(2 + Math.ceil(bytes.length / 4));
761
+ words[entry + 1] = bytes.length;
762
+ this.bytes.set(bytes, (entry + 2) * 4);
763
+ this.acquire(q + Q_LOCK, Date.now());
764
+ try {
765
+ const tail = Atomics.load(words, q + Q_TAIL);
766
+ if (tail === 0) {
767
+ Atomics.store(words, q + Q_HEAD, entry);
768
+ }
769
+ else {
770
+ Atomics.store(words, tail, entry);
771
+ }
772
+ Atomics.store(words, q + Q_TAIL, entry);
773
+ Atomics.add(words, q + Q_COUNT, 1);
774
+ }
775
+ finally {
776
+ this.release(q + Q_LOCK);
777
+ }
778
+ Atomics.notify(words, q + Q_COUNT);
779
+ }
780
+ /** Take the first entry of queue `q`, if it has one. */
781
+ shift(q) {
782
+ const words = this.words;
783
+ let entry;
784
+ this.acquire(q + Q_LOCK, Date.now());
785
+ try {
786
+ entry = Atomics.load(words, q + Q_HEAD);
787
+ if (entry === 0) {
788
+ return null;
789
+ }
790
+ const next = Atomics.load(words, entry);
791
+ Atomics.store(words, q + Q_HEAD, next);
792
+ if (next === 0) {
793
+ Atomics.store(words, q + Q_TAIL, 0);
794
+ }
795
+ Atomics.sub(words, q + Q_COUNT, 1);
796
+ }
797
+ finally {
798
+ this.release(q + Q_LOCK);
799
+ }
800
+ const at = (entry + 2) * 4;
801
+ const bytes = this.bytes.slice(at, at + words[entry + 1]);
802
+ this.free(entry);
803
+ return bytes;
804
+ }
805
+ /** Mark queue `q` closed, waking a thread that waits on it. */
806
+ close(q) {
807
+ Atomics.store(this.words, q + Q_CLOSED, 1);
808
+ Atomics.notify(this.words, q + Q_COUNT);
809
+ }
810
+ /** Block until queue `q` holds an entry or is closed. */
811
+ waitFor(q) {
812
+ const start = Date.now();
813
+ while (!this.closed(q)) {
814
+ const count = Atomics.load(this.words, q + Q_COUNT);
815
+ if (count > 0) {
816
+ return;
817
+ }
818
+ this.park(q + Q_COUNT, count, CHUNK, start);
819
+ }
820
+ }
821
+ }