wat4wasm 1.1.4 → 1.1.6

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.
@@ -4,21 +4,30 @@
4
4
 
5
5
 
6
6
 
7
+
8
+
7
9
  (func $unreferenced_by_user)
8
10
 
9
11
 
10
12
 
11
13
 
12
14
 
13
- (elem $wat4wasm declare func $unreferenced_by_user)
15
+ (elem $wat4wasm declare func $inline $unreferenced_by_user)
16
+
17
+
18
+
14
19
 
15
20
 
16
21
 
17
22
 
23
+ (memory $wat4wasm 1)
18
24
 
19
25
 
26
+ (func $inline
27
+ (local $a i32)
28
+ (local.set $a (i32.const 2))
29
+ )
20
30
 
21
31
 
22
32
 
23
- (start $wat4wasm)
24
33
  )
@@ -4,5 +4,12 @@
4
4
  (drop)
5
5
  )
6
6
 
7
+ (func $test_inline
8
+ (func $inline
9
+ (local $a i32)
10
+ (local.set $a (i32.const 2))
11
+ )
12
+ )
13
+
7
14
  (func $unreferenced_by_user)
8
15
  )
@@ -1,36 +1,29 @@
1
1
  cd 01-text
2
2
  wat4wasm --input=module.wat --output=module-output.wat
3
- rm wat4wasm
4
3
  cd ..
5
4
 
6
5
  cd 02-include
7
6
  wat4wasm --input=module.wat --output=module-output.wat
8
- rm wat4wasm
9
7
  cd ..
10
8
 
11
9
  cd 03-ref.extern
12
10
  wat4wasm --input=module.wat --output=module-output.wat
13
- rm wat4wasm
14
11
  cd ..
15
12
 
16
13
  cd 04-ref.func
17
14
  wat4wasm --input=module.wat --output=module-output.wat
18
- rm wat4wasm
19
15
  cd ..
20
16
 
21
17
  cd 05-global.get
22
18
  wat4wasm --input=module.wat --output=module-output.wat
23
- rm wat4wasm
24
19
  cd ..
25
20
 
26
21
  cd 06-async
27
22
  wat4wasm --input=module.wat --output=module-output.wat
28
- rm wat4wasm
29
23
  cd ..
30
24
 
31
25
  cd 07-data
32
26
  wat4wasm --input=module.wat --output=module-output.wat --wat2wasm=wat2wasm
33
- rm wat4wasm
34
27
  cd ..
35
28
 
36
29
  cd 08-reflectors
package/lib/helpers.js CHANGED
@@ -217,7 +217,7 @@ const helpers = {
217
217
  return keyword;
218
218
  },
219
219
 
220
- fixBlockKeyword(keyword, filter = {}) {
220
+ fixBlockKeyword(keyword = "", filter = {}) {
221
221
  if (keyword.split(/\s/).length > 1) {
222
222
  throw new Error(`Given keyword is wrong: ${keyword}`)
223
223
  }
@@ -499,6 +499,7 @@ const helpers = {
499
499
  after: this.input.substring(this.end)
500
500
  }
501
501
  },
502
+ mask: function (block) { return this.block = block.removedRaw(); },
502
503
  maskedRaw: function () { return this.replacedRaw(this.uuid); },
503
504
  removedRaw: function () { return this.replacedRaw(""); },
504
505
  replacedRaw: function (str) {
@@ -528,26 +529,54 @@ const helpers = {
528
529
  return blockName;
529
530
  }
530
531
  },
532
+ parentBlock: {
533
+ value: function () {
534
+ const lastBlockBefore = helpers.lastBlockBefore(this.toString(), this.begin);
535
+ if (lastBlockBefore) {
536
+ if (lastBlockBefore.end > this.end) {
537
+ return lastBlockBefore;
538
+ }
539
+ return lastBlockBefore.parentBlock();
540
+ }
541
+ }
542
+ },
531
543
  generateId: { value: function () { return helpers.generateId(this.toString()) } },
532
544
  name: { get: function () { return `${this.$name}`.substring(1); } },
533
545
  rawContent: { get: function () { return helpers.rawContent(this.toString()) } },
534
546
  blockContent: { get: function () { return helpers.blockContent(this.toString()) } },
535
547
  hasAnyBlock: { get: function () { return helpers.hasAnyBlock(this.toString()) } },
536
- indexOf: { value: function () { return this.block.indexOf(...arguments) } },
537
- includes: { value: function () { return this.block.includes(...arguments) } },
538
- lastIndexOf: { value: function () { return this.block.lastIndexOf(...arguments) } },
539
- split: { value: function () { return this.block.split(...arguments) } },
540
- at: { value: function () { return this.block.at(...arguments) } },
541
- length: { get: function () { return this.block.length } },
548
+ indexOf: { value: function () { return this.toString().indexOf(...arguments) } },
549
+ includes: { value: function () { return this.toString().includes(...arguments) } },
550
+ lastIndexOf: { value: function () { return this.toString().lastIndexOf(...arguments) } },
551
+ split: { value: function () { return this.toString().split(...arguments) } },
552
+ at: { value: function () { return this.toString().at(...arguments) } },
553
+ length: { get: function () { return this.toString().length } },
542
554
  charCodeAt: { value: function () { return this.block.charCodeAt(...arguments) } },
543
- concat: { value: function () { return this.block.concat(...arguments) } },
544
- startsWith: { value: function () { return this.block.startsWith(...arguments) } },
545
- endsWith: { value: function () { return this.block.endsWith(...arguments) } },
546
- substring: { value: function () { return this.block.substring(...arguments) } },
547
- replace: { value: function () { return this.block.replace(...arguments) } },
548
- replaceAll: { value: function () { return this.block.replaceAll(...arguments) } },
549
- lastBlockOf: { value: function () { return helpers.lastBlockOf(this.block, ...arguments) } },
550
- [Symbol.toPrimitive]: { value: function () { return this.block; } },
555
+ children: {
556
+ get: function () {
557
+ const blocks = new Array();
558
+ let firstBlock, code = this.toString().substring(1, this.length - 1);
559
+
560
+ while (code.includes("(")) {
561
+ firstBlock = helpers.parseBlockAt(
562
+ code, code.indexOf("(")
563
+ ).toString();
564
+
565
+ blocks.push(firstBlock);
566
+ code = code.replace(firstBlock, "");
567
+ }
568
+
569
+ return blocks;
570
+ }
571
+ },
572
+ concat: { value: function () { return this.toString().concat(...arguments) } },
573
+ startsWith: { value: function () { return this.toString().startsWith(...arguments) } },
574
+ endsWith: { value: function () { return this.toString().endsWith(...arguments) } },
575
+ substring: { value: function () { return this.toString().substring(...arguments) } },
576
+ replace: { value: function () { return this.toString().replace(...arguments) } },
577
+ replaceAll: { value: function () { return this.toString().replaceAll(...arguments) } },
578
+ lastBlockOf: { value: function () { return helpers.lastBlockOf(this.toString(), ...arguments) } },
579
+ [Symbol.toPrimitive]: { value: function () { return this.toString(); } },
551
580
  })
