Skip to content

Commit 5cbf872

Browse files
authored
Retain function source code in serialized bytecode (#218)
Also fix a small memory leak in the output from `qjsc -e`. Fixes: #217
1 parent 7474b28 commit 5cbf872

File tree

7 files changed

+53
-8
lines changed

7 files changed

+53
-8
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ jobs:
109109
./build/qjs examples/test_fib.js
110110
./build/qjs examples/test_point.js
111111
./build/qjs tests/test_bjson.js
112+
./build/function_source
112113
linux-shared:
113114
runs-on: ubuntu-latest
114115
steps:
@@ -213,6 +214,7 @@ jobs:
213214
./build/qjs examples/test_fib.js
214215
./build/qjs examples/test_point.js
215216
./build/qjs tests/test_bjson.js
217+
./build/function_source
216218
macos-shared:
217219
runs-on: macos-latest
218220
steps:
@@ -261,6 +263,7 @@ jobs:
261263
run: |
262264
cmake -B build -DCMAKE_BUILD_TYPE=${{matrix.buildType}} -G "Visual Studio 17 2022" -T ClangCL
263265
cmake --build build --target qjs_exe
266+
cmake --build build --target function_source
264267
- name: stats
265268
run: |
266269
cmd /r build\Debug\qjs.exe -qd
@@ -274,6 +277,7 @@ jobs:
274277
cmd /r build\Debug\qjs.exe tests\test_std.js
275278
cmd /r build\Debug\qjs.exe tests\test_worker.js
276279
cmd /r build\Debug\qjs.exe tests\test_queue_microtask.js
280+
cmd /r build\Debug\function_source.exe
277281
278282
windows-mingw:
279283
runs-on: windows-latest

CMakeLists.txt

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,21 @@ add_executable(unicode_gen EXCLUDE_FROM_ALL
236236
)
237237
target_compile_definitions(unicode_gen PRIVATE ${qjs_defines})
238238

239+
add_custom_command(
240+
OUTPUT function_source.c
241+
COMMAND qjsc -e -o function_source.c ${CMAKE_CURRENT_SOURCE_DIR}/tests/function_source.js
242+
DEPENDS qjsc ${CMAKE_CURRENT_SOURCE_DIR}/tests/function_source.js
243+
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
244+
COMMENT "Compile function_source.js to a C file with bytecode embedded"
245+
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/tests/function_source.js
246+
)
247+
add_executable(function_source
248+
${CMAKE_CURRENT_BINARY_DIR}/function_source.c
249+
quickjs-libc.c
250+
)
251+
target_include_directories(function_source PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
252+
target_compile_definitions(function_source PRIVATE ${qjs_defines})
253+
target_link_libraries(function_source ${qjs_libs})
239254

240255
# Examples
241256
#
@@ -246,7 +261,7 @@ if(BUILD_EXAMPLES AND NOT WIN32)
246261
COMMAND qjsc -e -o hello.c ${CMAKE_CURRENT_SOURCE_DIR}/examples/hello.js
247262
DEPENDS qjsc
248263
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
249-
COMMENT "Compile hello.js to a C file with bytecode embeddee"
264+
COMMENT "Compile hello.js to a C file with bytecode embedded"
250265
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/examples/hello.js
251266
)
252267
add_executable(hello
@@ -262,7 +277,7 @@ if(BUILD_EXAMPLES AND NOT WIN32)
262277
COMMAND qjsc -e -o hello_module.c -m ${CMAKE_CURRENT_SOURCE_DIR}/examples/hello_module.js
263278
DEPENDS qjsc
264279
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
265-
COMMENT "Compile hello_module.js to a C file with bytecode embeddee"
280+
COMMENT "Compile hello_module.js to a C file with bytecode embedded"
266281
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/examples/hello_module.js
267282
)
268283
add_executable(hello_module

cutils.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ int dbuf_realloc(DynBuf *s, size_t new_size)
129129
return 0;
130130
}
131131

132-
int dbuf_write(DynBuf *s, size_t offset, const uint8_t *data, size_t len)
132+
int dbuf_write(DynBuf *s, size_t offset, const void *data, size_t len)
133133
{
134134
size_t end;
135135
end = offset + len;
@@ -141,7 +141,7 @@ int dbuf_write(DynBuf *s, size_t offset, const uint8_t *data, size_t len)
141141
return 0;
142142
}
143143

144-
int dbuf_put(DynBuf *s, const uint8_t *data, size_t len)
144+
int dbuf_put(DynBuf *s, const void *data, size_t len)
145145
{
146146
if (unlikely((s->size + len) > s->allocated_size)) {
147147
if (dbuf_realloc(s, s->size + len))

cutils.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,8 +277,8 @@ typedef struct DynBuf {
277277
void dbuf_init(DynBuf *s);
278278
void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func);
279279
int dbuf_realloc(DynBuf *s, size_t new_size);
280-
int dbuf_write(DynBuf *s, size_t offset, const uint8_t *data, size_t len);
281-
int dbuf_put(DynBuf *s, const uint8_t *data, size_t len);
280+
int dbuf_write(DynBuf *s, size_t offset, const void *data, size_t len);
281+
int dbuf_put(DynBuf *s, const void *data, size_t len);
282282
int dbuf_put_self(DynBuf *s, size_t offset, size_t len);
283283
int dbuf_putc(DynBuf *s, uint8_t c);
284284
int dbuf_putstr(DynBuf *s, const char *str);

qjsc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ static const char main_c_template1[] =
305305
static const char main_c_template2[] =
306306
" js_std_loop(ctx);\n"
307307
" JS_FreeContext(ctx);\n"
308+
" js_std_free_handlers(rt);\n"
308309
" JS_FreeRuntime(rt);\n"
309310
" return 0;\n"
310311
"}\n";

quickjs.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32018,7 +32018,7 @@ typedef enum BCTagEnum {
3201832018
BC_TAG_OBJECT_REFERENCE,
3201932019
} BCTagEnum;
3202032020

32021-
#define BC_VERSION 7
32021+
#define BC_VERSION 8
3202232022

3202332023
typedef struct BCWriterState {
3202432024
JSContext *ctx;
@@ -32440,6 +32440,8 @@ static int JS_WriteFunctionTag(BCWriterState *s, JSValue obj)
3244032440
bc_put_leb128(s, b->col_num);
3244132441
bc_put_leb128(s, b->pc2line_len);
3244232442
dbuf_put(&s->dbuf, b->pc2line_buf, b->pc2line_len);
32443+
bc_put_leb128(s, b->source_len);
32444+
dbuf_put(&s->dbuf, b->source, b->source_len);
3244332445

3244432446
/* compatibility */
3244532447
dbuf_putc(&s->dbuf, 255);
@@ -33017,7 +33019,7 @@ static int bc_get_leb128_u16(BCReaderState *s, uint16_t *pval)
3301733019
return 0;
3301833020
}
3301933021

33020-
static int bc_get_buf(BCReaderState *s, uint8_t *buf, uint32_t buf_len)
33022+
static int bc_get_buf(BCReaderState *s, void *buf, uint32_t buf_len)
3302133023
{
3302233024
if (buf_len != 0) {
3302333025
if (unlikely(!buf || s->buf_end - s->ptr < buf_len))
@@ -33413,6 +33415,15 @@ static JSValue JS_ReadFunctionTag(BCReaderState *s)
3341333415
if (bc_get_buf(s, b->pc2line_buf, b->pc2line_len))
3341433416
goto fail;
3341533417
}
33418+
if (bc_get_leb128_int(s, &b->source_len))
33419+
goto fail;
33420+
if (b->source_len) {
33421+
b->source = js_mallocz(ctx, b->source_len);
33422+
if (!b->source)
33423+
goto fail;
33424+
if (bc_get_buf(s, b->source, b->source_len))
33425+
goto fail;
33426+
}
3341633427
if (s->buf_end - s->ptr > 3 && s->ptr[0] == 255 &&
3341733428
s->ptr[1] == 73 && s->ptr[2] == 67) {
3341833429
s->ptr += 3;

tests/function_source.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
"use strict"
2+
const expect = "function f() { return 42 }"
3+
function f() { return 42 }
4+
5+
{
6+
const actual = f.toString()
7+
if (actual !== expect) throw Error(actual)
8+
}
9+
10+
{
11+
const f = eval(expect + "f")
12+
const actual = f.toString()
13+
if (actual !== expect) throw Error(actual)
14+
}

0 commit comments

Comments
 (0)