Add strip option in qjsc
to reduce object size (#388)
- `-s` strips the source code - `-ss` strips source and line/column numbers information - `qjsc repl.js` generates an object size of **105726** bytes - `qjsc -s repl.js` generates an object size of **20853** bytes - `qjsc -ss repl.js` generates an object size of only **16147** bytes - compile repl.js with `-ss` - bump byte code version to 12
This commit is contained in:
parent
43dc65d605
commit
f326a7a195
9 changed files with 1362 additions and 12529 deletions
2
Makefile
2
Makefile
|
@ -61,7 +61,7 @@ clean:
|
|||
cmake --build $(BUILD_DIR) --target clean
|
||||
|
||||
codegen: $(QJSC)
|
||||
$(QJSC) -o gen/repl.c -m repl.js
|
||||
$(QJSC) -ss -o gen/repl.c -m repl.js
|
||||
$(QJSC) -e -o gen/function_source.c tests/function_source.js
|
||||
$(QJSC) -e -o gen/hello.c examples/hello.js
|
||||
$(QJSC) -e -o gen/hello_module.c -m examples/hello_module.js
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
const uint32_t qjsc_function_source_size = 384;
|
||||
|
||||
const uint8_t qjsc_function_source[384] = {
|
||||
0x0b, 0x06, 0x0c, 0x61, 0x63, 0x74, 0x75, 0x61,
|
||||
0x0c, 0x06, 0x0c, 0x61, 0x63, 0x74, 0x75, 0x61,
|
||||
0x6c, 0x02, 0x66, 0x30, 0x74, 0x65, 0x73, 0x74,
|
||||
0x73, 0x2f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63,
|
||||
|
@ -15,12 +15,12 @@ const uint8_t qjsc_function_source[384] = {
|
|||
0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
|
||||
0x66, 0x28, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65,
|
||||
0x74, 0x75, 0x72, 0x6e, 0x20, 0x34, 0x32, 0x20,
|
||||
0x7d, 0x0c, 0x00, 0x02, 0x01, 0x9e, 0x01, 0x00,
|
||||
0x7d, 0x0c, 0x00, 0xfa, 0x01, 0x9e, 0x01, 0x00,
|
||||
0x06, 0x00, 0x03, 0x00, 0x01, 0xa0, 0x01, 0x06,
|
||||
0xa0, 0x01, 0x00, 0x00, 0x00, 0xb2, 0x03, 0x02,
|
||||
0x00, 0x30, 0xb4, 0x03, 0x04, 0x00, 0x70, 0xb2,
|
||||
0x03, 0x04, 0x03, 0x70, 0x10, 0x00, 0x01, 0x00,
|
||||
0xe0, 0x01, 0x00, 0x01, 0x00, 0x0c, 0x43, 0x02,
|
||||
0xe0, 0x01, 0x00, 0x01, 0x00, 0x0c, 0x43, 0xfa,
|
||||
0x01, 0xb4, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x03, 0x00, 0xbb, 0x2a, 0x28, 0xb6, 0x03,
|
||||
0x03, 0x01, 0x04, 0x02, 0x1e, 0x0c, 0x0e, 0x1a,
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
const uint32_t qjsc_hello_size = 89;
|
||||
|
||||
const uint8_t qjsc_hello[89] = {
|
||||
0x0b, 0x04, 0x0e, 0x63, 0x6f, 0x6e, 0x73, 0x6f,
|
||||
0x0c, 0x04, 0x0e, 0x63, 0x6f, 0x6e, 0x73, 0x6f,
|
||||
0x6c, 0x65, 0x06, 0x6c, 0x6f, 0x67, 0x16, 0x48,
|
||||
0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72,
|
||||
0x6c, 0x64, 0x22, 0x65, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0x73, 0x2f, 0x68, 0x65, 0x6c, 0x6c,
|
||||
0x6f, 0x2e, 0x6a, 0x73, 0x0c, 0x00, 0x02, 0x00,
|
||||
0x6f, 0x2e, 0x6a, 0x73, 0x0c, 0x00, 0xfa, 0x00,
|
||||
0x9e, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00,
|
||||
0x14, 0x01, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x38,
|
||||
0xd9, 0x00, 0x00, 0x00, 0x42, 0xda, 0x00, 0x00,
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
const uint32_t qjsc_fib_module_size = 310;
|
||||
|
||||
const uint8_t qjsc_fib_module[310] = {
|
||||
0x0b, 0x03, 0x2c, 0x65, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x0c, 0x03, 0x2c, 0x65, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0x73, 0x2f, 0x66, 0x69, 0x62, 0x5f,
|
||||
0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x6a,
|
||||
0x73, 0x06, 0x66, 0x69, 0x62, 0x02, 0x6e, 0x0d,
|
||||
0xb2, 0x03, 0x00, 0x01, 0x00, 0x00, 0xb4, 0x03,
|
||||
0x00, 0x00, 0x0c, 0x20, 0x02, 0x01, 0x9e, 0x01,
|
||||
0x00, 0x00, 0x0c, 0x20, 0xfa, 0x01, 0x9e, 0x01,
|
||||
0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x09, 0x00,
|
||||
0xb4, 0x03, 0x00, 0x01, 0x0c, 0x43, 0x02, 0x01,
|
||||
0xb4, 0x03, 0x00, 0x01, 0x0c, 0x43, 0xfa, 0x01,
|
||||
0xb4, 0x03, 0x01, 0x00, 0x01, 0x04, 0x01, 0x00,
|
||||
0x1a, 0x01, 0xb6, 0x03, 0x00, 0x01, 0x00, 0xb4,
|
||||
0x03, 0x00, 0x00, 0xd0, 0xb3, 0xa7, 0xe9, 0x03,
|
||||
|
@ -49,7 +49,7 @@ const uint8_t qjsc_fib_module[310] = {
|
|||
const uint32_t qjsc_hello_module_size = 177;
|
||||
|
||||
const uint8_t qjsc_hello_module[177] = {
|
||||
0x0b, 0x07, 0x30, 0x65, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x0c, 0x07, 0x30, 0x65, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0x73, 0x2f, 0x68, 0x65, 0x6c, 0x6c,
|
||||
0x6f, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
|
||||
0x2e, 0x6a, 0x73, 0x1e, 0x2e, 0x2f, 0x66, 0x69,
|
||||
|
@ -60,7 +60,7 @@ const uint8_t qjsc_hello_module[177] = {
|
|||
0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x10,
|
||||
0x66, 0x69, 0x62, 0x28, 0x31, 0x30, 0x29, 0x3d,
|
||||
0x0d, 0xb2, 0x03, 0x01, 0xb4, 0x03, 0x00, 0x00,
|
||||
0x01, 0x00, 0xb6, 0x03, 0x00, 0x0c, 0x20, 0x02,
|
||||
0x01, 0x00, 0xb6, 0x03, 0x00, 0x0c, 0x20, 0xfa,
|
||||
0x01, 0x9e, 0x01, 0x00, 0x00, 0x00, 0x05, 0x01,
|
||||
0x00, 0x32, 0x00, 0xb6, 0x03, 0x00, 0x0c, 0x08,
|
||||
0xe9, 0x02, 0x29, 0x38, 0xdc, 0x00, 0x00, 0x00,
|
||||
|
|
13803
gen/repl.c
13803
gen/repl.c
File diff suppressed because it is too large
Load diff
|
@ -5,7 +5,7 @@
|
|||
const uint32_t qjsc_test_fib_size = 166;
|
||||
|
||||
const uint8_t qjsc_test_fib[166] = {
|
||||
0x0b, 0x07, 0x28, 0x65, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x0c, 0x07, 0x28, 0x65, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0x73, 0x2f, 0x74, 0x65, 0x73, 0x74,
|
||||
0x5f, 0x66, 0x69, 0x62, 0x2e, 0x6a, 0x73, 0x10,
|
||||
0x2e, 0x2f, 0x66, 0x69, 0x62, 0x2e, 0x73, 0x6f,
|
||||
|
@ -15,7 +15,7 @@ const uint8_t qjsc_test_fib[166] = {
|
|||
0x6f, 0x72, 0x6c, 0x64, 0x10, 0x66, 0x69, 0x62,
|
||||
0x28, 0x31, 0x30, 0x29, 0x3d, 0x0d, 0xb2, 0x03,
|
||||
0x01, 0xb4, 0x03, 0x00, 0x00, 0x01, 0x00, 0xb6,
|
||||
0x03, 0x00, 0x0c, 0x20, 0x02, 0x01, 0x9e, 0x01,
|
||||
0x03, 0x00, 0x0c, 0x20, 0xfa, 0x01, 0x9e, 0x01,
|
||||
0x00, 0x00, 0x00, 0x05, 0x01, 0x00, 0x32, 0x00,
|
||||
0xb6, 0x03, 0x00, 0x0c, 0x08, 0xe9, 0x02, 0x29,
|
||||
0x38, 0xdc, 0x00, 0x00, 0x00, 0x42, 0xdd, 0x00,
|
||||
|
|
17
qjsc.c
17
qjsc.c
|
@ -56,7 +56,7 @@ static namelist_t cmodule_list;
|
|||
static namelist_t init_module_list;
|
||||
static FILE *outfile;
|
||||
static const char *c_ident_prefix = "qjsc_";
|
||||
|
||||
static int strip;
|
||||
|
||||
void namelist_add(namelist_t *lp, const char *name, const char *short_name,
|
||||
int flags)
|
||||
|
@ -155,8 +155,15 @@ static void output_object_code(JSContext *ctx,
|
|||
{
|
||||
uint8_t *out_buf;
|
||||
size_t out_buf_len;
|
||||
int flags = JS_WRITE_OBJ_BYTECODE;
|
||||
|
||||
out_buf = JS_WriteObject(ctx, &out_buf_len, obj, JS_WRITE_OBJ_BYTECODE);
|
||||
if (strip) {
|
||||
flags |= JS_WRITE_OBJ_STRIP_SOURCE;
|
||||
if (strip > 1)
|
||||
flags |= JS_WRITE_OBJ_STRIP_DEBUG;
|
||||
}
|
||||
|
||||
out_buf = JS_WriteObject(ctx, &out_buf_len, obj, flags);
|
||||
if (!out_buf) {
|
||||
js_std_dump_error(ctx);
|
||||
exit(1);
|
||||
|
@ -354,6 +361,7 @@ int main(int argc, char **argv)
|
|||
cname = NULL;
|
||||
module = -1;
|
||||
verbose = 0;
|
||||
strip = 0;
|
||||
stack_size = 0;
|
||||
memset(&dynamic_module_list, 0, sizeof(dynamic_module_list));
|
||||
|
||||
|
@ -362,7 +370,7 @@ int main(int argc, char **argv)
|
|||
namelist_add(&cmodule_list, "os", "os", 0);
|
||||
|
||||
for(;;) {
|
||||
c = getopt(argc, argv, "ho:N:mxevM:p:S:D:");
|
||||
c = getopt(argc, argv, "ho:N:mxesvM:p:S:D:");
|
||||
if (c == -1)
|
||||
break;
|
||||
switch(c) {
|
||||
|
@ -399,6 +407,9 @@ int main(int argc, char **argv)
|
|||
case 'D':
|
||||
namelist_add(&dynamic_module_list, optarg, NULL, 0);
|
||||
break;
|
||||
case 's':
|
||||
strip++;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
|
|
39
quickjs.c
39
quickjs.c
|
@ -32601,7 +32601,7 @@ typedef enum BCTagEnum {
|
|||
BC_TAG_OBJECT_REFERENCE,
|
||||
} BCTagEnum;
|
||||
|
||||
#define BC_VERSION 11
|
||||
#define BC_VERSION 12
|
||||
|
||||
typedef struct BCWriterState {
|
||||
JSContext *ctx;
|
||||
|
@ -32609,6 +32609,8 @@ typedef struct BCWriterState {
|
|||
BOOL allow_bytecode : 8;
|
||||
BOOL allow_sab : 8;
|
||||
BOOL allow_reference : 8;
|
||||
BOOL allow_source : 1;
|
||||
BOOL allow_debug : 1;
|
||||
uint32_t first_atom;
|
||||
uint32_t *atom_to_idx;
|
||||
int atom_to_idx_size;
|
||||
|
@ -32971,6 +32973,7 @@ static int JS_WriteFunctionTag(BCWriterState *s, JSValue obj)
|
|||
bc_set_flags(&flags, &idx, b->super_allowed, 1);
|
||||
bc_set_flags(&flags, &idx, b->arguments_allowed, 1);
|
||||
bc_set_flags(&flags, &idx, b->backtrace_barrier, 1);
|
||||
bc_set_flags(&flags, &idx, s->allow_debug, 1);
|
||||
assert(idx <= 16);
|
||||
bc_put_u16(s, flags);
|
||||
bc_put_u8(s, b->js_mode);
|
||||
|
@ -33027,13 +33030,19 @@ static int JS_WriteFunctionTag(BCWriterState *s, JSValue obj)
|
|||
if (JS_WriteFunctionBytecode(s, b))
|
||||
goto fail;
|
||||
|
||||
bc_put_atom(s, b->filename);
|
||||
bc_put_leb128(s, b->line_num);
|
||||
bc_put_leb128(s, b->col_num);
|
||||
bc_put_leb128(s, b->pc2line_len);
|
||||
dbuf_put(&s->dbuf, b->pc2line_buf, b->pc2line_len);
|
||||
bc_put_leb128(s, b->source_len);
|
||||
dbuf_put(&s->dbuf, b->source, b->source_len);
|
||||
if (s->allow_debug) {
|
||||
bc_put_atom(s, b->filename);
|
||||
bc_put_leb128(s, b->line_num);
|
||||
bc_put_leb128(s, b->col_num);
|
||||
bc_put_leb128(s, b->pc2line_len);
|
||||
dbuf_put(&s->dbuf, b->pc2line_buf, b->pc2line_len);
|
||||
if (s->allow_source && b->source) {
|
||||
bc_put_leb128(s, b->source_len);
|
||||
dbuf_put(&s->dbuf, b->source, b->source_len);
|
||||
} else {
|
||||
bc_put_leb128(s, 0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
return -1;
|
||||
|
@ -33409,6 +33418,8 @@ uint8_t *JS_WriteObject2(JSContext *ctx, size_t *psize, JSValue obj,
|
|||
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);
|
||||
s->allow_source = ((flags & JS_WRITE_OBJ_STRIP_SOURCE) == 0);
|
||||
s->allow_debug = ((flags & JS_WRITE_OBJ_STRIP_DEBUG) == 0);
|
||||
/* XXX: could use a different version when bytecode is included */
|
||||
if (s->allow_bytecode)
|
||||
s->first_atom = JS_ATOM_END;
|
||||
|
@ -33864,7 +33875,7 @@ static JSValue JS_ReadFunctionTag(BCReaderState *s)
|
|||
JSValue obj = JS_UNDEFINED;
|
||||
uint16_t v16;
|
||||
uint8_t v8;
|
||||
int idx, i, local_count;
|
||||
int idx, i, local_count, has_debug_info;
|
||||
int function_size, cpool_offset, byte_code_offset;
|
||||
int closure_var_offset, vardefs_offset;
|
||||
uint32_t ic_len;
|
||||
|
@ -33887,6 +33898,7 @@ static JSValue JS_ReadFunctionTag(BCReaderState *s)
|
|||
bc.super_allowed = bc_get_flags(v16, &idx, 1);
|
||||
bc.arguments_allowed = bc_get_flags(v16, &idx, 1);
|
||||
bc.backtrace_barrier = bc_get_flags(v16, &idx, 1);
|
||||
has_debug_info = bc_get_flags(v16, &idx, 1);
|
||||
if (bc_get_u8(s, &v8))
|
||||
goto fail;
|
||||
bc.js_mode = v8;
|
||||
|
@ -34041,6 +34053,9 @@ static JSValue JS_ReadFunctionTag(BCReaderState *s)
|
|||
goto fail;
|
||||
bc_read_trace(s, "}\n");
|
||||
}
|
||||
if (!has_debug_info)
|
||||
goto nodebug;
|
||||
|
||||
/* read optional debug information */
|
||||
bc_read_trace(s, "debug {\n");
|
||||
if (bc_get_atom(s, &b->filename))
|
||||
|
@ -34078,8 +34093,11 @@ static JSValue JS_ReadFunctionTag(BCReaderState *s)
|
|||
goto fail;
|
||||
}
|
||||
bc_read_trace(s, "}\n");
|
||||
|
||||
nodebug:
|
||||
b->realm = JS_DupContext(ctx);
|
||||
return obj;
|
||||
|
||||
fail:
|
||||
JS_FreeAtom(ctx, bc.func_name);
|
||||
JS_FreeValue(ctx, obj);
|
||||
|
@ -36510,7 +36528,8 @@ static JSValue js_function_toString(JSContext *ctx, JSValue this_val,
|
|||
p = JS_VALUE_GET_OBJ(this_val);
|
||||
if (js_class_has_bytecode(p->class_id)) {
|
||||
JSFunctionBytecode *b = p->u.func.function_bytecode;
|
||||
return JS_NewStringLen(ctx, b->source, b->source_len);
|
||||
if (b->source)
|
||||
return JS_NewStringLen(ctx, b->source, b->source_len);
|
||||
}
|
||||
{
|
||||
JSValue name;
|
||||
|
|
|
@ -816,9 +816,9 @@ JS_EXTERN int JS_ExecutePendingJob(JSRuntime *rt, JSContext **pctx);
|
|||
#define JS_WRITE_OBJ_BYTECODE (1 << 0) /* allow function/module */
|
||||
#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
|
||||
graph */
|
||||
#define JS_WRITE_OBJ_REFERENCE (1 << 3) /* allow object references to encode arbitrary object graph */
|
||||
#define JS_WRITE_OBJ_STRIP_SOURCE (1 << 4) /* do not write source code information */
|
||||
#define JS_WRITE_OBJ_STRIP_DEBUG (1 << 5) /* do not write debug information */
|
||||
JS_EXTERN uint8_t *JS_WriteObject(JSContext *ctx, size_t *psize, JSValue obj, int flags);
|
||||
JS_EXTERN uint8_t *JS_WriteObject2(JSContext *ctx, size_t *psize, JSValue obj,
|
||||
int flags, uint8_t ***psab_tab, size_t *psab_tab_len);
|
||||
|
|
Loading…
Reference in a new issue