552
581
  },
553
582
 
@@ -591,6 +620,10 @@ const helpers = {
591
620
  parseFirstBlock(raw) {
592
621
  raw = raw.toString();
593
622
  return this.parseBlockAt(raw, raw.indexOf("(", 1));
623
+ },
624
+
625
+ lastBlockBefore(raw, begin) {
626
+ return this.parseBlockAt(raw, raw.lastIndexOf("(", raw.substring(0, begin)));
594
627
  }
595
628
  };
596
629
 
@@ -1,12 +1,8 @@
1
1
  import helpers from "../helpers.js"
2
2
 
3
- export const DATA_BLOCK_NAME = "data";
4
- export const SIZE_BLOCK_NAME = "data.size";
5
- export const VIEW_BLOCK_NAME = "data.view";
6
-
7
3
  const GENERATE_DATA_VIEWER = (size, $name) => {
8
4
  return `
9
- (block ${$name}>
5
+ (block ${$name}
10
6
  (result externref)
11
7
 
12
8
  (global.set $wat4wasm (call $self.Array<>ext))
@@ -65,6 +61,178 @@ const GENERATE_DATA_VIEWER = (size, $name) => {
65
61
  `;
66
62
  };
67
63
 
64
+ const GENERATE_TEXT_VIEWER = (size, $name) => {
65
+ return `
66
+ (block ${$name}
67
+ (result externref)
68
+
69
+ (global.set $wat4wasm (call $self.Array<>ext))
70
+
71
+ (call $self.Reflect.set<ext.i32.i32>
72
+ (global.get $wat4wasm) (i32.const 0) (i32.const ${size})
73
+ )
74
+
75
+ (global.set $wat4wasm
76
+ (call $self.Reflect.construct<ext.ext>ext
77
+ (ref.extern $self.Uint8Array<ext>)
78
+ (global.get $wat4wasm)
79
+ )
80
+ )
81
+
82
+ (if (i32.const ${size})
83
+ (then
84
+ (i32.const 0)
85
+ (i64.load (i32.const 0))
86
+
87
+ (block $copy
88
+ (i32.store (i32.const 0) (i32.const ${size}))
89
+ (loop $i--
90
+ (if (i32.load (i32.const 0))
91
+ (then
92
+ (i32.store
93
+ (i32.const 0)
94
+ (i32.sub (i32.load (i32.const 0)) (i32.const 1))
95
+ )
96
+
97
+ (memory.init ${$name}
98
+ (i32.const 4)
99
+ (i32.load (i32.const 0))
100
+ (i32.const 1)
101
+ )
102
+
103
+ (call $self.Reflect.set<ext.i32.i32>
104
+ (global.get $wat4wasm)
105
+ (i32.load (i32.const 0))
106
+ (i32.load8_u (i32.const 4))
107
+ )
108
+
109
+ (br $i--)
110
+ )
111
+ )
112
+ )
113
+ )
114
+
115
+ (i64.store (; stack stack ;))
116
+ )
117
+ )
118
+
119
+
120
+ (local.set $arguments (call $self.Array<>ext))
121
+
122
+ (call $self.Reflect.set<ext.i32.ext>
123
+ (local.get $arguments)
124
+ (i32.const 0)
125
+ (global.get $wat4wasm)
126
+ )
127
+
128
+ (call $self.Reflect.apply<ext.ext.ext>ext
129
+ (local.get $textDecoder.decode)
130
+ (local.get $textDecoder)
131
+ (local.get $arguments)
132
+ )
133
+
134
+ (global.set $wat4wasm (null))
135
+ )
136
+ `;
137
+ };
138
+
139
+ const GENERATE_HREF_VIEWER = (size, $name) => {
140
+ return `
141
+ (block ${$name}
142
+ (result externref)
143
+
144
+ (global.set $wat4wasm (call $self.Array<>ext))
145
+
146
+ (call $self.Reflect.set<ext.i32.i32>
147
+ (global.get $wat4wasm) (i32.const 0) (i32.const ${size})
148
+ )
149
+
150
+ (global.set $wat4wasm
151
+ (call $self.Reflect.construct<ext.ext>ext
152
+ (ref.extern $self.Uint8Array<ext>)
153
+ (global.get $wat4wasm)
154
+ )
155
+ )
156
+
157
+ (if (i32.const ${size})
158
+ (then
159
+ (i32.const 0)
160
+ (i64.load (i32.const 0))
161
+
162
+ (block $copy
163
+ (i32.store (i32.const 0) (i32.const ${size}))
164
+ (loop $i--
165
+ (if (i32.load (i32.const 0))
166
+ (then
167
+ (i32.store
168
+ (i32.const 0)
169
+ (i32.sub (i32.load (i32.const 0)) (i32.const 1))
170
+ )
171
+
172
+ (memory.init ${$name}
173
+ (i32.const 4)
174
+ (i32.load (i32.const 0))
175
+ (i32.const 1)
176
+ )
177
+
178
+ (call $self.Reflect.set<ext.i32.i32>
179
+ (global.get $wat4wasm)
180
+ (i32.load (i32.const 0))
181
+ (i32.load8_u (i32.const 4))
182
+ )
183
+
184
+ (br $i--)
185
+ )
186
+ )
187
+ )
188
+ )
189
+
190
+ (i64.store (; stack stack ;))
191
+ )
192
+ )
193
+
194
+
195
+ (local.set $arguments (call $self.Array<>ext))
196
+
197
+ (call $self.Reflect.set<ext.i32.ext>
198
+ (local.get $arguments)
199
+ (i32.const 0)
200
+ (global.get $wat4wasm)
201
+ )
202
+
203
+ (call $self.Reflect.set<ext.i32.ext>
204
+ (local.get $arguments)
205
+ (i32.const 0)
206
+ (call $self.Reflect.apply<ext.ext.ext>ext
207
+ (local.get $textDecoder.decode)
208
+ (local.get $textDecoder)
209
+ (local.get $arguments)
210
+ )
211
+ )
212
+
213
+ (call $self.Reflect.set<ext.i32.ext>
214
+ (local.get $arguments)
215
+ (i32.const 0)
216
+ (call $self.Reflect.construct<ext.ext>ext
217
+ (call $self.Reflect.get<ext.ext>ext (self) (string "Blob"))
218
+ (local.get $arguments)
219
+ )
220
+ )
221
+
222
+ (call $self.Reflect.apply<ext.ext.ext>ext
223
+ (call $self.Reflect.get<ext.ext>ext
224
+ (call $self.Reflect.get<ext.ext>ext (self) (string "URL"))
225
+ (string "createObjectURL")
226
+ )
227
+ (null)
228
+ (local.get $arguments)
229
+ )
230
+
231
+ (global.set $wat4wasm (null))
232
+ )
233
+ `;
234
+ };
235
+
68
236
  export default function (wat, WAT4WASM) {
69
237
 
70
238
  const maskSet = new helpers.MaskSet(wat);
@@ -73,22 +241,36 @@ export default function (wat, WAT4WASM) {
73
241
  const segmentSizes = new Map();
74
242
  const sizeRequests = new Set();
75
243
  const viewRequests = new Set();
244
+ const textRequests = new Set();
245
+ const hrefRequests = new Set();
246
+
247
+ while (maskSet.hasBlock("data.text")) {
248
+ const block = maskSet.lastBlockOf("data.text");
249
+ textRequests.add(block);
250
+ maskSet.mask(block);
251
+ }
76
252
 
77
- while (maskSet.hasBlock(VIEW_BLOCK_NAME)) {
78
- const block = maskSet.lastBlockOf(VIEW_BLOCK_NAME);
253
+ while (maskSet.hasBlock("data.href")) {
254
+ const block = maskSet.lastBlockOf("data.href");
255
+ hrefRequests.add(block);
256
+ maskSet.mask(block);
257
+ }
258
+
259
+ while (maskSet.hasBlock("data.view")) {
260
+ const block = maskSet.lastBlockOf("data.view");
79
261
  viewRequests.add(block);
80
262
  maskSet.mask(block);
81
263
  }
82
264
 
83
- while (maskSet.hasBlock(SIZE_BLOCK_NAME)) {
84
- const block = maskSet.lastBlockOf(SIZE_BLOCK_NAME);
265
+ while (maskSet.hasBlock("data.size")) {
266
+ const block = maskSet.lastBlockOf("data.size");
85
267
  sizeRequests.add(block);
86
268
  maskSet.mask(block);
87
269
  }
88
270
 
89
- while (maskSet.hasBlock(DATA_BLOCK_NAME)) {
271
+ while (maskSet.hasBlock("data")) {
90
272
 
91
- const block = maskSet.lastBlockOf(DATA_BLOCK_NAME);
273
+ const block = maskSet.lastBlockOf("data");
92
274
  const content = helpers.findQuotedText(block);
93
275
 
94
276
  maskSet.mask(block);
@@ -155,9 +337,20 @@ export default function (wat, WAT4WASM) {
155
337
  maskSet.update(block, block.id);
156
338
  });
157
339
 
340
+ textRequests.forEach(block => {
341
+ block.id = helpers.referenceId();
342
+ maskSet.update(block, block.id);
343
+ });
344
+
345
+ hrefRequests.forEach(block => {
346
+ block.id = helpers.referenceId();
347
+ maskSet.update(block, block.id);
348
+ });
349
+
158
350
  wat = maskSet.restore();
159
351
 
160
352
  let oninit = String();
353
+
161
354
  viewRequests.forEach(block => {
162
355
  if (externgetter.has(block.$name) === false) {
163
356
  const size = segmentSizes.get(block.$name);
@@ -176,12 +369,60 @@ export default function (wat, WAT4WASM) {
176
369
  }
177
370
  });
178
371
 
372
+ textRequests.forEach(block => {
373
+ if (externgetter.has(block.$name) === false) {
374
+ const size = segmentSizes.get(block.$name);
375
+ const code = GENERATE_TEXT_VIEWER(size, block.$name);
376
+
377
+ const growRequest = WAT4WASM_GROW_EXTERN_TABLE(wat);
378
+ block.tableSetter = growRequest.generateSetter(code);
379
+
380
+ wat = growRequest.modifiedRaw;
381
+ oninit = `${oninit}\n\n${block.tableSetter}\n\n`;
382
+
383
+ externgetter.set(
384
+ block.$name,
385
+ growRequest.getter.concat(` ;; ${block.$name}\n`)
386
+ );
387
+ }
388
+ });
389
+
390
+ hrefRequests.forEach(block => {
391
+ if (externgetter.has(block.$name) === false) {
392
+ const size = segmentSizes.get(block.$name);
393
+ const code = GENERATE_HREF_VIEWER(size, block.$name);
394
+
395
+ const growRequest = WAT4WASM_GROW_EXTERN_TABLE(wat);
396
+ block.tableSetter = growRequest.generateSetter(code);
397
+
398
+ wat = growRequest.modifiedRaw;
399
+ oninit = `${oninit}\n\n${block.tableSetter}\n\n`;
400
+
401
+ externgetter.set(
402
+ block.$name,
403
+ growRequest.getter.concat(` ;; ${block.$name}\n`)
404
+ );
405
+ }
406
+ });
407
+
179
408
  viewRequests.forEach(block => {
180
409
  wat = wat.replaceAll(
181
410
  block.id, externgetter.get(block.$name)
182
411
  );
183
412
  });
184
413
 
414
+ textRequests.forEach(block => {
415
+ wat = wat.replaceAll(
416
+ block.id, externgetter.get(block.$name)
417
+ );
418
+ });
419
+
420
+ hrefRequests.forEach(block => {
421
+ wat = wat.replaceAll(
422
+ block.id, externgetter.get(block.$name)
423
+ );
424
+ });
425
+
185
426
  wat = APPEND_ON_EXTERN_READY(wat, oninit);
186
427
 
187
428
  return wat;
@@ -4,6 +4,31 @@ export const REF_FUNC_BLOCK_NAME = "ref.func";
4
4
 
5
5
  export default function (wat, WAT4WASM) {
6
6
 
7
+ const inlineFunctions = new Array();
8
+
9
+ helpers
10
+ .parseBlockAt(wat.toString(), 0)
11
+ .children
12
+ .filter(b => b.startsWith("(func"))
13
+ .filter(b => b.substring(1).includes("(func"))
14
+ .map(b => b.substring(5, b.length - 1).trim())
15
+ .forEach(content => {
16
+ const maskSet = new helpers.MaskSet(content);
17
+ while (maskSet.hasBlock("func")) {
18
+ const inl = maskSet.lastBlockOf("func");
19
+ inlineFunctions.push(helpers.parseBlockAt(inl.toString(), 0));
20
+ maskSet.mask(inl);
21
+ }
22
+ })
23
+ ;
24
+
25
+ if (inlineFunctions.length) {
26
+ inlineFunctions.forEach(func => {
27
+ wat = wat.replace(func.toString(), `(ref.func ${func.$name})`)
28
+ });
29
+ wat = helpers.append(wat, inlineFunctions.map(func => `\n\t${func}\n`).join("\n"));
30
+ }
31
+
7
32
  const maskSetElem = new helpers.MaskSet(wat);
8
33
  const elemSegments = new Array();
9
34
  const needReference = new Set();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wat4wasm",
3
- "version": "1.1.4",
3
+ "version": "1.1.6",
4
4
  "description": "",
5
5
  "homepage": "https://github.com/central-network/wat4wasm#readme",
6
6
  "bugs": {
package/wat4wasm CHANGED
@@ -483,7 +483,7 @@ function wat4beauty(watContent, alignIndentsWith = "\t", exportPadStart = 90) {
483
483
  }
484
484
  return keyword;
485
485
  },
486
- fixBlockKeyword(keyword, filter = {}) {
486
+ fixBlockKeyword(keyword = "", filter = {}) {
487
487
  if (keyword.split(/\s/).length > 1) {
488
488
  throw new Error(`Given keyword is wrong: ${keyword}`)
489
489
  }
@@ -704,6 +704,7 @@ function wat4beauty(watContent, alignIndentsWith = "\t", exportPadStart = 90) {
704
704
  after: this.input.substring(this.end)
705
705
  }
706
706
  },
707
+ mask: function (block) { return this.block = block.removedRaw(); },
707
708
  maskedRaw: function () { return this.replacedRaw(this.uuid); },
708
709
  removedRaw: function () { return this.replacedRaw(""); },
709
710
  replacedRaw: function (str) {
@@ -731,26 +732,51 @@ function wat4beauty(watContent, alignIndentsWith = "\t", exportPadStart = 90) {
731
732
  return blockName;
732
733
  }
733
734
  },
735
+ parentBlock: {
736
+ value: function () {
737
+ const lastBlockBefore = helpers.lastBlockBefore(this.toString(), this.begin);
738
+ if (lastBlockBefore) {
739
+ if (lastBlockBefore.end > this.end) {
740
+ return lastBlockBefore;
741
+ }
742
+ return lastBlockBefore.parentBlock();
743
+ }
744
+ }
745
+ },
734
746
  generateId: { value: function () { return helpers.generateId(this.toString()) } },
735
747
  name: { get: function () { return `${this.$name}`.substring(1); } },
736
748
  rawContent: { get: function () { return helpers.rawContent(this.toString()) } },
737
749
  blockContent: { get: function () { return helpers.blockContent(this.toString()) } },
738
750
  hasAnyBlock: { get: function () { return helpers.hasAnyBlock(this.toString()) } },
739
- indexOf: { value: function () { return this.block.indexOf(...arguments) } },
740
- includes: { value: function () { return this.block.includes(...arguments) } },
741
- lastIndexOf: { value: function () { return this.block.lastIndexOf(...arguments) } },
742
- split: { value: function () { return this.block.split(...arguments) } },
743
- at: { value: function () { return this.block.at(...arguments) } },
744
- length: { get: function () { return this.block.length } },
751
+ indexOf: { value: function () { return this.toString().indexOf(...arguments) } },
752
+ includes: { value: function () { return this.toString().includes(...arguments) } },
753
+ lastIndexOf: { value: function () { return this.toString().lastIndexOf(...arguments) } },
754
+ split: { value: function () { return this.toString().split(...arguments) } },
755
+ at: { value: function () { return this.toString().at(...arguments) } },
756
+ length: { get: function () { return this.toString().length } },
745
757
  charCodeAt: { value: function () { return this.block.charCodeAt(...arguments) } },
746
- concat: { value: function () { return this.block.concat(...arguments) } },
747
- startsWith: { value: function () { return this.block.startsWith(...arguments) } },
748
- endsWith: { value: function () { return this.block.endsWith(...arguments) } },
749
- substring: { value: function () { return this.block.substring(...arguments) } },
750
- replace: { value: function () { return this.block.replace(...arguments) } },
751
- replaceAll: { value: function () { return this.block.replaceAll(...arguments) } },
752
- lastBlockOf: { value: function () { return helpers.lastBlockOf(this.block, ...arguments) } },
753
- [Symbol.toPrimitive]: { value: function () { return this.block; } },
758
+ children: {
759
+ get: function () {
760
+ const blocks = new Array();
761
+ let firstBlock, code = this.toString().substring(1, this.length - 1);
762
+ while (code.includes("(")) {
763
+ firstBlock = helpers.parseBlockAt(
764
+ code, code.indexOf("(")
765
+ ).toString();
766
+ blocks.push(firstBlock);
767
+ code = code.replace(firstBlock, "");
768
+ }
769
+ return blocks;
770
+ }
771
+ },
772
+ concat: { value: function () { return this.toString().concat(...arguments) } },
773
+ startsWith: { value: function () { return this.toString().startsWith(...arguments) } },
774
+ endsWith: { value: function () { return this.toString().endsWith(...arguments) } },
775
+ substring: { value: function () { return this.toString().substring(...arguments) } },
776
+ replace: { value: function () { return this.toString().replace(...arguments) } },
777
+ replaceAll: { value: function () { return this.toString().replaceAll(...arguments) } },
778
+ lastBlockOf: { value: function () { return helpers.lastBlockOf(this.toString(), ...arguments) } },
779
+ [Symbol.toPrimitive]: { value: function () { return this.toString(); } },
754
780
  })
755
781
  },
756
782
  lastBlockOf(raw, keyword, filter) {
@@ -782,6 +808,9 @@ function wat4beauty(watContent, alignIndentsWith = "\t", exportPadStart = 90) {
782
808
  parseFirstBlock(raw) {
783
809
  raw = raw.toString();
784
810
  return this.parseBlockAt(raw, raw.indexOf("(", 1));
811
+ },
812
+ lastBlockBefore(raw, begin) {
813
+ return this.parseBlockAt(raw, raw.lastIndexOf("(", raw.substring(0, begin)));
785
814
  }
786
815
  };
787
816
 
@@ -823,12 +852,9 @@ function ASYNC (wat, WAT4WASM) {
823
852
  return wat;
824
853
  }
825
854
 
826
- const DATA_BLOCK_NAME = "data";
827
- const SIZE_BLOCK_NAME = "data.size";
828
- const VIEW_BLOCK_NAME = "data.view";
829
855
  const GENERATE_DATA_VIEWER = (size, $name) => {
830
856
  return `
831
- (block ${$name}>
857
+ (block ${$name}
832
858
  (result externref)
833
859
  (global.set $wat4wasm (call $self.Array<>ext))
834
860
 
@@ -878,24 +904,186 @@ const GENERATE_DATA_VIEWER = (size, $name) => {
878
904
  )
879
905
  `;
880
906
  };
907
+ const GENERATE_TEXT_VIEWER = (size, $name) => {
908
+ return `
909
+ (block ${$name}
910
+ (result externref)
911
+ (global.set $wat4wasm (call $self.Array<>ext))
912
+
913
+ (call $self.Reflect.set<ext.i32.i32>
914
+ (global.get $wat4wasm) (i32.const 0) (i32.const ${size})
915
+ )
916
+ (global.set $wat4wasm
917
+ (call $self.Reflect.construct<ext.ext>ext
918
+ (ref.extern $self.Uint8Array<ext>)
919
+ (global.get $wat4wasm)
920
+ )
921
+ )
922
+
923
+ (if (i32.const ${size})
924
+ (then
925
+ (i32.const 0)
926
+ (i64.load (i32.const 0))
927
+ (block $copy
928
+ (i32.store (i32.const 0) (i32.const ${size}))
929
+ (loop $i--
930
+ (if (i32.load (i32.const 0))
931
+ (then
932
+ (i32.store
933
+ (i32.const 0)
934
+ (i32.sub (i32.load (i32.const 0)) (i32.const 1))
935
+ )
936
+ (memory.init ${$name}
937
+ (i32.const 4)
938
+ (i32.load (i32.const 0))
939
+ (i32.const 1)
940
+ )
941
+ (call $self.Reflect.set<ext.i32.i32>
942
+ (global.get $wat4wasm)
943
+ (i32.load (i32.const 0))
944
+ (i32.load8_u (i32.const 4))
945
+ )
946
+ (br $i--)
947
+ )
948
+ )
949
+ )
950
+ )
951
+ (i64.store (; stack stack ;))
952
+ )
953
+ )
954
+
955
+ (local.set $arguments (call $self.Array<>ext))
956
+
957
+ (call $self.Reflect.set<ext.i32.ext>
958
+ (local.get $arguments)
959
+ (i32.const 0)
960
+ (global.get $wat4wasm)
961
+ )
962
+ (call $self.Reflect.apply<ext.ext.ext>ext
963
+ (local.get $textDecoder.decode)
964
+ (local.get $textDecoder)
965
+ (local.get $arguments)
966
+ )
967
+
968
+ (global.set $wat4wasm (null))
969
+ )
970
+ `;
971
+ };
972
+ const GENERATE_HREF_VIEWER = (size, $name) => {
973
+ return `
974
+ (block ${$name}
975
+ (result externref)
976
+ (global.set $wat4wasm (call $self.Array<>ext))
977
+
978
+ (call $self.Reflect.set<ext.i32.i32>
979
+ (global.get $wat4wasm) (i32.const 0) (i32.const ${size})
980
+ )
981
+ (global.set $wat4wasm
982
+ (call $self.Reflect.construct<ext.ext>ext
983
+ (ref.extern $self.Uint8Array<ext>)
984
+ (global.get $wat4wasm)
985
+ )
986
+ )
987
+
988
+ (if (i32.const ${size})
989
+ (then
990
+ (i32.const 0)
991
+ (i64.load (i32.const 0))
992
+ (block $copy
993
+ (i32.store (i32.const 0) (i32.const ${size}))
994
+ (loop $i--
995
+ (if (i32.load (i32.const 0))
996
+ (then
997
+ (i32.store
998
+ (i32.const 0)
999
+ (i32.sub (i32.load (i32.const 0)) (i32.const 1))
1000
+ )
1001
+ (memory.init ${$name}
1002
+ (i32.const 4)
1003
+ (i32.load (i32.const 0))
1004
+ (i32.const 1)
1005
+ )
1006
+ (call $self.Reflect.set<ext.i32.i32>
1007
+ (global.get $wat4wasm)
1008
+ (i32.load (i32.const 0))
1009
+ (i32.load8_u (i32.const 4))
1010
+ )
1011
+ (br $i--)
1012
+ )
1013
+ )
1014
+ )
1015
+ )
1016
+ (i64.store (; stack stack ;))
1017
+ )
1018
+ )
1019
+
1020
+ (local.set $arguments (call $self.Array<>ext))
1021
+
1022
+ (call $self.Reflect.set<ext.i32.ext>
1023
+ (local.get $arguments)
1024
+ (i32.const 0)
1025
+ (global.get $wat4wasm)
1026
+ )
1027
+ (call $self.Reflect.set<ext.i32.ext>
1028
+ (local.get $arguments)
1029
+ (i32.const 0)
1030
+ (call $self.Reflect.apply<ext.ext.ext>ext
1031
+ (local.get $textDecoder.decode)
1032
+ (local.get $textDecoder)
1033
+ (local.get $arguments)
1034
+ )
1035
+ )
1036
+ (call $self.Reflect.set<ext.i32.ext>
1037
+ (local.get $arguments)
1038
+ (i32.const 0)
1039
+ (call $self.Reflect.construct<ext.ext>ext
1040
+ (call $self.Reflect.get<ext.ext>ext (self) (string "Blob"))
1041
+ (local.get $arguments)
1042
+ )
1043
+ )
1044
+ (call $self.Reflect.apply<ext.ext.ext>ext
1045
+ (call $self.Reflect.get<ext.ext>ext
1046
+ (call $self.Reflect.get<ext.ext>ext (self) (string "URL"))
1047
+ (string "createObjectURL")
1048
+ )
1049
+ (null)
1050
+ (local.get $arguments)
1051
+ )
1052
+
1053
+ (global.set $wat4wasm (null))
1054
+ )
1055
+ `;
1056
+ };
881
1057
  function DATA (wat, WAT4WASM) {
882
1058
  const maskSet = new helpers.MaskSet(wat);
883
1059
  const externgetter = new Map();
884
1060
  const segmentSizes = new Map();
885
1061
  const sizeRequests = new Set();
886
1062
  const viewRequests = new Set();
887
- while (maskSet.hasBlock(VIEW_BLOCK_NAME)) {
888
- const block = maskSet.lastBlockOf(VIEW_BLOCK_NAME);
1063
+ const textRequests = new Set();
1064
+ const hrefRequests = new Set();
1065
+ while (maskSet.hasBlock("data.text")) {
1066
+ const block = maskSet.lastBlockOf("data.text");
1067
+ textRequests.add(block);
1068
+ maskSet.mask(block);
1069
+ }
1070
+ while (maskSet.hasBlock("data.href")) {
1071
+ const block = maskSet.lastBlockOf("data.href");
1072
+ hrefRequests.add(block);
1073
+ maskSet.mask(block);
1074
+ }
1075
+ while (maskSet.hasBlock("data.view")) {
1076
+ const block = maskSet.lastBlockOf("data.view");
889
1077
  viewRequests.add(block);
890
1078
  maskSet.mask(block);
891
1079
  }
892
- while (maskSet.hasBlock(SIZE_BLOCK_NAME)) {
893
- const block = maskSet.lastBlockOf(SIZE_BLOCK_NAME);
1080
+ while (maskSet.hasBlock("data.size")) {
1081
+ const block = maskSet.lastBlockOf("data.size");
894
1082
  sizeRequests.add(block);
895
1083
  maskSet.mask(block);
896
1084
  }
897
- while (maskSet.hasBlock(DATA_BLOCK_NAME)) {
898
- const block = maskSet.lastBlockOf(DATA_BLOCK_NAME);
1085
+ while (maskSet.hasBlock("data")) {
1086
+ const block = maskSet.lastBlockOf("data");
899
1087
  const content = helpers.findQuotedText(block);
900
1088
  maskSet.mask(block);
901
1089
  if (helpers.hasProtocol(content) === false) {
@@ -946,6 +1134,14 @@ function DATA (wat, WAT4WASM) {
946
1134
  block.id = helpers.referenceId();
947
1135
  maskSet.update(block, block.id);
948
1136
  });
1137
+ textRequests.forEach(block => {
1138
+ block.id = helpers.referenceId();
1139
+ maskSet.update(block, block.id);
1140
+ });
1141
+ hrefRequests.forEach(block => {
1142
+ block.id = helpers.referenceId();
1143
+ maskSet.update(block, block.id);
1144
+ });
949
1145
  wat = maskSet.restore();
950
1146
  let oninit = String();
951
1147
  viewRequests.forEach(block => {
@@ -962,11 +1158,49 @@ function DATA (wat, WAT4WASM) {
962
1158
  );
963
1159
  }
964
1160
  });
1161
+ textRequests.forEach(block => {
1162
+ if (externgetter.has(block.$name) === false) {
1163
+ const size = segmentSizes.get(block.$name);
1164
+ const code = GENERATE_TEXT_VIEWER(size, block.$name);
1165
+ const growRequest = WAT4WASM_GROW_EXTERN_TABLE(wat);
1166
+ block.tableSetter = growRequest.generateSetter(code);
1167
+ wat = growRequest.modifiedRaw;
1168
+ oninit = `${oninit}\n\n${block.tableSetter}\n\n`;
1169
+ externgetter.set(
1170
+ block.$name,
1171
+ growRequest.getter.concat(` ;; ${block.$name}\n`)
1172
+ );
1173
+ }
1174
+ });
1175
+ hrefRequests.forEach(block => {
1176
+ if (externgetter.has(block.$name) === false) {
1177
+ const size = segmentSizes.get(block.$name);
1178
+ const code = GENERATE_HREF_VIEWER(size, block.$name);
1179
+ const growRequest = WAT4WASM_GROW_EXTERN_TABLE(wat);
1180
+ block.tableSetter = growRequest.generateSetter(code);
1181
+ wat = growRequest.modifiedRaw;
1182
+ oninit = `${oninit}\n\n${block.tableSetter}\n\n`;
1183
+ externgetter.set(
1184
+ block.$name,
1185
+ growRequest.getter.concat(` ;; ${block.$name}\n`)
1186
+ );
1187
+ }
1188
+ });
965
1189
  viewRequests.forEach(block => {
966
1190
  wat = wat.replaceAll(
967
1191
  block.id, externgetter.get(block.$name)
968
1192
  );
969
1193
  });
1194
+ textRequests.forEach(block => {
1195
+ wat = wat.replaceAll(
1196
+ block.id, externgetter.get(block.$name)
1197
+ );
1198
+ });
1199
+ hrefRequests.forEach(block => {
1200
+ wat = wat.replaceAll(
1201
+ block.id, externgetter.get(block.$name)
1202
+ );
1203
+ });
970
1204
  wat = APPEND_ON_EXTERN_READY(wat, oninit);
971
1205
  return wat;
972
1206
  }
@@ -1186,6 +1420,28 @@ function REF_EXTERN (wat, WAT4WASM) {
1186
1420
 
1187
1421
  const REF_FUNC_BLOCK_NAME = "ref.func";
1188
1422
  function REF_FUNC (wat, WAT4WASM) {
1423
+ const inlineFunctions = new Array();
1424
+ helpers
1425
+ .parseBlockAt(wat.toString(), 0)
1426
+ .children
1427
+ .filter(b => b.startsWith("(func"))
1428
+ .filter(b => b.substring(1).includes("(func"))
1429
+ .map(b => b.substring(5, b.length - 1).trim())
1430
+ .forEach(content => {
1431
+ const maskSet = new helpers.MaskSet(content);
1432
+ while (maskSet.hasBlock("func")) {
1433
+ const inl = maskSet.lastBlockOf("func");
1434
+ inlineFunctions.push(helpers.parseBlockAt(inl.toString(), 0));
1435
+ maskSet.mask(inl);
1436
+ }
1437
+ })
1438
+ ;
1439
+ if (inlineFunctions.length) {
1440
+ inlineFunctions.forEach(func => {
1441
+ wat = wat.replace(func.toString(), `(ref.func ${func.$name})`)
1442
+ });
1443
+ wat = helpers.append(wat, inlineFunctions.map(func => `\n\t${func}\n`).join("\n"));
1444
+ }
1189
1445
  const maskSetElem = new helpers.MaskSet(wat);
1190
1446
  const elemSegments = new Array();
1191
1447
  const needReference = new Set();