@@ -119,6 +119,7 @@ export class JSBuilder extends ExportsWalker {
119119 private needsRetain : bool = false ;
120120 private needsRelease : bool = false ;
121121 private needsNotNull : bool = false ;
122+ private needsStoreRef : bool = false ;
122123
123124 private deferredLifts : Set < Element > = new Set ( ) ;
124125 private deferredLowers : Set < Element > = new Set ( ) ;
@@ -851,6 +852,12 @@ export class JSBuilder extends ExportsWalker {
851852 }
852853` ) ;
853854 }
855+ if ( this . needsStoreRef ) {
856+ sb . push ( ` function __store_ref(pointer, value) {
857+ new Uint32Array(memory.buffer)[pointer >>> 2] = value;
858+ }
859+ ` ) ;
860+ }
854861
855862 let exportStart = options . exportStart ;
856863 if ( exportStart ) {
@@ -1177,36 +1184,44 @@ export class JSBuilder extends ExportsWalker {
11771184 skipTail = false ;
11781185 }
11791186 if ( valueType . isInternalReference ) {
1187+ // The RHS is typically another lowering to memory, which may trigger
1188+ // memory growth. Use a helper closure to delay evaluation of `memory`.
1189+ this . needsStoreRef = true ;
1190+ sb . push ( "__store_ref(" ) ;
1191+ sb . push ( targetName ) ;
1192+ sb . push ( ", " ) ;
1193+ this . makeLowerToValue ( valueName , valueType , sb ) ;
1194+ sb . push ( ")" ) ;
1195+ if ( ! skipTail ) sb . push ( "; }" ) ;
1196+ return ;
1197+ }
1198+ if ( valueType == Type . i8 ) {
1199+ sb . push ( "new Int8Array(memory.buffer)[" ) ;
1200+ } else if ( valueType == Type . u8 || valueType == Type . bool ) {
1201+ sb . push ( "new Uint8Array(memory.buffer)[" ) ;
1202+ } else if ( valueType == Type . i16 ) {
1203+ sb . push ( "new Int16Array(memory.buffer)[" ) ;
1204+ } else if ( valueType == Type . u16 ) {
1205+ sb . push ( "new Uint16Array(memory.buffer)[" ) ;
1206+ } else if ( valueType == Type . i32 || valueType == Type . isize32 ) {
1207+ sb . push ( "new Int32Array(memory.buffer)[" ) ;
1208+ } else if ( valueType == Type . u32 || valueType == Type . usize32 ) {
11801209 sb . push ( "new Uint32Array(memory.buffer)[" ) ;
1210+ } else if ( valueType == Type . i64 || valueType == Type . isize64 ) {
1211+ sb . push ( "new BigInt64Array(memory.buffer)[" ) ;
1212+ } else if ( valueType == Type . u64 || valueType == Type . usize64 ) {
1213+ sb . push ( "new BigUint64Array(memory.buffer)[" ) ;
1214+ } else if ( valueType == Type . f32 ) {
1215+ sb . push ( "new Float32Array(memory.buffer)[" ) ;
1216+ } else if ( valueType == Type . f64 ) {
1217+ sb . push ( "new Float64Array(memory.buffer)[" ) ;
11811218 } else {
1182- if ( valueType == Type . i8 ) {
1183- sb . push ( "new Int8Array(memory.buffer)[" ) ;
1184- } else if ( valueType == Type . u8 || valueType == Type . bool ) {
1185- sb . push ( "new Uint8Array(memory.buffer)[" ) ;
1186- } else if ( valueType == Type . i16 ) {
1187- sb . push ( "new Int16Array(memory.buffer)[" ) ;
1188- } else if ( valueType == Type . u16 ) {
1189- sb . push ( "new Uint16Array(memory.buffer)[" ) ;
1190- } else if ( valueType == Type . i32 || valueType == Type . isize32 ) {
1191- sb . push ( "new Int32Array(memory.buffer)[" ) ;
1192- } else if ( valueType == Type . u32 || valueType == Type . usize32 ) {
1193- sb . push ( "new Uint32Array(memory.buffer)[" ) ;
1194- } else if ( valueType == Type . i64 || valueType == Type . isize64 ) {
1195- sb . push ( "new BigInt64Array(memory.buffer)[" ) ;
1196- } else if ( valueType == Type . u64 || valueType == Type . usize64 ) {
1197- sb . push ( "new BigUint64Array(memory.buffer)[" ) ;
1198- } else if ( valueType == Type . f32 ) {
1199- sb . push ( "new Float32Array(memory.buffer)[" ) ;
1200- } else if ( valueType == Type . f64 ) {
1201- sb . push ( "new Float64Array(memory.buffer)[" ) ;
1219+ if ( skipTail ) {
1220+ sb . push ( "(() => { throw Error(\"unsupported type\") })()" ) ;
12021221 } else {
1203- if ( skipTail ) {
1204- sb . push ( "(() => { throw Error(\"unsupported type\") })()" ) ;
1205- } else {
1206- sb . push ( "throw Error(\"unsupported type\"); }" ) ;
1207- }
1208- return ;
1222+ sb . push ( "throw Error(\"unsupported type\"); }" ) ;
12091223 }
1224+ return ;
12101225 }
12111226 sb . push ( targetName ) ;
12121227 sb . push ( " >>> " ) ;
0 commit comments