Skip to content

Add JS_Eval* overloads taking line #822

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
Feb 3, 2025
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
65 changes: 50 additions & 15 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ struct JSContext {
/* if NULL, eval is not supported */
JSValue (*eval_internal)(JSContext *ctx, JSValue this_obj,
const char *input, size_t input_len,
const char *filename, int flags, int scope_idx);
const char *filename, int line, int flags, int scope_idx);
void *user_opaque;
};

Expand Down Expand Up @@ -1236,7 +1236,7 @@ static void js_async_function_resolve_mark(JSRuntime *rt, JSValue val,
JS_MarkFunc *mark_func);
static JSValue JS_EvalInternal(JSContext *ctx, JSValue this_obj,
const char *input, size_t input_len,
const char *filename, int flags, int scope_idx);
const char *filename, int line, int flags, int scope_idx);
static void js_free_module_def(JSContext *ctx, JSModuleDef *m);
static void js_mark_module_def(JSRuntime *rt, JSModuleDef *m,
JS_MarkFunc *mark_func);
Expand Down Expand Up @@ -33431,12 +33431,12 @@ static __exception int js_parse_program(JSParseState *s)

static void js_parse_init(JSContext *ctx, JSParseState *s,
const char *input, size_t input_len,
const char *filename)
const char *filename, int line)
{
memset(s, 0, sizeof(*s));
s->ctx = ctx;
s->filename = filename;
s->line_num = 1;
s->line_num = line;
s->col_num = 1;
s->buf_start = s->buf_ptr = (const uint8_t *)input;
s->buf_end = s->buf_ptr + input_len;
Expand Down Expand Up @@ -33488,7 +33488,7 @@ JSValue JS_EvalFunction(JSContext *ctx, JSValue fun_obj)
/* `export_name` and `input` may be pure ASCII or UTF-8 encoded */
static JSValue __JS_EvalInternal(JSContext *ctx, JSValue this_obj,
const char *input, size_t input_len,
const char *filename, int flags, int scope_idx)
const char *filename, int line, int flags, int scope_idx)
{
JSParseState s1, *s = &s1;
int err, eval_type;
Expand All @@ -33500,7 +33500,7 @@ static JSValue __JS_EvalInternal(JSContext *ctx, JSValue this_obj,
JSModuleDef *m;
bool is_strict_mode;

js_parse_init(ctx, s, input, input_len, filename);
js_parse_init(ctx, s, input, input_len, filename, line);
skip_shebang(&s->buf_ptr, s->buf_end);

eval_type = flags & JS_EVAL_TYPE_MASK;
Expand Down Expand Up @@ -33530,7 +33530,7 @@ static JSValue __JS_EvalInternal(JSContext *ctx, JSValue this_obj,
is_strict_mode = true;
}
}
fd = js_new_function_def(ctx, NULL, true, false, filename, 1, 1);
fd = js_new_function_def(ctx, NULL, true, false, filename, line, 1);
if (!fd)
goto fail1;
s->cur_func = fd;
Expand Down Expand Up @@ -33603,12 +33603,12 @@ static JSValue __JS_EvalInternal(JSContext *ctx, JSValue this_obj,
/* the indirection is needed to make 'eval' optional */
static JSValue JS_EvalInternal(JSContext *ctx, JSValue this_obj,
const char *input, size_t input_len,
const char *filename, int flags, int scope_idx)
const char *filename, int line, int flags, int scope_idx)
{
if (unlikely(!ctx->eval_internal)) {
return JS_ThrowTypeError(ctx, "eval is not supported");
}
return ctx->eval_internal(ctx, this_obj, input, input_len, filename,
return ctx->eval_internal(ctx, this_obj, input, input_len, filename, line,
flags, scope_idx);
}

Expand All @@ -33624,7 +33624,7 @@ static JSValue JS_EvalObject(JSContext *ctx, JSValue this_obj,
str = JS_ToCStringLen(ctx, &len, val);
if (!str)
return JS_EXCEPTION;
ret = JS_EvalInternal(ctx, this_obj, str, len, "<input>", flags, scope_idx);
ret = JS_EvalInternal(ctx, this_obj, str, len, "<input>", 1, flags, scope_idx);
JS_FreeCString(ctx, str);
return ret;

Expand All @@ -33634,20 +33634,55 @@ JSValue JS_EvalThis(JSContext *ctx, JSValue this_obj,
const char *input, size_t input_len,
const char *filename, int eval_flags)
{
JSEvalOptions options = {
.version = JS_EVAL_OPTIONS_VERSION,
.filename = filename,
.line_num = 1,
.eval_flags = eval_flags
};
return JS_EvalThis2(ctx, this_obj, input, input_len, &options);
}

JSValue JS_EvalThis2(JSContext *ctx, JSValue this_obj,
const char *input, size_t input_len,
JSEvalOptions *options)
{
const char *filename = "<unnamed>";
int line = 1;
int eval_flags = 0;
if (options) {
if (options->version != JS_EVAL_OPTIONS_VERSION)
return JS_ThrowInternalError(ctx, "bad JSEvalOptions version");
if (options->filename)
filename = options->filename;
if (options->line_num != 0)
line = options->line_num;
eval_flags = options->eval_flags;
}
JSValue ret;

assert((eval_flags & JS_EVAL_TYPE_MASK) == JS_EVAL_TYPE_GLOBAL ||
(eval_flags & JS_EVAL_TYPE_MASK) == JS_EVAL_TYPE_MODULE);
ret = JS_EvalInternal(ctx, this_obj, input, input_len, filename,
ret = JS_EvalInternal(ctx, this_obj, input, input_len, filename, line,
eval_flags, -1);
return ret;
}

JSValue JS_Eval(JSContext *ctx, const char *input, size_t input_len,
const char *filename, int eval_flags)
{
return JS_EvalThis(ctx, ctx->global_obj, input, input_len, filename,
eval_flags);
JSEvalOptions options = {
.version = JS_EVAL_OPTIONS_VERSION,
.filename = filename,
.line_num = 1,
.eval_flags = eval_flags
};
return JS_EvalThis2(ctx, ctx->global_obj, input, input_len, &options);
}

JSValue JS_Eval2(JSContext *ctx, const char *input, size_t input_len, JSEvalOptions *options)
{
return JS_EvalThis2(ctx, ctx->global_obj, input, input_len, options);
}

int JS_ResolveModule(JSContext *ctx, JSValue obj)
Expand Down Expand Up @@ -45293,7 +45328,7 @@ JSValue JS_ParseJSON(JSContext *ctx, const char *buf, size_t buf_len, const char
JSParseState s1, *s = &s1;
JSValue val = JS_UNDEFINED;

js_parse_init(ctx, s, buf, buf_len, filename);
js_parse_init(ctx, s, buf, buf_len, filename, 1);
if (json_next_token(s))
goto fail;
val = json_parse_value(s);
Expand Down Expand Up @@ -56236,7 +56271,7 @@ bool JS_DetectModule(const char *input, size_t input_len)
return false;
}
JS_AddIntrinsicRegExp(ctx); // otherwise regexp literals don't parse
val = __JS_EvalInternal(ctx, JS_UNDEFINED, input, input_len, "<unnamed>",
val = __JS_EvalInternal(ctx, JS_UNDEFINED, input, input_len, "<unnamed>", 1,
JS_EVAL_TYPE_MODULE|JS_EVAL_FLAG_COMPILE_ONLY, -1);
if (JS_IsException(val)) {
const char *msg = JS_ToCString(ctx, rt->current_exception);
Expand Down
16 changes: 15 additions & 1 deletion quickjs.h
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,16 @@ typedef struct JSClassDef {
JSClassExoticMethods *exotic;
} JSClassDef;

#define JS_EVAL_OPTIONS_VERSION 1

typedef struct JSEvalOptions {
int version;
int eval_flags;
const char *filename;
int line_num;
// can add new fields in ABI-compatible manner by incrementing JS_EVAL_OPTIONS_VERSION
} JSEvalOptions;

#define JS_INVALID_CLASS_ID 0
JS_EXTERN JSClassID JS_NewClassID(JSRuntime *rt, JSClassID *pclass_id);
/* Returns the class ID if `v` is an object, otherwise returns JS_INVALID_CLASS_ID. */
Expand Down Expand Up @@ -803,10 +813,14 @@ JS_EXTERN bool JS_DetectModule(const char *input, size_t input_len);
/* 'input' must be zero terminated i.e. input[input_len] = '\0'. */
JS_EXTERN JSValue JS_Eval(JSContext *ctx, const char *input, size_t input_len,
const char *filename, int eval_flags);
/* same as JS_Eval() but with an explicit 'this_obj' parameter */
JS_EXTERN JSValue JS_Eval2(JSContext *ctx, const char *input, size_t input_len,
JSEvalOptions *options);
JS_EXTERN JSValue JS_EvalThis(JSContext *ctx, JSValue this_obj,
const char *input, size_t input_len,
const char *filename, int eval_flags);
JS_EXTERN JSValue JS_EvalThis2(JSContext *ctx, JSValue this_obj,
const char *input, size_t input_len,
JSEvalOptions *options);
JS_EXTERN JSValue JS_GetGlobalObject(JSContext *ctx);
JS_EXTERN int JS_IsInstanceOf(JSContext *ctx, JSValue val, JSValue obj);
JS_EXTERN int JS_DefineProperty(JSContext *ctx, JSValue this_obj,
Expand Down