zuzu-js 0.1.0

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 (167) hide show
  1. package/LICENSE +5 -0
  2. package/README.md +113 -0
  3. package/bin/zuzu +17 -0
  4. package/bin/zuzu-build-browser-bundle +57 -0
  5. package/bin/zuzu-generate-browser-stdlib +584 -0
  6. package/bin/zuzu-js +23 -0
  7. package/bin/zuzu-js-compile +152 -0
  8. package/bin/zuzu-js-electron +19 -0
  9. package/dist/zuzu-browser-worker.js +45574 -0
  10. package/dist/zuzu-browser.js +45362 -0
  11. package/lib/browser-bundle-entry.js +160 -0
  12. package/lib/browser-gui-renderer.js +387 -0
  13. package/lib/browser-runtime.js +167 -0
  14. package/lib/browser-worker-entry.js +413 -0
  15. package/lib/browser-ztests/runner.html +103 -0
  16. package/lib/browser-ztests/runner.js +369 -0
  17. package/lib/cli.js +350 -0
  18. package/lib/collections.js +367 -0
  19. package/lib/compiler.js +303 -0
  20. package/lib/electron/launcher.js +70 -0
  21. package/lib/electron/main.js +956 -0
  22. package/lib/electron/preload.js +80 -0
  23. package/lib/electron/renderer.html +122 -0
  24. package/lib/electron/renderer.js +24 -0
  25. package/lib/execution-metadata.js +18 -0
  26. package/lib/gui/dom-renderer.js +778 -0
  27. package/lib/host/browser-host.js +278 -0
  28. package/lib/host/capabilities.js +47 -0
  29. package/lib/host/electron-host.js +15 -0
  30. package/lib/host/node-host.js +74 -0
  31. package/lib/paths.js +150 -0
  32. package/lib/runtime-entrypoints.js +60 -0
  33. package/lib/runtime-helpers.js +886 -0
  34. package/lib/runtime.js +3529 -0
  35. package/lib/tap.js +37 -0
  36. package/lib/transpiler-new/ast.js +23 -0
  37. package/lib/transpiler-new/codegen.js +2455 -0
  38. package/lib/transpiler-new/errors.js +28 -0
  39. package/lib/transpiler-new/index.js +26 -0
  40. package/lib/transpiler-new/lexer.js +834 -0
  41. package/lib/transpiler-new/parser.js +2332 -0
  42. package/lib/transpiler-new/validate-bindings.js +326 -0
  43. package/lib/transpiler-utils.js +95 -0
  44. package/lib/transpiler.js +33 -0
  45. package/lib/zuzu.js +53 -0
  46. package/modules/javascript.js +193 -0
  47. package/modules/std/archive.js +603 -0
  48. package/modules/std/clib.js +338 -0
  49. package/modules/std/data/csv.js +1331 -0
  50. package/modules/std/data/json.js +531 -0
  51. package/modules/std/data/xml.js +441 -0
  52. package/modules/std/data/yaml.js +256 -0
  53. package/modules/std/db-worker.js +250 -0
  54. package/modules/std/db.js +664 -0
  55. package/modules/std/digest/_hash.js +443 -0
  56. package/modules/std/digest/md5.js +26 -0
  57. package/modules/std/digest/sha.js +72 -0
  58. package/modules/std/eval.js +10 -0
  59. package/modules/std/gui/objects.js +1519 -0
  60. package/modules/std/internals.js +571 -0
  61. package/modules/std/io/socks-worker.js +318 -0
  62. package/modules/std/io/socks.js +186 -0
  63. package/modules/std/io.js +475 -0
  64. package/modules/std/marshal/cbor.js +463 -0
  65. package/modules/std/marshal/graph.js +1624 -0
  66. package/modules/std/marshal.js +87 -0
  67. package/modules/std/math/bignum.js +91 -0
  68. package/modules/std/math.js +79 -0
  69. package/modules/std/net/dns.js +306 -0
  70. package/modules/std/net/http.js +820 -0
  71. package/modules/std/net/smtp.js +943 -0
  72. package/modules/std/net/url.js +109 -0
  73. package/modules/std/proc.js +602 -0
  74. package/modules/std/secure.js +3724 -0
  75. package/modules/std/string/base64.js +138 -0
  76. package/modules/std/string.js +299 -0
  77. package/modules/std/task.js +914 -0
  78. package/modules/std/time.js +579 -0
  79. package/modules/std/tui.js +188 -0
  80. package/modules/std/worker-thread.js +246 -0
  81. package/modules/std/worker.js +790 -0
  82. package/package.json +67 -0
  83. package/stdlib/modules/javascript.zzm +99 -0
  84. package/stdlib/modules/perl.zzm +105 -0
  85. package/stdlib/modules/std/archive.zzm +132 -0
  86. package/stdlib/modules/std/cache/lru.zzm +174 -0
  87. package/stdlib/modules/std/clib.zzm +112 -0
  88. package/stdlib/modules/std/colour.zzm +220 -0
  89. package/stdlib/modules/std/config.zzm +818 -0
  90. package/stdlib/modules/std/data/cbor.zzm +497 -0
  91. package/stdlib/modules/std/data/csv.zzm +285 -0
  92. package/stdlib/modules/std/data/ini.zzm +472 -0
  93. package/stdlib/modules/std/data/json/schema/core.zzm +573 -0
  94. package/stdlib/modules/std/data/json/schema/format.zzm +581 -0
  95. package/stdlib/modules/std/data/json/schema/model.zzm +255 -0
  96. package/stdlib/modules/std/data/json/schema/output.zzm +272 -0
  97. package/stdlib/modules/std/data/json/schema/relative_pointer.zzm +299 -0
  98. package/stdlib/modules/std/data/json/schema/validation.zzm +1503 -0
  99. package/stdlib/modules/std/data/json/schema.zzm +306 -0
  100. package/stdlib/modules/std/data/json.zzm +102 -0
  101. package/stdlib/modules/std/data/kdl/json.zzm +460 -0
  102. package/stdlib/modules/std/data/kdl/xml.zzm +387 -0
  103. package/stdlib/modules/std/data/kdl.zzm +1631 -0
  104. package/stdlib/modules/std/data/toml.zzm +756 -0
  105. package/stdlib/modules/std/data/toon.zzm +1017 -0
  106. package/stdlib/modules/std/data/xml/escape.zzm +156 -0
  107. package/stdlib/modules/std/data/xml.zzm +276 -0
  108. package/stdlib/modules/std/data/yaml.zzm +94 -0
  109. package/stdlib/modules/std/db.zzm +173 -0
  110. package/stdlib/modules/std/defer.zzm +75 -0
  111. package/stdlib/modules/std/digest/crc32.zzm +196 -0
  112. package/stdlib/modules/std/digest/md5.zzm +54 -0
  113. package/stdlib/modules/std/digest/sha.zzm +83 -0
  114. package/stdlib/modules/std/dump.zzm +317 -0
  115. package/stdlib/modules/std/eval.zzm +63 -0
  116. package/stdlib/modules/std/getopt.zzm +432 -0
  117. package/stdlib/modules/std/gui/dialogue.zzm +592 -0
  118. package/stdlib/modules/std/gui/objects.zzm +123 -0
  119. package/stdlib/modules/std/gui.zzm +1914 -0
  120. package/stdlib/modules/std/internals.zzm +139 -0
  121. package/stdlib/modules/std/io/socks.zzm +139 -0
  122. package/stdlib/modules/std/io.zzm +157 -0
  123. package/stdlib/modules/std/lingua/en.zzm +347 -0
  124. package/stdlib/modules/std/log.zzm +169 -0
  125. package/stdlib/modules/std/mail.zzm +2726 -0
  126. package/stdlib/modules/std/marshal.zzm +138 -0
  127. package/stdlib/modules/std/math/bignum.zzm +98 -0
  128. package/stdlib/modules/std/math/range.zzm +116 -0
  129. package/stdlib/modules/std/math/roman.zzm +156 -0
  130. package/stdlib/modules/std/math.zzm +141 -0
  131. package/stdlib/modules/std/net/dns.zzm +93 -0
  132. package/stdlib/modules/std/net/http.zzm +278 -0
  133. package/stdlib/modules/std/net/smtp.zzm +257 -0
  134. package/stdlib/modules/std/net/url.zzm +69 -0
  135. package/stdlib/modules/std/path/jsonpointer.zzm +526 -0
  136. package/stdlib/modules/std/path/kdl.zzm +1003 -0
  137. package/stdlib/modules/std/path/simple.zzm +520 -0
  138. package/stdlib/modules/std/path/z/context.zzm +147 -0
  139. package/stdlib/modules/std/path/z/evaluate.zzm +549 -0
  140. package/stdlib/modules/std/path/z/functions.zzm +874 -0
  141. package/stdlib/modules/std/path/z/lexer.zzm +490 -0
  142. package/stdlib/modules/std/path/z/node.zzm +1455 -0
  143. package/stdlib/modules/std/path/z/operators.zzm +445 -0
  144. package/stdlib/modules/std/path/z/parser.zzm +359 -0
  145. package/stdlib/modules/std/path/z.zzm +403 -0
  146. package/stdlib/modules/std/path/zz/functions.zzm +828 -0
  147. package/stdlib/modules/std/path/zz/operators.zzm +1036 -0
  148. package/stdlib/modules/std/path/zz.zzm +100 -0
  149. package/stdlib/modules/std/proc.zzm +155 -0
  150. package/stdlib/modules/std/result.zzm +149 -0
  151. package/stdlib/modules/std/secure.zzm +606 -0
  152. package/stdlib/modules/std/string/base64.zzm +66 -0
  153. package/stdlib/modules/std/string/quoted_printable.zzm +485 -0
  154. package/stdlib/modules/std/string.zzm +179 -0
  155. package/stdlib/modules/std/task.zzm +221 -0
  156. package/stdlib/modules/std/template/z.zzm +531 -0
  157. package/stdlib/modules/std/template/zz.zzm +62 -0
  158. package/stdlib/modules/std/time.zzm +188 -0
  159. package/stdlib/modules/std/tui.zzm +89 -0
  160. package/stdlib/modules/std/uuid.zzm +223 -0
  161. package/stdlib/modules/std/web/session.zzm +388 -0
  162. package/stdlib/modules/std/web/static.zzm +329 -0
  163. package/stdlib/modules/std/web.zzm +1942 -0
  164. package/stdlib/modules/std/worker.zzm +202 -0
  165. package/stdlib/modules/std/zuzuzoo.zzm +3960 -0
  166. package/stdlib/modules/test/more.zzm +528 -0
  167. package/stdlib/modules/test/parser.zzm +209 -0
