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
3 changes: 2 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@
js primitives in bytecode/native. It should help if one tries
to understand the source of the call with gdb (see #677)
* Runtime: re-enable marshalling of floats, disabled in jsoo 2.0
* Runtime: new runtime api for channels

## Bug fixes

* Compiler: fix variable renaming for property binding and assignment target
* Compiler: fix separate compilation of toplevels (broken since 5.7.0)
* Compiler: fix assertion while checking stack compatibility
* Compiler: fix assertion while checking stack compatibility (#1600)

# 5.7.2 (2024-04-03) - Lille

Expand Down
8 changes: 8 additions & 0 deletions lib/runtime/js_of_ocaml_runtime_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,14 @@ void caml_list_to_js_array () {
caml_fatal_error("Unimplemented Javascript primitive caml_list_to_js_array!");
}

void caml_ml_channel_redirect () {
caml_fatal_error("Unimplemented Javascript primitive caml_ml_channel_redirect!");
}

void caml_ml_channel_restore () {
caml_fatal_error("Unimplemented Javascript primitive caml_ml_channel_restore!");
}

void caml_ml_set_channel_output () {
caml_fatal_error("Unimplemented Javascript primitive caml_ml_set_channel_output!");
}
Expand Down
8 changes: 8 additions & 0 deletions lib/runtime/jsoo_runtime.ml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,14 @@ module Sys = struct

external unmount : string -> unit = "caml_unmount"

type redirection

external redirect_channel : out_channel -> into:out_channel -> redirection
= "caml_ml_channel_redirect"

external restore_channel : out_channel -> redirection -> unit
= "caml_ml_channel_restore"

module Config = struct
external use_js_string : unit -> bool = "caml_jsoo_flags_use_js_string"

Expand Down
110 changes: 66 additions & 44 deletions runtime/io.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,38 @@ function caml_sys_open (name, flags, _perms) {
// ocaml Channels

//Provides: caml_ml_set_channel_name
//Requires: caml_ml_channels
//Requires: caml_ml_channel_get
function caml_ml_set_channel_name(chanid, name) {
var chan = caml_ml_channels[chanid];
var chan = caml_ml_channel_get(chanid);
chan.name = name;
return 0;
}

//Provides: caml_ml_channels
var caml_ml_channels = new Array();

//Provides: caml_ml_channel_redirect
//Requires: caml_ml_channel_get, caml_ml_channels
function caml_ml_channel_redirect (captured, into){
var to_restore = caml_ml_channel_get(captured);
var new_ = caml_ml_channel_get(into);
caml_ml_channels[captured] = new_; // XXX
return to_restore;
}

//Provides: caml_ml_channel_restore
//Requires: caml_ml_channels
function caml_ml_channel_restore (captured, to_restore){
caml_ml_channels[captured] = to_restore; // XXX
return 0;
}

//Provides: caml_ml_channel_get
//Requires: caml_ml_channels
function caml_ml_channel_get(id) {
return caml_ml_channels[id]; // XXX
}

//Provides: caml_ml_out_channels_list
//Requires: caml_ml_channels
function caml_ml_out_channels_list () {
Expand Down Expand Up @@ -171,37 +193,37 @@ function caml_ml_open_descriptor_out_with_flags(fd, flags){
}

//Provides: caml_channel_descriptor
//Requires: caml_ml_channels
//Requires: caml_ml_channel_get
//Alias: win_filedescr_of_channel
function caml_channel_descriptor(chanid){
var chan = caml_ml_channels[chanid];
var chan = caml_ml_channel_get(chanid);
return chan.fd;
}

//Provides: caml_ml_set_binary_mode
//Requires: caml_ml_channels
//Requires: caml_ml_channel_get
function caml_ml_set_binary_mode(chanid,mode){
var chan = caml_ml_channels[chanid];
var chan = caml_ml_channel_get(chanid);
chan.file.flags.text = !mode
chan.file.flags.binary = mode
return 0;
}

//Provides: caml_ml_is_binary_mode
//Requires: caml_ml_channels
//Requires: caml_ml_channel_get
//Version: >= 5.2
function caml_ml_is_binary_mode(chanid) {
var chan = caml_ml_channels[chanid];
var chan = caml_ml_channel_get(chanid);
return chan.file.flags.binary
}

//Input from in_channel

//Provides: caml_ml_close_channel
//Requires: caml_ml_flush, caml_ml_channels
//Requires: caml_ml_flush, caml_ml_channel_get
//Requires: caml_sys_close
function caml_ml_close_channel (chanid) {
var chan = caml_ml_channels[chanid];
var chan = caml_ml_channel_get(chanid);
if(chan.opened) {
chan.opened = false;
caml_sys_close(chan.fd);
Expand All @@ -214,31 +236,31 @@ function caml_ml_close_channel (chanid) {
}

//Provides: caml_ml_channel_size
//Requires: caml_ml_channels
//Requires: caml_ml_channel_get
function caml_ml_channel_size(chanid) {
var chan = caml_ml_channels[chanid];
var chan = caml_ml_channel_get(chanid);
return chan.file.length();
}

//Provides: caml_ml_channel_size_64
//Requires: caml_int64_of_float,caml_ml_channels
//Requires: caml_int64_of_float,caml_ml_channel_get
function caml_ml_channel_size_64(chanid) {
var chan = caml_ml_channels[chanid];
var chan = caml_ml_channel_get(chanid);
return caml_int64_of_float(chan.file.length ());
}

//Provides: caml_ml_set_channel_output
//Requires: caml_ml_channels
//Requires: caml_ml_channel_get
function caml_ml_set_channel_output(chanid,f) {
var chan = caml_ml_channels[chanid];
var chan = caml_ml_channel_get(chanid);
chan.output = (function (s) {f(s)});
return 0;
}

//Provides: caml_ml_set_channel_refill
//Requires: caml_ml_channels
//Requires: caml_ml_channel_get
function caml_ml_set_channel_refill(chanid,f) {
caml_ml_channels[chanid].refill = f;
caml_ml_channel_get(chanid).refill = f;
return 0;
}

Expand Down Expand Up @@ -285,9 +307,9 @@ function caml_ml_input_bigarray (chanid, b, i, l) {
}

//Provides: caml_ml_input_block
//Requires: caml_refill, caml_ml_channels
//Requires: caml_refill, caml_ml_channel_get
function caml_ml_input_block (chanid, ba, i, l) {
var chan = caml_ml_channels[chanid];
var chan = caml_ml_channel_get(chanid);
var n = l;
var avail = chan.buffer_max - chan.buffer_curr;
if(l <= avail) {
Expand All @@ -311,11 +333,11 @@ function caml_ml_input_block (chanid, ba, i, l) {
}

//Provides: caml_input_value
//Requires: caml_marshal_data_size, caml_input_value_from_bytes, caml_create_bytes, caml_ml_channels, caml_bytes_of_array
//Requires: caml_marshal_data_size, caml_input_value_from_bytes, caml_create_bytes, caml_ml_channel_get, caml_bytes_of_array
//Requires: caml_refill, caml_failwith, caml_raise_end_of_file
//Requires: caml_marshal_header_size
function caml_input_value (chanid) {
var chan = caml_ml_channels[chanid];
var chan = caml_ml_channel_get(chanid);
var header = new Uint8Array(caml_marshal_header_size);
function block(buffer, offset, n) {
var r = 0;
Expand Down Expand Up @@ -358,9 +380,9 @@ function caml_input_value_to_outside_heap(c) {

//Provides: caml_ml_input_char
//Requires: caml_raise_end_of_file, caml_array_bound_error
//Requires: caml_ml_channels, caml_refill
//Requires: caml_ml_channel_get, caml_refill
function caml_ml_input_char (chanid) {
var chan = caml_ml_channels[chanid];
var chan = caml_ml_channel_get(chanid);
if(chan.buffer_curr >= chan.buffer_max){
chan.buffer_curr = 0;
chan.buffer_max = 0;
Expand All @@ -375,9 +397,9 @@ function caml_ml_input_char (chanid) {

//Provides: caml_ml_input_int
//Requires: caml_raise_end_of_file
//Requires: caml_ml_input_char, caml_ml_channels
//Requires: caml_ml_input_char, caml_ml_channel_get
function caml_ml_input_int (chanid) {
var chan = caml_ml_channels[chanid];
var chan = caml_ml_channel_get(chanid);
var res = 0;
for(var i = 0; i < 4; i++){
res = (res << 8) + caml_ml_input_char(chanid) | 0;
Expand All @@ -386,9 +408,9 @@ function caml_ml_input_int (chanid) {
}

//Provides: caml_seek_in
//Requires: caml_raise_sys_error, caml_ml_channels
//Requires: caml_raise_sys_error, caml_ml_channel_get
function caml_seek_in(chanid, pos) {
var chan = caml_ml_channels[chanid];
var chan = caml_ml_channel_get(chanid);
if (chan.refill != null) caml_raise_sys_error("Illegal seek");
if(pos >= chan.offset - chan.buffer_max
&& pos <= chan.offset
Expand Down Expand Up @@ -416,9 +438,9 @@ function caml_ml_seek_in_64(chanid,pos){
}

//Provides: caml_pos_in
//Requires: caml_ml_channels
//Requires: caml_ml_channel_get
function caml_pos_in(chanid) {
var chan = caml_ml_channels[chanid];
var chan = caml_ml_channel_get(chanid);
return chan.offset - (chan.buffer_max - chan.buffer_curr) | 0;
}

Expand All @@ -436,9 +458,9 @@ function caml_ml_pos_in_64(chanid) {

//Provides: caml_ml_input_scan_line
//Requires: caml_array_bound_error
//Requires: caml_ml_channels, caml_refill
//Requires: caml_ml_channel_get, caml_refill
function caml_ml_input_scan_line(chanid){
var chan = caml_ml_channels[chanid];
var chan = caml_ml_channel_get(chanid);
var p = chan.buffer_curr;
do {
if(p >= chan.buffer_max) {
Expand All @@ -462,10 +484,10 @@ function caml_ml_input_scan_line(chanid){
}

//Provides: caml_ml_flush
//Requires: caml_raise_sys_error, caml_ml_channels
//Requires: caml_raise_sys_error, caml_ml_channel_get
//Requires: caml_subarray_to_jsbytes
function caml_ml_flush (chanid) {
var chan = caml_ml_channels[chanid];
var chan = caml_ml_channel_get(chanid);
if(! chan.opened) caml_raise_sys_error("Cannot flush a closed channel");
if(!chan.buffer || chan.buffer_curr == 0) return 0;
if(chan.output) {
Expand All @@ -482,9 +504,9 @@ function caml_ml_flush (chanid) {

//Provides: caml_ml_output_ta
//Requires: caml_ml_flush,caml_ml_bytes_length
//Requires: caml_raise_sys_error, caml_ml_channels
//Requires: caml_raise_sys_error, caml_ml_channel_get
function caml_ml_output_ta(chanid,buffer,offset,len) {
var chan = caml_ml_channels[chanid];
var chan = caml_ml_channel_get(chanid);
if(! chan.opened) caml_raise_sys_error("Cannot output to a closed channel");
buffer = buffer.subarray(offset, offset + len);
if(chan.buffer_curr + buffer.length > chan.buffer.length) {
Expand Down Expand Up @@ -566,10 +588,10 @@ function caml_output_value (chanid,v,flags) {


//Provides: caml_seek_out
//Requires: caml_ml_channels, caml_ml_flush
//Requires: caml_ml_channel_get, caml_ml_flush
function caml_seek_out(chanid, pos){
caml_ml_flush(chanid);
var chan = caml_ml_channels[chanid];
var chan = caml_ml_channel_get(chanid);
chan.offset = pos;
return 0;
}
Expand All @@ -587,9 +609,9 @@ function caml_ml_seek_out_64(chanid,pos){
}

//Provides: caml_pos_out
//Requires: caml_ml_channels, caml_ml_flush
//Requires: caml_ml_channel_get, caml_ml_flush
function caml_pos_out(chanid) {
var chan = caml_ml_channels[chanid];
var chan = caml_ml_channel_get(chanid);
return chan.offset + chan.buffer_curr
}

Expand All @@ -616,15 +638,15 @@ function caml_ml_output_int (chanid,i) {
}

//Provides: caml_ml_is_buffered
//Requires: caml_ml_channels
//Requires: caml_ml_channel_get
function caml_ml_is_buffered(chanid) {
return caml_ml_channels[chanid].buffered ? 1 : 0
return caml_ml_channel_get(chanid).buffered ? 1 : 0
}

//Provides: caml_ml_set_buffered
//Requires: caml_ml_channels, caml_ml_flush
//Requires: caml_ml_channel_get, caml_ml_flush
function caml_ml_set_buffered(chanid,v) {
caml_ml_channels[chanid].buffered = v;
caml_ml_channel_get(chanid).buffered = v;
if(!v) caml_ml_flush(chanid);
return 0
}