Skip to content
Closed
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
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

* Compiler: fix variable renaming for property binding and assignment target
* Compiler: fix separate compilation of toplevels (broken since 5.7.0)
* Runtime: no longer leak channels

# 5.7.2 (2024-04-03) - Lille

Expand Down
68 changes: 55 additions & 13 deletions runtime/io.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ var caml_sys_fds = new Array(3);
//Provides: caml_sys_close
//Requires: caml_sys_fds
function caml_sys_close(fd) {
var file = caml_sys_fds[fd];
if(file) file.close();
var x = caml_sys_fds[fd];
if(x && x.file) x.file.close();
delete caml_sys_fds[fd];
return 0;
}
Expand All @@ -41,10 +41,17 @@ function caml_sys_close(fd) {
//Requires: caml_sys_fds
//Requires: caml_sys_open_for_node
function caml_sys_open_internal(file,idx) {
var chanid;
if(idx == undefined){
idx = caml_sys_fds.length;
chanid = Symbol(idx.toString());
}
caml_sys_fds[idx] = file;
else if(caml_sys_fds[idx]){
chanid = caml_sys_fds[idx].chanid;
}
else
chanid = Symbol(idx.toString ());
caml_sys_fds[idx] = {file:file, chanid: chanid};
return idx | 0;
}
function caml_sys_open (name, flags, _perms) {
Expand Down Expand Up @@ -96,15 +103,49 @@ function caml_ml_set_channel_name(chanid, name) {
}

//Provides: caml_ml_channels
var caml_ml_channels = new Array();
function caml_ml_channels_state() {
this.map = new globalThis.WeakMap ();
this.opened = new globalThis.Set();
}
caml_ml_channels_state.prototype.close = function (chanid) {
this.opened.delete(chanid);
}
caml_ml_channels_state.prototype.get = function (chanid) {
return this.map.get(chanid);
}
caml_ml_channels_state.prototype.set = function (chanid, val) {
if(val.opened) this.opened.add(chanid);
return this.map.set(chanid,val);
}
caml_ml_channels_state.prototype.all = function () {
return this.opened.values();
}

var channels_handlers = {
get (target, prop, receiver) {
if(typeof prop == "symbol"){
return target.get(prop);
}
return globalThis.Reflect.get(...arguments);
},
set (target, prop, new_val, receiver) {
if(typeof prop == "symbol"){
target.set(prop, new_val);
}
return true;
}
}
var caml_ml_channels = new globalThis.Proxy(new caml_ml_channels_state, channels_handlers);

//Provides: caml_ml_out_channels_list
//Requires: caml_ml_channels
//Requires: caml_sys_fds
function caml_ml_out_channels_list () {
var l = 0;
for(var c = 0; c < caml_ml_channels.length; c++){
if(caml_ml_channels[c] && caml_ml_channels[c].opened && caml_ml_channels[c].out)
l=[0,caml_ml_channels[c].fd,l];
var keys = caml_ml_channels.all();
for(var k of keys){
var chan = caml_ml_channels[k];
if(chan.opened && chan.out) l=[0,k,l];
}
return l;
}
Expand All @@ -115,7 +156,7 @@ function caml_ml_out_channels_list () {
//Requires: caml_raise_sys_error
//Requires: caml_sys_open
function caml_ml_open_descriptor_out (fd) {
var file = caml_sys_fds[fd];
var s = caml_sys_fds[fd], file = s.file, chanid = s.chanid;
if(file.flags.rdonly) caml_raise_sys_error("fd "+ fd + " is readonly");
var buffered = (file.flags.buffered !== undefined) ? file.flags.buffered : 1;
var channel = {
Expand All @@ -128,16 +169,16 @@ function caml_ml_open_descriptor_out (fd) {
buffer:new Uint8Array(65536),
buffered:buffered
};
caml_ml_channels[channel.fd]=channel;
return channel.fd;
caml_ml_channels[chanid] = channel;
return chanid;
}

//Provides: caml_ml_open_descriptor_in
//Requires: caml_ml_channels, caml_sys_fds
//Requires: caml_raise_sys_error
//Requires: caml_sys_open
function caml_ml_open_descriptor_in (fd) {
var file = caml_sys_fds[fd];
var s = caml_sys_fds[fd], file = s.file, chanid = s.chanid;
if(file.flags.wronly) caml_raise_sys_error("fd "+ fd + " is writeonly");
var refill = null;
var channel = {
Expand All @@ -151,8 +192,8 @@ function caml_ml_open_descriptor_in (fd) {
buffer:new Uint8Array(65536),
refill:refill
};
caml_ml_channels[channel.fd]=channel;
return channel.fd;
caml_ml_channels[chanid] = channel;
return chanid;
}


Expand Down Expand Up @@ -204,6 +245,7 @@ function caml_ml_close_channel (chanid) {
var chan = caml_ml_channels[chanid];
if(chan.opened) {
chan.opened = false;
caml_ml_channels.close(chanid);
caml_sys_close(chan.fd);
chan.fd = -1;
chan.buffer = new Uint8Array(0);
Expand Down
3 changes: 2 additions & 1 deletion runtime/parsing.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ var caml_parser_trace = 0;
//Requires: caml_lex_array, caml_parser_trace,caml_jsstring_of_string
//Requires: caml_ml_output, caml_ml_string_length, caml_string_of_jsbytes
//Requires: caml_jsbytes_of_string, MlBytes
//Requires: caml_sys_fds
function caml_parse_engine(tables, env, cmd, arg)
{
var ERRCODE = 256;
Expand Down Expand Up @@ -84,7 +85,7 @@ function caml_parse_engine(tables, env, cmd, arg)

function log(x) {
var s = caml_string_of_jsbytes(x + "\n");
caml_ml_output(2, s, 0, caml_ml_string_length(s));
caml_ml_output(caml_sys_fds[2].chanid, s, 0, caml_ml_string_length(s));
}

function token_name(names, number)
Expand Down