Skip to content

Commit

Permalink
Runtime: use map to store file descriptor information
Browse files Browse the repository at this point in the history
So that it still works when file descriptors are not small integers.
  • Loading branch information
vouillon committed Dec 20, 2023
1 parent c4ad40d commit 6a6d736
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 70 deletions.
156 changes: 86 additions & 70 deletions runtime/wasm/io.wat
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@
(import "sys" "caml_handle_sys_error"
(func $caml_handle_sys_error (param externref)))

(import "bindings" "map_new" (func $map_new (result (ref extern))))
(import "bindings" "map_get"
(func $map_get
(param (ref extern)) (param i32) (result (ref $fd_offset))))
(import "bindings" "map_set"
(func $map_set
(param (ref extern)) (param i32) (param (ref $fd_offset))))
(import "bindings" "map_delete"
(func $map_delete (param (ref extern)) (param i32)))

(type $block (array (mut (ref eq))))
(type $string (array (mut i8)))
(type $offset_array (array (mut i64)))
Expand Down Expand Up @@ -109,38 +119,35 @@
(field $size (mut i32))
(field $unbuffered (mut i32)))))

(global $fd_offsets (export "fd_offsets") (mut (ref $offset_array))
(array.new $offset_array (i64.const 0) (i32.const 3)))
(global $fd_seeked (mut (ref $string))
(array.new $string (i32.const 0) (i32.const 3)))
(type $fd_offset
(struct (field $offset (mut i64)) (field $seeked (mut i32))))

(func $initialize_fd_offset (param $fd i32) (param $offset i64)
(local $len i32)
(local $a (ref $offset_array))
(local $b (ref $string))
(local.set $len (array.len (global.get $fd_offsets)))
(if (i32.ge_u (local.get $fd) (local.get $len))
(global $fd_offsets (mut externref) (ref.null extern))

(func $get_fd_offsets (result (ref extern))
(local $m (ref extern))
(if (ref.is_null (global.get $fd_offsets))
(then
(loop $loop
(local.set $len (i32.shl (local.get $len) (i32.const 1)))
(br_if $loop (i32.ge_u (local.get $fd) (local.get $len))))
(local.set $a
(array.new $offset_array (i64.const 0) (local.get $len)))
(array.copy $offset_array $offset_array
(local.get $a) (i32.const 0)
(global.get $fd_offsets) (i32.const 0)
(array.len (global.get $fd_offsets)))
(global.set $fd_offsets (local.get $a))
(local.set $b
(array.new $string (i32.const 0) (local.get $len)))
(array.copy $string $string
(local.get $b) (i32.const 0)
(global.get $fd_seeked) (i32.const 0)
(array.len (global.get $fd_seeked)))
(global.set $fd_seeked (local.get $b))))
(array.set $offset_array (global.get $fd_offsets) (local.get $fd)
(local.get $offset))
(array.set $string (global.get $fd_seeked) (local.get $fd) (i32.const 0)))
(local.set $m (call $map_new))
(call $map_set (local.get $m) (i32.const 0)
(struct.new $fd_offset (i64.const 0) (i32.const 0)))
(call $map_set (local.get $m) (i32.const 1)
(struct.new $fd_offset (i64.const 0) (i32.const 0)))
(call $map_set (local.get $m) (i32.const 2)
(struct.new $fd_offset (i64.const 0) (i32.const 0)))
(global.set $fd_offsets (local.get $m))))
(ref.as_non_null (global.get $fd_offsets)))

(func $initialize_fd_offset (param $fd i32) (param $offset i64)
(call $map_set (call $get_fd_offsets)
(local.get $fd)
(struct.new $fd_offset (local.get $offset) (i32.const 0))))

(func $release_fd_offset (param $fd i32)
(call $map_delete (call $get_fd_offsets) (local.get $fd)))

(func $get_fd_offset (param $fd i32) (result (ref $fd_offset))
(call $map_get (call $get_fd_offsets) (local.get $fd)))

(global $IO_BUFFER_SIZE i32 (i32.const 65536))

Expand Down Expand Up @@ -197,9 +204,12 @@
(ref.i31 (local.get $fd)))

(func (export "caml_sys_close") (param (ref eq)) (result (ref eq))
(local $fd i32)
(local.set $fd (i31.get_u (ref.cast (ref i31) (local.get 0))))
(call $release_fd_offset (local.get $fd))
(try
(do
(call $close (i31.get_u (ref.cast (ref i31) (local.get 0)))))
(call $close (local.get $fd)))
(catch $javascript_exception
(call $caml_handle_sys_error (pop externref))))
(ref.i31 (i32.const 0)))
Expand Down Expand Up @@ -259,22 +269,24 @@
(then
(struct.set $channel $fd (local.get $ch) (i32.const -1))
(call $unregister_channel (local.get $ch))
(call $release_fd_offset (local.get $fd))
(call $close (local.get $fd))))
(ref.i31 (i32.const 0)))

