@@ -1167,22 +1167,45 @@ export class Module {
11671167 ) : void {
11681168 var cStr = this . allocStringCached ( exportName ) ;
11691169 var k = segments . length ;
1170- var segs = new Array < usize > ( k ) ;
1171- var psvs = new Array < i8 > ( k ) ;
1172- var offs = new Array < ExpressionRef > ( k ) ;
1173- var sizs = new Array < Index > ( k ) ;
1174- for ( let i = 0 ; i < k ; ++ i ) {
1175- let buffer = segments [ i ] . buffer ;
1176- let offset = segments [ i ] . offset ;
1177- segs [ i ] = allocU8Array ( buffer ) ;
1178- psvs [ i ] = 0 ; // no passive segments currently
1179- offs [ i ] = target == Target . WASM64
1180- ? this . i64 ( i64_low ( offset ) , i64_high ( offset ) )
1181- : this . i32 ( i64_low ( offset ) ) ;
1182- sizs [ i ] = buffer . length ;
1183- }
11841170 var mbase = this . mbase ;
1185- if ( mbase ) for ( let i = 0 ; i < k ; ++ i ) offs [ i ] = this . relocMem ( offs [ i ] ) ;
1171+ var segs : usize [ ] , psvs : i8 [ ] , offs : ExpressionRef [ ] , sizs : Index [ ] ;
1172+ if ( mbase ) {
1173+ // Offset expressions cannot currently use an addition but are restricted
1174+ // to a constant or a global.get, so make one large memory segment in the
1175+ // relocation case that starts exactly at the value of __memory_base.
1176+ let maxOffset = i64_zero ;
1177+ for ( let i = 0 ; i < k ; ++ i ) {
1178+ let segment = segments [ i ] ;
1179+ let endOffset = i64_add ( segment . offset , i64_new ( segment . buffer . length ) ) ;
1180+ if ( i64_gt ( endOffset , maxOffset ) ) maxOffset = endOffset ;
1181+ }
1182+ assert ( ! i64_high ( maxOffset ) ) ; // TODO: WASM64
1183+ let buffer = new Uint8Array ( i64_low ( maxOffset ) ) ;
1184+ for ( let i = 0 ; i < k ; ++ i ) {
1185+ let segment = segments [ i ] ;
1186+ buffer . set ( segment . buffer , i64_low ( segment . offset ) ) ;
1187+ }
1188+ segs = [ allocU8Array ( buffer ) ] ;
1189+ psvs = [ 0 ] ;
1190+ offs = [ _BinaryenGlobalGet ( this . ref , mbase , target == Target . WASM64 ? NativeType . I64 : NativeType . I32 ) ] ;
1191+ sizs = [ buffer . length ] ;
1192+ k = 1 ;
1193+ } else {
1194+ segs = new Array < usize > ( k ) ;
1195+ psvs = new Array < i8 > ( k ) ;
1196+ offs = new Array < ExpressionRef > ( k ) ;
1197+ sizs = new Array < Index > ( k ) ;
1198+ for ( let i = 0 ; i < k ; ++ i ) {
1199+ let buffer = segments [ i ] . buffer ;
1200+ let offset = segments [ i ] . offset ;
1201+ segs [ i ] = allocU8Array ( buffer ) ;
1202+ psvs [ i ] = 0 ; // no passive segments currently
1203+ offs [ i ] = target == Target . WASM64
1204+ ? this . i64 ( i64_low ( offset ) , i64_high ( offset ) )
1205+ : this . i32 ( i64_low ( offset ) ) ;
1206+ sizs [ i ] = buffer . length ;
1207+ }
1208+ }
11861209 var cArr1 = allocI32Array ( segs ) ;
11871210 var cArr2 = allocU8Array ( psvs ) ;
11881211 var cArr3 = allocI32Array ( offs ) ;
@@ -1796,7 +1819,7 @@ export class Relooper {
17961819// helpers
17971820// can't do stack allocation here: STACKTOP is a global in WASM but a hidden variable in asm.js
17981821
1799- function allocU8Array ( u8s : Uint8Array | null ) : usize {
1822+ function allocU8Array ( u8s : u8 [ ] | null ) : usize {
18001823 if ( ! u8s ) return 0 ;
18011824 var numValues = u8s . length ;
18021825 var ptr = memory . allocate ( numValues ) ;
0 commit comments