Handle serialization endianness transparently (#152)
Change JS_WriteObject() and JS_WriteObject2() to write little-endian data and update JS_ReadObject() to byte-swap data when running on a big-endian system. Obsoletes the JS_WRITE_OBJ_BSWAP flag, it is now a no-op. Fixes: https://github.com/quickjs-ng/quickjs/issues/125
This commit is contained in:
parent
0ecb2c86b5
commit
a6e73ca73c
4 changed files with 18 additions and 36 deletions
|
@ -167,9 +167,6 @@ find the name of the dynamically loaded modules.
|
|||
Add initialization code for an external C module. See the
|
||||
@code{c_module} example.
|
||||
|
||||
@item -x
|
||||
Byte swapped output (only used for cross compilation).
|
||||
|
||||
@item -flto
|
||||
Use link time optimization. The compilation is slower but the
|
||||
executable is smaller and faster. This option is automatically set
|
||||
|
|
13
qjsc.c
13
qjsc.c
|
@ -51,7 +51,6 @@ static namelist_t cname_list;
|
|||
static namelist_t cmodule_list;
|
||||
static namelist_t init_module_list;
|
||||
static FILE *outfile;
|
||||
static BOOL byte_swap;
|
||||
static const char *c_ident_prefix = "qjsc_";
|
||||
|
||||
|
||||
|
@ -152,11 +151,8 @@ static void output_object_code(JSContext *ctx,
|
|||
{
|
||||
uint8_t *out_buf;
|
||||
size_t out_buf_len;
|
||||
int flags;
|
||||
flags = JS_WRITE_OBJ_BYTECODE;
|
||||
if (byte_swap)
|
||||
flags |= JS_WRITE_OBJ_BSWAP;
|
||||
out_buf = JS_WriteObject(ctx, &out_buf_len, obj, flags);
|
||||
|
||||
out_buf = JS_WriteObject(ctx, &out_buf_len, obj, JS_WRITE_OBJ_BYTECODE);
|
||||
if (!out_buf) {
|
||||
js_std_dump_error(ctx);
|
||||
exit(1);
|
||||
|
@ -322,7 +318,6 @@ void help(void)
|
|||
"-m compile as Javascript module (default=autodetect)\n"
|
||||
"-D module_name compile a dynamically loaded module or worker\n"
|
||||
"-M module_name[,cname] add initialization code for an external C module\n"
|
||||
"-x byte swapped output\n"
|
||||
"-p prefix set the prefix of the generated C names\n"
|
||||
"-S n set the maximum stack size to 'n' bytes (default=%d)\n",
|
||||
JS_GetVersion(),
|
||||
|
@ -352,7 +347,6 @@ int main(int argc, char **argv)
|
|||
output_type = OUTPUT_C;
|
||||
cname = NULL;
|
||||
module = -1;
|
||||
byte_swap = FALSE;
|
||||
verbose = 0;
|
||||
stack_size = 0;
|
||||
memset(&dynamic_module_list, 0, sizeof(dynamic_module_list));
|
||||
|
@ -399,9 +393,6 @@ int main(int argc, char **argv)
|
|||
case 'D':
|
||||
namelist_add(&dynamic_module_list, optarg, NULL, 0);
|
||||
break;
|
||||
case 'x':
|
||||
byte_swap = TRUE;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
|
|
36
quickjs.c
36
quickjs.c
|
@ -31664,18 +31664,11 @@ typedef enum BCTagEnum {
|
|||
BC_TAG_OBJECT_REFERENCE,
|
||||
} BCTagEnum;
|
||||
|
||||
#define BC_BASE_VERSION 2
|
||||
#define BC_BE_VERSION 0x40
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define BC_VERSION (BC_BASE_VERSION | BC_BE_VERSION)
|
||||
#else
|
||||
#define BC_VERSION BC_BASE_VERSION
|
||||
#endif
|
||||
#define BC_VERSION 3
|
||||
|
||||
typedef struct BCWriterState {
|
||||
JSContext *ctx;
|
||||
DynBuf dbuf;
|
||||
BOOL byte_swap : 8;
|
||||
BOOL allow_bytecode : 8;
|
||||
BOOL allow_sab : 8;
|
||||
BOOL allow_reference : 8;
|
||||
|
@ -31717,6 +31710,15 @@ static const char * const bc_tag_str[] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
static inline BOOL is_be(void)
|
||||
{
|
||||
union {
|
||||
uint16_t a;
|
||||
uint8_t b;
|
||||
} u = {0x100};
|
||||
return u.b;
|
||||
}
|
||||
|
||||
static void bc_put_u8(BCWriterState *s, uint8_t v)
|
||||
{
|
||||
dbuf_putc(&s->dbuf, v);
|
||||
|
@ -31724,21 +31726,21 @@ static void bc_put_u8(BCWriterState *s, uint8_t v)
|
|||
|
||||
static void bc_put_u16(BCWriterState *s, uint16_t v)
|
||||
{
|
||||
if (s->byte_swap)
|
||||
if (is_be())
|
||||
v = bswap16(v);
|
||||
dbuf_put_u16(&s->dbuf, v);
|
||||
}
|
||||
|
||||
static __maybe_unused void bc_put_u32(BCWriterState *s, uint32_t v)
|
||||
{
|
||||
if (s->byte_swap)
|
||||
if (is_be())
|
||||
v = bswap32(v);
|
||||
dbuf_put_u32(&s->dbuf, v);
|
||||
}
|
||||
|
||||
static void bc_put_u64(BCWriterState *s, uint64_t v)
|
||||
{
|
||||
if (s->byte_swap)
|
||||
if (is_be())
|
||||
v = bswap64(v);
|
||||
dbuf_put(&s->dbuf, (uint8_t *)&v, sizeof(v));
|
||||
}
|
||||
|
@ -31908,7 +31910,7 @@ static int JS_WriteFunctionBytecode(BCWriterState *s,
|
|||
pos += len;
|
||||
}
|
||||
|
||||
if (s->byte_swap)
|
||||
if (is_be())
|
||||
bc_byte_swap(bc_buf, bc_len);
|
||||
|
||||
dbuf_put(&s->dbuf, bc_buf, bc_len);
|
||||
|
@ -32405,15 +32407,10 @@ static int JS_WriteObjectAtoms(BCWriterState *s)
|
|||
JSRuntime *rt = s->ctx->rt;
|
||||
DynBuf dbuf1;
|
||||
int i, atoms_size;
|
||||
uint8_t version;
|
||||
|
||||
dbuf1 = s->dbuf;
|
||||
js_dbuf_init(s->ctx, &s->dbuf);
|
||||
|
||||
version = BC_VERSION;
|
||||
if (s->byte_swap)
|
||||
version ^= BC_BE_VERSION;
|
||||
bc_put_u8(s, version);
|
||||
bc_put_u8(s, BC_VERSION);
|
||||
|
||||
bc_put_leb128(s, s->idx_to_atom_count);
|
||||
for(i = 0; i < s->idx_to_atom_count; i++) {
|
||||
|
@ -32446,8 +32443,6 @@ uint8_t *JS_WriteObject2(JSContext *ctx, size_t *psize, JSValueConst obj,
|
|||
|
||||
memset(s, 0, sizeof(*s));
|
||||
s->ctx = ctx;
|
||||
/* XXX: byte swapped output is untested */
|
||||
s->byte_swap = ((flags & JS_WRITE_OBJ_BSWAP) != 0);
|
||||
s->allow_bytecode = ((flags & JS_WRITE_OBJ_BYTECODE) != 0);
|
||||
s->allow_sab = ((flags & JS_WRITE_OBJ_SAB) != 0);
|
||||
s->allow_reference = ((flags & JS_WRITE_OBJ_REFERENCE) != 0);
|
||||
|
@ -33531,7 +33526,6 @@ static int JS_ReadObjectAtoms(BCReaderState *s)
|
|||
|
||||
if (bc_get_u8(s, &v8))
|
||||
return -1;
|
||||
/* XXX: could support byte swapped input */
|
||||
if (v8 != BC_VERSION) {
|
||||
JS_ThrowSyntaxError(s->ctx, "invalid version (%d expected=%d)",
|
||||
v8, BC_VERSION);
|
||||
|
|
|
@ -838,7 +838,7 @@ JS_EXTERN int JS_ExecutePendingJob(JSRuntime *rt, JSContext **pctx);
|
|||
|
||||
/* Object Writer/Reader (currently only used to handle precompiled code) */
|
||||
#define JS_WRITE_OBJ_BYTECODE (1 << 0) /* allow function/module */
|
||||
#define JS_WRITE_OBJ_BSWAP (1 << 1) /* byte swapped output */
|
||||
#define JS_WRITE_OBJ_BSWAP (0) /* byte swapped output (obsolete, handled transparently) */
|
||||
#define JS_WRITE_OBJ_SAB (1 << 2) /* allow SharedArrayBuffer */
|
||||
#define JS_WRITE_OBJ_REFERENCE (1 << 3) /* allow object references to
|
||||
encode arbitrary object
|
||||
|
|
Loading…
Reference in a new issue