Skip to content

Commit e9d0cca

Browse files
committed
Fold memory and data into memory
1 parent 9dbd0c4 commit e9d0cca

File tree

7 files changed

+57
-34
lines changed

7 files changed

+57
-34
lines changed

ml-proto/src/ast.ml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,14 @@ and arm' =
105105

106106
(* Functions and Modules *)
107107

108-
109-
type segment = Memory.segment Source.phrase
108+
type memory = memory' Source.phrase
109+
and memory' =
110+
{
111+
initial : Memory.size;
112+
max : Memory.size;
113+
segments : segment list;
114+
}
115+
and segment = Memory.segment Source.phrase
110116

111117
type func = func' Source.phrase
112118
and func' =
@@ -125,8 +131,7 @@ type table = var list Source.phrase
125131
type modul = modul' Source.phrase
126132
and modul' =
127133
{
128-
memory : Memory.size * Memory.size;
129-
data : segment list;
134+
memory : memory option;
130135
funcs : func list;
131136
exports : export list;
132137
tables : table list;

ml-proto/src/check.ml

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -275,16 +275,24 @@ let check_export c ex =
275275
let {name = _; func = x} = ex.it in
276276
ignore (func c x)
277277

278-
let check_data_segment memory prev_end s =
279-
let mem_end = fst memory in
280-
let seg_end = s.it.Memory.addr + String.length s.it.Memory.data in
281-
require (s.it.Memory.addr >= prev_end) s.at "data section not disjoint and ordered";
282-
require (mem_end >= seg_end) s.at "data section does not fit memory";
278+
let check_segment memory prev_end seg =
279+
let seg_end = seg.it.Memory.addr + String.length seg.it.Memory.data in
280+
require (seg.it.Memory.addr >= prev_end) seg.at
281+
"data section not disjoint and ordered";
282+
require (memory.it.initial >= seg_end) seg.at
283+
"data section does not fit memory";
283284
seg_end
284285

286+
let check_memory memory =
287+
require (memory.it.initial <= memory.it.max) memory.at
288+
"initial memory size must be less than maximum";
289+
ignore (List.fold_left (check_segment memory) 0 memory.it.segments)
290+
285291
let check_module m =
286-
let {funcs; exports; tables; globals; memory; data} = m.it in
287-
ignore (List.fold_left (check_data_segment memory) 0 data);
292+
let {funcs; exports; tables; globals; memory} = m.it in
293+
match memory with
294+
| Some memory -> check_memory memory
295+
| None -> ();
288296
let c = {c0 with funcs = List.map type_func funcs;
289297
globals = List.map it globals} in
290298
let c' = List.fold_left check_table c tables in

ml-proto/src/eval.ml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,14 @@ and eval_func m f vs =
244244
(* Modules *)
245245

246246
let init m =
247-
let {Ast.funcs; exports; tables; globals; memory = (n, _); data} = m.it in
248-
let memory = Memory.create n in
249-
Memory.init memory (List.map (fun seg -> seg.it) data);
247+
let {Ast.funcs; exports; tables; globals; memory} = m.it in
248+
let memory = match memory with
249+
| Some {it = {initial; segments} } ->
250+
let m = Memory.create initial in
251+
Memory.init m (List.map (fun seg -> seg.it) segments);
252+
m
253+
| None -> Memory.create 0
254+
in
250255
let func x = List.nth funcs x.it in
251256
let export ex = ExportMap.add ex.it.name (func ex.it.func) in
252257
let exports = List.fold_right export exports ExportMap.empty in

ml-proto/src/lexer.mll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ rule token = parse
245245
| "local" { LOCAL }
246246
| "module" { MODULE }
247247
| "memory" { MEMORY }
248-
| "data" { DATA }
248+
| "segment" { SEGMENT }
249249
| "global" { GLOBAL }
250250
| "import" { IMPORT }
251251
| "export" { EXPORT }

ml-proto/src/memory.ml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,13 @@ let create n =
5050
mem
5151

5252
let init_seg mem seg =
53-
if String.length seg.data > Array1.dim mem then raise Bounds;
5453
(* There currently is no way to blit from a string. *)
5554
for i = 0 to String.length seg.data - 1 do
5655
(view mem : char_view).{seg.addr + i} <- seg.data.[i]
5756
done
5857

5958
let init mem segs =
60-
List.iter (init_seg mem) segs
59+
try List.iter (init_seg mem) segs with Invalid_argument _ -> raise Bounds
6160

6261
(* Alignment *)
6362

ml-proto/src/parser.mly

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ let anon_label c = {c with labels = VarMap.map ((+) 1) c.labels}
9797
%token CALL DISPATCH RETURN DESTRUCT
9898
%token GETLOCAL SETLOCAL GETGLOBAL SETGLOBAL GETMEMORY SETMEMORY
9999
%token CONST UNARY BINARY COMPARE CONVERT
100-
%token FUNC PARAM RESULT LOCAL MODULE MEMORY DATA GLOBAL IMPORT EXPORT TABLE
100+
%token FUNC PARAM RESULT LOCAL MODULE MEMORY SEGMENT GLOBAL IMPORT EXPORT TABLE
101101
%token INVOKE ASSERTEQ
102102
%token EOF
103103

@@ -150,10 +150,6 @@ bind_var :
150150
| VAR { $1 @@ at() }
151151
;
152152
153-
data :
154-
| LPAR DATA INT TEXT RPAR { {Memory.addr = int_of_string $3; Memory.data = $4} @@ at() }
155-
;
156-
157153
expr :
158154
| LPAR oper RPAR { let at = at() in fun c -> $2 c @@ at }
159155
;
@@ -255,6 +251,21 @@ func :
255251
256252
/* Modules */
257253
254+
segment :
255+
| LPAR SEGMENT INT TEXT RPAR { {Memory.addr = int_of_string $3; Memory.data = $4} @@ at() }
256+
;
257+
segment_list :
258+
| /* empty */ { [] }
259+
| segment segment_list { $1 :: $2 }
260+
;
261+
262+
memory :
263+
| LPAR MEMORY INT INT segment_list RPAR
264+
{ {initial = int_of_string $3; max = int_of_string $4; segments = $5 } @@ at() }
265+
| LPAR MEMORY INT segment_list RPAR
266+
{ {initial = int_of_string $3; max = int_of_string $3; segments = $4 } @@ at() }
267+
;
268+
258269
export :
259270
| LPAR EXPORT TEXT var RPAR
260271
{ let at = at() in fun c -> {name = $3; func = $4 c func} @@ at }
@@ -263,7 +274,7 @@ export :
263274
module_fields :
264275
| /* empty */
265276
{ fun c ->
266-
{memory = (0, 0); data = []; funcs = []; exports = []; globals = []; tables = []} }
277+
{memory = None; funcs = []; exports = []; globals = []; tables = []} }
267278
| func module_fields
268279
{ fun c -> let f = $1 c in let m = $2 c in
269280
{m with funcs = f () :: m.funcs} }
@@ -279,14 +290,11 @@ module_fields :
279290
| LPAR TABLE var_list RPAR module_fields
280291
{ fun c -> let m = $5 c in
281292
{m with tables = ($3 c func @@ ati 3) :: m.tables} }
282-
| LPAR MEMORY INT INT RPAR module_fields
283-
{ fun c -> let m = $6 c in
284-
{m with memory = (int_of_string $3, int_of_string $4)} }
285-
| LPAR MEMORY INT RPAR module_fields /* Sugar */
286-
{ fun c -> let m = $5 c in
287-
{m with memory = (int_of_string $3, int_of_string $3)} }
288-
| data module_fields
289-
{ fun c -> let m = $2 c in {m with data = $1 :: m.data} }
293+
| memory module_fields
294+
{ fun c -> let m = $2 c in
295+
match m.memory with
296+
| Some _ -> Error.error $1.at "more than one memory section"
297+
| None -> {m with memory = Some $1} }
290298
;
291299
modul :
292300
| LPAR MODULE module_fields RPAR { $3 (c0 ()) @@ at() }

ml-proto/test/memory.wasm

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
;; (c) 2015 Andreas Rossberg
22

33
(module
4-
(memory 1024)
5-
(data 0 "ABC\a7D")
6-
(data 20 "WASM")
4+
(memory 1024 (segment 0 "ABC\a7D") (segment 20 "WASM"))
75

86
;; Data section
97
(func $data (result i32)

0 commit comments

Comments
 (0)