rm atoms
This commit is contained in:
117
plan.md
117
plan.md
@@ -132,42 +132,78 @@ Categories remaining:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Phase 6: Update Bytecode Serialization
|
## Phase 6: Update Bytecode Serialization ✓
|
||||||
|
|
||||||
### 6.1 JS_WriteObjectTag Changes
|
### 6.1 JS_WriteObjectTag Changes ✓
|
||||||
- [ ] Write cpool values as JSValue (text serialization)
|
- [x] Changed JS_WriteObjectTag to use bc_put_key() directly for property keys
|
||||||
- [ ] Variable opcodes reference cpool indices (already u32)
|
- [x] Removed JS_ValueToAtom/bc_put_atom path (was broken anyway)
|
||||||
|
- [x] cpool values serialized via JS_WriteObjectRec()
|
||||||
|
|
||||||
### 6.2 JS_ReadObject Changes
|
### 6.2 JS_ReadObject Changes ✓
|
||||||
- [ ] Read cpool values as JSValue
|
- [x] Changed JS_ReadObjectTag to use bc_get_key() for property keys
|
||||||
- [ ] Variable opcode operands are cpool indices
|
- [x] Uses JS_SetPropertyInternal with JSValue keys
|
||||||
|
|
||||||
### 6.3 Version Bump
|
### 6.3 Opcode Format Updates ✓
|
||||||
- [ ] Increment bytecode version to indicate new format
|
- [x] Added OP_FMT_key_u8, OP_FMT_key_u16, OP_FMT_key_label_u16 formats
|
||||||
|
- [x] Updated variable opcodes to use key formats instead of atom formats
|
||||||
|
- [x] Updated bc_byte_swap() to handle new key formats
|
||||||
|
- [x] Updated JS_WriteFunctionBytecode() to skip key format opcodes
|
||||||
|
- [x] Updated JS_ReadFunctionBytecode() to skip key format opcodes
|
||||||
|
|
||||||
|
### 6.4 Version Bump ✓
|
||||||
|
- [x] Incremented BC_VERSION from 5 to 6
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Phase 7: Final Cleanup
|
## Phase 7: Final Cleanup ✓
|
||||||
|
|
||||||
### 7.1 Remove JSAtom Type and Functions
|
### 7.1 Additional Parser/Compiler Fixes ✓
|
||||||
- [ ] Remove `typedef uint32_t JSAtom`
|
- [x] Fixed TOK_IDENT case to use JSValue name, JS_DupValue, emit_key
|
||||||
- [ ] Remove JS_NewAtom, JS_NewAtomString
|
- [x] Fixed TOK_TRY catch clause to use JSValue name
|
||||||
- [ ] Remove JS_FreeAtom, JS_DupAtom (currently stubs)
|
- [x] Fixed js_parse_statement_or_decl label_name to use JSValue
|
||||||
- [ ] Remove JS_AtomToValue, JS_ValueToAtom
|
- [x] Fixed OP_scope_get_var "eval" check to use js_key_equal_str
|
||||||
- [ ] Remove JS_AtomToCString, JS_AtomGetStr
|
- [x] Fixed js_parse_delete to use JSValue for name comparison
|
||||||
- [ ] Remove all JS_ATOM_* constants
|
- [x] Fixed JSON parsing to use js_key_from_string for property names
|
||||||
- [ ] Remove JSAtomStruct and related
|
- [x] Added js_key_from_string() helper function
|
||||||
|
- [x] Added JS_KEY__ret_, JS_KEY__eval_, JS_KEY__var_ for internal names
|
||||||
|
- [x] Updated add_closure_var, get_closure_var2, get_closure_var to use JSValue var_name
|
||||||
|
- [x] Updated set_closure_from_var to use JS_DupValue
|
||||||
|
- [x] Updated add_closure_variables to use JS_DupValue
|
||||||
|
- [x] Updated instantiate_hoisted_definitions to use fd_cpool_add for keys
|
||||||
|
- [x] Updated resolve_variables to use js_key_equal and fd_cpool_add
|
||||||
|
|
||||||
### 7.2 Remove quickjs-atom.h
|
### 7.1.1 Property Access and Runtime Fixes ✓
|
||||||
- [ ] Delete or convert to JSValue text initialization
|
- [x] Fixed JS_GetPropertyValue to use js_key_from_string instead of JS_ValueToAtom
|
||||||
|
- [x] Fixed JS_GetPropertyKey to use js_key_from_string for string keys
|
||||||
|
- [x] Fixed JS_SetPropertyKey to use js_key_from_string for string keys
|
||||||
|
- [x] Fixed JS_HasPropertyKey to use js_key_from_string for string keys
|
||||||
|
- [x] Fixed JS_DeletePropertyKey to use js_key_from_string for string keys
|
||||||
|
- [x] Updated JS_HasProperty signature to take JSValue prop
|
||||||
|
- [x] Fixed OP_get_ref_value handler to use JSValue key
|
||||||
|
- [x] Fixed OP_put_ref_value handler to use JSValue key
|
||||||
|
- [x] Updated free_func_def to use JS_FreeValue for JSValue fields
|
||||||
|
|
||||||
### 7.3 Remove Legacy JSObject Type
|
### 7.2 Remove JSAtom Type and Functions ✓
|
||||||
- [ ] Remove JS_GC_OBJ_TYPE_JS_OBJECT if unused
|
- [x] Removed most JS_ATOM_* constants (kept JS_ATOM_NULL, JS_ATOM_END for BC compat)
|
||||||
- [ ] Remove JSObject struct (replaced by JSRecord)
|
- [x] JS_NewAtomString now returns JSValue using js_key_new
|
||||||
|
- [x] JS_FreeAtom, JS_DupAtom are stubs (no-op for backward compat)
|
||||||
|
- [x] JS_AtomToValue, JS_ValueToAtom are stubs (minimal BC compat)
|
||||||
|
- [x] Replaced JS_ATOM_* usages with JS_KEY_* or JS_GetPropertyStr
|
||||||
|
|
||||||
### 7.4 Update quickjs.h Public API
|
### 7.3 Additional Runtime Fixes ✓
|
||||||
- [ ] Remove JSAtom references from public API
|
- [x] Fixed free_function_bytecode to use JS_FreeValueRT for JSValue fields
|
||||||
- [ ] Ensure all property functions use JSValue keys or const char*
|
- [x] Fixed JS_SetPropertyFunctionList to use JSValue keys via find_key()
|
||||||
|
- [x] Fixed JS_InstantiateFunctionListItem to use JSValue keys
|
||||||
|
- [x] Fixed internalize_json_property to use JSValue names
|
||||||
|
- [x] Fixed emit_break and push_break_entry to use JSValue label_name
|
||||||
|
- [x] Implemented JS_Invoke to use JSValue method key
|
||||||
|
|
||||||
|
### 7.4 Remaining Stubs (kept for bytecode backward compatibility)
|
||||||
|
- JSAtom typedef (uint32_t) - used in BC serialization
|
||||||
|
- JS_ATOM_NULL, JS_ATOM_END - bytecode format markers
|
||||||
|
- JS_FreeAtom, JS_DupAtom - no-op stubs
|
||||||
|
- JS_FreeAtomRT, JS_DupAtomRT - no-op stubs
|
||||||
|
- Legacy BC reader (idx_to_atom array) - for reading old bytecode
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -176,22 +212,26 @@ Categories remaining:
|
|||||||
**Build: SUCCEEDS** with warnings (unused variables, labels)
|
**Build: SUCCEEDS** with warnings (unused variables, labels)
|
||||||
|
|
||||||
**Statistics:**
|
**Statistics:**
|
||||||
- JS_ATOM_* usages: ~40 remaining (down from 171+)
|
- JS_ATOM_* usages: Minimal (only BC serialization compat)
|
||||||
- Most remaining are stub functions and debug code
|
- Property access uses JS_KEY_* macros or JS_GetPropertyStr
|
||||||
|
- BC_VERSION: 6 (updated for new key-based format)
|
||||||
|
|
||||||
**What Works:**
|
**What Works:**
|
||||||
|
- All property access via JSValue keys
|
||||||
- Keyword detection via string comparison
|
- Keyword detection via string comparison
|
||||||
- Function declaration parsing with JSValue names
|
- Function declaration parsing with JSValue names
|
||||||
- Variable definition with JSValue names
|
- Variable definition with JSValue names
|
||||||
- Property access with JSValue keys
|
|
||||||
- Closure variable tracking with JSValue names
|
- Closure variable tracking with JSValue names
|
||||||
- VM opcode handlers read cpool indices and look up JSValue
|
- VM opcode handlers read cpool indices and look up JSValue
|
||||||
- resolve_scope_var() uses JSValue throughout
|
- resolve_scope_var() uses JSValue throughout
|
||||||
- js_parse_property_name() returns JSValue
|
- js_parse_property_name() returns JSValue
|
||||||
|
- Bytecode serialization uses bc_put_key/bc_get_key for property keys
|
||||||
**Next Priority:**
|
- Variable opcodes use key format (cpool indices)
|
||||||
1. Update bytecode serialization (Phase 6)
|
- JSON parsing uses JSValue keys
|
||||||
2. Final cleanup - remove JSAtom type completely (Phase 7)
|
- Internal variable names use JS_KEY__ret_, JS_KEY__eval_, JS_KEY__var_
|
||||||
|
- JS_SetPropertyFunctionList uses JSValue keys
|
||||||
|
- JS_Invoke uses JSValue method keys
|
||||||
|
- break/continue labels use JSValue
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -206,14 +246,3 @@ Categories remaining:
|
|||||||
- JSRecord with open addressing is fully implemented
|
- JSRecord with open addressing is fully implemented
|
||||||
- js_key_hash and js_key_equal work with both immediate and heap text
|
- js_key_hash and js_key_equal work with both immediate and heap text
|
||||||
- js_key_equal_str enables comparison with C string literals for internal names
|
- js_key_equal_str enables comparison with C string literals for internal names
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Testing Strategy
|
|
||||||
|
|
||||||
After each sub-phase:
|
|
||||||
1. `make` - verify compilation
|
|
||||||
2. Run basic eval: `./cell -e "1+1"`
|
|
||||||
3. Run property test: `./cell -e "var o = {a:1}; o.a"`
|
|
||||||
4. Run function test: `./cell -e "(function f(x){return x*2})(3)"`
|
|
||||||
5. Run closure test: `./cell -e "var f = (function(){var x=1;return function(){return x++}})(); f(); f()"`
|
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ FMT(atom_label_u8)
|
|||||||
FMT(atom_label_u16)
|
FMT(atom_label_u16)
|
||||||
FMT(label_u16)
|
FMT(label_u16)
|
||||||
FMT(key)
|
FMT(key)
|
||||||
|
FMT(key_u8)
|
||||||
|
FMT(key_u16)
|
||||||
|
FMT(key_label_u16)
|
||||||
#undef FMT
|
#undef FMT
|
||||||
#endif /* FMT */
|
#endif /* FMT */
|
||||||
|
|
||||||
@@ -104,24 +107,24 @@ DEF( array_from, 3, 0, 1, npop) /* arguments are not counted in n_pop */
|
|||||||
DEF( return, 1, 1, 0, none)
|
DEF( return, 1, 1, 0, none)
|
||||||
DEF( return_undef, 1, 0, 0, none)
|
DEF( return_undef, 1, 0, 0, none)
|
||||||
DEF( throw, 1, 1, 0, none)
|
DEF( throw, 1, 1, 0, none)
|
||||||
DEF( throw_error, 6, 0, 0, atom_u8)
|
DEF( throw_error, 6, 0, 0, key_u8)
|
||||||
DEF( eval, 5, 1, 1, npop_u16) /* func args... -> ret_val */
|
DEF( eval, 5, 1, 1, npop_u16) /* func args... -> ret_val */
|
||||||
DEF( regexp, 1, 2, 1, none) /* create a RegExp object from the pattern and a
|
DEF( regexp, 1, 2, 1, none) /* create a RegExp object from the pattern and a
|
||||||
bytecode string */
|
bytecode string */
|
||||||
|
|
||||||
DEF( check_var, 5, 0, 1, atom) /* check if a variable exists */
|
DEF( check_var, 5, 0, 1, key) /* check if a variable exists */
|
||||||
DEF( get_var_undef, 5, 0, 1, atom) /* push undefined if the variable does not exist */
|
DEF( get_var_undef, 5, 0, 1, key) /* push undefined if the variable does not exist */
|
||||||
DEF( get_var, 5, 0, 1, atom) /* throw an exception if the variable does not exist */
|
DEF( get_var, 5, 0, 1, key) /* throw an exception if the variable does not exist */
|
||||||
DEF( put_var, 5, 1, 0, atom) /* must come after get_var */
|
DEF( put_var, 5, 1, 0, key) /* must come after get_var */
|
||||||
DEF( put_var_init, 5, 1, 0, atom) /* must come after put_var. Used to initialize a global lexical variable */
|
DEF( put_var_init, 5, 1, 0, key) /* must come after put_var. Used to initialize a global lexical variable */
|
||||||
DEF( put_var_strict, 5, 2, 0, atom) /* for strict mode variable write */
|
DEF( put_var_strict, 5, 2, 0, key) /* for strict mode variable write */
|
||||||
|
|
||||||
DEF( get_ref_value, 1, 2, 3, none)
|
DEF( get_ref_value, 1, 2, 3, none)
|
||||||
DEF( put_ref_value, 1, 3, 0, none)
|
DEF( put_ref_value, 1, 3, 0, none)
|
||||||
|
|
||||||
DEF( define_var, 6, 0, 0, atom_u8)
|
DEF( define_var, 6, 0, 0, key_u8)
|
||||||
DEF(check_define_var, 6, 0, 0, atom_u8)
|
DEF(check_define_var, 6, 0, 0, key_u8)
|
||||||
DEF( define_func, 6, 1, 0, atom_u8)
|
DEF( define_func, 6, 1, 0, key_u8)
|
||||||
DEF( get_field, 5, 1, 1, key)
|
DEF( get_field, 5, 1, 1, key)
|
||||||
DEF( get_field2, 5, 1, 2, key)
|
DEF( get_field2, 5, 1, 2, key)
|
||||||
DEF( put_field, 5, 2, 0, key)
|
DEF( put_field, 5, 2, 0, key)
|
||||||
@@ -130,14 +133,14 @@ DEF( get_array_el2, 1, 2, 2, none) /* obj prop -> obj value */
|
|||||||
DEF( get_array_el3, 1, 2, 3, none) /* obj prop -> obj prop1 value */
|
DEF( get_array_el3, 1, 2, 3, none) /* obj prop -> obj prop1 value */
|
||||||
DEF( put_array_el, 1, 3, 0, none)
|
DEF( put_array_el, 1, 3, 0, none)
|
||||||
DEF( define_field, 5, 2, 1, key)
|
DEF( define_field, 5, 2, 1, key)
|
||||||
DEF( set_name, 5, 1, 1, atom)
|
DEF( set_name, 5, 1, 1, key)
|
||||||
DEF(set_name_computed, 1, 2, 2, none)
|
DEF(set_name_computed, 1, 2, 2, none)
|
||||||
DEF(define_array_el, 1, 3, 2, none)
|
DEF(define_array_el, 1, 3, 2, none)
|
||||||
DEF(copy_data_properties, 2, 3, 3, u8)
|
DEF(copy_data_properties, 2, 3, 3, u8)
|
||||||
DEF( define_method, 6, 2, 1, atom_u8)
|
DEF( define_method, 6, 2, 1, key_u8)
|
||||||
DEF(define_method_computed, 2, 3, 1, u8) /* must come after define_method */
|
DEF(define_method_computed, 2, 3, 1, u8) /* must come after define_method */
|
||||||
DEF( define_class, 6, 2, 2, atom_u8) /* parent ctor -> ctor proto */
|
DEF( define_class, 6, 2, 2, key_u8) /* parent ctor -> ctor proto */
|
||||||
DEF( define_class_computed, 6, 3, 3, atom_u8) /* field_name parent ctor -> field_name ctor proto (class with computed name) */
|
DEF( define_class_computed, 6, 3, 3, key_u8) /* field_name parent ctor -> field_name ctor proto (class with computed name) */
|
||||||
|
|
||||||
DEF( get_loc, 3, 0, 1, loc)
|
DEF( get_loc, 3, 0, 1, loc)
|
||||||
DEF( put_loc, 3, 1, 0, loc) /* must come after get_loc */
|
DEF( put_loc, 3, 1, 0, loc) /* must come after get_loc */
|
||||||
@@ -169,10 +172,10 @@ DEF( to_object, 1, 1, 1, none)
|
|||||||
//DEF( to_string, 1, 1, 1, none)
|
//DEF( to_string, 1, 1, 1, none)
|
||||||
DEF( to_propkey, 1, 1, 1, none)
|
DEF( to_propkey, 1, 1, 1, none)
|
||||||
|
|
||||||
DEF( make_loc_ref, 7, 0, 2, atom_u16)
|
DEF( make_loc_ref, 7, 0, 2, key_u16)
|
||||||
DEF( make_arg_ref, 7, 0, 2, atom_u16)
|
DEF( make_arg_ref, 7, 0, 2, key_u16)
|
||||||
DEF(make_var_ref_ref, 7, 0, 2, atom_u16)
|
DEF(make_var_ref_ref, 7, 0, 2, key_u16)
|
||||||
DEF( make_var_ref, 5, 0, 2, atom)
|
DEF( make_var_ref, 5, 0, 2, key)
|
||||||
|
|
||||||
/* arithmetic/logic operations */
|
/* arithmetic/logic operations */
|
||||||
DEF( neg, 1, 1, 1, none)
|
DEF( neg, 1, 1, 1, none)
|
||||||
@@ -187,7 +190,7 @@ DEF( add_loc, 2, 1, 0, loc8)
|
|||||||
DEF( not, 1, 1, 1, none)
|
DEF( not, 1, 1, 1, none)
|
||||||
DEF( lnot, 1, 1, 1, none)
|
DEF( lnot, 1, 1, 1, none)
|
||||||
DEF( delete, 1, 2, 1, none)
|
DEF( delete, 1, 2, 1, none)
|
||||||
DEF( delete_var, 5, 0, 1, atom)
|
DEF( delete_var, 5, 0, 1, key)
|
||||||
|
|
||||||
DEF( mul, 1, 2, 1, none)
|
DEF( mul, 1, 2, 1, none)
|
||||||
DEF( mul_float, 1, 2, 1, none)
|
DEF( mul_float, 1, 2, 1, none)
|
||||||
@@ -227,15 +230,15 @@ def( label, 5, 0, 0, label) /* emitted in phase 1, removed in phase 3 *
|
|||||||
|
|
||||||
/* the following opcodes must be in the same order as the 'with_x' and
|
/* the following opcodes must be in the same order as the 'with_x' and
|
||||||
get_var_undef, get_var and put_var opcodes */
|
get_var_undef, get_var and put_var opcodes */
|
||||||
def(scope_get_var_undef, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
def(scope_get_var_undef, 7, 0, 1, key_u16) /* emitted in phase 1, removed in phase 2 */
|
||||||
def( scope_get_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
def( scope_get_var, 7, 0, 1, key_u16) /* emitted in phase 1, removed in phase 2 */
|
||||||
def( scope_put_var, 7, 1, 0, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
def( scope_put_var, 7, 1, 0, key_u16) /* emitted in phase 1, removed in phase 2 */
|
||||||
def(scope_delete_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
def(scope_delete_var, 7, 0, 1, key_u16) /* emitted in phase 1, removed in phase 2 */
|
||||||
def( scope_make_ref, 11, 0, 2, atom_label_u16) /* emitted in phase 1, removed in phase 2 */
|
def( scope_make_ref, 11, 0, 2, key_label_u16) /* emitted in phase 1, removed in phase 2 */
|
||||||
def( scope_get_ref, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
def( scope_get_ref, 7, 0, 2, key_u16) /* emitted in phase 1, removed in phase 2 */
|
||||||
def(scope_put_var_init, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
def(scope_put_var_init, 7, 0, 2, key_u16) /* emitted in phase 1, removed in phase 2 */
|
||||||
def(scope_get_var_checkthis, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2, only used to return 'this' in derived class constructors */
|
def(scope_get_var_checkthis, 7, 0, 1, key_u16) /* emitted in phase 1, removed in phase 2, only used to return 'this' in derived class constructors */
|
||||||
def(get_field_opt_chain, 5, 1, 1, atom) /* emitted in phase 1, removed in phase 2 */
|
def(get_field_opt_chain, 5, 1, 1, key) /* emitted in phase 1, removed in phase 2 */
|
||||||
def(get_array_el_opt_chain, 1, 2, 1, none) /* emitted in phase 1, removed in phase 2 */
|
def(get_array_el_opt_chain, 1, 2, 1, none) /* emitted in phase 1, removed in phase 2 */
|
||||||
def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */
|
def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */
|
||||||
|
|
||||||
|
|||||||
586
source/quickjs.c
586
source/quickjs.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user