Skip to content

Handle serialization endianness transparently #152

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 28, 2023
Merged
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
3 changes: 0 additions & 3 deletions doc/quickjs.texi
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 2 additions & 11 deletions qjsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_";


Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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;
Expand Down
36 changes: 15 additions & 21 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -31717,28 +31710,37 @@ 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);
}

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));
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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++) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion quickjs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down