@@ -34,13 +34,22 @@ const ARRAYBUFFERVIEW_SIZE = 12;
34
34
const ARRAY_LENGTH_OFFSET = 12 ;
35
35
const ARRAY_SIZE = 16 ;
36
36
37
+ const E_NO_EXPORT_TABLE = "Operation requires compiling with --exportTable" ;
38
+ const E_NO_EXPORT_RUNTIME = "Operation requires compiling with --exportRuntime" ;
39
+ const F_NO_EXPORT_RUNTIME = ( ) => { throw Error ( E_NO_EXPORT_RUNTIME ) ; } ;
40
+
37
41
const BIGINT = typeof BigUint64Array !== "undefined" ;
38
42
const THIS = Symbol ( ) ;
39
43
40
44
const STRING_SMALLSIZE = 192 ; // break-even point in V8
41
45
const STRING_CHUNKSIZE = 1024 ; // mitigate stack overflow
42
46
const utf16 = new TextDecoder ( "utf-16le" , { fatal : true } ) ; // != wtf16
43
47
48
+ /** polyfill for Object.hasOwn */
49
+ Object . hasOwn = Object . hasOwn || function ( obj , prop ) {
50
+ return Object . prototype . hasOwnProperty . call ( obj , prop ) ;
51
+ } ;
52
+
44
53
/** Gets a string from memory. */
45
54
function getStringImpl ( buffer , ptr ) {
46
55
let len = new Uint32Array ( buffer ) [ ptr + SIZE_OFFSET >>> 2 ] >>> 1 ;
@@ -83,51 +92,44 @@ function preInstantiate(imports) {
83
92
return extendedExports ;
84
93
}
85
94
86
- const E_NOEXPORTRUNTIME = "Operation requires compiling with --exportRuntime" ;
87
- const F_NOEXPORTRUNTIME = function ( ) { throw Error ( E_NOEXPORTRUNTIME ) ; } ;
88
-
89
95
/** Prepares the final module once instantiation is complete. */
90
96
function postInstantiate ( extendedExports , instance ) {
91
97
const exports = instance . exports ;
92
98
const memory = exports . memory ;
93
99
const table = exports . table ;
94
- const __new = exports . __new || F_NOEXPORTRUNTIME ;
95
- const __pin = exports . __pin || F_NOEXPORTRUNTIME ;
96
- const __unpin = exports . __unpin || F_NOEXPORTRUNTIME ;
97
- const __collect = exports . __collect || F_NOEXPORTRUNTIME ;
100
+ const __new = exports . __new || F_NO_EXPORT_RUNTIME ;
101
+ const __pin = exports . __pin || F_NO_EXPORT_RUNTIME ;
102
+ const __unpin = exports . __unpin || F_NO_EXPORT_RUNTIME ;
103
+ const __collect = exports . __collect || F_NO_EXPORT_RUNTIME ;
98
104
const __rtti_base = exports . __rtti_base ;
99
- const getRttiCount = __rtti_base
100
- ? function ( arr ) { return arr [ __rtti_base >>> 2 ] ; }
101
- : F_NOEXPORTRUNTIME ;
105
+ const getRttiCount = __rtti_base ? arr => arr [ __rtti_base >>> 2 ] : F_NO_EXPORT_RUNTIME ;
102
106
103
107
extendedExports . __new = __new ;
104
108
extendedExports . __pin = __pin ;
105
109
extendedExports . __unpin = __unpin ;
106
110
extendedExports . __collect = __collect ;
107
111
108
112
/** Gets the runtime type info for the given id. */
109
- function getInfo ( id ) {
113
+ function getRttInfo ( id ) {
114
+ const U32 = new Uint32Array ( memory . buffer ) ;
115
+ if ( ( id >>>= 0 ) >= getRttiCount ( U32 ) ) throw Error ( `invalid id: ${ id } ` ) ;
116
+ return U32 [ ( __rtti_base + 4 >>> 2 ) + ( id << 1 ) ] ;
117
+ }
118
+
119
+ /** Gets the runtime base id for the given id. */
120
+ function getRttBase ( id ) {
110
121
const U32 = new Uint32Array ( memory . buffer ) ;
111
- const count = getRttiCount ( U32 ) ;
112
- if ( ( id >>>= 0 ) >= count ) throw Error ( `invalid id: ${ id } ` ) ;
113
- return U32 [ ( __rtti_base + 4 >>> 2 ) + id * 2 ] ;
122
+ if ( ( id >>>= 0 ) >= getRttiCount ( U32 ) ) throw Error ( `invalid id: ${ id } ` ) ;
123
+ return U32 [ ( __rtti_base + 4 >>> 2 ) + ( id << 1 ) + 1 ] ;
114
124
}
115
125
116
126
/** Gets and validate runtime type info for the given id for array like objects */
117
127
function getArrayInfo ( id ) {
118
- const info = getInfo ( id ) ;
128
+ const info = getRttInfo ( id ) ;
119
129
if ( ! ( info & ( ARRAYBUFFERVIEW | ARRAY | STATICARRAY ) ) ) throw Error ( `not an array: ${ id } , flags=${ info } ` ) ;
120
130
return info ;
121
131
}
122
132
123
- /** Gets the runtime base id for the given id. */
124
- function getBase ( id ) {
125
- const U32 = new Uint32Array ( memory . buffer ) ;
126
- const count = getRttiCount ( U32 ) ;
127
- if ( ( id >>>= 0 ) >= count ) throw Error ( `invalid id: ${ id } ` ) ;
128
- return U32 [ ( __rtti_base + 4 >>> 2 ) + id * 2 + 1 ] ;
129
- }
130
-
131
133
/** Gets the runtime alignment of a collection's values. */
132
134
function getValueAlign ( info ) {
133
135
return 31 - Math . clz32 ( ( info >>> VAL_ALIGN_OFFSET ) & 31 ) ; // -1 if none
@@ -263,6 +265,15 @@ function postInstantiate(extendedExports, instance) {
263
265
264
266
extendedExports . __getArrayBuffer = __getArrayBuffer ;
265
267
268
+ /** Gets a function from poiner which contain table's index. */
269
+ function __getFunction ( ptr ) {
270
+ if ( ! table ) throw Error ( E_NO_EXPORT_TABLE ) ;
271
+ const index = new Uint32Array ( memory . buffer ) [ ptr >>> 2 ] ;
272
+ return table . get ( index ) ;
273
+ }
274
+
275
+ extendedExports . __getFunction = __getFunction ;
276
+
266
277
/** Copies a typed array's values from the module's memory. */
267
278
function getTypedArray ( Type , alignLog2 , ptr ) {
268
279
return new Type ( getTypedArrayView ( Type , alignLog2 , ptr ) ) ;
@@ -309,7 +320,7 @@ function postInstantiate(extendedExports, instance) {
309
320
if ( id <= getRttiCount ( U32 ) ) {
310
321
do {
311
322
if ( id == baseId ) return true ;
312
- id = getBase ( id ) ;
323
+ id = getRttBase ( id ) ;
313
324
} while ( id ) ;
314
325
}
315
326
return false ;
@@ -373,14 +384,13 @@ export function demangle(exports, extendedExports = {}) {
373
384
const setArgumentsLength = exports [ "__argumentsLength" ]
374
385
? length => { exports [ "__argumentsLength" ] . value = length ; }
375
386
: exports [ "__setArgumentsLength" ] || exports [ "__setargc" ] || ( ( ) => { /* nop */ } ) ;
376
- for ( let internalName in exports ) {
377
- if ( ! Object . prototype . hasOwnProperty . call ( exports , internalName ) ) continue ;
387
+ for ( let internalName of Object . keys ( exports ) ) {
378
388
const elem = exports [ internalName ] ;
379
389
let parts = internalName . split ( "." ) ;
380
390
let curr = extendedExports ;
381
391
while ( parts . length > 1 ) {
382
392
let part = parts . shift ( ) ;
383
- if ( ! Object . prototype . hasOwnProperty . call ( curr , part ) ) curr [ part ] = { } ;
393
+ if ( ! Object . hasOwn ( curr , part ) ) curr [ part ] = { } ;
384
394
curr = curr [ part ] ;
385
395
}
386
396
let name = parts [ 0 ] ;
@@ -406,7 +416,7 @@ export function demangle(exports, extendedExports = {}) {
406
416
name = name . substring ( hash + 1 ) ;
407
417
curr = curr [ className ] . prototype ;
408
418
if ( / ^ ( g e t | s e t ) : / . test ( name ) ) {
409
- if ( ! Object . prototype . hasOwnProperty . call ( curr , name = name . substring ( 4 ) ) ) {
419
+ if ( ! Object . hasOwn ( curr , name = name . substring ( 4 ) ) ) {
410
420
let getter = exports [ internalName . replace ( "set:" , "get:" ) ] ;
411
421
let setter = exports [ internalName . replace ( "get:" , "set:" ) ] ;
412
422
Object . defineProperty ( curr , name , {
@@ -417,7 +427,7 @@ export function demangle(exports, extendedExports = {}) {
417
427
}
418
428
} else {
419
429
if ( name === 'constructor' ) {
420
- ( curr [ name ] = ( ...args ) => {
430
+ ( curr [ name ] = function ( ...args ) {
421
431
setArgumentsLength ( args . length ) ;
422
432
return elem ( ...args ) ;
423
433
} ) . original = elem ;
@@ -430,7 +440,7 @@ export function demangle(exports, extendedExports = {}) {
430
440
}
431
441
} else {
432
442
if ( / ^ ( g e t | s e t ) : / . test ( name ) ) {
433
- if ( ! Object . prototype . hasOwnProperty . call ( curr , name = name . substring ( 4 ) ) ) {
443
+ if ( ! Object . hasOwn ( curr , name = name . substring ( 4 ) ) ) {
434
444
Object . defineProperty ( curr , name , {
435
445
get : exports [ internalName . replace ( "set:" , "get:" ) ] ,
436
446
set : exports [ internalName . replace ( "get:" , "set:" ) ] ,
0 commit comments