Skip to content

Commit

Permalink
Merge branch 'master' into br_table
Browse files Browse the repository at this point in the history
  • Loading branch information
rossberg committed Mar 7, 2016
2 parents ae6cfd1 + 8fa4dce commit f1469e1
Show file tree
Hide file tree
Showing 32 changed files with 379 additions and 204 deletions.
5 changes: 3 additions & 2 deletions ml-proto/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ OCB_FLAGS += $(DIRS:%=-I %)
OCB_FLAGS += $(LIBS:%=-libs %)
OCB = ocamlbuild $(OCB_FLAGS)

.PHONY: all opt unopt
.PHONY: opt unopt all land
unopt: $(NAME_UNOPT)
opt: $(NAME_OPT)
all: winmake.bat opt unopt test
all: opt unopt test
land: all winmake.bat

$(NAME_OPT): main.native
mv $< $@
Expand Down
35 changes: 20 additions & 15 deletions ml-proto/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,15 @@ To run the test suite,
```
make test
```
To do everything (advisable before committing changes),
To do everything:
```
make all
```
Be sure to run the latter before you upload a patch.
Before committing changes, you should do
```
make land
```
That builds `all`, plus updates `winmake.bat`.


#### Building on Windows
Expand Down Expand Up @@ -75,14 +79,15 @@ See `wasm -h` for (the few) options.
The implementation consumes a WebAssemlby AST given in S-expression syntax. Here is an overview of the grammar of types, expressions, functions, and modules, mirroring what's described in the [design doc](https://github.com/WebAssembly/design/blob/master/AstSemantics.md):

