rm some functions

This commit is contained in:
2026-02-12 18:08:56 -06:00
parent 4aedb8b0c5
commit 73bfa8d7b1
3 changed files with 4 additions and 552 deletions

View File

@@ -294,7 +294,6 @@ typedef enum JSErrorEnum {
#define __exception __attribute__ ((warn_unused_result))
/* Forward declaration for bytecode freeing */
struct JSFunctionBytecode;
#define JS_VALUE_GET_ARRAY(v) ((JSArray *)chase (v))
#define JS_VALUE_GET_OBJ(v) ((JSRecord *)chase (v))
@@ -302,7 +301,7 @@ struct JSFunctionBytecode;
#define JS_VALUE_GET_BLOB(v) ((JSBlob *)JS_VALUE_GET_PTR (v))
#define JS_VALUE_GET_FUNCTION(v) ((JSFunction *)chase (v))
#define JS_VALUE_GET_FRAME(v) ((JSFrame *)chase (v))
#define JS_VALUE_GET_CODE(v) ((JSFunctionBytecode *)JS_VALUE_GET_PTR (v))
#define JS_VALUE_GET_CODE(v) (JS_VALUE_GET_PTR (v))
#define JS_VALUE_GET_STRING(v) ((JSText *)chase (v))
/* Compatibility: JS_TAG_STRING is an alias for text type checks */
@@ -1237,11 +1236,6 @@ typedef struct JSFunction {
uint8_t cproto;
int16_t magic;
} cfunc;
struct {
struct JSFunctionBytecode *function_bytecode;
JSValue outer_frame; /* JSFrame JSValue, lexical parent for closures */
JSValue env_record; /* stone record, module environment */
} func;
struct {
JSCodeRegister *code; /* compiled register code (off-heap) */
JSValue env_record; /* stone record, module environment */
@@ -1250,107 +1244,12 @@ typedef struct JSFunction {
} u;
} JSFunction;
typedef struct JSClosureVar {
uint8_t is_local : 1;
uint8_t is_arg : 1;
uint8_t is_const : 1;
uint8_t is_lexical : 1;
uint8_t var_kind : 4; /* see JSVarKindEnum */
/* 8 bits available */
uint16_t var_idx; /* is_local = TRUE: index to a normal variable of the
parent function. otherwise: index to a closure
variable of the parent function */
JSValue var_name;
} JSClosureVar;
#define ARG_SCOPE_INDEX 1
#define ARG_SCOPE_END (-2)
typedef struct JSVarScope {
int parent; /* index into fd->scopes of the enclosing scope */
int first; /* index into fd->vars of the last variable in this scope */
} JSVarScope;
typedef enum {
/* XXX: add more variable kinds here instead of using bit fields */
JS_VAR_NORMAL,
JS_VAR_FUNCTION_DECL, /* lexical var with function declaration */
JS_VAR_NEW_FUNCTION_DECL, /* lexical var with async/generator
function declaration */
JS_VAR_CATCH,
JS_VAR_FUNCTION_NAME, /* function expression name */
} JSVarKindEnum;
/* XXX: could use a different structure in bytecode functions to save
memory */
typedef struct JSVarDef {
JSValue var_name;
/* index into fd->scopes of this variable lexical scope */
int scope_level;
/* during compilation:
- if scope_level = 0: scope in which the variable is defined
- if scope_level != 0: index into fd->vars of the next
variable in the same or enclosing lexical scope
in a bytecode function:
index into fd->vars of the next
variable in the same or enclosing lexical scope
*/
int scope_next;
uint8_t is_const : 1;
uint8_t is_lexical : 1;
uint8_t is_captured : 1;
uint8_t var_kind : 4; /* see JSVarKindEnum */
/* only used during compilation: function pool index for lexical
variables with var_kind =
JS_VAR_FUNCTION_DECL/JS_VAR_NEW_FUNCTION_DECL or scope level of
the definition of the 'var' variables (they have scope_level =
0) */
int func_pool_idx : 24; /* only used during compilation : index in
the constant pool for hoisted function
definition */
} JSVarDef;
/* for the encoding of the pc2line table */
#define PC2LINE_BASE (-1)
#define PC2LINE_RANGE 5
#define PC2LINE_OP_FIRST 1
#define PC2LINE_DIFF_PC_MAX ((255 - PC2LINE_OP_FIRST) / PC2LINE_RANGE)
typedef struct JSFunctionBytecode {
objhdr_t header; /* must come first */
uint8_t js_mode;
uint8_t has_prototype : 1; /* true if a prototype field is necessary */
uint8_t has_simple_parameter_list : 1;
uint8_t func_kind : 2;
uint8_t has_debug : 1;
uint8_t read_only_bytecode : 1;
uint8_t is_direct_or_indirect_eval
: 1; /* used by JS_GetScriptOrModuleName() */
/* XXX: 10 bits available */
uint8_t *byte_code_buf; /* (self pointer) */
int byte_code_len;
JSValue func_name;
JSVarDef *vardefs; /* arguments + local variables (arg_count + var_count)
(self pointer) */
JSClosureVar
*closure_var; /* list of variables in the closure (self pointer) */
uint16_t arg_count;
uint16_t var_count;
uint16_t defined_arg_count; /* for length function property */
uint16_t stack_size; /* maximum stack size */
JSValue *cpool; /* constant pool (self pointer) */
int cpool_count;
int closure_var_count;
struct {
/* debug info, move to separate structure to save memory? */
JSValue filename;
int source_len;
int pc2line_len;
uint8_t *pc2line_buf;
char *source;
} debug;
} JSFunctionBytecode;
/* New simplified compiled unit structure for Phase 1+ simplification.
Replaces JSFunctionBytecode with a simpler model:
- No closure machinery (uses outer_frame chain at runtime)
@@ -1390,10 +1289,6 @@ typedef struct JSCompiledUnit {
Struct definitions are in quickjs.h
============================================================ */
typedef struct JSProperty {
JSValue value;
} JSProperty;
#define JS_PROP_INITIAL_SIZE 2
#define JS_PROP_INITIAL_HASH_SIZE 4 /* must be a power of two */
#define JS_ARRAY_INITIAL_SIZE 2
@@ -1421,14 +1316,9 @@ void js_dump_value_write (void *opaque, const char *buf, size_t len);
void js_regexp_finalizer (JSRuntime *rt, JSValue val);
JSValue js_new_function (JSContext *ctx, JSFunctionKind kind);
/* Forward declarations for intrinsics (now declared in quickjs.h) */
/* Forward declaration - helper to set cap in objhdr */
static inline objhdr_t objhdr_set_cap56 (objhdr_t h, uint64_t cap);
/* JS_VALUE_GET_STRING is an alias for getting JSText from a string value */
/* Note: Uses chase() for GC safety - already defined at line 293 */
/* JS_ThrowMemoryError is an alias for JS_ThrowOutOfMemory */
#define JS_ThrowMemoryError(ctx) JS_ThrowOutOfMemory(ctx)
@@ -1611,118 +1501,6 @@ static inline __exception int js_poll_interrupts (JSContext *ctx) {
}
}
/* === Token enum (shared by parser, tokenizer, AST) === */
enum {
TOK_NUMBER = -128,
TOK_STRING,
TOK_TEMPLATE,
TOK_IDENT,
TOK_REGEXP,
/* warning: order matters (see js_parse_assign_expr) */
TOK_MUL_ASSIGN,
TOK_DIV_ASSIGN,
TOK_MOD_ASSIGN,
TOK_PLUS_ASSIGN,
TOK_MINUS_ASSIGN,
TOK_SHL_ASSIGN,
TOK_SAR_ASSIGN,
TOK_SHR_ASSIGN,
TOK_AND_ASSIGN,
TOK_XOR_ASSIGN,
TOK_OR_ASSIGN,
TOK_POW_ASSIGN,
TOK_LAND_ASSIGN,
TOK_LOR_ASSIGN,
TOK_DEC,
TOK_INC,
TOK_SHL,
TOK_SAR,
TOK_SHR,
TOK_LT,
TOK_LTE,
TOK_GT,
TOK_GTE,
TOK_EQ,
TOK_STRICT_EQ,
TOK_NEQ,
TOK_STRICT_NEQ,
TOK_LAND,
TOK_LOR,
TOK_POW,
TOK_ARROW,
TOK_ERROR,
TOK_PRIVATE_NAME,
TOK_EOF,
/* whitespace/comment tokens for tokenizer */
TOK_COMMENT,
TOK_NEWLINE,
TOK_SPACE,
/* keywords: WARNING: same order as atoms */
TOK_NULL, /* must be first */
TOK_FALSE,
TOK_TRUE,
TOK_IF,
TOK_ELSE,
TOK_RETURN,
TOK_GO,
TOK_VAR,
TOK_DEF,
TOK_THIS,
TOK_DELETE,
TOK_IN,
TOK_DO,
TOK_WHILE,
TOK_FOR,
TOK_BREAK,
TOK_CONTINUE,
TOK_DISRUPT,
TOK_DISRUPTION,
TOK_FUNCTION,
TOK_DEBUGGER,
TOK_WITH,
/* FutureReservedWord */
TOK_CLASS,
TOK_CONST,
TOK_ENUM,
TOK_EXPORT,
TOK_EXTENDS,
TOK_IMPORT,
TOK_SUPER,
/* FutureReservedWords when parsing strict mode code */
TOK_IMPLEMENTS,
TOK_INTERFACE,
TOK_LET,
TOK_PRIVATE,
TOK_PROTECTED,
TOK_PUBLIC,
TOK_STATIC,
TOK_YIELD,
TOK_AWAIT, /* must be last */
TOK_OF, /* only used for js_parse_skip_parens_token() */
};
#define TOK_FIRST_KEYWORD TOK_NULL
#define TOK_LAST_KEYWORD TOK_AWAIT
/* unicode code points */
#define CP_NBSP 0x00a0
#define CP_BOM 0xfeff
#define CP_LS 0x2028
#define CP_PS 0x2029
/* === Line/column cache === */
typedef struct {
/* last source position */
const uint8_t *ptr;
int line_num;
int col_num;
const uint8_t *buf_start;
} GetLineColCache;
/* === PPretext (parser pretext, system-malloc, used by cell_js.c parser) === */
typedef struct PPretext {
uint32_t *data;
@@ -1739,8 +1517,6 @@ extern JSClassID js_class_id_alloc;
/* runtime.c — line/column, GC, and VM dispatch */
int ctx_gc (JSContext *ctx, int allow_grow, size_t alloc_size);
JSValue JS_CallInternal (JSContext *ctx, JSValue func_obj, JSValue this_obj, int argc, JSValue *argv, int flags);
int get_line_col (int *pcol_num, const uint8_t *buf, size_t len);
int get_line_col_cached (GetLineColCache *s, int *pcol_num, const uint8_t *ptr);
/* runtime.c exports */
JSValue JS_ThrowStackOverflow (JSContext *ctx);
@@ -1792,7 +1568,7 @@ static inline JSValue *get_upvalue_ptr (JSValue frame_val, int depth, int slot)
JSFrame *frame = JS_VALUE_GET_FRAME(frame_val);
while (depth > 0) {
JSFunction *fn = JS_VALUE_GET_FUNCTION(frame->function);
frame_val = fn->u.func.outer_frame;
frame_val = fn->u.reg.outer_frame;
if (JS_IsNull(frame_val)) return NULL;
frame = JS_VALUE_GET_FRAME(frame_val);
depth--;

View File

@@ -92,7 +92,6 @@ static inline int objhdr_s (objhdr_t h) { return (h & OBJHDR_S_MASK) != 0; }
typedef struct JSRuntime JSRuntime; // the entire VM
typedef struct JSContext JSContext; // Each actor
typedef struct JSClass JSClass;
typedef struct JSFunctionBytecode JSFunctionBytecode;
typedef uint32_t JSClassID;
/* Forward declaration - JSGCRef moved after JSValue definition */

View File

@@ -2462,11 +2462,6 @@ JSValue js_new_function (JSContext *ctx, JSFunctionKind kind) {
func->kind = kind;
func->name = JS_NULL;
func->length = 0;
/* Initialize closure fields for bytecode functions */
if (kind == JS_FUNC_KIND_BYTECODE) {
func->u.func.outer_frame = JS_NULL;
func->u.func.env_record = JS_NULL;
}
return JS_MKPTR (func);
}
@@ -2494,66 +2489,10 @@ JSValue JS_GetException (JSContext *ctx) {
return val;
}
JS_BOOL
JS_HasException (JSContext *ctx) {
JS_BOOL JS_HasException (JSContext *ctx) {
return !JS_IsNull (ctx->current_exception);
}
/* get_line_col — compute line and column from a byte offset */
int get_line_col (int *pcol_num, const uint8_t *buf, size_t len) {
int line_num, col_num, c;
size_t i;
line_num = 0;
col_num = 0;
for (i = 0; i < len; i++) {
c = buf[i];
if (c == '\n') {
line_num++;
col_num = 0;
} else if (c < 0x80 || c >= 0xc0) {
col_num++;
}
}
*pcol_num = col_num;
return line_num;
}
int get_line_col_cached (GetLineColCache *s, int *pcol_num, const uint8_t *ptr) {
int line_num, col_num;
if (ptr >= s->ptr) {
line_num = get_line_col (&col_num, s->ptr, ptr - s->ptr);
if (line_num == 0) {
s->col_num += col_num;
} else {
s->line_num += line_num;
s->col_num = col_num;
}
} else {
line_num = get_line_col (&col_num, ptr, s->ptr - ptr);
if (line_num == 0) {
s->col_num -= col_num;
} else {
const uint8_t *p;
s->line_num -= line_num;
/* find the absolute column position */
col_num = 0;
for (p = ptr - 1; p >= s->buf_start; p--) {
if (*p == '\n') {
break;
} else if (*p < 0x80 || *p >= 0xc0) {
col_num++;
}
}
s->col_num = col_num;
}
}
s->ptr = ptr;
*pcol_num = s->col_num;
return s->line_num;
}
/* in order to avoid executing arbitrary code during the stack trace
generation, we only look at simple 'name' properties containing a
string. */
@@ -6563,22 +6502,13 @@ static JSValue js_cell_text (JSContext *ctx, JSValue this_val, int argc, JSValue
/* Handle function - return source or native stub */
if (JS_IsFunction (arg)) {
JSFunction *fn = JS_VALUE_GET_FUNCTION (arg);
if (fn->kind == JS_FUNC_KIND_BYTECODE) {
JSFunctionBytecode *b = fn->u.func.function_bytecode;
if (b->has_debug && b->debug.source)
return JS_NewStringLen (ctx, b->debug.source, b->debug.source_len);
}
const char *pref = "function ";
const char *suff = "() {\n [native code]\n}";
const char *name = "";
const char *name_cstr = NULL;
if (fn->kind == JS_FUNC_KIND_BYTECODE) {
JSFunctionBytecode *fb = fn->u.func.function_bytecode;
name_cstr = JS_ToCString (ctx, fb->func_name);
if (name_cstr) name = name_cstr;
} else if (!JS_IsNull (fn->name)) {
if (!JS_IsNull (fn->name)) {
name_cstr = JS_ToCString (ctx, fn->name);
if (name_cstr) name = name_cstr;
}
@@ -7628,259 +7558,6 @@ static JSValue js_stacktrace (JSContext *ctx, JSValue this_val, int argc, JSValu
return JS_NULL;
}
/* dump_bytecode_opcodes and JS_DumpFunctionBytecode removed — old stack VM deleted */
#if 0 /* dead code — old bytecode dump */
static void dump_bytecode_opcodes_DEAD (JSContext *ctx, JSFunctionBytecode *b) {
const uint8_t *tab = b->byte_code_buf;
int len = b->byte_code_len;
const JSValue *cpool = b->cpool;
uint32_t cpool_count = b->cpool_count;
const JSVarDef *vars = b->vardefs ? b->vardefs + b->arg_count : NULL;
int var_count = b->var_count;
int pos = 0;
while (pos < len) {
int op = tab[pos];
if (op >= OP_COUNT) {
printf (" %5d: <invalid opcode 0x%02x>\n", pos, op);
pos++;
continue;
}
const JSOpCode *oi = &short_opcode_info (op);
int size = oi->size;
if (pos + size > len) {
printf (" %5d: <truncated opcode 0x%02x>\n", pos, op);
break;
}
printf (" %5d: %s", pos, dump_opcode_names[op]);
pos++;
switch (oi->fmt) {
case OP_FMT_none_int:
printf (" %d", op - OP_push_0);
break;
case OP_FMT_npopx:
printf (" %d", op - OP_call0);
break;
case OP_FMT_u8:
printf (" %u", get_u8 (tab + pos));
break;
case OP_FMT_i8:
printf (" %d", get_i8 (tab + pos));
break;
case OP_FMT_u16:
case OP_FMT_npop:
printf (" %u", get_u16 (tab + pos));
break;
case OP_FMT_npop_u16:
printf (" %u,%u", get_u16 (tab + pos), get_u16 (tab + pos + 2));
break;
case OP_FMT_i16:
printf (" %d", get_i16 (tab + pos));
break;
case OP_FMT_i32:
printf (" %d", get_i32 (tab + pos));
break;
case OP_FMT_u32:
printf (" %u", get_u32 (tab + pos));
break;
case OP_FMT_label8:
printf (" ->%d", pos + get_i8 (tab + pos));
break;
case OP_FMT_label16:
printf (" ->%d", pos + get_i16 (tab + pos));
break;
case OP_FMT_label:
printf (" ->%u", pos + get_u32 (tab + pos));
break;
case OP_FMT_label_u16:
printf (" ->%u,%u", pos + get_u32 (tab + pos), get_u16 (tab + pos + 4));
break;
case OP_FMT_const8: {
uint32_t idx = get_u8 (tab + pos);
printf (" [%u]", idx);
if (idx < cpool_count) {
printf (": ");
JS_PrintValue (ctx, js_dump_value_write, stdout, cpool[idx], NULL);
}
break;
}
case OP_FMT_const: {
uint32_t idx = get_u32 (tab + pos);
printf (" [%u]", idx);
if (idx < cpool_count) {
printf (": ");
JS_PrintValue (ctx, js_dump_value_write, stdout, cpool[idx], NULL);
}
break;
}
case OP_FMT_key: {
uint32_t idx = get_u32 (tab + pos);
printf (" [%u]", idx);
if (idx < cpool_count) {
printf (": ");
JS_PrintValue (ctx, js_dump_value_write, stdout, cpool[idx], NULL);
}
break;
}
case OP_FMT_key_u8: {
uint32_t idx = get_u32 (tab + pos);
printf (" [%u],%d", idx, get_u8 (tab + pos + 4));
if (idx < cpool_count) {
printf (": ");
JS_PrintValue (ctx, js_dump_value_write, stdout, cpool[idx], NULL);
}
break;
}
case OP_FMT_key_u16: {
uint32_t idx = get_u32 (tab + pos);
printf (" [%u],%d", idx, get_u16 (tab + pos + 4));
if (idx < cpool_count) {
printf (": ");
JS_PrintValue (ctx, js_dump_value_write, stdout, cpool[idx], NULL);
}
break;
}
case OP_FMT_none_loc:
printf (" loc%d", (op - OP_get_loc0) % 4);
break;
case OP_FMT_loc8: {
int idx = get_u8 (tab + pos);
printf (" loc%d", idx);
if (vars && idx < var_count) {
char buf[KEY_GET_STR_BUF_SIZE];
printf (": %s", JS_KeyGetStr (ctx, buf, sizeof(buf), vars[idx].var_name));
}
break;
}
case OP_FMT_loc: {
int idx = get_u16 (tab + pos);
printf (" loc%d", idx);
if (vars && idx < var_count) {
char buf[KEY_GET_STR_BUF_SIZE];
printf (": %s", JS_KeyGetStr (ctx, buf, sizeof(buf), vars[idx].var_name));
}
break;
}
case OP_FMT_none_arg:
printf (" arg%d", (op - OP_get_arg0) % 4);
break;
case OP_FMT_arg:
printf (" arg%d", get_u16 (tab + pos));
break;
default:
break;
}
printf ("\n");
pos += size - 1; /* -1 because we already incremented pos after reading opcode */
}
}
void JS_DumpFunctionBytecode (JSContext *ctx, JSValue func_val) {
JSFunctionBytecode *b = NULL;
if (!JS_IsPtr (func_val)) {
printf ("JS_DumpFunctionBytecode: not a pointer value\n");
return;
}
/* Get the object header to check type */
void *ptr = JS_VALUE_GET_PTR (func_val);
objhdr_t hdr = *(objhdr_t *)ptr;
uint8_t type = objhdr_type (hdr);
if (type == OBJ_FUNCTION) {
/* It's a JSFunction - extract bytecode */
JSFunction *fn = (JSFunction *)ptr;
if (fn->kind != JS_FUNC_KIND_BYTECODE) {
printf ("JS_DumpFunctionBytecode: not a bytecode function (kind=%d)\n", fn->kind);
return;
}
b = fn->u.func.function_bytecode;
} else if (type == OBJ_CODE) {
/* It's raw bytecode from js_create_function */
b = (JSFunctionBytecode *)ptr;
} else {
printf ("JS_DumpFunctionBytecode: not a function or bytecode (type=%d)\n", type);
return;
}
if (!b) {
printf ("JS_DumpFunctionBytecode: no bytecode\n");
return;
}
char buf[KEY_GET_STR_BUF_SIZE];
printf ("=== Bytecode Dump ===\n");
/* Function name */
const char *fname = JS_KeyGetStr (ctx, buf, sizeof(buf), b->func_name);
printf ("Function: %s\n", fname ? fname : "<anonymous>");
/* Debug info */
if (b->has_debug && !JS_IsNull (b->debug.filename)) {
printf ("File: %s\n", JS_KeyGetStr (ctx, buf, sizeof(buf), b->debug.filename));
}
/* Basic stats */
printf ("Args: %d, Vars: %d, Stack: %d\n", b->arg_count, b->var_count, b->stack_size);
printf ("Bytecode length: %d bytes\n", b->byte_code_len);
/* Arguments */
if (b->arg_count > 0 && b->vardefs) {
printf ("\nArguments:\n");
for (int i = 0; i < b->arg_count; i++) {
printf (" %d: %s\n", i, JS_KeyGetStr (ctx, buf, sizeof(buf), b->vardefs[i].var_name));
}
}
/* Local variables */
if (b->var_count > 0 && b->vardefs) {
printf ("\nLocal variables:\n");
for (int i = 0; i < b->var_count; i++) {
JSVarDef *vd = &b->vardefs[b->arg_count + i];
const char *kind = vd->is_const ? "const" : vd->is_lexical ? "let" : "var";
printf (" %d: %s %s", i, kind, JS_KeyGetStr (ctx, buf, sizeof(buf), vd->var_name));
if (vd->scope_level) printf (" [scope:%d]", vd->scope_level);
printf ("\n");
}
}
/* Closure variables */
if (b->closure_var_count > 0) {
printf ("\nClosure variables:\n");
for (int i = 0; i < b->closure_var_count; i++) {
JSClosureVar *cv = &b->closure_var[i];
printf (" %d: %s (%s:%s%d)\n", i,
JS_KeyGetStr (ctx, buf, sizeof(buf), cv->var_name),
cv->is_local ? "local" : "parent",
cv->is_arg ? "arg" : "loc",
cv->var_idx);
}
}
/* Constant pool */
if (b->cpool_count > 0) {
printf ("\nConstant pool (%d entries):\n", b->cpool_count);
for (uint32_t i = 0; i < b->cpool_count; i++) {
printf (" [%u]: ", i);
JS_PrintValue (ctx, js_dump_value_write, stdout, b->cpool[i], NULL);
printf ("\n");
}
}
/* Bytecode instructions */
printf ("\nBytecode:\n");
dump_bytecode_opcodes (ctx, b);
printf ("=== End Bytecode Dump ===\n");
}
#endif /* dead code */
/* ----------------------------------------------------------------------------
* array function and sub-functions
* ----------------------------------------------------------------------------