@@ -34,6 +34,17 @@ let gensym_label = s => {
3434};
3535let reset_labels = () => gensym_counter := 0 ;
3636
37+ let data_segments : ref ((int , list (Memory . segment ))) = ref ((0 , [] ));
38+ let push_data_segment = segment => {
39+ let (count , segments ) = data_segments^;
40+ data_segments := (count + 1 , [ segment, ... segments] );
41+ };
42+ let get_data_segment_count = () => {
43+ let (count , _ ) = data_segments^;
44+ count;
45+ };
46+ let reset_data_segments = () => data_segments := (0 , [] );
47+
3748/* Number of swap variables to allocate */
3849let swap_slots_i32 = [| Type . int32, Type . int32, Type . int32|] ;
3950let swap_slots_i64 = [| Type . int64|] ;
@@ -117,6 +128,7 @@ let rec resolve_func = (~env, name) => {
117128
118129let reset = () => {
119130 reset_labels() ;
131+ reset_data_segments() ;
120132};
121133
122134let get_runtime_heap_start = wasm_mod =>
@@ -1267,45 +1279,93 @@ let call_lambda =
12671279};
12681280
12691281let allocate_byte_like_from_buffer = (wasm_mod, env, buf, tag, label) => {
1270- let ints_to_push : list (int64 ) = buf_to_ints(buf);
12711282 let get_swap = () => get_swap(wasm_mod, env, 0 );
12721283 let tee_swap = tee_swap(wasm_mod, env, 0 );
1273- let preamble = [
1274- store(
1275- ~offset= 0 ,
1276- wasm_mod,
1277- tee_swap(
1278- heap_allocate(wasm_mod, env, 2 + 2 * List . length(ints_to_push)),
1279- ),
1280- Expression . Const . make(
1281- wasm_mod,
1282- const_int32(tag_val_of_heap_tag_type(tag)),
1283- ),
1284- ),
1285- store(
1286- ~offset= 4 ,
1284+ if (Config . bulk_memory^ ) {
1285+ let segment_offset = get_data_segment_count() ;
1286+ let data_size = Buffer . length(buf);
1287+ Memory . (
1288+ push_data_segment({
1289+ data: Buffer . to_bytes(buf),
1290+ kind: Passive ,
1291+ size: data_size,
1292+ })
1293+ );
1294+ Expression . Block . make(
12871295 wasm_mod,
1288- get_swap() ,
1289- Expression . Const . make(wasm_mod, const_int32 @@ Buffer . length(buf)),
1290- ),
1291- ] ;
1292- let elts =
1293- List . mapi(
1294- (idx, i: int64 ) =>
1296+ gensym_label(label),
1297+ [
12951298 store(
1296- ~ty= Type . int64,
1297- ~offset= 8 * (idx + 1 ),
1299+ ~offset= 0 ,
1300+ wasm_mod,
1301+ // compute number of words (add 3 to account for floored division)
1302+ tee_swap(heap_allocate(wasm_mod, env, 2 + (data_size + 3 ) / 4 )),
1303+ Expression . Const . make(
1304+ wasm_mod,
1305+ const_int32(tag_val_of_heap_tag_type(tag)),
1306+ ),
1307+ ),
1308+ store(
1309+ ~offset= 4 ,
12981310 wasm_mod,
12991311 get_swap() ,
1300- Expression . Const . make(wasm_mod, wrap_int64(i)),
1312+ Expression . Const . make(wasm_mod, const_int32 @@ data_size),
1313+ ),
1314+ Expression . Memory_init . make(
1315+ wasm_mod,
1316+ segment_offset,
1317+ Expression . Binary . make(
1318+ wasm_mod,
1319+ Op . add_int32,
1320+ get_swap() ,
1321+ Expression . Const . make(wasm_mod, const_int32(8 )),
1322+ ),
1323+ Expression . Const . make(wasm_mod, const_int32(0 )),
1324+ Expression . Const . make(wasm_mod, const_int32(data_size)),
1325+ grain_memory,
13011326 ),
1302- ints_to_push,
1327+ get_swap() ,
1328+ ] ,
13031329 );
1304- Expression . Block . make(
1305- wasm_mod,
1306- gensym_label(label),
1307- List . concat([ preamble, elts, [ get_swap() ]] ),
1308- );
1330+ } else {
1331+ let ints_to_push : list (int64 ) = buf_to_ints(buf);
1332+ let preamble = [
1333+ store(
1334+ ~offset= 0 ,
1335+ wasm_mod,
1336+ tee_swap(
1337+ heap_allocate(wasm_mod, env, 2 + 2 * List . length(ints_to_push)),
1338+ ),
1339+ Expression . Const . make(
1340+ wasm_mod,
1341+ const_int32(tag_val_of_heap_tag_type(tag)),
1342+ ),
1343+ ),
1344+ store(
1345+ ~offset= 4 ,
1346+ wasm_mod,
1347+ get_swap() ,
1348+ Expression . Const . make(wasm_mod, const_int32 @@ Buffer . length(buf)),
1349+ ),
1350+ ] ;
1351+ let elts =
1352+ List . mapi(
1353+ (idx, i: int64 ) =>
1354+ store(
1355+ ~ty= Type . int64,
1356+ ~offset= 8 * (idx + 1 ),
1357+ wasm_mod,
1358+ get_swap() ,
1359+ Expression . Const . make(wasm_mod, wrap_int64(i)),
1360+ ),
1361+ ints_to_push,
1362+ );
1363+ Expression . Block . make(
1364+ wasm_mod,
1365+ gensym_label(label),
1366+ List . concat([ preamble, elts, [ get_swap() ]] ),
1367+ );
1368+ };
13091369};
13101370
13111371let allocate_byte_like_uninitialized = (wasm_mod, env, size, tag, label) => {
@@ -3378,7 +3438,7 @@ let compile_type_metadata = (wasm_mod, env, prog) => {
33783438 | (initial_memory , None ) => (initial_memory, Memory . unlimited)
33793439 };
33803440
3381- let data_segments =
3441+ let segments =
33823442 switch (metadata_tbl_data) {
33833443 | Some (data ) => [
33843444 Memory . {
@@ -3396,6 +3456,14 @@ let compile_type_metadata = (wasm_mod, env, prog) => {
33963456 ]
33973457 | None => []
33983458 };
3459+ let data_segments =
3460+ if (Config . bulk_memory^ ) {
3461+ let (_ , data_segments ) = data_segments^;
3462+ List . rev_append(data_segments, segments);
3463+ } else {
3464+ segments;
3465+ };
3466+
33993467 Memory . set_memory(
34003468 wasm_mod,
34013469 initial_memory,
@@ -3461,8 +3529,6 @@ let compile_wasm_module =
34613529 Option . is_none(Grain_utils . Config . memory_base^ ),
34623530 );
34633531
3464- compile_type_metadata(wasm_mod, env, prog);
3465-
34663532 ignore @@
34673533 Table . add_table(
34683534 wasm_mod,
@@ -3497,12 +3563,15 @@ let compile_wasm_module =
34973563
34983564 ignore @@ compile_main(wasm_mod, env, prog);
34993565
3566+ compile_type_metadata(wasm_mod, env, prog);
3567+
35003568 validate_module(~name? , wasm_mod);
35013569
35023570 switch (Config . profile^ ) {
35033571 | Some (Release ) => Optimize_mod . optimize(wasm_mod)
35043572 | None => ()
35053573 };
3574+
35063575 wasm_mod;
35073576};
35083577
0 commit comments