@@ -0,0 +1,571 @@
1
+ 'use strict';
2
+
3
+ const { getCompiledSource } = require( '../../lib/execution-metadata' );
4
+ const taskRuntime = require( './task' );
5
+
6
+ const frameProps = new Map();
7
+ const refIds = new WeakMap();
8
+ const scopeTrees = new Map();
9
+ const ZUZU_SKIP_BUILD = Symbol.for( 'zuzu.skip_build' );
10
+ let refSeq = 1;
11
+ let nodeFs;
12
+ let nodeFsLoaded = false;
13
+ let runtimePolicy = {
14
+ load_module: null,
15
+ builtin_class: null,
16
+ to_String: null,
17
+ to_Number: null,
18
+ to_Boolean: null,
19
+ to_Regexp: null,
20
+ to_Regexp_with_flags: null,
21
+ };
22
+
23
+ function setRuntimePolicy( policy = {} ) {
24
+ runtimePolicy = {
25
+ ...runtimePolicy,
26
+ ...policy,
27
+ };
28
+ }
29
+
30
+ function _thisModuleFilename() {
31
+ return typeof __filename === 'string' ? __filename : null;
32
+ }
33
+
34
+ function _nodeFs() {
35
+ if ( nodeFsLoaded ) {
36
+ return nodeFs;
37
+ }
38
+ nodeFsLoaded = true;
39
+ if ( typeof require !== 'function' ) {
40
+ nodeFs = null;
41
+ return nodeFs;
42
+ }
43
+ try {
44
+ nodeFs = require( 'node:fs' );
45
+ }
46
+ catch ( _err ) {
47
+ nodeFs = null;
48
+ }
49
+ return nodeFs;
50
+ }
51
+
52
+ function parseUserFrames() {
53
+ const lines = String( new Error().stack || '' ).split( '\n' ).slice( 1 );
54
+ const frames = [];
55
+ for ( const line of lines ) {
56
+ const trimmed = line.trim();
57
+ let match = trimmed.match( /^at\s+(.*?)\s+\((.+):(\d+):(\d+)\)$/ );
58
+ if ( !match ) {
59
+ match = trimmed.match( /^at\s+(.+):(\d+):(\d+)$/ );
60
+ if ( match ) {
61
+ match = [ match[0], '', match[1], match[2], match[3] ];
62
+ }
63
+ }
64
+ if ( !match ) {
65
+ continue;
66
+ }
67
+ const file = match[2];
68
+ if ( file.includes( '<anonymous>' ) || file.startsWith( 'eval at ' ) ) {
69
+ continue;
70
+ }
71
+ const thisFile = _thisModuleFilename();
72
+ if (
73
+ ( thisFile != null && file === thisFile ) ||
74
+ /[\\/]extras[\\/]zuzu-js[\\/]lib[\\/]runtime\.js$/.test( file ) ||
75
+ /[\\/]zuzu-js[\\/]lib[\\/]runtime\.js$/.test( file ) ||
76
+ /[\\/]zuzu-browser\.js$/.test( file ) ||
77
+ file.startsWith( 'node:' ) ||
78
+ file === '[stdin]'
79
+ ) {
80
+ continue;
81
+ }
82
+ frames.push( {
83
+ func: match[1] || '',
84
+ file,
85
+ line: Number( match[3] ),
86
+ col: Number( match[4] ),
87
+ } );
88
+ }
89
+ return frames;
90
+ }
91
+
92
+ function loadScopeTree( file ) {
93
+ if ( scopeTrees.has( file ) ) {
94
+ return scopeTrees.get( file );
95
+ }
96
+
97
+ let source = '';
98
+ const compiled = getCompiledSource( file );
99
+ if ( compiled != null ) {
100
+ source = compiled;
101
+ }
102
+ else try {
103
+ const fs = _nodeFs();
104
+ if ( !fs ) {
105
+ throw new Error( 'fs unavailable' );
106
+ }
107
+ source = fs.readFileSync( file, 'utf8' );
108
+ }
109
+ catch ( _err ) {
110
+ const fallback = {
111
+ nodes: [ { id: 0, parent: null, startLine: 1, endLine: Number.MAX_SAFE_INTEGER } ],
112
+ };
113
+ scopeTrees.set( file, fallback );
114
+ return fallback;
115
+ }
116
+
117
+ const nodes = [
118
+ { id: 0, parent: null, startLine: 1, endLine: Number.MAX_SAFE_INTEGER },
119
+ ];
120
+ const stack = [ 0 ];
121
+ let line = 1;
122
+ let mode = 'code';
123
+ let quote = '';
124
+ let escaped = false;
125
+ let atLineStart = true;
126
+ let inPod = false;
127
+
128
+ for ( let i = 0; i < source.length; i++ ) {
129
+ const ch = source[i];
130
+ const next = source[i + 1] || '';
131
+
132
+ if ( ch === '\n' ) {
133
+ line++;
134
+ atLineStart = true;
135
+ if ( mode === 'line-comment' ) {
136
+ mode = 'code';
137
+ }
138
+ continue;
139
+ }
140
+
141
+ if ( inPod ) {
142
+ if ( atLineStart && ch === '=' ) {
143
+ const end = source.indexOf( '\n', i );
144
+ const rest = source.slice( i, end === -1 ? source.length : end );
145
+ if ( /^=cut\b/.test( rest ) ) {
146
+ inPod = false;
147
+ }
148
+ }
149
+ atLineStart = false;
150
+ continue;
151
+ }
152
+
153
+ if ( atLineStart && ch === '=' ) {
154
+ const end = source.indexOf( '\n', i );
155
+ const rest = source.slice( i, end === -1 ? source.length : end );
156
+ if ( /^=\w+/.test( rest ) && !/^=cut\b/.test( rest ) ) {
157
+ inPod = true;
158
+ atLineStart = false;
159
+ continue;
160
+ }
161
+ }
162
+
163
+ atLineStart = false;
164
+
165
+ if ( mode === 'line-comment' ) {
166
+ continue;
167
+ }
168
+
169
+ if ( mode === 'block-comment' ) {
170
+ if ( ch === '*' && next === '/' ) {
171
+ mode = 'code';
172
+ i++;
173
+ }
174
+ continue;
175
+ }
176
+
177
+ if ( mode === 'string' ) {
178
+ if ( escaped ) {
179
+ escaped = false;
180
+ continue;
181
+ }
182
+ if ( ch === '\\' ) {
183
+ escaped = true;
184
+ continue;
185
+ }
186
+ if ( ch === quote ) {
187
+ mode = 'code';
188
+ }
189
+ continue;
190
+ }
191
+
192
+ if ( ch === '/' && next === '/' ) {
193
+ mode = 'line-comment';
194
+ i++;
195
+ continue;
196
+ }
197
+
198
+ if ( ch === '/' && next === '*' ) {
199
+ mode = 'block-comment';
200
+ i++;
201
+ continue;
202
+ }
203
+
204
+ if ( ch === '"' || ch === '\'' || ch === '`' ) {
205
+ mode = 'string';
206
+ quote = ch;
207
+ escaped = false;
208
+ continue;
209
+ }
210
+
211
+ if ( ch === '{' ) {
212
+ const id = nodes.length;
213
+ nodes.push( {
214
+ id,
215
+ parent: stack[stack.length - 1],
216
+ startLine: line,
217
+ endLine: Number.MAX_SAFE_INTEGER,
218
+ } );
219
+ stack.push( id );
220
+ continue;
221
+ }
222
+
223
+ if ( ch === '}' && stack.length > 1 ) {
224
+ const id = stack.pop();
225
+ nodes[id].endLine = line;
226
+ }
227
+ }
228
+
229
+ const tree = { nodes };
230
+ scopeTrees.set( file, tree );
231
+ return tree;
232
+ }
233
+
234
+ function scopePathForLocation( file, line ) {
235
+ const tree = loadScopeTree( file );
236
+ let current = 0;
237
+ let found = true;
238
+
239
+ while ( found ) {
240
+ found = false;
241
+ for ( let i = tree.nodes.length - 1; i >= 1; i-- ) {
242
+ const node = tree.nodes[i];
243
+ if ( node.parent !== current ) {
244
+ continue;
245
+ }
246
+ if ( node.startLine <= line && line <= node.endLine ) {
247
+ current = node.id;
248
+ found = true;
249
+ break;
250
+ }
251
+ }
252
+ }
253
+
254
+ const path = [];
255
+ let nodeId = current;
256
+ while ( nodeId != null ) {
257
+ path.push( nodeId );
258
+ nodeId = tree.nodes[nodeId].parent;
259
+ }
260
+ return path;
261
+ }
262
+
263
+ function contextAtDepth( depth = 0 ) {
264
+ const frames = parseUserFrames();
265
+ const frame = frames[depth];
266
+ if ( !frame ) {
267
+ return null;
268
+ }
269
+ const isVirtualBrowserPath = runtimePolicy.host_name === 'browser';
270
+ const line = isVirtualBrowserPath
271
+ ? frame.line - 2
272
+ : frame.line;
273
+
274
+ return {
275
+ activationKey: `file:${frame.file}`,
276
+ scopePath: scopePathForLocation( frame.file, Math.max( 1, line ) ),
277
+ };
278
+ }
279
+
280
+ function ensureFrame( activationKey, scopeId ) {
281
+ const key = `${activationKey}#${scopeId}`;
282
+ if ( !frameProps.has( key ) ) {
283
+ frameProps.set( key, new Map() );
284
+ }
285
+ return frameProps.get( key );
286
+ }
287
+
288
+ function getFrame( activationKey, scopeId ) {
289
+ return frameProps.get( `${activationKey}#${scopeId}` );
290
+ }
291
+
292
+ function class_name( value ) {
293
+ if ( value == null || typeof value !== 'object' ) {
294
+ return null;
295
+ }
296
+ return value.constructor && value.constructor.name ? value.constructor.name : null;
297
+ }
298
+
299
+ function classof( value ) {
300
+ if ( value == null ) {
301
+ return null;
302
+ }
303
+ if (
304
+ typeof value === 'boolean'
305
+ || typeof value === 'number'
306
+ || typeof value === 'string'
307
+ ) {
308
+ return null;
309
+ }
310
+ const builtinClass = typeof runtimePolicy.builtin_class === 'function'
311
+ ? runtimePolicy.builtin_class
312
+ : () => null;
313
+ if ( Array.isArray( value ) ) {
314
+ return builtinClass( 'Array' ) || value.constructor || null;
315
+ }
316
+ if ( Object.prototype.toString.call( value ) === '[object Set]' ) {
317
+ return builtinClass( 'Set' ) || value.constructor || null;
318
+ }
319
+ if ( value && value.constructor ) {
320
+ const ctor = value.constructor;
321
+ const name = ctor.__zuzu_class_name || ctor.name || '';
322
+ if ( name === 'Object' ) {
323
+ return builtinClass( 'Dict' ) || ctor;
324
+ }
325
+ if ( name === 'ZuzuBag' ) {
326
+ return builtinClass( 'Bag' ) || ctor;
327
+ }
328
+ return ctor;
329
+ }
330
+ if ( typeof value === 'function' ) {
331
+ const source = Function.prototype.toString.call( value );
332
+ if ( /^\s*class\b/.test( source ) ) {
333
+ return builtinClass( 'Class' ) || Function;
334
+ }
335
+ return builtinClass( 'Function' ) || Function;
336
+ }
337
+ return null;
338
+ }
339
+
340
+ function object_slots( value ) {
341
+ if ( value == null || typeof value !== 'object' ) {
342
+ return null;
343
+ }
344
+ const out = {};
345
+ for ( const key of Object.keys( value ) ) {
346
+ if ( !key.startsWith( '_' ) ) {
347
+ out[key] = value[key];
348
+ }
349
+ }
350
+ Object.defineProperty(
351
+ out,
352
+ 'get',
353
+ {
354
+ value( key ) {
355
+ const id = String( key );
356
+ return Object.prototype.hasOwnProperty.call( out, id ) ? out[id] : null;
357
+ },
358
+ enumerable: false,
359
+ }
360
+ );
361
+ Object.defineProperty(
362
+ out,
363
+ 'keys',
364
+ {
365
+ value() {
366
+ return Object.keys( out );
367
+ },
368
+ enumerable: false,
369
+ }
370
+ );
371
+ Object.defineProperty(
372
+ out,
373
+ 'sorted_keys',
374
+ {
375
+ value() {
376
+ return Object.keys( out ).sort();
377
+ },
378
+ enumerable: false,
379
+ }
380
+ );
381
+ return out;
382
+ }
383
+
384
+ function ansi_esc() {
385
+ return '\x1b';
386
+ }
387
+
388
+ function ref_id( value ) {
389
+ if ( value == null || ( typeof value !== 'object' && typeof value !== 'function' ) ) {
390
+ return null;
391
+ }
392
+ if ( !refIds.has( value ) ) {
393
+ refIds.set( value, `ref:${refSeq++}` );
394
+ }
395
+ return refIds.get( value );
396
+ }
397
+
398
+ function make_instance( klass, slots = null ) {
399
+ if (
400
+ typeof klass !== 'function'
401
+ || typeof klass.__zuzu_class_name !== 'string'
402
+ ) {
403
+ throw new Error( 'make_instance expects a user class' );
404
+ }
405
+ if ( slots == null ) {
406
+ return new klass( ZUZU_SKIP_BUILD );
407
+ }
408
+ if (
409
+ typeof slots !== 'object'
410
+ || Array.isArray( slots )
411
+ ) {
412
+ throw new Error( 'make_instance slot values must be Dict' );
413
+ }
414
+ return new klass( ZUZU_SKIP_BUILD, slots );
415
+ }
416
+
417
+ function currentUserFile() {
418
+ const frame = parseUserFrames()[0];
419
+ return frame && frame.file ? frame.file : null;
420
+ }
421
+
422
+ function moduleExportKeys( loaded ) {
423
+ return Reflect.ownKeys( Object( loaded ) )
424
+ .filter( (key) => typeof key === 'string' )
425
+ .filter( (key) => !key.startsWith( '__zuzu_' ) );
426
+ }
427
+
428
+ function load_module( moduleName, symbolName = null ) {
429
+ if ( arguments.length < 1 || arguments.length > 2 ) {
430
+ throw new Error( 'load_module expects 1 to 2 arguments' );
431
+ }
432
+ if ( typeof moduleName !== 'string' ) {
433
+ throw new Error( 'load_module module must be String' );
434
+ }
435
+ if ( symbolName != null && typeof symbolName !== 'string' ) {
436
+ throw new Error( 'load_module symbol must be String' );
437
+ }
438
+ if ( typeof runtimePolicy.load_module !== 'function' ) {
439
+ throw new Error( 'load_module is unavailable in this runtime' );
440
+ }
441
+
442
+ const loaded = runtimePolicy.load_module( moduleName, currentUserFile() );
443
+ if ( symbolName != null ) {
444
+ if ( !Object.prototype.hasOwnProperty.call( Object( loaded ), symbolName ) ) {
445
+ throw new Error( `Module '${moduleName}' has no export '${symbolName}'` );
446
+ }
447
+ return loaded[symbolName];
448
+ }
449
+
450
+ const out = {};
451
+ for ( const key of moduleExportKeys( loaded ) ) {
452
+ out[key] = loaded[key];
453
+ }
454
+ return out;
455
+ }
456
+
457
+ function requirePolicyFunction( name ) {
458
+ const fn = runtimePolicy[name];
459
+ if ( typeof fn !== 'function' ) {
460
+ throw new Error( `${name} is unavailable in this runtime` );
461
+ }
462
+ return fn;
463
+ }
464
+
465
+ function to_String( value ) {
466
+ return requirePolicyFunction( 'to_String' )( value );
467
+ }
468
+
469
+ function to_Number( value ) {
470
+ return requirePolicyFunction( 'to_Number' )( value );
471
+ }
472
+
473
+ function to_Boolean( value ) {
474
+ return requirePolicyFunction( 'to_Boolean' )( value );
475
+ }
476
+
477
+ function to_Regexp( value ) {
478
+ return requirePolicyFunction( 'to_Regexp' )( value );
479
+ }
480
+
481
+ function to_Regexp_with_flags( value, flags ) {
482
+ return requirePolicyFunction( 'to_Regexp_with_flags' )( value, flags );
483
+ }
484
+
485
+ function validateKey( key ) {
486
+ if ( typeof key !== 'string' ) {
487
+ throw new Error( 'getprop|setprop key must be String' );
488
+ }
489
+ }
490
+
491
+ function setprop( key, value ) {
492
+ validateKey( key );
493
+ const ctx = contextAtDepth( 0 );
494
+ if ( !ctx ) {
495
+ return value;
496
+ }
497
+ ensureFrame( ctx.activationKey, ctx.scopePath[0] ).set( key, value );
498
+ return value;
499
+ }
500
+
501
+ function getprop( key ) {
502
+ validateKey( key );
503
+ const ctx = contextAtDepth( 0 );
504
+ if ( !ctx ) {
505
+ return null;
506
+ }
507
+ for ( const scopeId of ctx.scopePath ) {
508
+ const frame = getFrame( ctx.activationKey, scopeId );
509
+ if ( frame && frame.has( key ) ) {
510
+ return frame.get( key );
511
+ }
512
+ }
513
+ return null;
514
+ }
515
+
516
+ function setupperprop( level, key, value ) {
517
+ validateKey( key );
518
+ const ctx = contextAtDepth( Number( level ?? 0 ) );
519
+ if ( !ctx ) {
520
+ return value;
521
+ }
522
+ ensureFrame( ctx.activationKey, ctx.scopePath[0] ).set( key, value );
523
+ return value;
524
+ }
525
+
526
+ function getupperprop( level, key ) {
527
+ validateKey( key );
528
+ const ctx = contextAtDepth( Number( level ?? 0 ) );
529
+ if ( !ctx ) {
530
+ return null;
531
+ }
532
+ for ( const scopeId of ctx.scopePath ) {
533
+ const frame = getFrame( ctx.activationKey, scopeId );
534
+ if ( frame && frame.has( key ) ) {
535
+ return frame.get( key );
536
+ }
537
+ }
538
+ return null;
539
+ }
540
+
541
+ const api = {
542
+ active_task_count: taskRuntime.activeCount,
543
+ ansi_esc,
544
+ class_name,
545
+ classof,
546
+ clear_task_trace: taskRuntime.clearTrace,
547
+ getprop,
548
+ getupperprop,
549
+ load_module,
550
+ make_instance,
551
+ object_slots,
552
+ ref_id,
553
+ setprop,
554
+ setupperprop,
555
+ shutdown_tasks: taskRuntime.shutdown,
556
+ task_trace: taskRuntime.taskTrace,
557
+ to_Boolean,
558
+ to_Number,
559
+ to_Regexp,
560
+ to_Regexp_with_flags,
561
+ to_String,
562
+ };
563
+
564
+ Object.defineProperty( api, '__zuzu_set_runtime_policy', {
565
+ value: setRuntimePolicy,
566
+ enumerable: false,
567
+ configurable: true,
568
+ writable: true,
569
+ } );
570
+
571
+ module.exports = api;