```
type: i32 | i64 | f32 | f64
value: <int> | <float>
var: <int> | $<name>
name: (<letter> | <digit> | _ | . | + | - | * | / | \ | ^ | ~ | = | < | > | ! | ? | @ | # | $ | % | & | | | : | ' | `)+
string: "(<char> | \n | \t | \\ | \' | \" | \<hex><hex>)*"
type: i32 | i64 | f32 | f64
unop: ctz | clz | popcnt | ...
binop: add | sub | mul | ...
selop: select
relop: eq | ne | lt | ...
sign: s|u
offset: offset=<uint>
Expand All @@ -91,13 +96,14 @@ cvtop: trunc_s | trunc_u | extend_s | extend_u | ...
expr:
( nop )
( block <name>? <expr>+ )
( block <name>? <expr>* )
( loop <name1>? <name2>? <expr>* ) ;; = (block <name1>? (loop <name2>? (block <expr>*)))
( if_else <expr> <expr> <expr> )
( if <expr> <expr> ) ;; = (if_else <expr> <expr> (nop))
( select <expr> <expr> <expr> )
( if <expr> ( then <name>? <expr>* ) ( else <name>? <expr>* )? )
( if <expr1> <expr2> <expr3>? ) ;; = (if <expr1> (then <expr2>) (else <expr3>?))
( br <var> <expr>? )
( br_if <var> <expr>? <expr> )
( br_table <var>+ <expr>? <expr> )
( br_table <var> <var> <expr>? <expr> )
( return <expr>? ) ;; = (br <current_depth> <expr>?)
( call <var> <expr>* )
( call_import <var> <expr>* )
Expand All @@ -109,7 +115,6 @@ expr:
( <type>.const <value> )
( <type>.<unop> <expr> )
( <type>.<binop> <expr> <expr> )
( <type>.<selop> <expr> <expr> <expr> )
( <type>.<relop> <expr> <expr> )
( <type>.<cvtop>/<type> <expr> )
( unreachable )
Expand All @@ -124,12 +129,12 @@ local: ( local <type>* ) | ( local <name> <type> )
module: ( module <type>* <func>* <import>* <export>* <table>* <memory>? <start>? )
type: ( type <name>? ( func <param>* <result>? ) )
import: ( import <name>? "<module_name>" "<func_name>" (param <type>* ) (result <type>)* )
export: ( export "<char>*" <var> )
import: ( import <name>? <string> <string> (param <type>* ) (result <type>)* )
export: ( export <string> <var> ) | ( export <string> memory)
start: ( start <var> )
table: ( table <var>* )
memory: ( memory <int> <int>? <segment>* )
segment: ( segment <int> "<char>*" )
segment: ( segment <int> <string> )
```

Here, productions marked with respective comments are abbreviation forms for equivalent expansions (see the explanation of the kernel AST below).
Expand All @@ -142,8 +147,8 @@ Comments can be written in one of two ways:

```
comment:
;; <character>* <eol>
(; (<character> | <comment>)* ;)
;; <char>* <eol>
(; (<char> | <comment>)* ;)
```

In particular, comments of the latter form nest properly.
Expand Down
3 changes: 2 additions & 1 deletion ml-proto/host/import/env.ml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
(*
* Emulation of (a subset of) the `env` module currently used by Binaryen,
* so that we can run modules generated by Binaryen.
* so that we can run modules generated by Binaryen. This is a stopgap until
* we have agreement on what libc should look like.
*)

open Values
Expand Down
10 changes: 3 additions & 7 deletions ml-proto/host/lexer.mll
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ rule token = parse
| "br_table" { BR_TABLE }
| "return" { RETURN }
| "if" { IF }
| "if_else" { IF_ELSE }
| "then" { THEN }
| "else" { ELSE }
| "select" { SELECT }
| "call" { CALL }
| "call_import" { CALL_IMPORT }
| "call_indirect" { CALL_INDIRECT }
Expand Down Expand Up @@ -268,11 +270,6 @@ rule token = parse
{ BINARY (fun (e1, e2) ->
floatop t (F32_copysign (e1, e2)) (F64_copysign (e1, e2))) }

| (nxx as t)".select"
{ SELECT (fun (e1, e2, e3) ->
numop t (I32_select (e1, e2, e3)) (I64_select (e1, e2, e3))
(F32_select (e1, e2, e3)) (F64_select (e1, e2, e3))) }

| (ixx as t)".eq"
{ COMPARE (fun (e1, e2) -> intop t (I32_eq (e1, e2)) (I64_eq (e1, e2))) }
| (ixx as t)".ne"
Expand Down Expand Up @@ -342,7 +339,6 @@ rule token = parse

| "memory_size" { MEMORY_SIZE }
| "grow_memory" { GROW_MEMORY }
| "has_feature" { HAS_FEATURE }

| "type" { TYPE }
| "func" { FUNC }
Expand Down
5 changes: 0 additions & 5 deletions ml-proto/host/params.ml

This file was deleted.

33 changes: 18 additions & 15 deletions ml-proto/host/parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ let empty_context () =

let enter_func c =
assert (VarMap.is_empty c.labels);
{c with labels = VarMap.add "return" 0 c.labels; locals = empty ()}
{c with labels = VarMap.empty; locals = empty ()}

let type_ c x =
try VarMap.find x.it c.types.tmap
Expand Down Expand Up @@ -125,13 +125,13 @@ let implicit_decl c t at =
%}

%token INT FLOAT TEXT VAR VALUE_TYPE LPAR RPAR
%token NOP BLOCK IF IF_ELSE LOOP BR BR_IF BR_TABLE
%token NOP BLOCK IF THEN ELSE SELECT LOOP BR BR_IF BR_TABLE
%token CALL CALL_IMPORT CALL_INDIRECT RETURN
%token GET_LOCAL SET_LOCAL LOAD STORE OFFSET ALIGN
%token CONST UNARY BINARY COMPARE CONVERT
%token FUNC START TYPE PARAM RESULT LOCAL
%token MODULE MEMORY SEGMENT IMPORT EXPORT TABLE
%token UNREACHABLE MEMORY_SIZE GROW_MEMORY HAS_FEATURE
%token UNREACHABLE MEMORY_SIZE GROW_MEMORY
%token ASSERT_INVALID ASSERT_RETURN ASSERT_RETURN_NAN ASSERT_TRAP INVOKE
%token EOF

Expand All @@ -143,7 +143,6 @@ let implicit_decl c t at =
%token<string Source.phrase -> Ast.expr' * Values.value> CONST
%token<Ast.expr -> Ast.expr'> UNARY
%token<Ast.expr * Ast.expr -> Ast.expr'> BINARY
%token<Ast.expr * Ast.expr * Ast.expr -> Ast.expr'> SELECT
%token<Ast.expr * Ast.expr -> Ast.expr'> COMPARE
%token<Ast.expr -> Ast.expr'> CONVERT
%token<Memory.offset * int option * Ast.expr -> Ast.expr'> LOAD
Expand Down Expand Up @@ -220,8 +219,7 @@ expr :
expr1 :
| NOP { fun c -> Nop }
| UNREACHABLE { fun c -> Unreachable }
| BLOCK labeling expr expr_list
{ fun c -> let c' = $2 c in Block ($3 c' :: $4 c') }
| BLOCK labeling expr_list { fun c -> let c' = $2 c in Block ($3 c') }
| LOOP labeling expr_list
{ fun c -> let c' = anon_label c in let c'' = $2 c' in Loop ($3 c'') }
| LOOP labeling1 labeling1 expr_list
Expand All @@ -235,11 +233,15 @@ expr1 :
| BR_TABLE var var_list expr expr
{ fun c -> let xs, x = Lib.List.split_last ($2 c label :: $3 c label) in
Br_table (xs, x, Some ($4 c), $5 c) }
| RETURN expr_opt
{ let at1 = ati 1 in
fun c -> Return (label c ("return" @@ at1) @@ at1, $2 c) }
| IF expr expr { fun c -> If ($2 c, $3 c) }
| IF_ELSE expr expr expr { fun c -> If_else ($2 c, $3 c, $4 c) }
| RETURN expr_opt { fun c -> Return ($2 c) }
| IF expr expr { fun c -> let c' = anon_label c in If ($2 c, [$3 c'], []) }
| IF expr expr expr
{ fun c -> let c' = anon_label c in If ($2 c, [$3 c'], [$4 c']) }
| IF expr LPAR THEN labeling expr_list RPAR
{ fun c -> let c' = $5 c in If ($2 c, $6 c', []) }
| IF expr LPAR THEN labeling expr_list RPAR LPAR ELSE labeling expr_list RPAR
{ fun c -> let c1 = $5 c in let c2 = $10 c in If ($2 c, $6 c1, $11 c2) }
| SELECT expr expr expr { fun c -> Select ($2 c, $3 c, $4 c) }
| CALL var expr_list { fun c -> Call ($2 c func, $3 c) }
| CALL_IMPORT var expr_list { fun c -> Call_import ($2 c import, $3 c) }
| CALL_INDIRECT var expr expr_list
Expand All @@ -251,12 +253,10 @@ expr1 :
| CONST literal { fun c -> fst (literal $1 $2) }
| UNARY expr { fun c -> $1 ($2 c) }
| BINARY expr expr { fun c -> $1 ($2 c, $3 c) }
| SELECT expr expr expr { fun c -> $1 ($2 c, $3 c, $4 c) }
| COMPARE expr expr { fun c -> $1 ($2 c, $3 c) }
| CONVERT expr { fun c -> $1 ($2 c) }
| MEMORY_SIZE { fun c -> Memory_size }
| GROW_MEMORY expr { fun c -> Grow_memory ($2 c) }
| HAS_FEATURE TEXT { fun c -> Has_feature $2 }
;
expr_opt :
| /* empty */ { fun c -> None }
Expand All @@ -273,7 +273,8 @@ expr_list :
func_fields :
| expr_list
{ empty_type,
fun c -> {ftype = -1 @@ at(); locals = []; body = $1 c} }
fun c -> let c' = anon_label c in
{ftype = -1 @@ at(); locals = []; body = $1 c'} }
| LPAR PARAM value_type_list RPAR func_fields
{ {(fst $5) with ins = $3 @ (fst $5).ins},
fun c -> anon_locals c $3; (snd $5) c }
Expand Down Expand Up @@ -373,7 +374,9 @@ import :
export :
| LPAR EXPORT TEXT var RPAR
{ let at = at () in fun c -> {name = $3; func = $4 c func} @@ at }
{ let at = at () in fun c -> ExportFunc ($3, ($4 c func)) @@ at }
| LPAR EXPORT TEXT MEMORY RPAR
{ let at = at () in fun c -> ExportMemory $3 @@ at }
;
module_fields :
Expand Down
11 changes: 8 additions & 3 deletions ml-proto/host/print.ml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ let print_var_sig prefix i t =
let print_func_sig m prefix i f =
printf "%s %d : %s\n" prefix i (string_of_func_type (func_type m f))

let print_export_sig m prefix n f =
printf "%s \"%s\" : %s\n" prefix n (string_of_func_type (func_type m f))
let print_export_sig m n f =
printf "export \"%s\" : %s\n" n (string_of_func_type (func_type m f))

let print_export_mem n =
printf "export \"%s\" : memory\n" n

let print_table_elem i x =
printf "table [%d] = func %d\n" i x.it
Expand All @@ -36,7 +39,9 @@ let print_func m i f =
print_func_sig m "func" i f

let print_export m i ex =
print_export_sig m "export" ex.it.name (List.nth m.it.funcs ex.it.func.it)
match ex.it with
| ExportFunc (n, x) -> print_export_sig m n (List.nth m.it.funcs x.it)
| ExportMemory n -> print_export_mem n

let print_module m =
let {funcs; start; exports; table} = m.it in
Expand Down
5 changes: 1 addition & 4 deletions ml-proto/host/script.ml
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,7 @@ let run_cmd cmd =
end;
trace "Initializing...";
let imports = Import.link m in
let host_params = {
Eval.has_feature = Params.has_feature
} in
current_module := Some (Eval.init m imports host_params)
current_module := Some (Eval.init m imports)

| Invoke (name, es) ->
trace "Invoking...";
Expand Down
13 changes: 3 additions & 10 deletions ml-proto/spec/ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ and expr' =
| Br of var * expr option
| Br_if of var * expr option * expr
| Br_table of var list * var * expr option * expr
| Return of var * expr option
| If of expr * expr
| If_else of expr * expr * expr
| Return of expr option
| If of expr * expr list * expr list
| Select of expr * expr * expr
| Call of var * expr list
| Call_import of var * expr list
| Call_indirect of var * expr * expr list
Expand Down Expand Up @@ -121,12 +121,6 @@ and expr' =
| F64_max of expr * expr
| F64_copysign of expr * expr

(* Select *)
| I32_select of expr * expr * expr
| I64_select of expr * expr * expr
| F32_select of expr * expr * expr
| F64_select of expr * expr * expr

(* Comparisons *)
| I32_eq of expr * expr
| I32_ne of expr * expr
Expand Down Expand Up @@ -191,7 +185,6 @@ and expr' =
(* Host queries *)
| Memory_size
| Grow_memory of expr
| Has_feature of string


(* Functions *)
Expand Down
26 changes: 11 additions & 15 deletions ml-proto/spec/check.ml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ let check_type actual expected at =
let type_value = Values.type_of
let type_unop = Values.type_of
let type_binop = Values.type_of
let type_selop = Values.type_of
let type_relop = Values.type_of

let type_cvtop at = function
Expand Down Expand Up @@ -94,7 +93,6 @@ let type_cvtop at = function
let type_hostop = function
| MemorySize -> ({ins = []; out = Some Int32Type}, true)
| GrowMemory -> ({ins = [Int32Type]; out = Some Int32Type}, true)
| HasFeature str -> ({ins = []; out = Some Int32Type}, false)


(* Type Analysis *)
Expand All @@ -119,12 +117,10 @@ let rec check_expr c et e =
| Unreachable ->
()

| Block es ->
require (es <> []) e.at "invalid block";
let es', eN = Lib.List.split_last es in
| Block (es, e) ->
let c' = {c with labels = et :: c.labels} in
List.iter (check_expr c' None) es';
check_expr c' et eN
List.iter (check_expr c' None) es;
check_expr c' et e

| Loop e1 ->
let c' = {c with labels = None :: c.labels} in
Expand All @@ -148,6 +144,11 @@ let rec check_expr c et e =
check_expr c et e2;
check_expr c et e3

| Select (e1, e2, e3) ->
check_expr c et e1;
check_expr c et e2;
check_expr c (Some Int32Type) e3

| Call (x, es) ->
let {ins; out} = func c x in
check_exprs c ins es e.at;
Expand Down Expand Up @@ -200,12 +201,6 @@ let rec check_expr c et e =
check_expr c (Some t) e2;
check_type (Some t) et e.at

| Select (selop, e1, e2, e3) ->
let t = type_selop selop in
check_expr c (Some t) e1;
check_expr c (Some t) e2;
check_expr c (Some Int32Type) e3

| Compare (relop, e1, e2) ->
let t = type_relop relop in
check_expr c (Some t) e1;
Expand Down Expand Up @@ -288,8 +283,9 @@ let check_elem c x =
module NameSet = Set.Make(String)

let check_export c set ex =
let {name; func = x} = ex.it in
ignore (func c x);
let name = match ex.it with
| ExportFunc (n, x) -> ignore (func c x); n
| ExportMemory n -> require (c.has_memory) ex.at "no memory to export"; n in
require (not (NameSet.mem name set)) ex.at
"duplicate export name";
NameSet.add name set
Expand Down
Loading

0 comments on commit f1469e1

Please sign in to comment.