(func $caml_do_read
(param $ch (ref $channel)) (param $pos i32) (param $len i32) (result i32)
(local $fd i32)
(local $fd_offset (ref $fd_offset))
(local $offset i64)
(local $n i32)
(local.set $fd (struct.get $channel $fd (local.get $ch)))
(local.set $offset
(array.get $offset_array (global.get $fd_offsets) (local.get $fd)))
(local.set $fd_offset (call $get_fd_offset (local.get $fd)))
(local.set $offset (struct.get $fd_offset $offset (local.get $fd_offset)))
(try
(do
(local.set $n
(if (result i32)
(array.get_u $string (global.get $fd_seeked) (local.get $fd))
(struct.get $fd_offset $seeked (local.get $fd_offset))
(then
(call $read
(local.get $fd)
Expand All @@ -291,8 +303,8 @@
(ref.null noextern))))))
(catch $javascript_exception
(call $caml_handle_sys_error (pop externref))))
(array.set $offset_array
(global.get $fd_offsets) (local.get $fd)
(struct.set $fd_offset $offset
(local.get $fd_offset)
(i64.add (local.get $offset) (i64.extend_i32_u (local.get $n))))
(local.get $n))

Expand Down Expand Up @@ -455,9 +467,9 @@
(ref.i31
(i32.sub
(i32.wrap_i64
(array.get $offset_array
(global.get $fd_offsets)
(struct.get $channel $fd (local.get $ch))))
(struct.get $fd_offset $offset
(call $get_fd_offset
(struct.get $channel $fd (local.get $ch)))))
(i32.sub
(struct.get $channel $max (local.get $ch))
(struct.get $channel $curr (local.get $ch))))))
Expand All @@ -468,9 +480,9 @@
(local.set $ch (ref.cast (ref $channel) (local.get $vch)))
(call $caml_copy_int64
(i64.sub
(array.get $offset_array
(global.get $fd_offsets)
(struct.get $channel $fd (local.get $ch)))
(struct.get $fd_offset $offset
(call $get_fd_offset
(struct.get $channel $fd (local.get $ch))))
(i64.extend_i32_s
(i32.sub
(struct.get $channel $max (local.get $ch))
Expand All @@ -483,9 +495,9 @@
(ref.i31
(i32.add
(i32.wrap_i64
(array.get $offset_array
(global.get $fd_offsets)
(struct.get $channel $fd (local.get $ch))))
(struct.get $fd_offset $offset
(call $get_fd_offset
(struct.get $channel $fd (local.get $ch)))))
(struct.get $channel $curr (local.get $ch)))))

(func (export "caml_ml_pos_out_64")
Expand All @@ -494,17 +506,19 @@
(local.set $ch (ref.cast (ref $channel) (local.get $vch)))
(call $caml_copy_int64
(i64.add
(array.get $offset_array
(global.get $fd_offsets)
(struct.get $channel $fd (local.get $ch)))
(struct.get $fd_offset $offset
(call $get_fd_offset
(struct.get $channel $fd (local.get $ch))))
(i64.extend_i32_s (struct.get $channel $curr (local.get $ch))))))

(func $caml_seek_in
(param $ch (ref $channel)) (param $dest i64) (result (ref eq))
(local $fd i32) (local $offset i64)
(local $fd_offset (ref $fd_offset))
(local.set $fd (struct.get $channel $fd (local.get $ch)))
(local.set $fd_offset (call $get_fd_offset (local.get $fd)))
(local.set $offset
(array.get $offset_array (global.get $fd_offsets) (local.get $fd)))
(struct.get $fd_offset $offset (local.get $fd_offset)))
(if (i32.and
(i64.ge_s
(local.get $dest)
Expand All @@ -521,9 +535,9 @@
(i64.sub (local.get $offset) (local.get $dest))))))
(else
;; ZZZ Check for error
(array.set $offset_array (global.get $fd_offsets) (local.get $fd)
(struct.set $fd_offset $offset (local.get $fd_offset)
(local.get $dest))
(array.set $string (global.get $fd_seeked) (local.get $fd)
(struct.set $fd_offset $seeked (local.get $fd_offset)
(i32.const 1))
(struct.set $channel $curr (local.get $ch) (i32.const 0))
(struct.set $channel $max (local.get $ch) (i32.const 0))))
Expand All @@ -543,30 +557,30 @@
(func (export "caml_ml_seek_out")
(param $vch (ref eq)) (param $voffset (ref eq)) (result (ref eq))
(local $ch (ref $channel))
(local $fd_offset (ref $fd_offset))
(local.set $ch (ref.cast (ref $channel) (local.get $vch)))
(call $caml_flush (local.get $ch))
;; ZZZ Check for error
(array.set $offset_array
(global.get $fd_offsets)
(struct.get $channel $fd (local.get $ch))
(local.set $fd_offset
(call $get_fd_offset (struct.get $channel $fd (local.get $ch))))
(struct.set $fd_offset $offset (local.get $fd_offset)
(i64.extend_i32_s
(i31.get_s (ref.cast (ref i31) (local.get $voffset)))))
(array.set $string (global.get $fd_seeked)
(struct.get $channel $fd (local.get $ch)) (i32.const 1))
(struct.set $fd_offset $seeked (local.get $fd_offset) (i32.const 1))
(ref.i31 (i32.const 0)))

(func (export "caml_ml_seek_out_64")
(param $vch (ref eq)) (param $voffset (ref eq)) (result (ref eq))
(local $ch (ref $channel))
(local $fd_offset (ref $fd_offset))
(local.set $ch (ref.cast (ref $channel) (local.get $vch)))
(call $caml_flush (local.get $ch))
;; ZZZ Check for error
(array.set $offset_array
(global.get $fd_offsets)
(struct.get $channel $fd (local.get $ch))
(local.set $fd_offset
(call $get_fd_offset (struct.get $channel $fd (local.get $ch))))
(struct.set $fd_offset $offset (local.get $fd_offset)
(call $Int64_val (local.get $voffset)))
(array.set $string (global.get $fd_seeked)
(struct.get $channel $fd (local.get $ch)) (i32.const 1))
(struct.set $fd_offset $seeked (local.get $fd_offset) (i32.const 1))
(ref.i31 (i32.const 0)))

(func (export "caml_ml_input_scan_line")
Expand Down Expand Up @@ -646,21 +660,21 @@

(func $caml_flush_partial (param $ch (ref $channel)) (result i32)
(local $towrite i32) (local $written i32) (local $fd i32)
(local $fd_offset (ref $fd_offset))
(local $offset i64) (local $buf (ref extern))
(local.set $towrite (struct.get $channel $curr (local.get $ch)))
(if (i32.gt_u (local.get $towrite) (i32.const 0))
(then
(local.set $buf (struct.get $channel $buffer (local.get $ch)))
(local.set $fd (struct.get $channel $fd (local.get $ch)))
(local.set $fd_offset (call $get_fd_offset (local.get $fd)))
(local.set $offset
(array.get $offset_array
(global.get $fd_offsets) (local.get $fd)))
(struct.get $fd_offset $offset (local.get $fd_offset)))
(try
(do
(local.set $written
(if (result i32)
(array.get_u $string (global.get $fd_seeked)
(local.get $fd))
(struct.get $fd_offset $seeked (local.get $fd_offset))
(then
(call $write
(local.get $fd)
Expand All @@ -677,8 +691,8 @@
(ref.null noextern))))))
(catch $javascript_exception
(call $caml_handle_sys_error (pop externref))))
(array.set $offset_array
(global.get $fd_offsets) (local.get $fd)
(struct.set $fd_offset $offset
(local.get $fd_offset)
(i64.add
(local.get $offset)
(i64.extend_i32_u (local.get $written))))
Expand Down Expand Up @@ -832,7 +846,9 @@
(struct.set $channel $fd
(ref.cast (ref $channel) (local.get 0)) (local.get 1)))

(func (export "caml_ml_get_channel_offset") (param (ref eq)) (result i64)
(array.get $offset_array (global.get $fd_offsets)
(struct.get $channel $fd (ref.cast (ref $channel) (local.get 0)))))
(func (export "caml_ml_get_channel_offset") (param $ch (ref eq)) (result i64)
(struct.get $fd_offset $offset
(call $get_fd_offset
(struct.get $channel $fd
(ref.cast (ref $channel) (local.get $ch))))))
)
1 change: 1 addition & 0 deletions runtime/wasm/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@
map_new:()=>new Map,
map_get:(m,x)=>{var v = m.get(x); return v==undefined?null:v},
map_set:(m,x,v)=>m.set(x,v),
map_delete:(m,x)=>m.delete(x),
log:(x)=>console.log('ZZZZZ', x)
}
const imports = {Math:math,bindings,env:{},js,strings,fragments}
Expand Down

0 comments on commit 6a6d736

Please sign in to comment.