@@ -37,6 +37,17 @@ let gensym_label = s => {
3737};
3838let reset_labels = () => gensym_counter := 0 ;
3939
40+ let data_segments : ref ((int , list (Memory . segment ))) = ref ((0 , [] ));
41+ let push_data_segment = segment => {
42+ let (count , segments ) = data_segments^;
43+ data_segments := (count + 1 , [ segment, ... segments] );
44+ };
45+ let get_data_segment_count = () => {
46+ let (count , _ ) = data_segments^;
47+ count;
48+ };
49+ let reset_data_segments = () => data_segments := (0 , [] );
50+
4051/* Number of swap variables to allocate */
4152let swap_slots_i32 = [| Type . int32, Type . int32, Type . int32|] ;
4253let swap_slots_i64 = [| Type . int64|] ;
@@ -121,6 +132,7 @@ let rec resolve_func = (~env, name) => {
121132
122133let reset = () => {
123134 reset_labels() ;
135+ reset_data_segments() ;
124136};
125137
126138let get_runtime_heap_start = wasm_mod =>
@@ -1271,45 +1283,93 @@ let call_lambda =
12711283};
12721284
12731285let allocate_byte_like_from_buffer = (wasm_mod, env, buf, tag, label) => {
1274- let ints_to_push : list (int64 ) = buf_to_ints(buf);
12751286 let get_swap = () => get_swap(wasm_mod, env, 0 );
12761287 let tee_swap = tee_swap(wasm_mod, env, 0 );
1277- let preamble = [
1278- store(
1279- ~offset= 0 ,
1280- wasm_mod,
1281- tee_swap(
1282- heap_allocate(wasm_mod, env, 2 + 2 * List . length(ints_to_push)),
1283- ),
1284- Expression . Const . make(
1285- wasm_mod,
1286- const_int32(tag_val_of_heap_tag_type(tag)),
1287- ),
1288- ),
1289- store(
1290- ~offset= 4 ,
1288+ if (Config . bulk_memory^ ) {
1289+ let segment_offset = get_data_segment_count() ;
1290+ let data_size = Buffer . length(buf);
1291+ Memory . (
1292+ push_data_segment({
1293+ data: Buffer . to_bytes(buf),
1294+ kind: Passive ,
1295+ size: data_size,
1296+ })
1297+ );
1298+ Expression . Block . make(
12911299 wasm_mod,
1292- get_swap() ,
1293- Expression . Const . make(wasm_mod, const_int32 @@ Buffer . length(buf)),
1294- ),
1295- ] ;
1296- let elts =
1297- List . mapi(
1298- (idx, i: int64 ) =>
1300+ gensym_label(label),
1301+ [
1302+ store(
1303+ ~offset= 0 ,
1304+ wasm_mod,
1305+ // compute number of words (add 3 to account for floored division)
1306+ tee_swap(heap_allocate(wasm_mod, env, 2 + (data_size + 3 ) / 4 )),
1307+ Expression . Const . make(
1308+ wasm_mod,
1309+ const_int32(tag_val_of_heap_tag_type(tag)),
1310+ ),
1311+ ),
12991312 store(
1300- ~ty= Type . int64,
1301- ~offset= 8 * (idx + 1 ),
1313+ ~offset= 4 ,
13021314 wasm_mod,
13031315 get_swap() ,
1304- Expression . Const . make(wasm_mod, wrap_int64(i)),
1316+ Expression . Const . make(wasm_mod, const_int32 @@ data_size),
1317+ ),
1318+ Expression . Memory_init . make(
1319+ wasm_mod,
1320+ segment_offset,
1321+ Expression . Binary . make(
1322+ wasm_mod,
1323+ Op . add_int32,
1324+ get_swap() ,
1325+ Expression . Const . make(wasm_mod, const_int32(8 )),
1326+ ),
1327+ Expression . Const . make(wasm_mod, const_int32(0 )),
1328+ Expression . Const . make(wasm_mod, const_int32(data_size)),
1329+ grain_memory,
1330+ ),
1331+ get_swap() ,
1332+ ] ,
1333+ );
1334+ } else {
1335+ let ints_to_push : list (int64 ) = buf_to_ints(buf);
1336+ let preamble = [
1337+ store(
1338+ ~offset= 0 ,
1339+ wasm_mod,
1340+ tee_swap(
1341+ heap_allocate(wasm_mod, env, 2 + 2 * List . length(ints_to_push)),
1342+ ),
1343+ Expression . Const . make(
1344+ wasm_mod,
1345+ const_int32(tag_val_of_heap_tag_type(tag)),
13051346 ),
1306- ints_to_push,
1347+ ),
1348+ store(
1349+ ~offset= 4 ,
1350+ wasm_mod,
1351+ get_swap() ,
1352+ Expression . Const . make(wasm_mod, const_int32 @@ Buffer . length(buf)),
1353+ ),
1354+ ] ;
1355+ let elts =
1356+ List . mapi(
1357+ (idx, i: int64 ) =>
1358+ store(
1359+ ~ty= Type . int64,
1360+ ~offset= 8 * (idx + 1 ),
1361+ wasm_mod,
1362+ get_swap() ,
1363+ Expression . Const . make(wasm_mod, wrap_int64(i)),
1364+ ),
1365+ ints_to_push,
1366+ );
1367+ Expression . Block . make(
1368+ wasm_mod,
1369+ gensym_label(label),
1370+ List . concat([ preamble, elts, [ get_swap() ]] ),
13071371 );
1308- Expression . Block . make(
1309- wasm_mod,
1310- gensym_label(label),
1311- List . concat([ preamble, elts, [ get_swap() ]] ),
1312- );
1372+ };
13131373};
13141374
13151375let allocate_byte_like_uninitialized = (wasm_mod, env, size, tag, label) => {
@@ -3405,7 +3465,7 @@ let compile_type_metadata = (wasm_mod, env, prog) => {
34053465 | (initial_memory , None ) => (initial_memory, Memory . unlimited)
34063466 };
34073467
3408- let data_segments =
3468+ let segments =
34093469 switch (metadata_tbl_data) {
34103470 | Some (data ) => [
34113471 Memory . {
@@ -3423,6 +3483,14 @@ let compile_type_metadata = (wasm_mod, env, prog) => {
34233483 ]
34243484 | None => []
34253485 };
3486+ let data_segments =
3487+ if (Config . bulk_memory^ ) {
3488+ let (_ , data_segments ) = data_segments^;
3489+ List . rev_append(data_segments, segments);
3490+ } else {
3491+ segments;
3492+ };
3493+
34263494 Memory . set_memory(
34273495 wasm_mod,
34283496 initial_memory,
@@ -3488,8 +3556,6 @@ let compile_wasm_module =
34883556 Option . is_none(Grain_utils . Config . memory_base^ ),
34893557 );
34903558
3491- compile_type_metadata(wasm_mod, env, prog);
3492-
34933559 ignore @@
34943560 Table . add_table(
34953561 wasm_mod,
@@ -3526,6 +3592,8 @@ let compile_wasm_module =
35263592
35273593 ignore @@ compile_main(wasm_mod, env, prog);
35283594
3595+ compile_type_metadata(wasm_mod, env, prog);
3596+
35293597 validate_module(~name? , wasm_mod);
35303598
35313599 switch (Config . profile^ ) {
0 commit comments