Files
noom/src/vm.h
2026-05-27 15:43:13 +02:00

315 lines
15 KiB
C

#ifndef NOOM_VM
#define NOOM_VM
#include "types.h"
#include "noom.h"
#ifndef NOOM_MAXSTACK
#define NOOM_MAXSTACK 4096
#endif
#ifndef NOOM_MAXCALL
#define NOOM_MAXCALL (NOOM_MAXSTACK/32)
#endif
// Defines values, threads, bullshit, idc
typedef enum noomV_ObjTag {
NOOMV_OSTR,
NOOMV_OFUNC,
NOOMV_OCLOSURE,
NOOMV_OTABLE,
NOOMV_OUSERDATA,
NOOMV_OPOINTER,
} noomV_ObjTag;
typedef struct noomV_Object {
noomV_ObjTag tag;
noom_bool_t marked;
struct noomV_Object *next;
struct noomV_Object *nextGray;
} noomV_Object;
typedef enum noomV_ValueTag : unsigned char {
NOOMV_VNIL,
NOOMV_VBOOL,
NOOMV_VINT,
NOOMV_VNUM,
NOOMV_VLUSER,
NOOMV_VCFUNC,
NOOMV_VOBJ,
} noomV_ValueTag;
typedef struct noomV_Value {
noomV_ValueTag tag;
// for stack slots
noom_bool_t autoclose;
// pointer to value
noom_bool_t isptr;
union {
noom_bool_t boolean;
noom_int_t integer;
noom_float_t number;
noomV_Object *obj;
struct noomV_Pointer *ptr;
};
} noomV_Value;
typedef struct noomV_String {
noomV_Object obj;
noom_uint_t len;
// Includes NUL-terminator!
char data[];
} noomV_String;
typedef struct noomV_Table {
noomV_Object obj;
struct noomV_Table *meta;
// amount of entries allocated
noom_uint_t entries;
// how many entries are defined.
// Note, this includes keys with null values, which are still scanned.
noom_uint_t used;
// cache of #t, for faster subsequent fetches
noom_uint_t len;
// actual values. Given index i, V[i] is the key and V[i+entries] is the value.
// This is because we mostly read the key, so we should put more keys in cache.
noomV_Value *entrydata;
} noomV_Table;
typedef struct noomV_Pointer {
noomV_Object obj;
noomV_Value value;
} noomV_Pointer;
typedef enum noomV_Opcode : unsigned char {
NOOMV_INSTR_NOP = 0,
// A = consts[uD]
NOOMV_INSTR_LOADC,
// load from A an array of uD nils
NOOMV_INSTR_LOAD_NILARR,
// load from A an array of uD/2 booleans, stored in uD&1
NOOMV_INSTR_LOAD_BOOLARR,
// A = B
NOOMV_INSTR_COPY,
// pc = uD
NOOMV_INSTR_JMP,
// if(A) pc = uD
NOOMV_INSTR_JC,
// if(not A) pc = uD
NOOMV_INSTR_JNC,
// A = B + C
NOOMV_INSTR_ADD,
// A = B - C
NOOMV_INSTR_SUB,
// A = -B
NOOMV_INSTR_NEG,
// A = B * C
NOOMV_INSTR_MUL,
// A = B / C
NOOMV_INSTR_DIV,
// A = B % C
NOOMV_INSTR_MOD,
// A = B // C
NOOMV_INSTR_FLOOR_DIV,
// A = B ^ C
NOOMV_INSTR_POW,
// A = B == C
NOOMV_INSTR_EQ,
// A = B ~= C
NOOMV_INSTR_NEQ,
// A = B < C
NOOMV_INSTR_LT,
// A = B <= C
NOOMV_INSTR_LTE,
// A = B > C
NOOMV_INSTR_GT,
// A = B >= C
NOOMV_INSTR_GTE,
// A = not B
NOOMV_INSTR_NOT,
// A = B & C
NOOMV_INSTR_BAND,
// A = B | C
NOOMV_INSTR_BOR,
// A = B ~ C
NOOMV_INSTR_BXOR,
// A = ~B
NOOMV_INSTR_BNOT,
// A = B << C
NOOMV_INSTR_LSHIFT,
// A = B >> C
NOOMV_INSTR_RSHIFT,
// A = B .. C
NOOMV_INSTR_CONCAT,
// A = #B
NOOMV_INSTR_LEN,
// A = B[C]
NOOMV_INSTR_GET,
// A[B] = C
NOOMV_INSTR_SET,
NOOMV_INSTR_NOP2 = 0xff,
} noomV_Opcode;
typedef struct noomV_Inst {
noomV_Opcode op;
unsigned char a;
union {
struct {
unsigned char b;
unsigned char c;
};
short ss;
unsigned short us;
};
} noomV_Inst;
typedef struct noomV_UpvalDesc {
char *name;
unsigned char idx;
// whether the index is a stack index
noom_bool_t isStack;
} noomV_UpvalDesc;
typedef struct noomV_LocalDesc {
char *name;
unsigned char stackIdx;
// offset of first instruction where local exists
unsigned int pcStart;
// offset of first instruction where local is dropped
unsigned int pcEnd;
} noomV_LocalDesc;
typedef struct noomV_Function {
noomV_Object obj;
// source location string
noomV_String *chunkname;
noomV_Inst *code;
noomV_Value *consts;
struct noomV_Function **protos;
noomV_UpvalDesc *upvals;
noomV_LocalDesc *locals;
unsigned int codesize;
// line of function
unsigned int linedefined;
// line of end
unsigned int lastlinedefined;
// very size limited
// ░░░░░░░░░ ░ ▒░░▒ ▒░ ░░ ░
// ░░░░░░░░░ █░█░▓▓ ░█▒████▒░ █░░████▓
// ░░░░░░░░░ ▓████████░█░▒████▓░████ ░█░
// ░░░░░░░░░ ░░░ ░█▓░█▒█░█░▒▒█▓████▒ ░█▒█ ░█░░
// ░░░░░░░░░ ░░░░░ ░█▓▓███▒█ ▓▓▒▒▒▓▓▒ ▒█▒█▓██▓▓
// ░░░░░░░░░ ░░ ░▓▓███▓█▒░░█▒▓█▓██▓ ▒▓█▓▓▓█▒▒
// ░░░░░░░░░░ ░░ ▒▓█░█▒█░ ░▓▓██████░░██░░▒█
// ░░░░░░░░░░ ░░░░ ░░ ▓▓█▒█▓█▒░ ▒▒▒█▒░█░ ███░░█
// ░░░░░░░░░░ ░░ ▓▒▓███░█▒ ▒░░░▓▓█░░██░▓▒██
// ░░░░░░░░░░ ░░ ░ ░░ ░░ ░░ ░░ ▒░ ░░░ ░░
// ░░░░░░░░░░ ░ ░░░ ░ ░ ░ ░
// ░░░░░░░░░░ ░░░░ ░░ ░
// ░ ░░░░░░░░░ ░░░░ ░ ░ ░ ░░ ░░░ ░░░ ░ ░░
// ░░░░░░░░░ ░ █████ ▒████ ░▓███▓░ ░████░ ░████▓ ░████░ ░▓███▓ ░████░
//░░ ░░░░░░░░░ █▓▒██░░██▓██▒░░██▒██░░██▒▓██░▒██▒██ ██▓▓██ ░██▒██░ ██▒▓██
//░░ ░░░░░░░░░░ ██░▒█▓ ░██░██▒ ▒█▒░██ ░██ ██░ ▓█▒░██ ░██░██░ ▓█▒░██ ██░
// ░░░░░░░░░░░ ░▓███░▒█▓ ██░██░ ▒██▒██ ░██░██ ▒█▒░██ ░██░██░ ▒█▓▒█▓ ░██░
// ░░░░░░░░░░ ░ ░▒███░ ▓████░▓█▒ ░██░██░ ▒██▒█▓ ░██░██ ░▒█▒░██ ░██░██░ ░██▒█▓ ░██░░
// ░░░░░░░░░ ░░ ░ ░░██▓▓█▓░░██ ██░ ▒█▓▒█▓ ██░██░ ▒█▒░██ ░██░██░ ░██▒█▓ ░██░░
// ░░░░░░░░░░ ░░░░ ░ ░███▒██ ░██ ██▒ ▓█▒▒██ ░██░██░ ██░░██░░██ ██▒ ▓█░░██ ░██
// ░░░░░░░░░ ░░░ ░█████▒░█████▒▒▓█████ ░█████▒ ▒█████▓██████▓ ▒██▓██░ █████▒
// ░░░░░░░░░ ░░ ░████▒ ░░███▒░█▒▒███░ ░███▓ ▓███░▓█░███▓░ ▒███░ ░███▒
// ░░░░░░░░░░ ░█░ ░ ░ ▒▒ ░
// ░░░░░░░░░ ░ ░
// ░░░░░░░░░ ░░░░
// ░░░░░░░░░ ░░░░░ ░░ ░ ░ ░ ░
// ░░░░░░░░░ ░░ ░░▒░░ ░▓▒ ░█▓ ░ ░ ░
// ░░░░░░░░░ ░░ ▒█████░ ░██ ░██ ░ ░
// ░░░░░░░░░░░░░ ██▒▒███ ░░ ░ ░ ░░ ░░ ░██
// ░ ░░░░░░░░░░░░░░░ ██░ ░▓▓ ░████ ░████░░█▓ ▒███▓░░██
// ░░░░░░░░░░░░░░░░░░░░░▓███░░ ░██████░██▓██▓▒██░██▓██▒▒██░
// ░░░░░░░░░░░░░░░░░░░░ ░████░░█▓ ██░██ ▓▓░██ ░░▒██▓▒██░ ░
// ░░░░░░░░░░░░░░░░░░░ ░░░░███▒█▓ ██▒██ ░░██░█████▓▒██░ ░░ ░
// ░░░░░░░░░░░░░░░░░░ ░██▒ ░██▒██░░██░██ ░█▓░██░██░▓█▓░██░ ░ ██▓████████▓▒██▒
// ░░░░░░░░░░░░░░░░░ ░██████▓ █████▓ █████▓▒██░█████▓░██░ ░ ░░░███████████▓█▓
// ░░░░░░░░░░░░░░░░░░ ░▓███▒ ░███▒ ░▓██▓ ░█▓ ▒██▓█▓░██░ ░████████████▓█░
// ░░░░░░░░░░░░░░░░░ ░ ░ ░█████████▓██
// ░░░░░░░░░░░░░░ ░░ ▒███████▓█▓
// ░ ░░░░░░░░░░░░░░ ░░░░ ██▓██▓▓▓███ ░
// ░░░░░░░░░░░░░░░ ░░ ░ ░███████████
// ░░░░░░░░░░░░ ░░ ░ ████████████ ▒
// ░░░░░░░░░░░░ ░░▒▒░░ ░ ░██░▓█░ ░ ░░████ ▒██████ █
// ░░░░░░░░░░░ ▓█████░ ░██ ██░░█▓░ ▓████ ▓█████ ░█ ▒▒
// ░░░░░░░░░░░ ▒██░░██▒░░░░░ ░░░░░ ░░░░██ ░░░██░ █████ ▒█████ ▒█ ▒█░
// ░░░░░░░░░░░░░ ██▒ ░█▓░████░████░ ░█████ ██▒████ █████ ▓████▒ ████░
// ░░░░░░░░░░░░ ██░ ▒███▓██▓▓██ ██▒▒██ ██░▒██░ ████▒ █████ ▒████████
// ░░░░░░░░░░ ██░ ░ ▒██░ ██▒▒██░██ ░██ ██ ░██░ ░████ ░█████ ▓██▓▒░░
// ░░░░░░░░░░ ██▒ ░▒░▒██ ░██████▒██ ░██░██░░██ ▒███▒ █████▒
// ░ ░░░░░░░░░ ▓█▓░ ▓█▓▒██ ░██░ ░░░██ ░██ ██░░██░ ░███░░░█████
// ░░░░░░░░░ ██████ ▒█▓ ▓█████ ██████ ██░░███░ ░██▒ █████▒
// ░░░░░░░░░ ░▓███░░░█▓ ░░▒███░░░██▓█▓ ▓█░ ▒█▓░ ▓▓ ░█████
// ░░░░░░░░░ ░░░░ ░░ ░░ ░ ░ ▓▒ ▓████░
// ░░░░░░░░ ░░ ░░ ░ ▒▓ ████▒
// ░ ░░░░░ ░ ░ ▒░▓███▒
// ░░░░ ░ ░▓▓██
// ░░░
// ░░░
// ░░
unsigned char argc;
unsigned char flags;
unsigned short constsize;
unsigned char protosize;
unsigned char upvalsize;
unsigned char localsize;
} noomV_Function;
typedef struct noomV_CallFrame {
// stack index of function
unsigned int funcIdx;
noom_bool_t isC;
union {
struct {
//
unsigned int pc;
// amount of varargs
unsigned int varargc;
} lua;
struct {
noom_KFunction *resumeFunc;
void *resumeCtx;
} c;
};
} noomV_CallFrame;
typedef struct noomV_Thread {
noomV_Object obj;
unsigned int stacklen, calldepth;
unsigned int stackcap, callcap;
// can have pointers!
noomV_Value *stack;
noomV_CallFrame *calls;
struct noomV_Thread *resumedBy;
struct noomV_Thread *resuming;
} noomV_Thread;
struct noom_LuaVM {
noomV_Object *heap;
noomV_Object *graySet;
noomV_Table *globals;
noomV_Table *registry;
noomV_Thread *mainThread;
noomV_Thread *currentThread;
noom_LuaVersion version;
};
// Allocating objects
noomV_Object *noomV_allocObj(noom_LuaVM *vm, noomV_ObjTag tag, noom_uint_t size);
void noomV_freeObj(noomV_Object *obj);
#endif