fixed the lvalue check in the assignment list in read.c
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
touched up fnblk handling in comp.c updated more code in hcl-x.c
This commit is contained in:
parent
2dad89e2e9
commit
f9bf37f8bf
19
bin/main-c.c
19
bin/main-c.c
@ -551,7 +551,7 @@ static int receive_raw_bytes (hcl_xproto_t* proto, int sck, hcl_ntime_t* idle_tm
|
|||||||
{
|
{
|
||||||
/* timeout explicity set. no activity for that duration. considered idle */
|
/* timeout explicity set. no activity for that duration. considered idle */
|
||||||
hcl_seterrbfmt (hcl, HCL_EGENERIC, "no activity on the socket %d", sck);
|
hcl_seterrbfmt (hcl, HCL_EGENERIC, "no activity on the socket %d", sck);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0; /* didn't read yet */
|
return 0; /* didn't read yet */
|
||||||
@ -559,7 +559,7 @@ static int receive_raw_bytes (hcl_xproto_t* proto, int sck, hcl_ntime_t* idle_tm
|
|||||||
|
|
||||||
if (pfd.revents & POLLERR)
|
if (pfd.revents & POLLERR)
|
||||||
{
|
{
|
||||||
hcl_seterrbfmt (hcl, HCL_EGENERIC, "error condition detected on socket %d", sck);
|
hcl_seterrbfmt (hcl, HCL_EGENERIC, "error condition detected on socket %d", sck);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -754,7 +754,20 @@ static int handle_request (hcl_client_t* client, const char* ipaddr, const char*
|
|||||||
iov[0].iov_len = HCL_SIZEOF(hdr);
|
iov[0].iov_len = HCL_SIZEOF(hdr);
|
||||||
send_iov (sck, iov, 1);
|
send_iov (sck, iov, 1);
|
||||||
|
|
||||||
if (shut_wr_after_req) shutdown (sck, SHUT_WR);
|
if (shut_wr_after_req)
|
||||||
|
{
|
||||||
|
shutdown (sck, SHUT_WR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hdr.type = HCL_XPKT_DISCONNECT;
|
||||||
|
hdr.id = 1; /* TODO: */
|
||||||
|
hdr.len = 0;
|
||||||
|
|
||||||
|
iov[0].iov_base = &hdr;
|
||||||
|
iov[0].iov_len = HCL_SIZEOF(hdr);
|
||||||
|
send_iov (sck, iov, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
71
lib/comp.c
71
lib/comp.c
@ -27,6 +27,7 @@
|
|||||||
/* limit the `do` expression to have not more than 1 expression and
|
/* limit the `do` expression to have not more than 1 expression and
|
||||||
* no variable declaration if not enclosed in parentheses */
|
* no variable declaration if not enclosed in parentheses */
|
||||||
#define LANG_LIMIT_DO
|
#define LANG_LIMIT_DO
|
||||||
|
#define CLEAR_FNBLK_ALWAYS
|
||||||
|
|
||||||
#define FOR_NONE (0)
|
#define FOR_NONE (0)
|
||||||
#define FOR_IF (1)
|
#define FOR_IF (1)
|
||||||
@ -1197,12 +1198,11 @@ static void pop_fnblk (hcl_t* hcl)
|
|||||||
hcl_fnblk_info_t* fbi;
|
hcl_fnblk_info_t* fbi;
|
||||||
|
|
||||||
HCL_ASSERT (hcl, hcl->c->fnblk.depth >= 0);
|
HCL_ASSERT (hcl, hcl->c->fnblk.depth >= 0);
|
||||||
/* if pop_cblk() has been called properly, the following assertion must be true
|
|
||||||
* and the assignment on the next line isn't necessary */
|
|
||||||
|
|
||||||
clear_fnblk_inners (hcl);
|
clear_fnblk_inners (hcl);
|
||||||
|
|
||||||
fbi = &hcl->c->fnblk.info[hcl->c->fnblk.depth];
|
fbi = &hcl->c->fnblk.info[hcl->c->fnblk.depth];
|
||||||
|
/* if pop_cblk() has been called properly, the following assertion must be true
|
||||||
|
* and the assignment on the next line isn't necessary */
|
||||||
HCL_ASSERT (hcl, hcl->c->cblk.depth == fbi->cblk_base);
|
HCL_ASSERT (hcl, hcl->c->cblk.depth == fbi->cblk_base);
|
||||||
HCL_ASSERT (hcl, fbi->clsblk_base <= -1 && fbi->clsblk_top <= -1);
|
HCL_ASSERT (hcl, fbi->clsblk_base <= -1 && fbi->clsblk_top <= -1);
|
||||||
|
|
||||||
@ -5856,16 +5856,24 @@ int hcl_compile (hcl_t* hcl, hcl_cnode_t* obj, int flags)
|
|||||||
{
|
{
|
||||||
hcl_oow_t saved_bc_len, saved_lit_len;
|
hcl_oow_t saved_bc_len, saved_lit_len;
|
||||||
hcl_bitmask_t log_default_type_mask;
|
hcl_bitmask_t log_default_type_mask;
|
||||||
|
#if !defined(CLEAR_FNBLK_ALWAYS)
|
||||||
hcl_fnblk_info_t top_fnblk_saved;
|
hcl_fnblk_info_t top_fnblk_saved;
|
||||||
|
int fnblk_pushed_here = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
hcl->c->flags = flags;
|
hcl->c->flags = flags;
|
||||||
|
|
||||||
|
HCL_ASSERT (hcl, hcl->c->fnblk.depth <= 0); /* 0 or 1 fnblk must exist at this phase */
|
||||||
HCL_ASSERT (hcl, GET_TOP_CFRAME_INDEX(hcl) < 0);
|
HCL_ASSERT (hcl, GET_TOP_CFRAME_INDEX(hcl) < 0);
|
||||||
if (flags & HCL_COMPILE_CLEAR_CODE)
|
#if !defined(CLEAR_FNBLK_ALWAYS)
|
||||||
|
if (flags & HCL_COMPILE_CLEAR_FNBLK)
|
||||||
{
|
{
|
||||||
hcl->code.bc.len = 0;
|
while (hcl->c->fnblk.depth >= 0) pop_fnblk (hcl);
|
||||||
hcl->code.lit.len = 0;
|
HCL_ASSERT (hcl, hcl->c->fnblk.depth == -1);
|
||||||
|
/* it will be recreated below */
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
if (flags & HCL_COMPILE_CLEAR_CODE) hcl_clearcode (hcl);
|
||||||
|
|
||||||
saved_bc_len = hcl->code.bc.len;
|
saved_bc_len = hcl->code.bc.len;
|
||||||
saved_lit_len = hcl->code.lit.len;
|
saved_lit_len = hcl->code.lit.len;
|
||||||
@ -5907,8 +5915,10 @@ int hcl_compile (hcl_t* hcl, hcl_cnode_t* obj, int flags)
|
|||||||
/* TODO: in case i implement all global variables as block arguments at the top level...what should i do? */
|
/* TODO: in case i implement all global variables as block arguments at the top level...what should i do? */
|
||||||
HCL_ASSERT (hcl, hcl->c->cblk.depth == -1);
|
HCL_ASSERT (hcl, hcl->c->cblk.depth == -1);
|
||||||
|
|
||||||
|
#if !defined(CLEAR_FNBLK_ALWAYS)
|
||||||
if (hcl->c->fnblk.depth <= -1)
|
if (hcl->c->fnblk.depth <= -1)
|
||||||
{
|
{
|
||||||
|
#endif
|
||||||
HCL_ASSERT (hcl, hcl->c->fnblk.depth == -1);
|
HCL_ASSERT (hcl, hcl->c->fnblk.depth == -1);
|
||||||
HCL_ASSERT (hcl, hcl->c->tv.s.len == 0);
|
HCL_ASSERT (hcl, hcl->c->tv.s.len == 0);
|
||||||
HCL_ASSERT (hcl, hcl->c->tv.wcount == 0);
|
HCL_ASSERT (hcl, hcl->c->tv.wcount == 0);
|
||||||
@ -5917,9 +5927,25 @@ int hcl_compile (hcl_t* hcl, hcl_cnode_t* obj, int flags)
|
|||||||
* pass HCL_TYPE_MAX(hcl_oow_t) as make_inst_pos because there is
|
* pass HCL_TYPE_MAX(hcl_oow_t) as make_inst_pos because there is
|
||||||
* no actual MAKE_LAMBDA/MAKE_FUNCTION instruction which otherwise
|
* no actual MAKE_LAMBDA/MAKE_FUNCTION instruction which otherwise
|
||||||
* would be patched in pop_fnblk(). */
|
* would be patched in pop_fnblk(). */
|
||||||
if (push_fnblk(hcl, HCL_NULL, 0, 0, 0, hcl->c->tv.wcount, hcl->c->tv.wcount, hcl->c->tv.s.len, HCL_TYPE_MAX(hcl_oow_t), 0, FUN_PLAIN) <= -1) return -1; /* must not goto oops */
|
|
||||||
|
if (push_fnblk(
|
||||||
|
hcl, HCL_NULL,
|
||||||
|
0, /* tmpr_va */
|
||||||
|
0, /* tmpr_nargs */
|
||||||
|
0, /* tmpr_nrvars */
|
||||||
|
hcl->c->tv.wcount, /* tmpr_nlvars */
|
||||||
|
hcl->c->tv.wcount, /* tmpr_count */
|
||||||
|
hcl->c->tv.s.len, /* tmpr_len */
|
||||||
|
HCL_TYPE_MAX(hcl_oow_t), /* make_inst_pos */
|
||||||
|
0, /* lfbase */
|
||||||
|
FUN_PLAIN /* fun_type */
|
||||||
|
) <= -1) return -1; /* must not goto oops */
|
||||||
|
|
||||||
|
#if !defined(CLEAR_FNBLK_ALWAYS)
|
||||||
|
fnblk_pushed_here = 1;
|
||||||
}
|
}
|
||||||
top_fnblk_saved = hcl->c->fnblk.info[0];
|
top_fnblk_saved = hcl->c->fnblk.info[0];
|
||||||
|
#endif
|
||||||
HCL_ASSERT (hcl, hcl->c->fnblk.depth == 0); /* ensure the virtual function block is added */
|
HCL_ASSERT (hcl, hcl->c->fnblk.depth == 0); /* ensure the virtual function block is added */
|
||||||
|
|
||||||
PUSH_CFRAME (hcl, COP_COMPILE_OBJECT, obj);
|
PUSH_CFRAME (hcl, COP_COMPILE_OBJECT, obj);
|
||||||
@ -6153,11 +6179,15 @@ int hcl_compile (hcl_t* hcl, hcl_cnode_t* obj, int flags)
|
|||||||
|
|
||||||
HCL_ASSERT (hcl, hcl->c->fnblk.depth == 0); /* ensure the virtual function block be the only one left */
|
HCL_ASSERT (hcl, hcl->c->fnblk.depth == 0); /* ensure the virtual function block be the only one left */
|
||||||
hcl->code.ngtmprs = hcl->c->fnblk.info[0].tmprcnt; /* populate the number of global temporary variables */
|
hcl->code.ngtmprs = hcl->c->fnblk.info[0].tmprcnt; /* populate the number of global temporary variables */
|
||||||
if (flags & HCL_COMPILE_CLEAR_FNBLK)
|
|
||||||
{
|
/* TODO: delete all !defined(CLEAR_FNBLK_ALWAYS) code
|
||||||
pop_fnblk (hcl);
|
* keep only defined(CLEAR_FNBLK_ALWAYS) code.
|
||||||
HCL_ASSERT (hcl, hcl->c->fnblk.depth == -1);
|
* not clearing the top fnblk for the reuse doesn't look very beneficial */
|
||||||
}
|
#if defined(CLEAR_FNBLK_ALWAYS)
|
||||||
|
pop_fnblk (hcl);
|
||||||
|
HCL_ASSERT (hcl, hcl->c->tv.s.len == 0);
|
||||||
|
HCL_ASSERT (hcl, hcl->c->tv.wcount == 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
hcl->log.default_type_mask = log_default_type_mask;
|
hcl->log.default_type_mask = log_default_type_mask;
|
||||||
return 0;
|
return 0;
|
||||||
@ -6171,23 +6201,30 @@ oops:
|
|||||||
hcl->code.bc.len = saved_bc_len;
|
hcl->code.bc.len = saved_bc_len;
|
||||||
hcl->code.lit.len = saved_lit_len;
|
hcl->code.lit.len = saved_lit_len;
|
||||||
|
|
||||||
hcl->c->tv.s.len = 0;
|
|
||||||
hcl->c->tv.wcount = 0;
|
|
||||||
|
|
||||||
while (hcl->c->fnblk.depth > 0) pop_fnblk (hcl);
|
while (hcl->c->fnblk.depth > 0) pop_fnblk (hcl);
|
||||||
|
HCL_ASSERT (hcl, hcl->c->fnblk.depth == 0);
|
||||||
|
|
||||||
if (flags & HCL_COMPILE_CLEAR_FNBLK)
|
#if !defined(CLEAR_FNBLK_ALWAYS)
|
||||||
|
if (fnblk_pushed_here)
|
||||||
{
|
{
|
||||||
|
#endif
|
||||||
pop_fnblk (hcl);
|
pop_fnblk (hcl);
|
||||||
HCL_ASSERT (hcl, hcl->c->fnblk.depth == -1);
|
HCL_ASSERT (hcl, hcl->c->fnblk.depth == -1);
|
||||||
|
HCL_ASSERT (hcl, hcl->c->tv.s.len == 0);
|
||||||
|
HCL_ASSERT (hcl, hcl->c->tv.wcount == 0);
|
||||||
|
#if !defined(CLEAR_FNBLK_ALWAYS)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* restore the top level function block as it's first captured in this functio */
|
hcl->c->tv.s.len = 0;
|
||||||
|
hcl->c->tv.wcount = 0;
|
||||||
|
|
||||||
|
/* restore the top level function block as it's first captured in this function */
|
||||||
clear_fnblk_inners (hcl);
|
clear_fnblk_inners (hcl);
|
||||||
HCL_ASSERT (hcl, hcl->c->fnblk.depth == 0);
|
HCL_ASSERT (hcl, hcl->c->fnblk.depth == 0);
|
||||||
hcl->c->fnblk.info[0] = top_fnblk_saved;
|
hcl->c->fnblk.info[0] = top_fnblk_saved;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
205
lib/hcl-x.c
205
lib/hcl-x.c
@ -123,7 +123,6 @@ struct hcl_server_proto_t
|
|||||||
hcl_server_proto_rcv_state_t state;
|
hcl_server_proto_rcv_state_t state;
|
||||||
hcl_oow_t len_needed;
|
hcl_oow_t len_needed;
|
||||||
unsigned int eof: 1;
|
unsigned int eof: 1;
|
||||||
unsigned int polled: 1;
|
|
||||||
|
|
||||||
hcl_oow_t len;
|
hcl_oow_t len;
|
||||||
hcl_uint8_t buf[4096];
|
hcl_uint8_t buf[4096];
|
||||||
@ -135,11 +134,6 @@ struct hcl_server_proto_t
|
|||||||
{
|
{
|
||||||
|
|
||||||
} snd;
|
} snd;
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
int ongoing;
|
|
||||||
} feed;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum hcl_server_worker_state_t
|
enum hcl_server_worker_state_t
|
||||||
@ -692,8 +686,8 @@ static void fini_hcl (hcl_t* hcl)
|
|||||||
|
|
||||||
static int on_fed_cnode (hcl_t* hcl, hcl_cnode_t* obj)
|
static int on_fed_cnode (hcl_t* hcl, hcl_cnode_t* obj)
|
||||||
{
|
{
|
||||||
worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl);
|
/*worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl);*/
|
||||||
hcl_server_proto_t* proto = xtn->proto;
|
/*hcl_server_proto_t* proto = xtn->proto;*/
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
printf ("on_fed_cnode......\n");
|
printf ("on_fed_cnode......\n");
|
||||||
@ -703,15 +697,6 @@ printf ("on_fed_cnode......\n");
|
|||||||
* if a single line or continued lines contain multiple expressions,
|
* if a single line or continued lines contain multiple expressions,
|
||||||
* execution is delayed until the last expression is compiled. */
|
* execution is delayed until the last expression is compiled. */
|
||||||
|
|
||||||
if (!proto->feed.ongoing)
|
|
||||||
{
|
|
||||||
/* the first expression in the current user input line.
|
|
||||||
* arrange to clear byte-codes before compiling the expression. */
|
|
||||||
flags = HCL_COMPILE_CLEAR_CODE | HCL_COMPILE_CLEAR_FNBLK;
|
|
||||||
proto->feed.ongoing = 1;
|
|
||||||
printf ("CLEARING...\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
printf ("COMPILING hcl_copingll......\n");
|
printf ("COMPILING hcl_copingll......\n");
|
||||||
if (hcl_compile(hcl, obj, flags) <= -1)
|
if (hcl_compile(hcl, obj, flags) <= -1)
|
||||||
{
|
{
|
||||||
@ -742,7 +727,6 @@ hcl_server_proto_t* hcl_server_proto_open (hcl_oow_t xtnsize, hcl_server_worker_
|
|||||||
proto->rcv.state = HCL_SERVER_PROTO_RCV_HEADER;
|
proto->rcv.state = HCL_SERVER_PROTO_RCV_HEADER;
|
||||||
proto->rcv.len_needed = HCL_SIZEOF(proto->rcv.hdr);
|
proto->rcv.len_needed = HCL_SIZEOF(proto->rcv.hdr);
|
||||||
proto->rcv.eof = 0;
|
proto->rcv.eof = 0;
|
||||||
proto->rcv.polled = 0;
|
|
||||||
|
|
||||||
proto->hcl = hcl_openstdwithmmgr(hcl_server_getmmgr(proto->worker->server), HCL_SIZEOF(*xtn), HCL_NULL);
|
proto->hcl = hcl_openstdwithmmgr(hcl_server_getmmgr(proto->worker->server), HCL_SIZEOF(*xtn), HCL_NULL);
|
||||||
if (HCL_UNLIKELY(!proto->hcl)) goto oops;
|
if (HCL_UNLIKELY(!proto->hcl)) goto oops;
|
||||||
@ -1016,77 +1000,64 @@ static int kill_server_worker (hcl_server_proto_t* proto, hcl_oow_t wid)
|
|||||||
return xret;
|
return xret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int receive_raw_request (hcl_server_proto_t* proto)
|
static int handle_packet (hcl_server_proto_t* proto, hcl_xpkt_type_t type, void* data, hcl_oow_t len)
|
||||||
{
|
{
|
||||||
hcl_server_worker_t* worker = proto->worker;
|
|
||||||
hcl_server_t* server = worker->server;
|
|
||||||
hcl_t* hcl = proto->hcl;
|
hcl_t* hcl = proto->hcl;
|
||||||
struct pollfd pfd;
|
|
||||||
int tmout, actual_tmout;
|
|
||||||
ssize_t x;
|
|
||||||
int n;
|
|
||||||
|
|
||||||
HCL_ASSERT (hcl, proto->rcv.len < proto->rcv.len_needed);
|
switch (type)
|
||||||
|
|
||||||
if (HCL_UNLIKELY(proto->rcv.eof))
|
|
||||||
{
|
{
|
||||||
hcl_seterrbfmt (hcl, HCL_EGENERIC, "connection closed");
|
case HCL_XPKT_CODEIN:
|
||||||
return -1;
|
printf ("FEEDING [%.*s]\n", (int)len, data);
|
||||||
}
|
if (hcl_feedbchars(hcl, data, len) <= -1)
|
||||||
|
|
||||||
if (HCL_LIKELY(!proto->rcv.polled))
|
|
||||||
{
|
|
||||||
tmout = HCL_SECNSEC_TO_MSEC(server->cfg.worker_idle_timeout.sec, server->cfg.worker_idle_timeout.nsec);
|
|
||||||
actual_tmout = (tmout <= 0)? 10000: tmout;
|
|
||||||
|
|
||||||
pfd.fd = worker->sck;
|
|
||||||
pfd.events = POLLIN | POLLERR;
|
|
||||||
pfd.revents = 0;
|
|
||||||
n = poll(&pfd, 1, actual_tmout);
|
|
||||||
if (n <= -1)
|
|
||||||
{
|
|
||||||
if (errno == EINTR) return 0;
|
|
||||||
hcl_seterrwithsyserr (hcl, 0, errno);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else if (n == 0)
|
|
||||||
{
|
|
||||||
/* timed out - no activity on the pfd */
|
|
||||||
if (tmout > 0)
|
|
||||||
{
|
{
|
||||||
/* timeout explicity set. no activity for that duration. considered idle */
|
/* TODO: backup error message...and create a new message */
|
||||||
hcl_seterrbfmt (hcl, HCL_EGENERIC, "no activity on the worker socket %d", worker->sck);
|
goto oops;
|
||||||
return -1;
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HCL_XPKT_EXECUTE:
|
||||||
|
{
|
||||||
|
hcl_oop_t retv;
|
||||||
|
printf ("EXECUTING hcl_executing......\n");
|
||||||
|
|
||||||
|
hcl_decode (hcl, hcl_getcode(hcl), 0, hcl_getbclen(hcl));
|
||||||
|
|
||||||
|
retv = hcl_execute(hcl);
|
||||||
|
hcl_flushudio (hcl);
|
||||||
|
hcl_clearcode (hcl);
|
||||||
|
if (!retv)
|
||||||
|
{
|
||||||
|
/* TODO: backup error message...and create a new message */
|
||||||
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0; /* didn't read yet */
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pfd.revents & POLLERR)
|
case HCL_XPKT_STDIN:
|
||||||
{
|
/* store ... push stdin pipe... */
|
||||||
hcl_seterrbfmt (hcl, HCL_EGENERIC, "error condition detected on workder socket %d", worker->sck);
|
/*if (hcl_feedstdin() <= -1) */
|
||||||
return -1;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
proto->rcv.polled = 1;
|
case HCL_XPKT_LIST_WORKERS:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HCL_XPKT_KILL_WORKER:
|
||||||
|
break;
|
||||||
|
case HCL_XPKT_DISCONNECT:
|
||||||
|
return 0; /* disconnect received */
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* unknown packet type */
|
||||||
|
/* TODO: proper error message */
|
||||||
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
x = recv(worker->sck, &proto->rcv.buf[proto->rcv.len], HCL_COUNTOF(proto->rcv.buf) - proto->rcv.len, 0);
|
return 1;
|
||||||
if (x <= -1)
|
|
||||||
{
|
|
||||||
if (errno == EINTR) return 0; /* didn't read read */
|
|
||||||
|
|
||||||
proto->rcv.polled = 0;
|
|
||||||
hcl_seterrwithsyserr (hcl, 0, errno);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
proto->rcv.polled = 0;
|
oops:
|
||||||
if (x == 0) proto->rcv.eof = 1;
|
return -1;
|
||||||
|
|
||||||
proto->rcv.len += x;
|
|
||||||
return 1; /* read some data */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1094,12 +1065,12 @@ static int handle_received_data (hcl_server_proto_t* proto)
|
|||||||
{
|
{
|
||||||
hcl_server_worker_t* worker = proto->worker;
|
hcl_server_worker_t* worker = proto->worker;
|
||||||
hcl_t* hcl = proto->hcl;
|
hcl_t* hcl = proto->hcl;
|
||||||
hcl_xpkt_hdr_t* hdr;
|
int n;
|
||||||
|
|
||||||
switch (proto->rcv.state)
|
switch (proto->rcv.state)
|
||||||
{
|
{
|
||||||
case HCL_SERVER_PROTO_RCV_HEADER:
|
case HCL_SERVER_PROTO_RCV_HEADER:
|
||||||
if (proto->rcv.len < HCL_SIZEOF(proto->rcv.hdr)) return 0; /* need more data */
|
if (proto->rcv.len < HCL_SIZEOF(proto->rcv.hdr)) goto carry_on; /* need more data */
|
||||||
|
|
||||||
HCL_MEMCPY (&proto->rcv.hdr, proto->rcv.buf, HCL_SIZEOF(proto->rcv.hdr));
|
HCL_MEMCPY (&proto->rcv.hdr, proto->rcv.buf, HCL_SIZEOF(proto->rcv.hdr));
|
||||||
/*proto->rcv.hdr.len = hcl_ntoh16(proto->rcv.hdr.len);*/ /* keep this in the host byte order */
|
/*proto->rcv.hdr.len = hcl_ntoh16(proto->rcv.hdr.len);*/ /* keep this in the host byte order */
|
||||||
@ -1109,54 +1080,26 @@ static int handle_received_data (hcl_server_proto_t* proto)
|
|||||||
proto->rcv.len -= HCL_SIZEOF(proto->rcv.hdr);
|
proto->rcv.len -= HCL_SIZEOF(proto->rcv.hdr);
|
||||||
|
|
||||||
/* switch to the payload mode */
|
/* switch to the payload mode */
|
||||||
proto->rcv.state = HCL_SERVER_PROTO_RCV_PAYLOAD;
|
if (proto->rcv.hdr.len > 0)
|
||||||
proto->rcv.len_needed = proto->rcv.hdr.len;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case HCL_SERVER_PROTO_RCV_PAYLOAD:
|
|
||||||
if (proto->rcv.len < proto->rcv.hdr.len) return 0; /* need more payload data */
|
|
||||||
|
|
||||||
if (proto->rcv.hdr.type == HCL_XPKT_CODEIN)
|
|
||||||
{
|
|
||||||
printf ("FEEDING [%.*s]\n", proto->rcv.hdr.len, proto->rcv.buf);
|
|
||||||
if (hcl_feedbchars(hcl, (const hcl_bch_t*)proto->rcv.buf, proto->rcv.hdr.len) <= -1)
|
|
||||||
{
|
|
||||||
/* TODO: backup error message...and create a new message */
|
|
||||||
goto fail_with_errmsg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (proto->rcv.hdr.type == HCL_XPKT_EXECUTE)
|
|
||||||
{
|
|
||||||
hcl_oop_t retv;
|
|
||||||
printf ("EXECUTING hcl_executing......\n");
|
|
||||||
proto->feed.ongoing = 0;
|
|
||||||
|
|
||||||
hcl_decode (hcl, hcl_getcode(hcl), 0, hcl_getbclen(hcl));
|
|
||||||
|
|
||||||
retv = hcl_execute(hcl);
|
|
||||||
hcl_flushudio (hcl);
|
|
||||||
if (!retv)
|
|
||||||
{
|
|
||||||
/* TODO: backup error message...and create a new message */
|
|
||||||
goto fail_with_errmsg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (proto->rcv.hdr.type == HCL_XPKT_STDIN)
|
|
||||||
{
|
|
||||||
/* store ... push stdin pipe... */
|
|
||||||
/*if (hcl_feedstdin() <= -1) */
|
|
||||||
}
|
|
||||||
else if (proto->rcv.hdr.type == HCL_XPKT_LIST_WORKERS)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
else if (proto->rcv.hdr.type == HCL_XPKT_KILL_WORKER)
|
|
||||||
{
|
{
|
||||||
|
proto->rcv.state = HCL_SERVER_PROTO_RCV_PAYLOAD;
|
||||||
|
proto->rcv.len_needed = proto->rcv.hdr.len;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* error ... unknown request type */
|
/* take shortcut */
|
||||||
|
n = handle_packet(proto, proto->rcv.hdr.type, proto->rcv.buf, proto->rcv.hdr.len);
|
||||||
|
if (n <= -1) goto fail_with_errmsg;
|
||||||
|
if (n == 0) return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HCL_SERVER_PROTO_RCV_PAYLOAD:
|
||||||
|
if (proto->rcv.len < proto->rcv.hdr.len) goto carry_on; /* need more payload data */
|
||||||
|
|
||||||
|
n = handle_packet(proto, proto->rcv.hdr.type, proto->rcv.buf, proto->rcv.hdr.len);
|
||||||
|
|
||||||
/* TODO: minimize the use of HCL_MEMOVE... use the buffer */
|
/* TODO: minimize the use of HCL_MEMOVE... use the buffer */
|
||||||
/* switch to the header mode */
|
/* switch to the header mode */
|
||||||
if (proto->rcv.hdr.len > 0)
|
if (proto->rcv.hdr.len > 0)
|
||||||
@ -1167,6 +1110,9 @@ printf ("EXECUTING hcl_executing......\n");
|
|||||||
proto->rcv.state = HCL_SERVER_PROTO_RCV_HEADER;
|
proto->rcv.state = HCL_SERVER_PROTO_RCV_HEADER;
|
||||||
proto->rcv.len_needed = HCL_SIZEOF(proto->rcv.hdr);
|
proto->rcv.len_needed = HCL_SIZEOF(proto->rcv.hdr);
|
||||||
|
|
||||||
|
if (n <= -1) goto fail_with_errmsg;
|
||||||
|
if (n == 0) return 0;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1174,7 +1120,8 @@ printf ("EXECUTING hcl_executing......\n");
|
|||||||
goto fail_with_errmsg;
|
goto fail_with_errmsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1; /* processed 1 packet */
|
carry_on:
|
||||||
|
return 1;
|
||||||
|
|
||||||
fail_with_errmsg:
|
fail_with_errmsg:
|
||||||
// TODO: proper error handling
|
// TODO: proper error handling
|
||||||
@ -1650,7 +1597,7 @@ static int worker_step (hcl_server_worker_t* worker)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0; /* didn't read yet */
|
goto carry_on;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pfd.revents & POLLERR)
|
if (pfd.revents & POLLERR)
|
||||||
@ -1668,9 +1615,8 @@ static int worker_step (hcl_server_worker_t* worker)
|
|||||||
x = recv(worker->sck, &proto->rcv.buf[proto->rcv.len], HCL_COUNTOF(proto->rcv.buf) - proto->rcv.len, 0);
|
x = recv(worker->sck, &proto->rcv.buf[proto->rcv.len], HCL_COUNTOF(proto->rcv.buf) - proto->rcv.len, 0);
|
||||||
if (x <= -1)
|
if (x <= -1)
|
||||||
{
|
{
|
||||||
if (errno == EINTR) return 0; /* didn't read read */
|
if (errno == EINTR) goto carry_on; /* didn't read read */
|
||||||
|
|
||||||
proto->rcv.polled = 0;
|
|
||||||
hcl_seterrwithsyserr (hcl, 0, errno);
|
hcl_seterrwithsyserr (hcl, 0, errno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1684,14 +1630,20 @@ static int worker_step (hcl_server_worker_t* worker)
|
|||||||
/* the receiver buffer has enough data */
|
/* the receiver buffer has enough data */
|
||||||
while (/*proto->rcv.len > 0 && */proto->rcv.len >= proto->rcv.len_needed)
|
while (/*proto->rcv.len > 0 && */proto->rcv.len >= proto->rcv.len_needed)
|
||||||
{
|
{
|
||||||
if (handle_received_data(proto) <= -1)
|
if ((n = handle_received_data(proto)) <= -1)
|
||||||
{
|
{
|
||||||
/* TODO: proper error message */
|
/* TODO: proper error message */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (n == 0)
|
||||||
|
{
|
||||||
|
/* TODO: chceck if there is remaining data in the buffer...?? */
|
||||||
|
return 0; /* tell the caller to break the step loop */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
carry_on:
|
||||||
|
return 1; /* carry on */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* worker_main (void* ctx)
|
static void* worker_main (void* ctx)
|
||||||
@ -1718,11 +1670,12 @@ static void* worker_main (void* ctx)
|
|||||||
/* the worker loop */
|
/* the worker loop */
|
||||||
while (!server->stopreq)
|
while (!server->stopreq)
|
||||||
{
|
{
|
||||||
|
int n;
|
||||||
worker->opstate = HCL_SERVER_WORKER_OPSTATE_WAIT;
|
worker->opstate = HCL_SERVER_WORKER_OPSTATE_WAIT;
|
||||||
|
|
||||||
if (worker_step(worker) <= -1)
|
if ((n = worker_step(worker)) <= 0)
|
||||||
{
|
{
|
||||||
worker->opstate = HCL_SERVER_WORKER_OPSTATE_ERROR;
|
worker->opstate = (n <= -1)? HCL_SERVER_WORKER_OPSTATE_ERROR: HCL_SERVER_WORKER_OPSTATE_IDLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,9 @@ enum hcl_xpkt_type_t
|
|||||||
HCL_XPKT_STDOUT,
|
HCL_XPKT_STDOUT,
|
||||||
|
|
||||||
HCL_XPKT_LIST_WORKERS,
|
HCL_XPKT_LIST_WORKERS,
|
||||||
HCL_XPKT_KILL_WORKER
|
HCL_XPKT_KILL_WORKER,
|
||||||
|
|
||||||
|
HCL_XPKT_DISCONNECT
|
||||||
};
|
};
|
||||||
typedef enum hcl_xpkt_type_t hcl_xpkt_type_t;
|
typedef enum hcl_xpkt_type_t hcl_xpkt_type_t;
|
||||||
|
|
||||||
|
@ -397,6 +397,13 @@ void hcl_reset (hcl_t* hcl)
|
|||||||
hcl_gc (hcl, 1);
|
hcl_gc (hcl, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hcl_clearcode (hcl_t* hcl)
|
||||||
|
{
|
||||||
|
/* clear the code buffer and the literal frame only */
|
||||||
|
hcl->code.bc.len = 0;
|
||||||
|
hcl->code.lit.len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int dup_str_opt (hcl_t* hcl, const hcl_ooch_t* value, hcl_oocs_t* tmp)
|
static int dup_str_opt (hcl_t* hcl, const hcl_ooch_t* value, hcl_oocs_t* tmp)
|
||||||
{
|
{
|
||||||
if (value)
|
if (value)
|
||||||
|
@ -2548,6 +2548,10 @@ HCL_EXPORT int hcl_decode (
|
|||||||
hcl_oow_t end
|
hcl_oow_t end
|
||||||
);
|
);
|
||||||
|
|
||||||
|
HCL_EXPORT void hcl_clearcode (
|
||||||
|
hcl_t* hcl
|
||||||
|
);
|
||||||
|
|
||||||
#if defined(HCL_HAVE_INLINE)
|
#if defined(HCL_HAVE_INLINE)
|
||||||
static HCL_INLINE hcl_code_t* hcl_getcode (hcl_t* hcl) { return &hcl->code; }
|
static HCL_INLINE hcl_code_t* hcl_getcode (hcl_t* hcl) { return &hcl->code; }
|
||||||
static HCL_INLINE hcl_oob_t* hcl_getbcptr (hcl_t* hcl) { return hcl->code.bc.ptr; }
|
static HCL_INLINE hcl_oob_t* hcl_getbcptr (hcl_t* hcl) { return hcl->code.bc.ptr; }
|
||||||
|
@ -667,7 +667,7 @@ static HCL_INLINE hcl_cnode_t* leave_list (hcl_t* hcl, hcl_loc_t* list_loc, int*
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!HCL_CNODE_IS_SYMBOL_PLAIN(lval))
|
if (!HCL_CNODE_IS_SYMBOL_PLAIN(lval) && !HCL_CNODE_IS_DSYMBOL_CLA(lval))
|
||||||
{
|
{
|
||||||
hcl_setsynerrbfmt (hcl, HCL_SYNERR_LVALUE, HCL_CNODE_GET_LOC(lval), HCL_CNODE_GET_TOK(lval), "invalid lvalue - not symbol");
|
hcl_setsynerrbfmt (hcl, HCL_SYNERR_LVALUE, HCL_CNODE_GET_LOC(lval), HCL_CNODE_GET_TOK(lval), "invalid lvalue - not symbol");
|
||||||
goto oops;
|
goto oops;
|
||||||
|
@ -24,3 +24,30 @@ else { printf "OK: value is %d\n" v };
|
|||||||
v := (dic.get j 4512);
|
v := (dic.get j 4512);
|
||||||
if (nqv? v 1234) { printf "ERROR: v is not 1234\n" } \
|
if (nqv? v 1234) { printf "ERROR: v is not 1234\n" } \
|
||||||
else { printf "OK: value is %d\n" v };
|
else { printf "OK: value is %d\n" v };
|
||||||
|
|
||||||
|
## --------------------------------------------------------------
|
||||||
|
|
||||||
|
class X | a b c d | {
|
||||||
|
fun :*new() {
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
fun x() {
|
||||||
|
a := 20 ; self.b:=(a + 10); c := (b + 20)
|
||||||
|
printf "%d %d %d\n" self.a self.b self.c
|
||||||
|
return (+ self.a self.b self.c)
|
||||||
|
}
|
||||||
|
fun y() {
|
||||||
|
self.d := (fun(k) {
|
||||||
|
return (k + 1)
|
||||||
|
})
|
||||||
|
return self.d
|
||||||
|
}
|
||||||
|
|
||||||
|
}; a := (X:new); v := (a:x)
|
||||||
|
if (nqv? v 100) { printf "ERROR: v is not 100\n" } \
|
||||||
|
else { printf "OK: value is %d\n" v }
|
||||||
|
|
||||||
|
v := ((a:y) 20);
|
||||||
|
if (nqv? v 21) { printf "ERROR: v is not 21\n" } \
|
||||||
|
else { printf "OK: value is %d\n" v }
|
||||||
|
Loading…
Reference in New Issue
Block a user