@@ -459,6 +459,37 @@ export class Module {
459459
460460 private constructor ( ) { }
461461
462+ // relocation
463+
464+ private mbase : usize = 0 ;
465+ private tbase : usize = 0 ;
466+
467+ setMemoryBase ( globalName : string | null ) : void {
468+ this . mbase = globalName ? this . allocStringCached ( globalName ) : 0 ;
469+ }
470+
471+ setTableBase ( globalName : string | null ) : void {
472+ this . tbase = globalName ? this . allocStringCached ( globalName ) : 0 ;
473+ }
474+
475+ private relocMem ( ptr : ExpressionRef ) : ExpressionRef {
476+ var mbase = this . mbase ;
477+ if ( ! mbase ) return ptr ;
478+ var ref = this . ref ;
479+ switch ( _BinaryenExpressionGetType ( ptr ) ) {
480+ default : assert ( false ) ;
481+ case NativeType . I32 : return _BinaryenBinary ( ref , BinaryOp . AddI32 , _BinaryenGlobalGet ( ref , mbase , NativeType . I32 ) , ptr ) ;
482+ case NativeType . I64 : return _BinaryenBinary ( ref , BinaryOp . AddI64 , _BinaryenGlobalGet ( ref , mbase , NativeType . I64 ) , ptr ) ;
483+ }
484+ }
485+
486+ private relocTbl ( idx : ExpressionRef ) : ExpressionRef {
487+ var tbase = this . tbase ;
488+ if ( ! tbase ) return idx ;
489+ var ref = this . ref ;
490+ return _BinaryenBinary ( ref , BinaryOp . AddI32 , _BinaryenGlobalGet ( ref , tbase , NativeType . I32 ) , idx ) ;
491+ }
492+
462493 // types
463494
464495 addFunctionType (
@@ -587,7 +618,7 @@ export class Module {
587618 offset : Index = 0 ,
588619 align : Index = bytes // naturally aligned by default
589620 ) : ExpressionRef {
590- return _BinaryenLoad ( this . ref , bytes , signed ? 1 : 0 , offset , align , type , ptr ) ;
621+ return _BinaryenLoad ( this . ref , bytes , signed ? 1 : 0 , offset , align , type , this . relocMem ( ptr ) ) ;
591622 }
592623
593624 store (
@@ -598,8 +629,7 @@ export class Module {
598629 offset : Index = 0 ,
599630 align : Index = bytes // naturally aligned by default
600631 ) : ExpressionRef {
601- if ( type < NativeType . None || type > NativeType . V128 ) throw new Error ( "here: " + type ) ;
602- return _BinaryenStore ( this . ref , bytes , offset , align , ptr , value , type ) ;
632+ return _BinaryenStore ( this . ref , bytes , offset , align , this . relocMem ( ptr ) , value , type ) ;
603633 }
604634
605635 atomic_load (
@@ -608,7 +638,7 @@ export class Module {
608638 type : NativeType ,
609639 offset : Index = 0
610640 ) : ExpressionRef {
611- return _BinaryenAtomicLoad ( this . ref , bytes , offset , type , ptr ) ;
641+ return _BinaryenAtomicLoad ( this . ref , bytes , offset , type , this . relocMem ( ptr ) ) ;
612642 }
613643
614644 atomic_store (
@@ -618,7 +648,7 @@ export class Module {
618648 type : NativeType ,
619649 offset : Index = 0
620650 ) : ExpressionRef {
621- return _BinaryenAtomicStore ( this . ref , bytes , offset , ptr , value , type ) ;
651+ return _BinaryenAtomicStore ( this . ref , bytes , offset , this . relocMem ( ptr ) , value , type ) ;
622652 }
623653
624654 atomic_rmw (
@@ -629,7 +659,7 @@ export class Module {
629659 value : ExpressionRef ,
630660 type : NativeType
631661 ) : ExpressionRef {
632- return _BinaryenAtomicRMW ( this . ref , op , bytes , offset , ptr , value , type ) ;
662+ return _BinaryenAtomicRMW ( this . ref , op , bytes , offset , this . relocMem ( ptr ) , value , type ) ;
633663 }
634664
635665 atomic_cmpxchg (
@@ -640,7 +670,7 @@ export class Module {
640670 replacement : ExpressionRef ,
641671 type : NativeType
642672 ) : ExpressionRef {
643- return _BinaryenAtomicCmpxchg ( this . ref , bytes , offset , ptr , expected , replacement , type ) ;
673+ return _BinaryenAtomicCmpxchg ( this . ref , bytes , offset , this . relocMem ( ptr ) , expected , replacement , type ) ;
644674 }
645675
646676 atomic_wait (
@@ -649,14 +679,14 @@ export class Module {
649679 timeout : ExpressionRef ,
650680 expectedType : NativeType
651681 ) : ExpressionRef {
652- return _BinaryenAtomicWait ( this . ref , ptr , expected , timeout , expectedType ) ;
682+ return _BinaryenAtomicWait ( this . ref , this . relocMem ( ptr ) , expected , timeout , expectedType ) ;
653683 }
654684
655685 atomic_notify (
656686 ptr : ExpressionRef ,
657687 notifyCount : ExpressionRef
658688 ) : ExpressionRef {
659- return _BinaryenAtomicNotify ( this . ref , ptr , notifyCount ) ;
689+ return _BinaryenAtomicNotify ( this . ref , this . relocMem ( ptr ) , notifyCount ) ;
660690 }
661691
662692 atomic_fence ( ) : ExpressionRef {
@@ -798,8 +828,8 @@ export class Module {
798828 var cArr = allocPtrArray ( operands ) ;
799829 try {
800830 return isReturn
801- ? _BinaryenReturnCallIndirect ( this . ref , index , cArr , operands && operands . length || 0 , cStr )
802- : _BinaryenCallIndirect ( this . ref , index , cArr , operands && operands . length || 0 , cStr ) ;
831+ ? _BinaryenReturnCallIndirect ( this . ref , this . relocTbl ( index ) , cArr , operands && operands . length || 0 , cStr )
832+ : _BinaryenCallIndirect ( this . ref , this . relocTbl ( index ) , cArr , operands && operands . length || 0 , cStr ) ;
803833 } finally {
804834 memory . free ( cArr ) ;
805835 }
@@ -1151,6 +1181,8 @@ export class Module {
11511181 : this . i32 ( i64_low ( offset ) ) ;
11521182 sizs [ i ] = buffer . length ;
11531183 }
1184+ var mbase = this . mbase ;
1185+ if ( mbase ) for ( let i = 0 ; i < k ; ++ i ) offs [ i ] = this . relocMem ( offs [ i ] ) ;
11541186 var cArr1 = allocI32Array ( segs ) ;
11551187 var cArr2 = allocU8Array ( psvs ) ;
11561188 var cArr3 = allocI32Array ( offs ) ;
@@ -1176,6 +1208,8 @@ export class Module {
11761208 for ( let i = 0 ; i < numNames ; ++ i ) {
11771209 names [ i ] = this . allocStringCached ( funcs [ i ] ) ;
11781210 }
1211+ // FIXME: Relocating the function table is not possible currently due to
1212+ // the C-API only accepting an array of names, but no offsets.
11791213 var cArr = allocI32Array ( names ) ;
11801214 try {
11811215 _BinaryenSetFunctionTable ( this . ref , initial , maximum , cArr , numNames ) ;
0 commit comments