diff --git a/lib/comp.c b/lib/comp.c index f4c4a03..8f596a8 100644 --- a/lib/comp.c +++ b/lib/comp.c @@ -1949,6 +1949,34 @@ static HCL_INLINE int post_catch (hcl_t* hcl) return 0; } +static int compile_throw (hcl_t* hcl, hcl_cnode_t* src) +{ + hcl_cnode_t* cmd, * obj; + hcl_cframe_t* cf; + hcl_ooi_t jump_inst_pos; + + HCL_ASSERT (hcl, HCL_CNODE_IS_CONS(src)); + + HCL_ASSERT (hcl, HCL_CNODE_IS_SYMBOL_SYNCODED(HCL_CNODE_CONS_CAR(src), HCL_SYNCODE_THROW)); + + cmd = HCL_CNODE_CONS_CDR(src); + obj = HCL_CNODE_CONS_CDR(src); + + if (!obj) + { + /* no value */ + hcl_setsynerrbfmt (hcl, HCL_SYNERR_ARGCOUNT, HCL_CNODE_GET_LOC(src), HCL_NULL, "no expression specified in %.*js", HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd)); + return -1; + } + else if (!HCL_CNODE_IS_CONS(obj)) + { + hcl_setsynerrbfmt (hcl, HCL_SYNERR_DOTBANNED, HCL_CNODE_GET_LOC(obj), HCL_CNODE_GET_TOK(obj), "redundant cdr in %.*js", HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd)); + return -1; + } + + return 0; +} + /* ========================================================================= */ static int compile_while (hcl_t* hcl, hcl_cnode_t* src, int next_cop) @@ -2165,6 +2193,10 @@ static int compile_cons_xlist_expression (hcl_t* hcl, hcl_cnode_t* obj) if (compile_return(hcl, obj, 1) <= -1) return -1; break; + case HCL_SYNCODE_THROW: + if (compile_throw(hcl, obj) <= -1) return -1; + break; + case HCL_SYNCODE_TRY: if (compile_try(hcl, obj) <= -1) return -1; break; diff --git a/lib/gc.c b/lib/gc.c index c6f1b6b..b1e0de6 100644 --- a/lib/gc.c +++ b/lib/gc.c @@ -54,7 +54,8 @@ static struct { 16, { 'r','e','t','u','r','n','-','f','r','o','m','-','h','o','m','e'}, HCL_SYNCODE_RETURN_FROM_HOME, HCL_OFFSETOF(hcl_t,_return_from_home) }, { 3, { 's','e','t' }, HCL_SYNCODE_SET, HCL_OFFSETOF(hcl_t,_set) }, - { 3, { 't','r','y' }, HCL_SYNCODE_TRY, HCL_OFFSETOF(hcl_t,_try) }, + { 5, { 't','h','r','o','w' }, HCL_SYNCODE_THROW, HCL_OFFSETOF(hcl_t,_throw) }, + { 3, { 't','r','y' }, HCL_SYNCODE_TRY, HCL_OFFSETOF(hcl_t,_try) }, { 5, { 'u','n','t','i','l' }, HCL_SYNCODE_UNTIL, HCL_OFFSETOF(hcl_t,_until) }, { 5, { 'w','h','i','l','e' }, HCL_SYNCODE_WHILE, HCL_OFFSETOF(hcl_t,_while) } }; diff --git a/lib/hcl.h b/lib/hcl.h index c105ce8..bb4abc7 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -1416,6 +1416,7 @@ struct hcl_t hcl_oop_t _return; /* symbol */ hcl_oop_t _return_from_home; /* symbol */ hcl_oop_t _set; /* symbol */ + hcl_oop_t _throw; /* symbol */ hcl_oop_t _try; /* symbol */ hcl_oop_t _until; /* symbol */ hcl_oop_t _while; /* symbol */ @@ -1689,6 +1690,7 @@ enum hcl_syncode_t HCL_SYNCODE_RETURN, HCL_SYNCODE_RETURN_FROM_HOME, HCL_SYNCODE_SET, + HCL_SYNCODE_THROW, HCL_SYNCODE_TRY, HCL_SYNCODE_UNTIL, HCL_SYNCODE_WHILE diff --git a/lib/heap.c b/lib/heap.c index 52dd8f0..b577d64 100644 --- a/lib/heap.c +++ b/lib/heap.c @@ -38,7 +38,7 @@ static void* xma_realloc (hcl_mmgr_t* mmgr, void* ptr, hcl_oow_t size) static void xma_free (hcl_mmgr_t* mmgr, void* ptr) { - return hcl_xma_free (mmgr->ctx, ptr); + hcl_xma_free (mmgr->ctx, ptr); } hcl_heap_t* hcl_makeheap (hcl_t* hcl, hcl_oow_t size) diff --git a/lib/xutl-sa.h b/lib/xutl-sa.h index 1788112..c30137c 100644 --- a/lib/xutl-sa.h +++ b/lib/xutl-sa.h @@ -184,7 +184,7 @@ int str_to_sockaddr (hcl_t* hcl, const ooch_t* str, hcl_oow_t len, hcl_sckaddr_t if (*p == '%') { /* handle scope id */ - hcl_uint32_t x; + hcl_uint32_t x, y; p++; /* skip % */ @@ -198,19 +198,20 @@ int str_to_sockaddr (hcl_t* hcl, const ooch_t* str, hcl_oow_t len, hcl_sckaddr_t if (*p >= '0' && *p <= '9') { /* numeric scope id */ - nwad->in6.sin6_scope_id = 0; + y = 0; do { - x = nwad->in6.sin6_scope_id * 10 + (*p - '0'); - if (x < nwad->in6.sin6_scope_id) + x = y * 10 + (*p - '0'); + if (x < y) { if (hcl) hcl_seterrbfmt (hcl, HCL_EINVAL, "scope id too large"); return -1; /* overflow */ } - nwad->in6.sin6_scope_id = x; + y = x; p++; } while (p < end && *p >= '0' && *p <= '9'); + //nwad->in6.sin6_scope_id = y; } else { @@ -220,7 +221,7 @@ TODO: const ooch_t* stmp = p; unsigned int index; do p++; while (p < end && *p != ']'); - if (hcl_nwifwcsntoindex (stmp, p - stmp, &index) <= -1) return -1; + if (hcl_nwifwcsntoindex(stmp, p - stmp, &index) <= -1) return -1; tmpad.u.in6.scope = index; #endif } @@ -259,7 +260,7 @@ TODO: if (p < end && *p == '%') { /* handle scope id */ - hcl_uint32_t x; + hcl_uint32_t x, y; p++; /* skip % */ @@ -273,19 +274,20 @@ TODO: if (*p >= '0' && *p <= '9') { /* numeric scope id */ - nwad->in6.sin6_scope_id = 0; + y = 0; do { - x = nwad->in6.sin6_scope_id * 10 + (*p - '0'); - if (x < nwad->in6.sin6_scope_id) + x = y * 10 + (*p - '0'); + if (x < y) { if (hcl) hcl_seterrbfmt (hcl, HCL_EINVAL, "scope id too large"); return -1; /* overflow */ } - nwad->in6.sin6_scope_id = x; + y = x; p++; } while (p < end && *p >= '0' && *p <= '9'); + //nwad->in6.sin6_scope_id = y; } else {