Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions interpreter/binary/encode.ml
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,8 @@ struct
| ExternConvert Internalize -> op 0xfb; op 0x1a
| ExternConvert Externalize -> op 0xfb; op 0x1b

| FuncNew (x, y, z) -> op 0xfb; op 0x27; byte 0x00; idx x; idx y; idx z

| Const {it = I32 c; _} -> op 0x41; s32 c
| Const {it = I64 c; _} -> op 0x42; s64 c
| Const {it = F32 c; _} -> op 0x43; f32 c
Expand Down
2 changes: 2 additions & 0 deletions interpreter/syntax/ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ type localidx = idx
type labelidx = idx
type fieldidx = I32.t
type laneidx = I8.t
type envidx = idx

type num = Value.num Source.phrase
type vec = Value.vec Source.phrase
Expand Down Expand Up @@ -240,6 +241,7 @@ and instr' =
| ArrayInitData of typeidx * dataidx (* fill array from data segment *)
| ArrayInitElem of typeidx * elemidx (* fill array from elem segment *)
| ExternConvert of externop (* extern conversion *)
| FuncNew of memoryidx * typeidx * envidx (* create new function *)
| Const of num (* numeric constant *)
| Test of testop (* numeric test *)
| Compare of relop (* numeric comparison *)
Expand Down
1 change: 1 addition & 0 deletions interpreter/syntax/free.ml
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ let rec instr (e : instr) =
| ArrayInitData (x, y) -> types (idx x) ++ datas (idx y)
| ArrayInitElem (x, y) -> types (idx x) ++ elems (idx y)
| ExternConvert _ -> empty
| FuncNew (_, y, _) -> types (idx y)
| Const _ | Test _ | Compare _ | Unary _ | Binary _ | Convert _ -> empty
| VecConst _ | VecTest _
| VecUnary _ | VecBinary _ | VecTernary _ | VecCompare _
Expand Down
2 changes: 2 additions & 0 deletions interpreter/syntax/mnemonics.ml
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ let array_init_elem x y = ArrayInitElem (x, y)
let any_convert_extern = ExternConvert Internalize
let extern_convert_any = ExternConvert Externalize

let func_new x y z = FuncNew (x, y, z)

let i32_clz = Unary (I32 I32Op.Clz)
let i32_ctz = Unary (I32 I32Op.Ctz)
let i32_popcnt = Unary (I32 I32Op.Popcnt)
Expand Down
1 change: 1 addition & 0 deletions interpreter/text/arrange.ml
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,7 @@ let rec instr e =
| ArrayInitData (x, y) -> "array.init_data " ^ idx x ^ " " ^ idx y, []
| ArrayInitElem (x, y) -> "array.init_elem " ^ idx x ^ " " ^ idx y, []
| ExternConvert op -> externop op, []
| FuncNew (x, y, z) -> "func.new " ^ idx x ^ " " ^ idx y ^ " " ^ idx z, []
| Const n -> constop n.it ^ " " ^ num n, []
| Test op -> testop op, []
| Compare op -> relop op, []
Expand Down
2 changes: 2 additions & 0 deletions interpreter/text/lexer.mll
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,8 @@ rule token = parse
| "any.convert_extern" -> EXTERN_CONVERT any_convert_extern
| "extern.convert_any" -> EXTERN_CONVERT extern_convert_any

| "func.new" -> FUNC_NEW

| "i32.clz" -> UNARY i32_clz
| "i32.ctz" -> UNARY i32_ctz
| "i32.popcnt" -> UNARY i32_popcnt
Expand Down
1 change: 1 addition & 0 deletions interpreter/text/parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ let parse_annots (m : module_) : Custom.section list =
%token ARRAY_SET ARRAY_LEN
%token ARRAY_COPY ARRAY_FILL ARRAY_INIT_DATA ARRAY_INIT_ELEM
%token<Ast.instr'> EXTERN_CONVERT
%token FUNC_NEW
%token<Ast.idx -> int option -> Memory.offset -> Ast.instr'> VEC_LOAD VEC_STORE
%token<Ast.idx -> int option -> Memory.offset -> Ast.laneidx -> Ast.instr'> VEC_LOAD_LANE VEC_STORE_LANE
%token<V128.shape -> string Source.phrase list -> Source.region -> Ast.instr' * Value.vec> VEC_CONST
Expand Down
6 changes: 6 additions & 0 deletions interpreter/valid/valid.ml
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,12 @@ let rec check_instr (c : context) (e : instr) (s : infer_resulttype) : infer_ins
let (nul, _ht) = peek_ref 0 s e.at in
[RefT (nul, ht1)] --> [RefT (nul, ht2)], []

| FuncNew (x, y, z) -> (* TODO: validate scope index z *)
let MemoryT (at, _lim) = memory c x in
let _ft = func_type c y in
[NumT (numtype_of_addrtype at);
NumT (numtype_of_addrtype at)] --> [RefT (Null, UseHT (Def (type_ c y)))], []

| Const v ->
let t = NumT (type_num v.it) in
[] --> [t], []
Expand Down
16 changes: 16 additions & 0 deletions proposals/jit-interface/Explainer.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,20 @@ This implies AOT scenarios need to either disable the feature, e.g. reject code

In the future, we could consider additional restrictions, such as an explicit list of allowable bytecodes for new functions. That could allow a module to limit language features for new functions and greatly reduce the runtime system requirement. Since this is a restriction a module imposes on itself, it need not be standardized. As an example of the usefulness of this, a module could limit its `func.new` capabilities to only allow `i32` arithmetic and control flow. An AOT implementation could then provide a runtime execution tier that *only* supported that restricted set, keeping it both simple and optimized for the use case.

## Binary format

### Instructions

The `func.new` instruction is encoded as follows:

```
instr ::= ...
| 0xFB 39:u32 0:byte x:memoryidx y:typeidx z:scopeidx =>
func_new x y z
```

The byte following the opcode is reserved to be `0`, to account for future extensibility, such as encoding asynchrony, TBD.

### Scope section

TBD.