2023-12-23 12:43:26 +09:00
|
|
|
/*
|
|
|
|
Copyright (c) 2016-2018 Chung, Hyung-Hwan. All rights reserved.
|
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
|
|
modification, are permitted provided that the following conditions
|
|
|
|
are met:
|
|
|
|
1. Redistributions of source code must retain the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer in the
|
|
|
|
documentation and/or other materials provided with the distribution.
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
|
|
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
#include "hak-prv.h"
|
2023-12-23 12:43:26 +09:00
|
|
|
|
|
|
|
/* compiler's literal representation */
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
#include <hak-pac1.h>
|
|
|
|
struct hak_xchg_hdr_t
|
2023-12-23 12:43:26 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_uint8_t ver;
|
|
|
|
hak_uint8_t oow_size;
|
2023-12-23 12:43:26 +09:00
|
|
|
};
|
2025-09-02 23:58:15 +09:00
|
|
|
typedef struct hak_xchg_hdr_t hak_xchg_hdr_t;
|
|
|
|
#include <hak-upac.h>
|
2023-12-23 12:43:26 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
enum hak_xchg_type_t
|
2023-12-23 12:43:26 +09:00
|
|
|
{
|
2023-12-27 09:09:40 +09:00
|
|
|
/* byte code */
|
2025-09-02 23:58:15 +09:00
|
|
|
HAK_XCHG_BC = 0x00,
|
2023-12-27 09:09:40 +09:00
|
|
|
|
|
|
|
/* literals */
|
2025-09-02 23:58:15 +09:00
|
|
|
HAK_XCHG_STRING_U,
|
|
|
|
HAK_XCHG_STRING_B,
|
|
|
|
HAK_XCHG_SYMLIT_U, /* literal symbol */
|
|
|
|
HAK_XCHG_SYMLIT_B, /* literal symbol */
|
|
|
|
HAK_XCHG_SYMBOL_U, /* contained in a cons cell */
|
|
|
|
HAK_XCHG_SYMBOL_B, /* contained in a cons cell */
|
|
|
|
HAK_XCHG_SMOOI,
|
|
|
|
HAK_XCHG_PBIGINT,
|
|
|
|
HAK_XCHG_NBIGINT,
|
|
|
|
HAK_XCHG_FPDEC_1, /* smooi + smooi */
|
|
|
|
HAK_XCHG_FPDEC_2, /* pbigint + smooi */
|
|
|
|
HAK_XCHG_FPDEC_3, /* nbigint + smooi */
|
|
|
|
HAK_XCHG_PRIM,
|
2023-12-27 09:09:40 +09:00
|
|
|
|
|
|
|
/* end marker */
|
2025-09-02 23:58:15 +09:00
|
|
|
HAK_XCHG_END =0xFF /* end marker. not a real literal type */
|
2023-12-23 12:43:26 +09:00
|
|
|
};
|
2025-09-02 23:58:15 +09:00
|
|
|
typedef enum hak_xchg_type_t hak_xchg_type_t;
|
2023-12-23 12:43:26 +09:00
|
|
|
|
2023-12-30 22:28:04 +09:00
|
|
|
/* -------------------------------------------------------------------- */
|
2023-12-23 12:43:26 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
int hak_marshalcode (hak_t* hak, const hak_code_t* code, hak_xchg_writer_t wrtr, void* ctx)
|
2023-12-23 12:43:26 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_oow_t i, lfbase = 0;
|
|
|
|
hak_oop_t tmp;
|
|
|
|
hak_oop_class_t _class;
|
2023-12-23 12:43:26 +09:00
|
|
|
int brand;
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_oow_t tsize;
|
|
|
|
hak_uint8_t b;
|
|
|
|
hak_oow_t w;
|
|
|
|
hak_xchg_hdr_t h;
|
2024-04-14 18:33:15 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
lfbase = (hak->option.trait & HAK_TRAIT_INTERACTIVE)? hak->c->funblk.info[hak->c->funblk.depth].lfbase: 0;
|
2023-12-23 12:43:26 +09:00
|
|
|
|
|
|
|
/* start with a header */
|
|
|
|
h.ver = 1;
|
2025-09-02 23:58:15 +09:00
|
|
|
h.oow_size = (hak_uint8_t)HAK_SIZEOF(hak_oow_t); /* the size must not exceed 256 */
|
|
|
|
if (wrtr(hak, &h, HAK_SIZEOF(h), ctx) <= -1) goto oops;
|
2023-12-23 12:43:26 +09:00
|
|
|
|
2023-12-27 09:09:40 +09:00
|
|
|
/* write the byte-code */
|
2025-09-02 23:58:15 +09:00
|
|
|
b = HAK_XCHG_BC;
|
|
|
|
if (wrtr(hak, &b, HAK_SIZEOF(b), ctx) <= -1) goto oops;
|
|
|
|
w = hak_htoleoow(code->bc.len);
|
|
|
|
if (wrtr(hak, &w, HAK_SIZEOF(w), ctx) <= -1) goto oops;
|
|
|
|
if (wrtr(hak, code->bc.ptr, code->bc.len, ctx) <= -1) goto oops;
|
2023-12-27 09:09:40 +09:00
|
|
|
|
2023-12-23 12:43:26 +09:00
|
|
|
/* write actual literals */
|
2023-12-27 09:09:40 +09:00
|
|
|
for (i = lfbase; i < code->lit.len; i++)
|
2023-12-23 12:43:26 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
tmp = ((hak_oop_oop_t)code->lit.arr)->slot[i];
|
|
|
|
if (HAK_OOP_IS_SMOOI(tmp))
|
2024-01-02 01:41:41 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
b = HAK_XCHG_SMOOI;
|
|
|
|
if (wrtr(hak, &b, HAK_SIZEOF(b), ctx) <= -1) goto oops;
|
|
|
|
w = hak_htoleoow((hak_oow_t)HAK_OOP_TO_SMOOI(tmp));
|
|
|
|
if (wrtr(hak, &w, HAK_SIZEOF(w), ctx) <= -1) goto oops;
|
2024-01-02 01:41:41 +09:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
_class = (hak_oop_class_t)HAK_CLASSOF(hak, tmp);
|
|
|
|
brand = HAK_OOP_TO_SMOOI(_class->ibrand);
|
|
|
|
tsize = HAK_OBJ_GET_SIZE(tmp);
|
2023-12-23 12:43:26 +09:00
|
|
|
|
|
|
|
switch (brand)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
case HAK_BRAND_PBIGINT:
|
|
|
|
case HAK_BRAND_NBIGINT:
|
2023-12-23 12:43:26 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_oow_t nbytes;
|
|
|
|
hak_oow_t j;
|
|
|
|
hak_liw_t liw;
|
2023-12-23 12:43:26 +09:00
|
|
|
|
|
|
|
/* write the brand */
|
2025-09-02 23:58:15 +09:00
|
|
|
b = (brand == HAK_BRAND_PBIGINT ? HAK_XCHG_PBIGINT : HAK_XCHG_NBIGINT);
|
|
|
|
if (wrtr(hak, &b, HAK_SIZEOF(b), ctx) <= -1) goto oops;
|
2023-12-23 12:43:26 +09:00
|
|
|
|
2023-12-27 09:09:40 +09:00
|
|
|
bigint_body:
|
2023-12-23 12:43:26 +09:00
|
|
|
/* write the number of bytes in the little-endian */
|
2025-09-02 23:58:15 +09:00
|
|
|
nbytes = tsize * HAK_SIZEOF(hak_liw_t);
|
|
|
|
w = hak_htoleoow(nbytes);
|
|
|
|
if (wrtr(hak, &w, HAK_SIZEOF(w), ctx) <= -1) goto oops;
|
2023-12-23 12:43:26 +09:00
|
|
|
|
|
|
|
for (j = 0; j < tsize; j++)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
liw = HAK_OBJ_GET_LIWORD_VAL(tmp, j);
|
|
|
|
liw = hak_htoleliw(liw);
|
|
|
|
if (wrtr(hak, &liw, HAK_SIZEOF(liw), ctx) <= -1) goto oops;
|
2023-12-23 12:43:26 +09:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
case HAK_BRAND_FPDEC:
|
2023-12-23 12:43:26 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_oop_fpdec_t f;
|
2023-12-23 12:43:26 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
f = (hak_oop_fpdec_t)tmp;
|
|
|
|
HAK_ASSERT (hak, HAK_OOP_IS_SMOOI(f->scale));
|
|
|
|
HAK_ASSERT(hak, HAK_OOP_IS_SMOOI(f->value) || HAK_OOP_IS_POINTER(f->value));
|
2023-12-23 12:43:26 +09:00
|
|
|
|
|
|
|
/* write 1-byte brand */
|
2025-09-02 23:58:15 +09:00
|
|
|
if (HAK_OOP_IS_SMOOI(f->value)) b = HAK_XCHG_FPDEC_1;
|
|
|
|
else if (HAK_IS_PBIGINT(hak, f->value)) b = HAK_XCHG_FPDEC_2;
|
2023-12-23 12:43:26 +09:00
|
|
|
else
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
HAK_ASSERT(hak, HAK_IS_NBIGINT(hak, f->value));
|
|
|
|
b = HAK_XCHG_FPDEC_2;
|
2023-12-23 12:43:26 +09:00
|
|
|
}
|
2025-09-02 23:58:15 +09:00
|
|
|
if (wrtr(hak, &b, HAK_SIZEOF(b), ctx) <= -1) goto oops;
|
2023-12-23 12:43:26 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
/* cast the scale part from hak_ooi_t to hak_oow_t and write it */
|
|
|
|
w = hak_htoleoow((hak_oow_t)HAK_OOP_TO_SMOOI(f->scale));
|
|
|
|
if (wrtr(hak, &w, HAK_SIZEOF(w), ctx) <= -1) goto oops;
|
2023-12-23 12:43:26 +09:00
|
|
|
|
2023-12-27 09:09:40 +09:00
|
|
|
/* write the value part */
|
2025-09-02 23:58:15 +09:00
|
|
|
if (b == HAK_XCHG_FPDEC_1)
|
2023-12-27 09:09:40 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
w = hak_htoleoow((hak_oow_t)HAK_OOP_TO_SMOOI(f->value));
|
|
|
|
if (wrtr(hak, &w, HAK_SIZEOF(w), ctx) <= -1) goto oops;
|
2023-12-27 09:09:40 +09:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tmp = f->value;
|
2025-09-02 23:58:15 +09:00
|
|
|
tsize = HAK_OBJ_GET_SIZE(tmp);
|
2023-12-27 09:09:40 +09:00
|
|
|
goto bigint_body;
|
|
|
|
}
|
2023-12-23 12:43:26 +09:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
case HAK_BRAND_CONS:
|
2023-12-27 09:09:40 +09:00
|
|
|
{
|
|
|
|
/* write 1-byte brand */
|
2025-09-02 23:58:15 +09:00
|
|
|
#if defined(HAK_OOCH_IS_UCH)
|
|
|
|
b = (hak_uint8_t)HAK_XCHG_SYMBOL_U;
|
2023-12-27 09:09:40 +09:00
|
|
|
#else
|
2025-09-02 23:58:15 +09:00
|
|
|
b = (hak_uint8_t)HAK_XCHG_SYMBOL_B;
|
2023-12-27 09:09:40 +09:00
|
|
|
#endif
|
2025-09-02 23:58:15 +09:00
|
|
|
if (wrtr(hak, &b, HAK_SIZEOF(b), ctx) <= -1) goto oops;
|
2023-12-27 09:09:40 +09:00
|
|
|
|
|
|
|
/* get the symbol at CAR and make it as if it is the current object processed.*/
|
2025-09-02 23:58:15 +09:00
|
|
|
tmp = HAK_CONS_CAR(tmp);
|
|
|
|
tsize = HAK_OBJ_GET_SIZE(tmp);
|
2023-12-27 09:09:40 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
HAK_ASSERT(hak, HAK_CLASSOF(hak, tmp) == (hak_oop_t)hak->c_symbol);
|
2023-12-27 09:09:40 +09:00
|
|
|
goto string_body;
|
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
case HAK_BRAND_STRING:
|
|
|
|
case HAK_BRAND_SYMBOL:
|
2023-12-23 12:43:26 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
#if defined(HAK_OOCH_IS_UCH)
|
|
|
|
hak_uch_t* ucsptr;
|
|
|
|
hak_oow_t ucspos, ucslen;
|
|
|
|
hak_bch_t bcsbuf[128];
|
|
|
|
hak_oow_t bcslen;
|
2023-12-23 12:43:26 +09:00
|
|
|
int n;
|
|
|
|
|
|
|
|
/* write 1-byte brand */
|
2025-09-02 23:58:15 +09:00
|
|
|
b = (hak_uint8_t)(brand == HAK_BRAND_STRING? HAK_XCHG_STRING_U: HAK_XCHG_SYMLIT_U);
|
|
|
|
if (wrtr(hak, &b, HAK_SIZEOF(b), ctx) <= -1) goto oops;
|
2023-12-23 12:43:26 +09:00
|
|
|
|
|
|
|
string_body:
|
2025-09-02 23:58:15 +09:00
|
|
|
ucsptr = HAK_OBJ_GET_CHAR_SLOT(tmp);
|
2023-12-23 12:43:26 +09:00
|
|
|
ucslen = tsize;
|
2025-09-02 23:58:15 +09:00
|
|
|
if (hak_convutobchars(hak, ucsptr, &ucslen, HAK_NULL, &bcslen) <= -1) goto oops;
|
2023-12-23 12:43:26 +09:00
|
|
|
|
2023-12-27 09:09:40 +09:00
|
|
|
/* write the number of characters in the little endian */
|
2025-09-02 23:58:15 +09:00
|
|
|
w = hak_htoleoow(tsize);
|
|
|
|
if (wrtr(hak, &w, HAK_SIZEOF(w), ctx) <= -1) goto oops;
|
2023-12-27 09:09:40 +09:00
|
|
|
|
|
|
|
/* write the number of bytes in the little endian */
|
2025-09-02 23:58:15 +09:00
|
|
|
w = hak_htoleoow(bcslen);
|
|
|
|
if (wrtr(hak, &w, HAK_SIZEOF(w), ctx) <= -1) goto oops;
|
2023-12-23 12:43:26 +09:00
|
|
|
|
|
|
|
/* write string in bytess and write to the callback.*/
|
|
|
|
ucspos = 0;
|
|
|
|
while (ucspos < tsize)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
bcslen = HAK_COUNTOF(bcsbuf);
|
2023-12-23 12:43:26 +09:00
|
|
|
ucslen = tsize - ucspos;
|
2025-09-02 23:58:15 +09:00
|
|
|
n = hak_convutobchars(hak, &ucsptr[ucspos], &ucslen, bcsbuf, &bcslen);
|
2023-12-23 12:43:26 +09:00
|
|
|
if (n <= -1 && bcslen == 0) goto oops;
|
2025-09-02 23:58:15 +09:00
|
|
|
if (wrtr(hak, bcsbuf, bcslen, ctx) <= -1) goto oops;
|
2023-12-23 12:43:26 +09:00
|
|
|
ucspos += ucslen;
|
|
|
|
}
|
|
|
|
#else
|
2023-12-27 09:09:40 +09:00
|
|
|
/* write 1-byte brand */
|
2025-09-02 23:58:15 +09:00
|
|
|
if (wrtr(hak, &b, HAK_SIZEOF(b), ctx) <= -1) goto oops;
|
2023-12-27 09:09:40 +09:00
|
|
|
|
|
|
|
string_body:
|
2025-09-02 23:58:15 +09:00
|
|
|
w = hak_htoleoow(tsize);
|
|
|
|
if (wrtr(hak, &w, HAK_SIZEOF(w), ctx) <= -1) goto oops;
|
2023-12-27 09:09:40 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
if (wrtr(hak, HAK_OBJ_GET_CHAR_SLOT(tmp), tsize, ctx) <= -1) goto oops;
|
2023-12-23 12:43:26 +09:00
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
case HAK_BRAND_PRIM:
|
2023-12-27 09:09:40 +09:00
|
|
|
/* TODO: can't have resolved pointer... need module name and the functio name??? */
|
2023-12-23 12:43:26 +09:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
b = HAK_XCHG_END;
|
|
|
|
if (wrtr(hak, &b, HAK_SIZEOF(b), ctx) <= -1) goto oops;
|
2023-12-23 12:43:26 +09:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
oops:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2023-12-30 22:28:04 +09:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
static void set_rdr_ioerr (hak_t* hak, const hak_bch_t* msg)
|
2023-12-27 09:09:40 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
const hak_ooch_t* orgmsg = hak_backuperrmsg(hak);
|
|
|
|
hak_seterrbfmt(hak, HAK_EIOERR, "%hs - %js", orgmsg);
|
2023-12-27 09:09:40 +09:00
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
int hak_unmarshalcode (hak_t* hak, hak_code_t* code, hak_xchg_reader_t rdr, void* ctx)
|
2023-12-23 12:43:26 +09:00
|
|
|
{
|
|
|
|
int n;
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_xchg_hdr_t h;
|
|
|
|
hak_uint8_t b;
|
|
|
|
hak_oow_t w;
|
2023-12-27 09:09:40 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_uch_t* usym_buf = HAK_NULL;
|
|
|
|
hak_oow_t usym_buf_capa = 0;
|
2024-09-26 19:50:57 +09:00
|
|
|
|
2023-12-27 09:09:40 +09:00
|
|
|
/* [NOTE]
|
|
|
|
* this function may pollute the code data when it fails because it doesn't
|
|
|
|
* roll back changed made to the memory pointed to by 'code'. the caller side
|
2025-09-02 23:58:15 +09:00
|
|
|
* may use two code structs. and switch between them for each call to hak_unmarshalcode()
|
2023-12-27 09:09:40 +09:00
|
|
|
* to avoid this issue.
|
|
|
|
*/
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
if (hak_brewcode(hak, code) <= -1) goto oops;
|
2023-12-27 09:09:40 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
n = rdr(hak, &h, HAK_SIZEOF(h), ctx);
|
2023-12-27 09:09:40 +09:00
|
|
|
if (n <= -1)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
set_rdr_ioerr(hak, "erroneous or insufficient header");
|
2023-12-27 09:09:40 +09:00
|
|
|
goto oops;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (h.ver != 1)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_seterrbfmt(hak, HAK_EIOERR, "unsupported header version %d", (int)h.ver);
|
2023-12-27 09:09:40 +09:00
|
|
|
goto oops;
|
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
if (h.oow_size != HAK_SIZEOF(hak_oow_t))
|
2023-12-27 09:09:40 +09:00
|
|
|
{
|
|
|
|
/* no support for cross-architecture exchange yet */
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_seterrbfmt(hak, HAK_EIOERR, "unsupported word size %d", (int)h.oow_size);
|
2023-12-27 09:09:40 +09:00
|
|
|
goto oops;
|
|
|
|
}
|
2023-12-23 12:43:26 +09:00
|
|
|
|
|
|
|
while (1)
|
|
|
|
{
|
2023-12-27 09:09:40 +09:00
|
|
|
/* read 1-byte brand */
|
2025-09-02 23:58:15 +09:00
|
|
|
n = rdr(hak, &b, HAK_SIZEOF(b), ctx);
|
2023-12-27 09:09:40 +09:00
|
|
|
if (n <= -1)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
set_rdr_ioerr(hak, "erroneous or insufficient record type");
|
2023-12-27 09:09:40 +09:00
|
|
|
goto oops;
|
|
|
|
}
|
2023-12-23 12:43:26 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
if (b == HAK_XCHG_END) break;
|
2023-12-27 09:09:40 +09:00
|
|
|
|
|
|
|
switch (b)
|
2023-12-23 12:43:26 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
case HAK_XCHG_BC:
|
2023-12-27 09:09:40 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_oow_t nbytes;
|
2023-12-27 09:09:40 +09:00
|
|
|
|
|
|
|
/* this must appear only once but never mind about multiple occurrences */
|
2025-09-02 23:58:15 +09:00
|
|
|
n = rdr(hak, &w, HAK_SIZEOF(w), ctx);
|
2023-12-27 09:09:40 +09:00
|
|
|
if (n <= -1)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
set_rdr_ioerr(hak, "erroneous or insufficient record length");
|
2023-12-27 09:09:40 +09:00
|
|
|
goto oops;
|
|
|
|
}
|
2025-09-02 23:58:15 +09:00
|
|
|
nbytes = hak_leoowtoh(w);
|
2023-12-27 09:09:40 +09:00
|
|
|
|
|
|
|
if (nbytes > code->bc.capa)
|
|
|
|
{
|
|
|
|
/* grow the buffer */
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_oow_t newcapa;
|
|
|
|
hak_oob_t* newptr;
|
2023-12-27 09:09:40 +09:00
|
|
|
|
|
|
|
newcapa = nbytes;
|
2025-09-02 23:58:15 +09:00
|
|
|
if (HAK_UNLIKELY(newcapa <= 0)) newcapa++;
|
|
|
|
newcapa = HAK_ALIGN(newcapa, HAK_BC_BUFFER_ALIGN);
|
|
|
|
newptr = (hak_oob_t*)hak_reallocmem(hak, code->bc.ptr, newcapa);
|
|
|
|
if (HAK_UNLIKELY(!newptr)) goto oops;
|
2023-12-27 09:09:40 +09:00
|
|
|
|
|
|
|
code->bc.ptr = newptr;
|
|
|
|
code->bc.capa = newcapa;
|
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
n = rdr(hak, code->bc.ptr, nbytes, ctx);
|
2023-12-27 09:09:40 +09:00
|
|
|
if (n <= -1) goto oops;
|
|
|
|
|
|
|
|
code->bc.len = nbytes;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
case HAK_XCHG_STRING_U:
|
|
|
|
case HAK_XCHG_SYMLIT_U:
|
|
|
|
case HAK_XCHG_SYMBOL_U:
|
2023-12-27 09:09:40 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_bch_t bcsbuf[64];
|
|
|
|
hak_uch_t* ucsptr;
|
|
|
|
hak_oow_t bcslen, bcsres, ucslen, ucspos;
|
|
|
|
hak_oow_t nbytes, nchars;
|
|
|
|
hak_oop_t ns;
|
2023-12-27 09:09:40 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
n = rdr(hak, &w, HAK_SIZEOF(w), ctx);
|
2023-12-27 09:09:40 +09:00
|
|
|
if (n <= -1)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
set_rdr_ioerr(hak, "erroneous or insufficient record length");
|
2023-12-27 09:09:40 +09:00
|
|
|
goto oops;
|
|
|
|
}
|
2025-09-02 23:58:15 +09:00
|
|
|
nchars = hak_leoowtoh(w);
|
2023-12-27 09:09:40 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
n = rdr(hak, &w, HAK_SIZEOF(w), ctx);
|
2023-12-27 09:09:40 +09:00
|
|
|
if (n <= -1)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
set_rdr_ioerr(hak, "erroneous or insufficient record length");
|
2023-12-27 09:09:40 +09:00
|
|
|
goto oops;
|
|
|
|
}
|
2025-09-02 23:58:15 +09:00
|
|
|
nbytes = hak_leoowtoh(w);
|
2023-12-27 09:09:40 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
if (b == HAK_XCHG_STRING_U)
|
2024-09-26 19:50:57 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
ns = hak_makestring(hak, HAK_NULL, nchars);
|
|
|
|
if (HAK_UNLIKELY(!ns)) goto oops;
|
|
|
|
ucsptr = HAK_OBJ_GET_CHAR_PTR(ns, 0);
|
2024-09-26 19:50:57 +09:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (nchars > usym_buf_capa)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
usym_buf_capa = nchars * HAK_SIZEOF(usym_buf[0]);
|
|
|
|
usym_buf = (hak_uch_t*)hak_allocmem(hak, usym_buf_capa);
|
|
|
|
if (HAK_UNLIKELY(!usym_buf)) goto oops;
|
2024-09-26 19:50:57 +09:00
|
|
|
}
|
|
|
|
ucsptr = usym_buf;
|
|
|
|
}
|
2023-12-27 09:09:40 +09:00
|
|
|
|
|
|
|
ucspos = 0;
|
|
|
|
bcsres = 0;
|
|
|
|
while (nbytes > 0)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
bcslen = nbytes <= HAK_SIZEOF(bcsbuf)? nbytes : HAK_SIZEOF(bcsbuf);
|
|
|
|
n = rdr(hak, &bcsbuf[bcsres], bcslen - bcsres, ctx);
|
2023-12-27 09:09:40 +09:00
|
|
|
if (n <= -1)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
set_rdr_ioerr(hak, "erroneous or insufficient record data");
|
2023-12-27 09:09:40 +09:00
|
|
|
goto oops;
|
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
HAK_ASSERT(hak, ucspos < nchars);
|
2023-12-27 09:09:40 +09:00
|
|
|
bcsres = bcslen;
|
|
|
|
ucslen = nchars - ucspos;
|
2025-09-02 23:58:15 +09:00
|
|
|
if (hak_convbtouchars(hak, bcsbuf, &bcslen, &ucsptr[ucspos], &ucslen) <= -1 && bcslen <= 0)
|
2023-12-27 09:09:40 +09:00
|
|
|
{
|
|
|
|
goto oops;
|
|
|
|
}
|
|
|
|
|
|
|
|
ucspos += ucslen;
|
|
|
|
nbytes -= bcslen;
|
|
|
|
bcsres -= bcslen;
|
2025-09-02 23:58:15 +09:00
|
|
|
if (bcsres > 0) HAK_MEMMOVE(bcsbuf, &bcsbuf[bcslen], bcsres);
|
2023-12-27 09:09:40 +09:00
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
HAK_ASSERT(hak, ucspos == nchars);
|
2023-12-27 09:09:40 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
if (b != HAK_XCHG_STRING_U)
|
2023-12-27 09:09:40 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
ns = hak_makesymbol(hak, usym_buf, nchars);
|
|
|
|
if (HAK_UNLIKELY(!ns)) goto oops;
|
2024-09-26 19:50:57 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
if (b == HAK_XCHG_SYMBOL_U)
|
2024-09-26 19:50:57 +09:00
|
|
|
{
|
2023-12-27 09:09:40 +09:00
|
|
|
/* form a cons cell */
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_oop_t nc;
|
|
|
|
hak_pushvolat(hak, &ns);
|
|
|
|
nc = hak_makecons(hak, ns, hak->_nil);
|
|
|
|
hak_popvolat(hak);
|
|
|
|
if (HAK_UNLIKELY(!nc)) goto oops;
|
2024-09-26 19:50:57 +09:00
|
|
|
ns = nc;
|
|
|
|
}
|
2023-12-27 09:09:40 +09:00
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
if (hak_addliteraltocode(hak, code, ns, 0, HAK_NULL) <= -1) goto oops;
|
2023-12-27 09:09:40 +09:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
case HAK_XCHG_STRING_B:
|
|
|
|
case HAK_XCHG_SYMBOL_B:
|
2023-12-27 09:09:40 +09:00
|
|
|
/* TODO */
|
|
|
|
break;
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
case HAK_XCHG_SMOOI:
|
2024-01-02 01:41:41 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_oop_t ns;
|
|
|
|
if (rdr(hak, &w, HAK_SIZEOF(w), ctx) <= -1) goto oops;
|
|
|
|
w = hak_leoowtoh(w);
|
|
|
|
ns = HAK_SMOOI_TO_OOP((hak_ooi_t)w);
|
|
|
|
if (hak_addliteraltocode(hak, code, ns, 0, HAK_NULL) <= -1) goto oops;
|
2024-01-02 01:41:41 +09:00
|
|
|
break;
|
|
|
|
}
|
2023-12-27 09:09:40 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
case HAK_XCHG_PBIGINT:
|
|
|
|
case HAK_XCHG_NBIGINT:
|
2023-12-27 09:09:40 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_oow_t nbytes, nwords, j;
|
|
|
|
hak_liw_t liw;
|
|
|
|
hak_oop_t ns;
|
2023-12-27 09:09:40 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
n = rdr(hak, &w, HAK_SIZEOF(w), ctx);
|
2023-12-27 09:09:40 +09:00
|
|
|
if (n <= -1)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
set_rdr_ioerr(hak, "erroneous or insufficient bigint length");
|
2023-12-27 09:09:40 +09:00
|
|
|
goto oops;
|
|
|
|
}
|
2025-09-02 23:58:15 +09:00
|
|
|
nbytes = hak_leoowtoh(w);
|
2023-12-27 09:09:40 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
if (nbytes % HAK_SIZEOF(hak_liw_t)) goto oops; /* not the right number of bytes */
|
|
|
|
nwords = nbytes / HAK_SIZEOF(hak_liw_t);
|
2023-12-27 09:09:40 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
ns = hak_instantiate(hak, ((b == HAK_XCHG_PBIGINT)? hak->c_large_positive_integer: hak->c_large_negative_integer), HAK_NULL, nwords);
|
|
|
|
if (HAK_UNLIKELY(!ns)) goto oops;
|
2023-12-27 09:09:40 +09:00
|
|
|
|
|
|
|
for (j = 0; j < nwords; j ++)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
if (rdr(hak, &liw, HAK_SIZEOF(liw), ctx) <= -1) goto oops;
|
|
|
|
liw = hak_leliwtoh(liw);
|
|
|
|
HAK_OBJ_SET_LIWORD_VAL(ns, j, liw);
|
2023-12-27 09:09:40 +09:00
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
if (hak_addliteraltocode(hak, code, ns, 0, HAK_NULL) <= -1) goto oops;
|
2023-12-27 09:09:40 +09:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
case HAK_XCHG_FPDEC_1:
|
|
|
|
case HAK_XCHG_FPDEC_2:
|
|
|
|
case HAK_XCHG_FPDEC_3:
|
2023-12-23 12:43:26 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_ooi_t scale;
|
|
|
|
hak_oop_t ns;
|
2023-12-27 09:09:40 +09:00
|
|
|
|
|
|
|
/* read scale */
|
2025-09-02 23:58:15 +09:00
|
|
|
n = rdr(hak, &w, HAK_SIZEOF(w), ctx);
|
2023-12-27 09:09:40 +09:00
|
|
|
if (n <= -1)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
set_rdr_ioerr(hak, "erroneous or insufficient record length");
|
2023-12-27 09:09:40 +09:00
|
|
|
goto oops;
|
|
|
|
}
|
2025-09-02 23:58:15 +09:00
|
|
|
scale = (hak_ooi_t)hak_leoowtoh(w);
|
2023-12-27 09:09:40 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
if (b == HAK_XCHG_FPDEC_1)
|
2023-12-27 09:09:40 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_ooi_t value;
|
|
|
|
n = rdr(hak, &w, HAK_SIZEOF(w), ctx);
|
2023-12-27 09:09:40 +09:00
|
|
|
if (n <= -1)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
set_rdr_ioerr(hak, "erroneous or insufficient record length");
|
2023-12-27 09:09:40 +09:00
|
|
|
goto oops;
|
|
|
|
}
|
2025-09-02 23:58:15 +09:00
|
|
|
value = (hak_ooi_t)hak_leoowtoh(w);
|
|
|
|
ns = hak_makefpdec(hak, HAK_SMOOI_TO_OOP(value), scale);
|
|
|
|
if (HAK_UNLIKELY(!ns)) goto oops;
|
2023-12-27 09:09:40 +09:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_oow_t j, nbytes, nwords;
|
|
|
|
hak_liw_t liw;
|
|
|
|
hak_oop_t v;
|
2023-12-27 09:09:40 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
n = rdr(hak, &w, HAK_SIZEOF(w), ctx);
|
2023-12-27 09:09:40 +09:00
|
|
|
if (n <= -1)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
set_rdr_ioerr(hak, "erroneous or insufficient record length");
|
2023-12-27 09:09:40 +09:00
|
|
|
goto oops;
|
|
|
|
}
|
2025-09-02 23:58:15 +09:00
|
|
|
nbytes = hak_leoowtoh(w);
|
2023-12-27 09:09:40 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
if (nbytes % HAK_SIZEOF(hak_liw_t)) goto oops; /* not the right number of bytes */
|
|
|
|
nwords = nbytes / HAK_SIZEOF(hak_liw_t);
|
2023-12-27 09:09:40 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
v = hak_instantiate(hak, ((b == HAK_XCHG_FPDEC_2) ? hak->c_large_positive_integer : hak->c_large_negative_integer), HAK_NULL, nwords);
|
|
|
|
if (HAK_UNLIKELY(!v)) goto oops;
|
2023-12-27 09:09:40 +09:00
|
|
|
|
|
|
|
for (j = 0; j < nwords; j++)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
if (rdr(hak, &liw, HAK_SIZEOF(liw), ctx) <= -1) goto oops;
|
|
|
|
liw = hak_leliwtoh(liw);
|
|
|
|
HAK_OBJ_SET_LIWORD_VAL(v, j, liw);
|
2023-12-27 09:09:40 +09:00
|
|
|
}
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_pushvolat (hak, &v);
|
|
|
|
ns = hak_makefpdec(hak, v, scale);
|
|
|
|
hak_popvolat (hak);
|
|
|
|
if (HAK_UNLIKELY(!ns)) goto oops;
|
2023-12-27 09:09:40 +09:00
|
|
|
}
|
2025-09-02 23:58:15 +09:00
|
|
|
if (hak_addliteraltocode(hak, code, ns, 0, HAK_NULL) <= -1) goto oops;
|
2023-12-27 09:09:40 +09:00
|
|
|
break;
|
2023-12-23 12:43:26 +09:00
|
|
|
}
|
2023-12-27 09:09:40 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
case HAK_XCHG_PRIM:
|
2023-12-27 09:09:40 +09:00
|
|
|
/* TODO: */
|
|
|
|
break;
|
2023-12-23 12:43:26 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
oops:
|
2025-09-02 23:58:15 +09:00
|
|
|
if (usym_buf) hak_freemem (hak, usym_buf);
|
2023-12-23 12:43:26 +09:00
|
|
|
return -1;
|
2023-12-27 09:09:40 +09:00
|
|
|
}
|
2023-12-30 22:28:04 +09:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
static int mem_code_writer (hak_t* hak, const void* ptr, hak_oow_t len, void* ctx)
|
2023-12-30 22:28:04 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_ptlc_t* dst = (hak_ptlc_t*)ctx;
|
|
|
|
const hak_uint8_t* p = (const hak_uint8_t*)ptr;
|
|
|
|
const hak_uint8_t* e = p + len;
|
2023-12-30 22:28:04 +09:00
|
|
|
|
|
|
|
if (dst->capa - dst->len < len)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_oow_t newcapa;
|
|
|
|
hak_uint8_t* newptr;
|
2023-12-30 22:28:04 +09:00
|
|
|
|
|
|
|
newcapa = dst->len + len;
|
2025-09-02 23:58:15 +09:00
|
|
|
newcapa = HAK_ALIGN_POW2(newcapa, 64);
|
|
|
|
newptr = (hak_uint8_t*)hak_reallocmem(hak, dst->ptr, newcapa);
|
|
|
|
if (HAK_UNLIKELY(!newptr)) return -1;
|
2023-12-30 22:28:04 +09:00
|
|
|
|
|
|
|
dst->ptr = newptr;
|
|
|
|
dst->capa = newcapa;
|
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
while (p < e) ((hak_uint8_t*)dst->ptr)[dst->len++] = *p++;
|
2023-12-30 22:28:04 +09:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
int hak_marshalcodetomem (hak_t* hak, const hak_code_t* code, hak_ptlc_t* dst)
|
2023-12-30 22:28:04 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
return hak_marshalcode(hak, code, mem_code_writer, dst);
|
2023-12-30 22:28:04 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
struct cmr_t
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
const hak_ptl_t* src;
|
|
|
|
hak_oow_t pos;
|
2023-12-30 22:28:04 +09:00
|
|
|
};
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
static int mem_code_reader(hak_t* hak, void* ptr, hak_oow_t len, void* ctx)
|
2023-12-30 22:28:04 +09:00
|
|
|
{
|
|
|
|
struct cmr_t* cmr = (struct cmr_t*)ctx;
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_uint8_t* p = (hak_uint8_t*)ptr;
|
|
|
|
hak_uint8_t* e = p + len;
|
2023-12-30 22:28:04 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
HAK_ASSERT (hak, cmr->pos <= cmr->src->len);
|
2023-12-30 22:28:04 +09:00
|
|
|
|
|
|
|
if (cmr->src->len - cmr->pos < len)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_seterrbfmt (hak, HAK_ENOENT, "no more data");
|
2023-12-30 22:28:04 +09:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
while (p < e) *p++ = ((const hak_uint8_t*)cmr->src->ptr)[cmr->pos++];
|
2023-12-30 22:28:04 +09:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
int hak_unmarshalcodefrommem (hak_t* hak, hak_code_t* code, const hak_ptl_t* src)
|
2023-12-30 22:28:04 +09:00
|
|
|
{
|
|
|
|
struct cmr_t cmr;
|
|
|
|
cmr.src = src;
|
|
|
|
cmr.pos = 0;
|
2025-09-02 23:58:15 +09:00
|
|
|
return hak_unmarshalcode(hak, code, mem_code_reader, &cmr);
|
2023-12-30 22:28:04 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
2023-12-28 00:27:27 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
int hak_brewcode (hak_t* hak, hak_code_t* code)
|
2023-12-28 00:27:27 +09:00
|
|
|
{
|
2024-02-25 13:55:03 +09:00
|
|
|
/* create space to hold byte code and debug information */
|
|
|
|
|
2023-12-28 00:27:27 +09:00
|
|
|
if (!code->bc.ptr)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
code->bc.ptr = (hak_oob_t*)hak_allocmem(hak, HAK_SIZEOF(*code->bc.ptr) * HAK_BC_BUFFER_INIT); /* TODO: set a proper intial size */
|
|
|
|
if (HAK_UNLIKELY(!code->bc.ptr))
|
2024-09-26 19:50:57 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
const hak_ooch_t* orgmsg = hak_backuperrmsg(hak);
|
|
|
|
hak_seterrbfmt (hak, HAK_ERRNUM(hak), "unable to allocate code buffer - %js", orgmsg);
|
2024-09-26 19:50:57 +09:00
|
|
|
return -1;
|
|
|
|
}
|
2025-09-02 23:58:15 +09:00
|
|
|
HAK_ASSERT (hak, code->bc.len == 0);
|
|
|
|
code->bc.capa = HAK_BC_BUFFER_INIT;
|
2023-12-28 00:27:27 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!code->dbgi)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
code->dbgi = (hak_dbgi_t*)hak_allocmem(hak, HAK_SIZEOF(*code->dbgi) * HAK_BC_BUFFER_INIT);
|
|
|
|
if (HAK_UNLIKELY(!code->dbgi))
|
2023-12-28 00:27:27 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
const hak_ooch_t* orgmsg = hak_backuperrmsg(hak);
|
|
|
|
hak_seterrbfmt (hak, HAK_ERRNUM(hak), "unable to allocate debug info buffer - %js", orgmsg);
|
2024-09-26 19:50:57 +09:00
|
|
|
|
2023-12-28 00:27:27 +09:00
|
|
|
/* bc.ptr and dbgi go together. so free bc.ptr if dbgi allocation fails */
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_freemem (hak, code->bc.ptr);
|
|
|
|
code->bc.ptr = HAK_NULL;
|
2023-12-28 00:27:27 +09:00
|
|
|
code->bc.len = 0;
|
|
|
|
code->bc.capa = 0;
|
2024-09-26 19:50:57 +09:00
|
|
|
|
2023-12-28 00:27:27 +09:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
HAK_MEMSET (code->dbgi, 0, HAK_SIZEOF(*code->dbgi) * HAK_BC_BUFFER_INIT);
|
2023-12-28 00:27:27 +09:00
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
/* TODO: move code.lit.arr creation to hak_init() after swithching to hak_allocmem? */
|
2023-12-28 00:27:27 +09:00
|
|
|
if (!code->lit.arr)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
code->lit.arr = (hak_oop_oop_t)hak_makengcarray(hak, HAK_LIT_BUFFER_INIT); /* TOOD: set a proper initial size */
|
|
|
|
if (HAK_UNLIKELY(!code->lit.arr))
|
2024-09-26 19:50:57 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
const hak_ooch_t* orgmsg = hak_backuperrmsg(hak);
|
|
|
|
hak_seterrbfmt (hak, HAK_ERRNUM(hak), "unable to allocate literal frame - %js", orgmsg);
|
2024-09-26 19:50:57 +09:00
|
|
|
return -1;
|
|
|
|
}
|
2025-09-02 23:58:15 +09:00
|
|
|
HAK_ASSERT (hak, code->lit.len == 0);
|
2023-12-28 00:27:27 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
void hak_purgecode (hak_t* hak, hak_code_t* code)
|
2023-12-28 00:27:27 +09:00
|
|
|
{
|
|
|
|
if (code->dbgi)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_freemem (hak, code->dbgi);
|
|
|
|
code->dbgi = HAK_NULL;
|
2023-12-28 00:27:27 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
if (code->bc.ptr)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_freemem (hak, code->bc.ptr);
|
|
|
|
code->bc.ptr = HAK_NULL;
|
2023-12-28 00:27:27 +09:00
|
|
|
code->bc.len = 0;
|
|
|
|
code->bc.capa = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (code->lit.arr)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_freengcobj (hak, (hak_oop_t)code->lit.arr);
|
|
|
|
code->lit.arr = HAK_NULL;
|
2023-12-28 00:27:27 +09:00
|
|
|
code->lit.len = 0;
|
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
HAK_MEMSET (&code, 0, HAK_SIZEOF(code));
|
2023-12-28 00:27:27 +09:00
|
|
|
}
|
|
|
|
|
2023-12-30 22:28:04 +09:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
int hak_addliteraltocode (hak_t* hak, hak_code_t* code, hak_oop_t obj, hak_oow_t lfbase, hak_oow_t* index)
|
2023-12-28 00:27:27 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_oow_t capa, i;
|
|
|
|
hak_oop_t tmp;
|
2023-12-28 00:27:27 +09:00
|
|
|
|
|
|
|
/* TODO: speed up the following duplicate check loop */
|
|
|
|
for (i = lfbase; i < code->lit.len; i++)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
tmp = ((hak_oop_oop_t)code->lit.arr)->slot[i];
|
2023-12-28 00:27:27 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
if (tmp == obj || hak_equalobjs(hak, obj, tmp))
|
2023-12-28 00:27:27 +09:00
|
|
|
{
|
2024-09-25 00:40:46 +09:00
|
|
|
/* this removes redundancy of symbols, characters, and integers.
|
|
|
|
* a string object requires equality check. however,
|
|
|
|
* the string created to the literal frame
|
|
|
|
* must be made immutable. non-immutable string literals are
|
|
|
|
* source of various problems */
|
2023-12-28 00:27:27 +09:00
|
|
|
if (index) *index = i - lfbase;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
capa = HAK_OBJ_GET_SIZE(code->lit.arr);
|
2023-12-28 00:27:27 +09:00
|
|
|
if (code->lit.len >= capa)
|
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
hak_oop_t tmp;
|
|
|
|
hak_oow_t newcapa;
|
2023-12-28 00:27:27 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
newcapa = HAK_ALIGN(capa + 1, HAK_LIT_BUFFER_ALIGN);
|
|
|
|
tmp = hak_remakengcarray(hak, (hak_oop_t)code->lit.arr, newcapa);
|
|
|
|
if (HAK_UNLIKELY(!tmp))
|
2024-09-26 19:50:57 +09:00
|
|
|
{
|
2025-09-02 23:58:15 +09:00
|
|
|
const hak_ooch_t* orgmsg = hak_backuperrmsg(hak);
|
|
|
|
hak_seterrbfmt (hak, HAK_ERRNUM(hak), "unable to resize literal frame - %js", orgmsg);
|
2024-09-26 19:50:57 +09:00
|
|
|
return -1;
|
|
|
|
}
|
2023-12-28 00:27:27 +09:00
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
code->lit.arr = (hak_oop_oop_t)tmp;
|
2023-12-28 00:27:27 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
if (index) *index = code->lit.len - lfbase;
|
|
|
|
|
2025-09-02 23:58:15 +09:00
|
|
|
((hak_oop_oop_t)code->lit.arr)->slot[code->lit.len++] = obj;
|
2024-09-26 19:50:57 +09:00
|
|
|
/* make read-only an object in the literal table.
|
|
|
|
* some immutable objects(e.g. literal symbol) don't need this part
|
|
|
|
* but we just execute it regardless */
|
2025-09-02 23:58:15 +09:00
|
|
|
if (HAK_OOP_IS_POINTER(obj)) HAK_OBJ_SET_FLAGS_RDONLY (obj, 1);
|
2023-12-28 00:27:27 +09:00
|
|
|
return 0;
|
|
|
|
}
|