@@ -34,13 +34,22 @@ const ARRAYBUFFERVIEW_SIZE = 12;
3434const ARRAY_LENGTH_OFFSET = 12 ;
3535const ARRAY_SIZE = 16 ;
3636
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+
3741const BIGINT = typeof BigUint64Array !== "undefined" ;
3842const THIS = Symbol ( ) ;
3943
4044const STRING_SMALLSIZE = 192 ; // break-even point in V8
4145const STRING_CHUNKSIZE = 1024 ; // mitigate stack overflow
4246const utf16 = new TextDecoder ( "utf-16le" , { fatal : true } ) ; // != wtf16
4347
48+ /** polyfill for Object.hasOwn */
49+ Object . hasOwn = Object . hasOwn || function ( obj , prop ) {
50+ return Object . prototype . hasOwnProperty . call ( obj , prop ) ;
51+ } ;
52+
4453/** Gets a string from memory. */
4554function getStringImpl ( buffer , ptr ) {
4655 let len = new Uint32Array ( buffer ) [ ptr + SIZE_OFFSET >>> 2 ] >>> 1 ;
@@ -83,51 +92,44 @@ function preInstantiate(imports) {
8392 return extendedExports ;
8493}
8594
86- const E_NOEXPORTRUNTIME = "Operation requires compiling with --exportRuntime" ;
87- const F_NOEXPORTRUNTIME = function ( ) { throw Error ( E_NOEXPORTRUNTIME ) ; } ;
88-
8995/** Prepares the final module once instantiation is complete. */
9096function postInstantiate ( extendedExports , instance ) {
9197 const exports = instance . exports ;
9298 const memory = exports . memory ;
9399 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 ;
98104 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 ;
102106
103107 extendedExports . __new = __new ;
104108 extendedExports . __pin = __pin ;
105109 extendedExports . __unpin = __unpin ;
106110 extendedExports . __collect = __collect ;
107111
108112 /** 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 ) {
110121 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 ] ;
114124 }
115125
116126 /** Gets and validate runtime type info for the given id for array like objects */
117127 function getArrayInfo ( id ) {
118- const info = getInfo ( id ) ;
128+ const info = getRttInfo ( id ) ;
119129 if ( ! ( info & ( ARRAYBUFFERVIEW | ARRAY | STATICARRAY ) ) ) throw Error ( `not an array: ${ id } , flags=${ info } ` ) ;
120130 return info ;
121131 }
122132
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-
131133 /** Gets the runtime alignment of a collection's values. */
132134 function getValueAlign ( info ) {
133135 return 31 - Math . clz32 ( ( info >>> VAL_ALIGN_OFFSET ) & 31 ) ; // -1 if none
@@ -263,6 +265,15 @@ function postInstantiate(extendedExports, instance) {
263265
264266 extendedExports . __getArrayBuffer = __getArrayBuffer ;
265267
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+
266277 /** Copies a typed array's values from the module's memory. */
267278 function getTypedArray ( Type , alignLog2 , ptr ) {
268279 return new Type ( getTypedArrayView ( Type , alignLog2 , ptr ) ) ;
@@ -309,7 +320,7 @@ function postInstantiate(extendedExports, instance) {
309320 if ( id <= getRttiCount ( U32 ) ) {
310321 do {
311322 if ( id == baseId ) return true ;
312- id = getBase ( id ) ;
323+ id = getRttBase ( id ) ;
313324 } while ( id ) ;
314325 }
315326 return false ;
@@ -373,14 +384,13 @@ export function demangle(exports, extendedExports = {}) {
373384 const setArgumentsLength = exports [ "__argumentsLength" ]
374385 ? length => { exports [ "__argumentsLength" ] . value = length ; }
375386 : 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 ) ) {
378388 const elem = exports [ internalName ] ;
379389 let parts = internalName . split ( "." ) ;
380390 let curr = extendedExports ;
381391 while ( parts . length > 1 ) {
382392 let part = parts . shift ( ) ;
383- if ( ! Object . prototype . hasOwnProperty . call ( curr , part ) ) curr [ part ] = { } ;
393+ if ( ! Object . hasOwn ( curr , part ) ) curr [ part ] = { } ;
384394 curr = curr [ part ] ;
385395 }
386396 let name = parts [ 0 ] ;
@@ -406,7 +416,7 @@ export function demangle(exports, extendedExports = {}) {
406416 name = name . substring ( hash + 1 ) ;
407417 curr = curr [ className ] . prototype ;
408418 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 ) ) ) {
410420 let getter = exports [ internalName . replace ( "set:" , "get:" ) ] ;
411421 let setter = exports [ internalName . replace ( "get:" , "set:" ) ] ;
412422 Object . defineProperty ( curr , name , {
@@ -417,7 +427,7 @@ export function demangle(exports, extendedExports = {}) {
417427 }
418428 } else {
419429 if ( name === 'constructor' ) {
420- ( curr [ name ] = ( ...args ) => {
430+ ( curr [ name ] = function ( ...args ) {
421431 setArgumentsLength ( args . length ) ;
422432 return elem ( ...args ) ;
423433 } ) . original = elem ;
@@ -430,7 +440,7 @@ export function demangle(exports, extendedExports = {}) {
430440 }
431441 } else {
432442 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 ) ) ) {
434444 Object . defineProperty ( curr , name , {
435445 get : exports [ internalName . replace ( "set:" , "get:" ) ] ,
436446 set : exports [ internalName . replace ( "get:" , "set:" ) ] ,
0 commit comments