Drop support for "use strip"
Ref: https://github.com/quickjs-ng/quickjs/issues/20
This commit is contained in:
parent
1fb9a5010f
commit
e2ae8746ca
5 changed files with 61 additions and 114 deletions
|
@ -286,8 +286,6 @@ ECMA402 (Internationalization API) is not supported.
|
||||||
|
|
||||||
@itemize
|
@itemize
|
||||||
|
|
||||||
@item The directive @code{"use strip"} indicates that the debug information (including the source code of the functions) should not be retained to save memory. As @code{"use strict"}, the directive can be global to a script or local to a function.
|
|
||||||
|
|
||||||
@item The first line of a script beginning with @code{#!} is ignored.
|
@item The first line of a script beginning with @code{#!} is ignored.
|
||||||
|
|
||||||
@end itemize
|
@end itemize
|
||||||
|
@ -305,10 +303,6 @@ standard Javascript. See @code{jsbignum.pdf} for more information.
|
||||||
|
|
||||||
@item Operator overloading.
|
@item Operator overloading.
|
||||||
|
|
||||||
@item The directive @code{"use bigint"} enables the bigint mode where integers are @code{BigInt} by default.
|
|
||||||
|
|
||||||
@item The directive @code{"use math"} enables the math mode where the division and power operators on integers produce fractions. Floating point literals are @code{BigFloat} by default and integers are @code{BigInt} by default.
|
|
||||||
|
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
@section Modules
|
@section Modules
|
||||||
|
|
56
quickjs.c
56
quickjs.c
|
@ -313,7 +313,6 @@ struct JSClass {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define JS_MODE_STRICT (1 << 0)
|
#define JS_MODE_STRICT (1 << 0)
|
||||||
#define JS_MODE_STRIP (1 << 1)
|
|
||||||
|
|
||||||
typedef struct JSStackFrame {
|
typedef struct JSStackFrame {
|
||||||
struct JSStackFrame *prev_frame; /* NULL if first stack frame */
|
struct JSStackFrame *prev_frame; /* NULL if first stack frame */
|
||||||
|
@ -22961,14 +22960,11 @@ static __exception int js_parse_class(JSParseState *s, BOOL is_class_expr,
|
||||||
put_u32(fd->byte_code.buf + ctor_cpool_offset, ctor_fd->parent_cpool_idx);
|
put_u32(fd->byte_code.buf + ctor_cpool_offset, ctor_fd->parent_cpool_idx);
|
||||||
|
|
||||||
/* store the class source code in the constructor. */
|
/* store the class source code in the constructor. */
|
||||||
if (!(fd->js_mode & JS_MODE_STRIP)) {
|
|
||||||
js_free(ctx, ctor_fd->source);
|
js_free(ctx, ctor_fd->source);
|
||||||
ctor_fd->source_len = s->buf_ptr - class_start_ptr;
|
ctor_fd->source_len = s->buf_ptr - class_start_ptr;
|
||||||
ctor_fd->source = js_strndup(ctx, (const char *)class_start_ptr,
|
ctor_fd->source = js_strndup(ctx, (const char *)class_start_ptr, ctor_fd->source_len);
|
||||||
ctor_fd->source_len);
|
|
||||||
if (!ctor_fd->source)
|
if (!ctor_fd->source)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
|
||||||
|
|
||||||
/* consume the '}' */
|
/* consume the '}' */
|
||||||
if (next_token(s))
|
if (next_token(s))
|
||||||
|
@ -30871,7 +30867,7 @@ static void add_pc2line_info(JSFunctionDef *s, uint32_t pc, int line_num)
|
||||||
|
|
||||||
static void compute_pc2line_info(JSFunctionDef *s)
|
static void compute_pc2line_info(JSFunctionDef *s)
|
||||||
{
|
{
|
||||||
if (!(s->js_mode & JS_MODE_STRIP) && s->line_number_slots) {
|
if (s->line_number_slots) {
|
||||||
int last_line_num = s->line_num;
|
int last_line_num = s->line_num;
|
||||||
uint32_t last_pc = 0;
|
uint32_t last_pc = 0;
|
||||||
int i;
|
int i;
|
||||||
|
@ -31098,7 +31094,7 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* XXX: Should skip this phase if not generating SHORT_OPCODES */
|
/* XXX: Should skip this phase if not generating SHORT_OPCODES */
|
||||||
if (s->line_number_size && !(s->js_mode & JS_MODE_STRIP)) {
|
if (s->line_number_size) {
|
||||||
s->line_number_slots = js_mallocz(s->ctx, sizeof(*s->line_number_slots) * s->line_number_size);
|
s->line_number_slots = js_mallocz(s->ctx, sizeof(*s->line_number_slots) * s->line_number_size);
|
||||||
if (s->line_number_slots == NULL)
|
if (s->line_number_slots == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -32243,7 +32239,6 @@ static JSValue js_create_function(JSContext *ctx, JSFunctionDef *fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DUMP_BYTECODE) && (DUMP_BYTECODE & 4)
|
#if defined(DUMP_BYTECODE) && (DUMP_BYTECODE & 4)
|
||||||
if (!(fd->js_mode & JS_MODE_STRIP)) {
|
|
||||||
printf("pass 1\n");
|
printf("pass 1\n");
|
||||||
dump_byte_code(ctx, 1, fd->byte_code.buf, fd->byte_code.size,
|
dump_byte_code(ctx, 1, fd->byte_code.buf, fd->byte_code.size,
|
||||||
fd->args, fd->arg_count, fd->vars, fd->var_count,
|
fd->args, fd->arg_count, fd->vars, fd->var_count,
|
||||||
|
@ -32251,14 +32246,12 @@ static JSValue js_create_function(JSContext *ctx, JSFunctionDef *fd)
|
||||||
fd->cpool, fd->cpool_count, fd->source, fd->line_num,
|
fd->cpool, fd->cpool_count, fd->source, fd->line_num,
|
||||||
fd->label_slots, NULL);
|
fd->label_slots, NULL);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (resolve_variables(ctx, fd))
|
if (resolve_variables(ctx, fd))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
#if defined(DUMP_BYTECODE) && (DUMP_BYTECODE & 2)
|
#if defined(DUMP_BYTECODE) && (DUMP_BYTECODE & 2)
|
||||||
if (!(fd->js_mode & JS_MODE_STRIP)) {
|
|
||||||
printf("pass 2\n");
|
printf("pass 2\n");
|
||||||
dump_byte_code(ctx, 2, fd->byte_code.buf, fd->byte_code.size,
|
dump_byte_code(ctx, 2, fd->byte_code.buf, fd->byte_code.size,
|
||||||
fd->args, fd->arg_count, fd->vars, fd->var_count,
|
fd->args, fd->arg_count, fd->vars, fd->var_count,
|
||||||
|
@ -32266,7 +32259,6 @@ static JSValue js_create_function(JSContext *ctx, JSFunctionDef *fd)
|
||||||
fd->cpool, fd->cpool_count, fd->source, fd->line_num,
|
fd->cpool, fd->cpool_count, fd->source, fd->line_num,
|
||||||
fd->label_slots, NULL);
|
fd->label_slots, NULL);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (resolve_labels(ctx, fd))
|
if (resolve_labels(ctx, fd))
|
||||||
|
@ -32275,17 +32267,11 @@ static JSValue js_create_function(JSContext *ctx, JSFunctionDef *fd)
|
||||||
if (compute_stack_size(ctx, fd, &stack_size) < 0)
|
if (compute_stack_size(ctx, fd, &stack_size) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (fd->js_mode & JS_MODE_STRIP) {
|
|
||||||
function_size = offsetof(JSFunctionBytecode, debug);
|
|
||||||
} else {
|
|
||||||
function_size = sizeof(*b);
|
function_size = sizeof(*b);
|
||||||
}
|
|
||||||
cpool_offset = function_size;
|
cpool_offset = function_size;
|
||||||
function_size += fd->cpool_count * sizeof(*fd->cpool);
|
function_size += fd->cpool_count * sizeof(*fd->cpool);
|
||||||
vardefs_offset = function_size;
|
vardefs_offset = function_size;
|
||||||
if (!(fd->js_mode & JS_MODE_STRIP) || fd->has_eval_call) {
|
|
||||||
function_size += (fd->arg_count + fd->var_count) * sizeof(*b->vardefs);
|
function_size += (fd->arg_count + fd->var_count) * sizeof(*b->vardefs);
|
||||||
}
|
|
||||||
closure_var_offset = function_size;
|
closure_var_offset = function_size;
|
||||||
function_size += fd->closure_var_count * sizeof(*fd->closure_var);
|
function_size += fd->closure_var_count * sizeof(*fd->closure_var);
|
||||||
byte_code_offset = function_size;
|
byte_code_offset = function_size;
|
||||||
|
@ -32304,26 +32290,11 @@ static JSValue js_create_function(JSContext *ctx, JSFunctionDef *fd)
|
||||||
|
|
||||||
b->func_name = fd->func_name;
|
b->func_name = fd->func_name;
|
||||||
if (fd->arg_count + fd->var_count > 0) {
|
if (fd->arg_count + fd->var_count > 0) {
|
||||||
if ((fd->js_mode & JS_MODE_STRIP) && !fd->has_eval_call) {
|
|
||||||
/* Strip variable definitions not needed at runtime */
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < fd->var_count; i++) {
|
|
||||||
JS_FreeAtom(ctx, fd->vars[i].var_name);
|
|
||||||
}
|
|
||||||
for(i = 0; i < fd->arg_count; i++) {
|
|
||||||
JS_FreeAtom(ctx, fd->args[i].var_name);
|
|
||||||
}
|
|
||||||
for(i = 0; i < fd->closure_var_count; i++) {
|
|
||||||
JS_FreeAtom(ctx, fd->closure_var[i].var_name);
|
|
||||||
fd->closure_var[i].var_name = JS_ATOM_NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
b->vardefs = (void *)((uint8_t*)b + vardefs_offset);
|
b->vardefs = (void *)((uint8_t*)b + vardefs_offset);
|
||||||
if (fd->arg_count > 0)
|
if (fd->arg_count > 0)
|
||||||
memcpy(b->vardefs, fd->args, fd->arg_count * sizeof(fd->args[0]));
|
memcpy(b->vardefs, fd->args, fd->arg_count * sizeof(fd->args[0]));
|
||||||
if (fd->var_count > 0)
|
if (fd->var_count > 0)
|
||||||
memcpy(b->vardefs + fd->arg_count, fd->vars, fd->var_count * sizeof(fd->vars[0]));
|
memcpy(b->vardefs + fd->arg_count, fd->vars, fd->var_count * sizeof(fd->vars[0]));
|
||||||
}
|
|
||||||
b->var_count = fd->var_count;
|
b->var_count = fd->var_count;
|
||||||
b->arg_count = fd->arg_count;
|
b->arg_count = fd->arg_count;
|
||||||
b->defined_arg_count = fd->defined_arg_count;
|
b->defined_arg_count = fd->defined_arg_count;
|
||||||
|
@ -32340,10 +32311,6 @@ static JSValue js_create_function(JSContext *ctx, JSFunctionDef *fd)
|
||||||
|
|
||||||
b->stack_size = stack_size;
|
b->stack_size = stack_size;
|
||||||
|
|
||||||
if (fd->js_mode & JS_MODE_STRIP) {
|
|
||||||
JS_FreeAtom(ctx, fd->filename);
|
|
||||||
dbuf_free(&fd->pc2line); // probably useless
|
|
||||||
} else {
|
|
||||||
/* XXX: source and pc2line info should be packed at the end of the
|
/* XXX: source and pc2line info should be packed at the end of the
|
||||||
JSFunctionBytecode structure, avoiding allocation overhead
|
JSFunctionBytecode structure, avoiding allocation overhead
|
||||||
*/
|
*/
|
||||||
|
@ -32360,7 +32327,7 @@ static JSValue js_create_function(JSContext *ctx, JSFunctionDef *fd)
|
||||||
b->debug.pc2line_len = fd->pc2line.size;
|
b->debug.pc2line_len = fd->pc2line.size;
|
||||||
b->debug.source = fd->source;
|
b->debug.source = fd->source;
|
||||||
b->debug.source_len = fd->source_len;
|
b->debug.source_len = fd->source_len;
|
||||||
}
|
|
||||||
if (fd->scopes != fd->def_scope_array)
|
if (fd->scopes != fd->def_scope_array)
|
||||||
js_free(ctx, fd->scopes);
|
js_free(ctx, fd->scopes);
|
||||||
|
|
||||||
|
@ -32389,9 +32356,7 @@ static JSValue js_create_function(JSContext *ctx, JSFunctionDef *fd)
|
||||||
add_gc_object(ctx->rt, &b->header, JS_GC_OBJ_TYPE_FUNCTION_BYTECODE);
|
add_gc_object(ctx->rt, &b->header, JS_GC_OBJ_TYPE_FUNCTION_BYTECODE);
|
||||||
|
|
||||||
#if defined(DUMP_BYTECODE) && (DUMP_BYTECODE & 1)
|
#if defined(DUMP_BYTECODE) && (DUMP_BYTECODE & 1)
|
||||||
if (!(fd->js_mode & JS_MODE_STRIP)) {
|
|
||||||
js_dump_function_bytecode(ctx, b);
|
js_dump_function_bytecode(ctx, b);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fd->parent) {
|
if (fd->parent) {
|
||||||
|
@ -32531,11 +32496,6 @@ static __exception int js_parse_directives(JSParseState *s)
|
||||||
s->cur_func->has_use_strict = TRUE;
|
s->cur_func->has_use_strict = TRUE;
|
||||||
s->cur_func->js_mode |= JS_MODE_STRICT;
|
s->cur_func->js_mode |= JS_MODE_STRICT;
|
||||||
}
|
}
|
||||||
#if !defined(DUMP_BYTECODE) || !(DUMP_BYTECODE & 8)
|
|
||||||
else if (!strcmp(str, "use strip")) {
|
|
||||||
s->cur_func->js_mode |= JS_MODE_STRIP;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return js_parse_seek_token(s, &pos);
|
return js_parse_seek_token(s, &pos);
|
||||||
}
|
}
|
||||||
|
@ -33009,7 +32969,6 @@ static __exception int js_parse_function_decl2(JSParseState *s,
|
||||||
else
|
else
|
||||||
emit_op(s, OP_return);
|
emit_op(s, OP_return);
|
||||||
|
|
||||||
if (!(fd->js_mode & JS_MODE_STRIP)) {
|
|
||||||
/* save the function source code */
|
/* save the function source code */
|
||||||
/* the end of the function source code is after the last
|
/* the end of the function source code is after the last
|
||||||
token of the function source stored into s->last_ptr */
|
token of the function source stored into s->last_ptr */
|
||||||
|
@ -33017,7 +32976,7 @@ static __exception int js_parse_function_decl2(JSParseState *s,
|
||||||
fd->source = js_strndup(ctx, (const char *)ptr, fd->source_len);
|
fd->source = js_strndup(ctx, (const char *)ptr, fd->source_len);
|
||||||
if (!fd->source)
|
if (!fd->source)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33036,13 +32995,12 @@ static __exception int js_parse_function_decl2(JSParseState *s,
|
||||||
if (js_parse_source_element(s))
|
if (js_parse_source_element(s))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (!(fd->js_mode & JS_MODE_STRIP)) {
|
|
||||||
/* save the function source code */
|
/* save the function source code */
|
||||||
fd->source_len = s->buf_ptr - ptr;
|
fd->source_len = s->buf_ptr - ptr;
|
||||||
fd->source = js_strndup(ctx, (const char *)ptr, fd->source_len);
|
fd->source = js_strndup(ctx, (const char *)ptr, fd->source_len);
|
||||||
if (!fd->source)
|
if (!fd->source)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
|
||||||
|
|
||||||
if (next_token(s)) {
|
if (next_token(s)) {
|
||||||
/* consume the '}' */
|
/* consume the '}' */
|
||||||
|
@ -33331,8 +33289,6 @@ static JSValue __JS_EvalInternal(JSContext *ctx, JSValueConst this_obj,
|
||||||
js_mode = 0;
|
js_mode = 0;
|
||||||
if (flags & JS_EVAL_FLAG_STRICT)
|
if (flags & JS_EVAL_FLAG_STRICT)
|
||||||
js_mode |= JS_MODE_STRICT;
|
js_mode |= JS_MODE_STRICT;
|
||||||
if (flags & JS_EVAL_FLAG_STRIP)
|
|
||||||
js_mode |= JS_MODE_STRIP;
|
|
||||||
if (eval_type == JS_EVAL_TYPE_MODULE) {
|
if (eval_type == JS_EVAL_TYPE_MODULE) {
|
||||||
JSAtom module_name = JS_NewAtom(ctx, filename);
|
JSAtom module_name = JS_NewAtom(ctx, filename);
|
||||||
if (module_name == JS_ATOM_NULL)
|
if (module_name == JS_ATOM_NULL)
|
||||||
|
|
|
@ -300,7 +300,7 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
|
||||||
#define JS_EVAL_TYPE_MASK (3 << 0)
|
#define JS_EVAL_TYPE_MASK (3 << 0)
|
||||||
|
|
||||||
#define JS_EVAL_FLAG_STRICT (1 << 3) /* force 'strict' mode */
|
#define JS_EVAL_FLAG_STRICT (1 << 3) /* force 'strict' mode */
|
||||||
#define JS_EVAL_FLAG_STRIP (1 << 4) /* force 'strip' mode */
|
#define JS_EVAL_FLAG_UNUSED (1 << 4) /* unused */
|
||||||
/* compile but do not run. The result is an object with a
|
/* compile but do not run. The result is an object with a
|
||||||
JS_TAG_FUNCTION_BYTECODE or JS_TAG_MODULE tag. It can be executed
|
JS_TAG_FUNCTION_BYTECODE or JS_TAG_MODULE tag. It can be executed
|
||||||
with JS_EvalFunction(). */
|
with JS_EvalFunction(). */
|
||||||
|
|
2
repl.js
2
repl.js
|
@ -22,8 +22,6 @@
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
"use strip";
|
|
||||||
|
|
||||||
import * as std from "std";
|
import * as std from "std";
|
||||||
import * as os from "os";
|
import * as os from "os";
|
||||||
|
|
||||||
|
|
|
@ -1550,8 +1550,7 @@ int run_test_buf(const char *filename, char *harness, namelist_t *ip,
|
||||||
add_helpers(ctx);
|
add_helpers(ctx);
|
||||||
|
|
||||||
for (i = 0; i < ip->count; i++) {
|
for (i = 0; i < ip->count; i++) {
|
||||||
if (eval_file(ctx, harness, ip->array[i],
|
if (eval_file(ctx, harness, ip->array[i], JS_EVAL_TYPE_GLOBAL)) {
|
||||||
JS_EVAL_TYPE_GLOBAL | JS_EVAL_FLAG_STRIP)) {
|
|
||||||
fatal(1, "error including %s for %s", ip->array[i], filename);
|
fatal(1, "error including %s for %s", ip->array[i], filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue