Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2917325
bytecode.h
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
13 KB
Referenced Files
None
Subscribers
None
bytecode.h
View Options
#ifndef ANT_BYTECODE_H
#define ANT_BYTECODE_H
#include
"ant.h"
#include
<stdint.h>
#include
<stdbool.h>
// Bytecode instruction format:
// [opcode:8] [operand:24] for most instructions
// Some instructions use immediate values in following slots
typedef
uint32_t
bc_inst_t
;
#define BC_OP(inst) ((uint8_t)((inst) >> 24))
#define BC_ARG(inst) ((inst) & 0x00FFFFFF)
#define BC_SARG(inst) ((int32_t)((inst) << 8) >> 8)
// sign-extended 24-bit
#define BC_MAKE(op, arg) (((uint32_t)(op) << 24) | ((arg) & 0x00FFFFFF))
// ============================================================================
// Opcode definitions
// ============================================================================
typedef
enum
{
// Stack operations (0x00-0x0F)
OP_NOP
=
0x00
,
// no-op
OP_POP
=
0x01
,
// pop TOS
OP_DUP
=
0x02
,
// duplicate TOS
OP_SWAP
=
0x03
,
// swap TOS and TOS-1
OP_ROT3
=
0x04
,
// rotate top 3: [a,b,c] -> [b,c,a]
OP_DUP2
=
0x05
,
// duplicate TOS and TOS-1
OP_POPN
=
0x06
,
// pop arg items from stack
// Constants (0x10-0x1F)
OP_CONST
=
0x10
,
// push constant pool[arg]
OP_UNDEF
=
0x11
,
// push undefined
OP_NULL
=
0x12
,
// push null
OP_TRUE
=
0x13
,
// push true
OP_FALSE
=
0x14
,
// push false
OP_ZERO
=
0x15
,
// push 0
OP_ONE
=
0x16
,
// push 1
OP_IMM_I8
=
0x17
,
// push signed 8-bit immediate (in arg)
OP_IMM_I24
=
0x18
,
// push signed 24-bit immediate
OP_GLOBAL_THIS
=
0x19
,
// push globalThis
// Arithmetic (0x20-0x2F)
OP_ADD
=
0x20
,
// TOS = TOS-1 + TOS
OP_SUB
=
0x21
,
// TOS = TOS-1 - TOS
OP_MUL
=
0x22
,
// TOS = TOS-1 * TOS
OP_DIV
=
0x23
,
// TOS = TOS-1 / TOS
OP_MOD
=
0x24
,
// TOS = TOS-1 % TOS
OP_EXP
=
0x25
,
// TOS = TOS-1 ** TOS
OP_NEG
=
0x26
,
// TOS = -TOS
OP_POS
=
0x27
,
// TOS = +TOS (to number)
OP_INC
=
0x28
,
// TOS = TOS + 1
OP_DEC
=
0x29
,
// TOS = TOS - 1
OP_INC_LOCAL
=
0x2A
,
// ++locals[arg], push result
OP_DEC_LOCAL
=
0x2B
,
// --locals[arg], push result
OP_POST_INC_LOCAL
=
0x2C
,
// locals[arg]++, push old value
OP_POST_DEC_LOCAL
=
0x2D
,
// locals[arg]--, push old value
// Bitwise (0x30-0x3F)
OP_BITOR
=
0x30
,
// TOS = TOS-1 | TOS
OP_BITAND
=
0x31
,
// TOS = TOS-1 & TOS
OP_BITXOR
=
0x32
,
// TOS = TOS-1 ^ TOS
OP_BITNOT
=
0x33
,
// TOS = ~TOS
OP_SHL
=
0x34
,
// TOS = TOS-1 << TOS
OP_SHR
=
0x35
,
// TOS = TOS-1 >> TOS (signed)
OP_USHR
=
0x36
,
// TOS = TOS-1 >>> TOS (unsigned)
// Comparison (0x40-0x4F)
OP_EQ
=
0x40
,
// TOS = TOS-1 == TOS
OP_NE
=
0x41
,
// TOS = TOS-1 != TOS
OP_SEQ
=
0x42
,
// TOS = TOS-1 === TOS
OP_SNE
=
0x43
,
// TOS = TOS-1 !== TOS
OP_LT
=
0x44
,
// TOS = TOS-1 < TOS
OP_LE
=
0x45
,
// TOS = TOS-1 <= TOS
OP_GT
=
0x46
,
// TOS = TOS-1 > TOS
OP_GE
=
0x47
,
// TOS = TOS-1 >= TOS
// Logical (0x50-0x5F)
OP_NOT
=
0x50
,
// TOS = !TOS
OP_TYPEOF
=
0x51
,
// TOS = typeof TOS
OP_INSTANCEOF
=
0x52
,
// TOS = TOS-1 instanceof TOS
OP_IN
=
0x53
,
// TOS = TOS-1 in TOS
OP_VOID
=
0x54
,
// TOS = void TOS (always undefined)
OP_DELETE
=
0x55
,
// TOS = delete TOS (for delete identifier)
// Control flow (0x60-0x6F)
OP_JMP
=
0x60
,
// pc = arg (absolute)
OP_JMP_REL
=
0x61
,
// pc += sarg (relative, signed)
OP_JT
=
0x62
,
// if (TOS) pc = arg; pop
OP_JF
=
0x63
,
// if (!TOS) pc = arg; pop
OP_JT_REL
=
0x64
,
// if (TOS) pc += sarg; pop
OP_JF_REL
=
0x65
,
// if (!TOS) pc += sarg; pop
OP_JNULLISH
=
0x66
,
// if (TOS === null || TOS === undefined) pc = arg; NO pop
OP_LOOP
=
0x67
,
// backward jump (for loop optimization hints)
OP_JT_KEEP
=
0x68
,
// if (TOS) pc = arg; keep TOS (for ||)
OP_JF_KEEP
=
0x69
,
// if (!TOS) pc = arg; keep TOS (for &&)
OP_CASE
=
0x6A
,
// switch case: if TOS-1 === TOS, pop & jump, else pop TOS only
OP_JNULLISH_POP
=
0x6B
,
// if (TOS === null || TOS === undefined) pc = arg; pop
// Variables (0x70-0x7F)
OP_LOAD_LOCAL
=
0x70
,
// push locals[arg]
OP_STORE_LOCAL
=
0x71
,
// locals[arg] = TOS; pop
OP_LOAD_GLOBAL
=
0x72
,
// push global[names[arg]]
OP_STORE_GLOBAL
=
0x73
,
// global[names[arg]] = TOS; pop
OP_LOAD_UPVAL
=
0x74
,
// push upvalues[arg]
OP_STORE_UPVAL
=
0x75
,
// upvalues[arg] = TOS; pop
OP_LOAD_NAME
=
0x76
,
// push scope lookup names[arg]
OP_STORE_NAME
=
0x77
,
// scope[names[arg]] = TOS; pop
OP_DEF_VAR
=
0x78
,
// define var in current scope (for hoisting)
OP_DEF_LET
=
0x79
,
// define let in current block scope
OP_DEF_CONST
=
0x7A
,
// define const in current block scope
OP_DEL_NAME
=
0x7B
,
// delete names[arg] from scope
OP_STORE_LOCAL_KEEP
=
0x7C
,
// locals[arg] = TOS; keep TOS
OP_STORE_NAME_KEEP
=
0x7D
,
// scope[names[arg]] = TOS; keep TOS
// Objects & Arrays (0x80-0x8F)
OP_NEW_OBJ
=
0x80
,
// push {}
OP_NEW_ARR
=
0x81
,
// push []
OP_GET_PROP
=
0x82
,
// TOS = TOS[names[arg]]; (replaces TOS)
OP_SET_PROP
=
0x83
,
// TOS-1[names[arg]] = TOS; pop 2, push TOS
OP_GET_ELEM
=
0x84
,
// TOS = TOS-1[TOS]; pop 1
OP_SET_ELEM
=
0x85
,
// TOS-2[TOS-1] = TOS; pop 2, push TOS
OP_DEL_PROP
=
0x86
,
// TOS = delete TOS[names[arg]]
OP_DEL_ELEM
=
0x87
,
// TOS = delete TOS-1[TOS]
OP_INIT_PROP
=
0x88
,
// obj init: TOS-1[names[arg]] = TOS, pop value keep obj
OP_INIT_ELEM
=
0x89
,
// arr init: TOS-1.push(TOS), pop value keep arr
OP_SPREAD
=
0x8A
,
// spread TOS into array/object on TOS-1
OP_GET_SUPER
=
0x8B
,
// TOS = super[names[arg]]
OP_SET_SUPER
=
0x8C
,
// super[names[arg]] = TOS; pop, push TOS
OP_GET_PROP_OPT
=
0x8D
,
// TOS = TOS?.[names[arg]] (optional chain)
OP_GET_ELEM_OPT
=
0x8E
,
// TOS = TOS-1?.[TOS] (optional chain)
OP_INIT_COMPUTED
=
0x8F
,
// obj[TOS-1] = TOS; for computed property names
// Functions (0x90-0x9F)
OP_CALL
=
0x90
,
// call TOS-arg-1 with arg arguments
OP_CALL_METHOD
=
0x91
,
// obj.method(args): TOS-arg-1=obj, TOS-arg=method, args on stack
OP_NEW
=
0x92
,
// new TOS-arg with arg arguments
OP_RET
=
0x93
,
// return TOS
OP_RET_UNDEF
=
0x94
,
// return undefined
OP_CLOSURE
=
0x95
,
// create closure from func_pool[arg]
OP_THIS
=
0x96
,
// push this
OP_ARGS
=
0x97
,
// push arguments object
OP_REST
=
0x98
,
// collect rest params starting at arg
OP_SUPER
=
0x99
,
// push super
OP_NEW_TARGET
=
0x9A
,
// push new.target
OP_CALL_OPT
=
0x9B
,
// func?.(...args) optional call
OP_SUPER_CALL
=
0x9C
,
// super(...args) with arg arguments
OP_SPREAD_ARG
=
0x9D
,
// mark TOS as spread argument for next call
// Iterators & Generators (0xA0-0xAF)
OP_GET_ITER
=
0xA0
,
// TOS = TOS[Symbol.iterator]()
OP_ITER_NEXT
=
0xA1
,
// push {value, done} = TOS.next()
OP_FOR_IN
=
0xA2
,
// setup for-in iteration
OP_FOR_OF
=
0xA3
,
// setup for-of iteration
OP_YIELD
=
0xA4
,
// yield TOS
OP_YIELD_STAR
=
0xA5
,
// yield* TOS
OP_AWAIT
=
0xA6
,
// await TOS
OP_ITER_CLOSE
=
0xA7
,
// close iterator (for break/return in for-of)
OP_ASYNC_ITER
=
0xA8
,
// TOS = TOS[Symbol.asyncIterator]()
// Exception handling (0xB0-0xBF)
OP_THROW
=
0xB0
,
// throw TOS
OP_TRY_START
=
0xB1
,
// arg = catch handler offset
OP_TRY_END
=
0xB2
,
// end try block
OP_CATCH
=
0xB3
,
// catch handler (binds exception to local)
OP_FINALLY
=
0xB4
,
// finally handler
OP_RETHROW
=
0xB5
,
// rethrow current exception
OP_EXCEPTION
=
0xB6
,
// push current exception value
// Scope (0xC0-0xCF)
OP_PUSH_SCOPE
=
0xC0
,
// create new block scope
OP_POP_SCOPE
=
0xC1
,
// exit block scope
OP_PUSH_WITH
=
0xC2
,
// enter with(TOS) scope
OP_POP_WITH
=
0xC3
,
// exit with scope
// Classes (0xD0-0xDF)
OP_CLASS
=
0xD0
,
// create class from constructor func[arg]
OP_CLASS_EXTEND
=
0xD1
,
// set TOS as superclass for class on TOS-1
OP_INIT_METHOD
=
0xD2
,
// add method TOS to class TOS-1, name=names[arg]
OP_INIT_GETTER
=
0xD3
,
// add getter TOS to class TOS-1, name=names[arg]
OP_INIT_SETTER
=
0xD4
,
// add setter TOS to class TOS-1, name=names[arg]
OP_INIT_STATIC
=
0xD5
,
// add static method TOS to class TOS-1
OP_INIT_STATIC_GET
=
0xD6
,
// add static getter
OP_INIT_STATIC_SET
=
0xD7
,
// add static setter
OP_INIT_FIELD
=
0xD8
,
// initialize instance field
OP_INIT_PRIVATE
=
0xD9
,
// initialize private field/method
// Template literals (0xE0-0xEF)
OP_TEMPLATE
=
0xE0
,
// build template literal, arg = num parts
OP_TAGGED_TEMPLATE
=
0xE1
,
// tagged template call
// Destructuring (0xE8-0xEF)
OP_UNPACK_ARR
=
0xE8
,
// unpack array: TOS = iterable, pushes elements
OP_UNPACK_OBJ
=
0xE9
,
// unpack object: TOS = object, uses names for keys
OP_UNPACK_REST
=
0xEA
,
// collect remaining elements into array/object
// Misc (0xF0-0xFF)
OP_DEBUG
=
0xF0
,
// debugger statement
OP_LINE
=
0xF1
,
// source line number for debugging
OP_COL
=
0xF2
,
// source column for debugging
OP_FILENAME
=
0xF3
,
// source filename index
OP_HALT
=
0xFF
,
// stop execution
}
bc_opcode_t
;
// ============================================================================
// Bytecode function prototype
// ============================================================================
typedef
struct
bc_func
{
bc_inst_t
*
code
;
// instruction array
uint32_t
code_len
;
// number of instructions
uint32_t
code_cap
;
// allocated capacity
jsval_t
*
constants
;
// constant pool
uint32_t
const_len
;
uint32_t
const_cap
;
char
**
names
;
// name table for variables/properties
uint32_t
names_len
;
uint32_t
names_cap
;
uint8_t
arity
;
// number of parameters
uint8_t
nlocals
;
// number of local variables (including params)
const
char
*
name
;
// function name (for debugging)
}
bc_func_t
;
// ============================================================================
// Bytecode chunk - a compiled unit of code (module/script level)
// ============================================================================
typedef
struct
{
bc_inst_t
*
code
;
// instruction array
uint32_t
code_len
;
// number of instructions
uint32_t
code_cap
;
// allocated capacity
jsval_t
*
constants
;
// constant pool
uint32_t
const_len
;
// number of constants
uint32_t
const_cap
;
// allocated capacity
char
**
names
;
// name table for variables/properties
uint32_t
names_len
;
uint32_t
names_cap
;
bc_func_t
**
functions
;
// function table
uint32_t
func_len
;
uint32_t
func_cap
;
uint16_t
*
lines
;
// line number table (1:1 with code)
const
char
*
filename
;
uint8_t
nlocals
;
// number of top-level locals
}
bc_chunk_t
;
// ============================================================================
// VM state
// ============================================================================
#define BC_STACK_MAX 4096
#define BC_CALL_MAX 256
#define BC_LOCALS_MAX 256
typedef
struct
bc_frame
{
bc_func_t
*
func
;
// function being executed (NULL for top-level)
bc_chunk_t
*
chunk
;
// chunk (for top-level or constants access)
uint32_t
ip
;
// instruction pointer
uint32_t
bp
;
// base pointer (stack frame start)
jsval_t
locals
[
BC_LOCALS_MAX
];
// local variables
uint8_t
nlocals
;
}
bc_frame_t
;
typedef
struct
bc_vm
{
struct
js
*
js
;
// reference to JS runtime (for value ops)
jsval_t
stack
[
BC_STACK_MAX
];
uint32_t
sp
;
// stack pointer
bc_frame_t
frames
[
BC_CALL_MAX
];
uint32_t
fp
;
// frame pointer
jsval_t
globals
[
BC_LOCALS_MAX
];
// global variables
uint8_t
nglobals
;
bool
has_error
;
jsval_t
error
;
}
bc_vm_t
;
// ============================================================================
// API
// ============================================================================
// Chunk operations
bc_chunk_t
*
bc_chunk_new
(
void
);
void
bc_chunk_free
(
bc_chunk_t
*
chunk
);
uint32_t
bc_emit
(
bc_chunk_t
*
chunk
,
bc_inst_t
inst
);
uint32_t
bc_emit_op
(
bc_chunk_t
*
chunk
,
bc_opcode_t
op
);
uint32_t
bc_add_const
(
bc_chunk_t
*
chunk
,
jsval_t
val
);
uint32_t
bc_add_name
(
bc_chunk_t
*
chunk
,
const
char
*
name
);
void
bc_patch
(
bc_chunk_t
*
chunk
,
uint32_t
offset
,
bc_inst_t
inst
);
// Function operations
bc_func_t
*
bc_func_new
(
const
char
*
name
,
uint8_t
arity
);
void
bc_func_free
(
bc_func_t
*
func
);
uint32_t
bc_func_emit
(
bc_func_t
*
func
,
bc_inst_t
inst
);
uint32_t
bc_func_emit_op
(
bc_func_t
*
func
,
bc_opcode_t
op
);
uint32_t
bc_func_add_const
(
bc_func_t
*
func
,
jsval_t
val
);
uint32_t
bc_func_add_name
(
bc_func_t
*
func
,
const
char
*
name
);
uint32_t
bc_add_func
(
bc_chunk_t
*
chunk
,
bc_func_t
*
func
);
// VM operations
bc_vm_t
*
bc_vm_new
(
struct
js
*
js
);
void
bc_vm_free
(
bc_vm_t
*
vm
);
void
bc_vm_reset
(
bc_vm_t
*
vm
);
jsval_t
bc_vm_run
(
bc_vm_t
*
vm
,
bc_chunk_t
*
chunk
);
jsval_t
bc_vm_call
(
bc_vm_t
*
vm
,
bc_func_t
*
func
,
jsval_t
*
args
,
int
nargs
);
void
bc_vm_push
(
bc_vm_t
*
vm
,
jsval_t
val
);
jsval_t
bc_vm_pop
(
bc_vm_t
*
vm
);
jsval_t
bc_vm_peek
(
bc_vm_t
*
vm
,
int
distance
);
void
bc_vm_set_global
(
bc_vm_t
*
vm
,
uint8_t
slot
,
jsval_t
val
);
jsval_t
bc_vm_get_global
(
bc_vm_t
*
vm
,
uint8_t
slot
);
// Compiler
bc_chunk_t
*
bc_compile
(
struct
js
*
js
,
const
char
*
code
,
size_t
len
);
bc_chunk_t
*
bc_compile_program
(
struct
js
*
js
,
const
char
*
code
,
size_t
len
);
void
bc_compile_debug
(
struct
js
*
js
,
const
char
*
code
,
size_t
len
);
jsval_t
bc_compile_run
(
struct
js
*
js
,
const
char
*
code
,
size_t
len
);
jsval_t
bc_run_program
(
struct
js
*
js
,
const
char
*
code
,
size_t
len
);
// Debug
void
bc_disassemble
(
bc_chunk_t
*
chunk
,
const
char
*
name
);
void
bc_disassemble_func
(
bc_func_t
*
func
);
void
bc_disassemble_inst
(
bc_chunk_t
*
chunk
,
uint32_t
offset
);
void
bc_disassemble_func_inst
(
bc_func_t
*
func
,
uint32_t
offset
);
const
char
*
bc_opcode_name
(
bc_opcode_t
op
);
#endif
// ANT_BYTECODE_H
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Thu, Mar 26, 9:12 PM (1 d, 23 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
512251
Default Alt Text
bytecode.h (13 KB)
Attached To
Mode
rANT Ant
Attached
Detach File
Event Timeline
Log In to Comment