Language: yield/signal/coroutine become keywords, start is contextual. Coroutine methods (func Name() coroutine) with start and yield / wait / frames / fixed / await; signals with Emit/Connect and Connection handles; ScriptRef<T> and node.GetScript<T>() for fields, plain methods and signals of other scripts. Diagnostics AES2050-AES2059. Bytecode v3: ScriptRefs, XFields, XMethods and Connects tables resolved by name in vm.Link, per-script signals, coroutine flag on functions; new opcodes START/YIELD/EMIT/CONNECT/DISCONNECT/CONNECTED/COSTOP/CORUN/ SELFREF/GETSCRIPT/GETXF/SETXF/CALLR, checked by verify. Runtime: script/coroutine scheduler (frames/fixed counters, time heap, await lists; only due coroutines are visited) and script/signal registry (snapshot per Emit, deferred removal, no allocations in steady state). Hot reload cancels coroutines of changed scripts, rebinds connections by name and signature, then runs Reloaded. Tooling: script/build removed, aego check/test/dump run on the workspace (test builds include _test.aes); langsvc completion, hover, signatures and semantic tokens for the new syntax; editor highlighting, snippets with placeholders, coroutine/signal profiler graphs and stats. Docs (script.md sections 16-19, editor.md, ARCHITECTURE), test fixtures and golden files, platformer enemies wired to the player, scriptreload demo, and run.Config.FrameTime for deterministic headless fixed steps. Modules (6.5): engine/module registry and ComponentBuilder are the one registration path for engine subsystems and native code; render2d, render3d and script/engine are modules over scene/frame, the script component moved to scene/scriptcomp, and scene/components and scene/systems are gone. Editor inspector, templates, picking shapes and extension hooks are driven by descriptors and editor/builtins; sdk gains Component/EditorHook; depcheck checks the module graph and the aego_runtime graph. Also: stop tracking built tool binaries; gl33 activates the scratch unit before binding for texture updates. Verification: typed component method adapters (Method0..2, Proc0..2) with direct field access and no allocations; app.Build as the single construction path for run and the editor; modules attach per scene document; depcheck aego_editor pass; diagnostic codes in one place and every code covered by a test; indexed coroutine heaps with eager cancel; dead component references and nil intrinsics fault with AES6004, host faults keep their code; GC roots of struct fields checked in verify and vm.Link; 255-field limit; AES4010 for script packages shadowing host modules; architecture registry D111-D147. Golden: the harness renders on the thread that owns the GL context, ReadPixels returns rows in memory order (render targets are top-down per D17), and the first rendering references are committed.
304 lines
5.2 KiB
Go
304 lines
5.2 KiB
Go
package bytecode
|
|
|
|
import "strconv"
|
|
|
|
type Opcode uint8
|
|
|
|
const (
|
|
NOP Opcode = iota
|
|
MOVE
|
|
MOVEN
|
|
LOADK
|
|
LOADI
|
|
LOADNIL
|
|
LOADBOOL
|
|
ADDI
|
|
SUBI
|
|
MULI
|
|
DIVI
|
|
MODI
|
|
NEGI
|
|
ADDF
|
|
SUBF
|
|
MULF
|
|
DIVF
|
|
NEGF
|
|
ITOF
|
|
FTOI
|
|
ITOS
|
|
FTOS
|
|
BTOS
|
|
ADDS
|
|
LENS
|
|
EQ
|
|
EQF
|
|
EQS
|
|
EQV
|
|
LTI
|
|
LEI
|
|
LTF
|
|
LEF
|
|
LTS
|
|
LES
|
|
NOT
|
|
JMP
|
|
JMPIF
|
|
JMPNOT
|
|
CALL
|
|
CALLX
|
|
CALLH
|
|
RET
|
|
GETSF
|
|
SETSF
|
|
GETCF
|
|
SETCF
|
|
NEWSLICE
|
|
ENSURE
|
|
LEN
|
|
INDEX
|
|
SETINDEX
|
|
APPEND
|
|
VEC2
|
|
VEC3
|
|
VEC4
|
|
GETL
|
|
SETL
|
|
VADD
|
|
VSUB
|
|
VMULS
|
|
VDIVS
|
|
VNEG
|
|
ISNIL
|
|
FAULT
|
|
START
|
|
YIELD
|
|
COSTOP
|
|
CORUN
|
|
EMIT
|
|
CONNECT
|
|
DISCONNECT
|
|
CONNECTED
|
|
GETSCRIPT
|
|
GETXF
|
|
SETXF
|
|
CALLR
|
|
SELFREF
|
|
opCount
|
|
)
|
|
|
|
type Format uint8
|
|
|
|
const (
|
|
FormatABC Format = iota
|
|
FormatABx
|
|
FormatAsBx
|
|
)
|
|
|
|
type Operand uint8
|
|
|
|
const (
|
|
OpNone Operand = iota
|
|
OpReg
|
|
OpInt
|
|
OpBool
|
|
OpCount
|
|
OpLane
|
|
OpConst
|
|
OpJump
|
|
OpFunc
|
|
OpExtern
|
|
OpHost
|
|
OpSelf
|
|
OpType
|
|
OpField
|
|
OpYield
|
|
OpSignal
|
|
OpConnect
|
|
OpScriptRef
|
|
OpXField
|
|
OpXMethod
|
|
)
|
|
|
|
type OpInfo struct {
|
|
Name string
|
|
Format Format
|
|
A, B, C Operand
|
|
}
|
|
|
|
func abc(name string, a, b, c Operand) OpInfo {
|
|
return OpInfo{Name: name, Format: FormatABC, A: a, B: b, C: c}
|
|
}
|
|
|
|
func abx(name string, a, b Operand) OpInfo {
|
|
return OpInfo{Name: name, Format: FormatABx, A: a, B: b}
|
|
}
|
|
|
|
func asbx(name string, a, b Operand) OpInfo {
|
|
return OpInfo{Name: name, Format: FormatAsBx, A: a, B: b}
|
|
}
|
|
|
|
func bin(name string) OpInfo {
|
|
return abc(name, OpReg, OpReg, OpReg)
|
|
}
|
|
|
|
func un(name string) OpInfo {
|
|
return abc(name, OpReg, OpReg, OpNone)
|
|
}
|
|
|
|
func reg(name string) OpInfo {
|
|
return abc(name, OpReg, OpNone, OpNone)
|
|
}
|
|
|
|
var opInfo = [opCount]OpInfo{
|
|
NOP: abc("NOP", OpNone, OpNone, OpNone),
|
|
MOVE: un("MOVE"),
|
|
MOVEN: abc("MOVEN", OpReg, OpReg, OpCount),
|
|
LOADK: abx("LOADK", OpReg, OpConst),
|
|
LOADI: asbx("LOADI", OpReg, OpInt),
|
|
LOADNIL: reg("LOADNIL"),
|
|
LOADBOOL: abc("LOADBOOL", OpReg, OpBool, OpNone),
|
|
ADDI: bin("ADDI"),
|
|
SUBI: bin("SUBI"),
|
|
MULI: bin("MULI"),
|
|
DIVI: bin("DIVI"),
|
|
MODI: bin("MODI"),
|
|
NEGI: un("NEGI"),
|
|
ADDF: bin("ADDF"),
|
|
SUBF: bin("SUBF"),
|
|
MULF: bin("MULF"),
|
|
DIVF: bin("DIVF"),
|
|
NEGF: un("NEGF"),
|
|
ITOF: un("ITOF"),
|
|
FTOI: un("FTOI"),
|
|
ITOS: un("ITOS"),
|
|
FTOS: un("FTOS"),
|
|
BTOS: un("BTOS"),
|
|
ADDS: bin("ADDS"),
|
|
LENS: un("LENS"),
|
|
EQ: bin("EQ"),
|
|
EQF: bin("EQF"),
|
|
EQS: bin("EQS"),
|
|
EQV: bin("EQV"),
|
|
LTI: bin("LTI"),
|
|
LEI: bin("LEI"),
|
|
LTF: bin("LTF"),
|
|
LEF: bin("LEF"),
|
|
LTS: bin("LTS"),
|
|
LES: bin("LES"),
|
|
NOT: un("NOT"),
|
|
JMP: asbx("JMP", OpNone, OpJump),
|
|
JMPIF: asbx("JMPIF", OpReg, OpJump),
|
|
JMPNOT: asbx("JMPNOT", OpReg, OpJump),
|
|
CALL: abx("CALL", OpReg, OpFunc),
|
|
CALLX: abx("CALLX", OpReg, OpExtern),
|
|
CALLH: abx("CALLH", OpReg, OpHost),
|
|
RET: abc("RET", OpReg, OpCount, OpNone),
|
|
GETSF: abx("GETSF", OpReg, OpSelf),
|
|
SETSF: abx("SETSF", OpReg, OpSelf),
|
|
GETCF: abc("GETCF", OpReg, OpReg, OpField),
|
|
SETCF: abc("SETCF", OpReg, OpReg, OpField),
|
|
NEWSLICE: abx("NEWSLICE", OpReg, OpType),
|
|
ENSURE: abx("ENSURE", OpReg, OpType),
|
|
LEN: un("LEN"),
|
|
INDEX: bin("INDEX"),
|
|
SETINDEX: bin("SETINDEX"),
|
|
APPEND: bin("APPEND"),
|
|
VEC2: un("VEC2"),
|
|
VEC3: un("VEC3"),
|
|
VEC4: un("VEC4"),
|
|
GETL: abc("GETL", OpReg, OpReg, OpLane),
|
|
SETL: abc("SETL", OpReg, OpReg, OpLane),
|
|
VADD: bin("VADD"),
|
|
VSUB: bin("VSUB"),
|
|
VMULS: bin("VMULS"),
|
|
VDIVS: bin("VDIVS"),
|
|
VNEG: un("VNEG"),
|
|
ISNIL: un("ISNIL"),
|
|
FAULT: abx("FAULT", OpNone, OpConst),
|
|
START: abx("START", OpReg, OpFunc),
|
|
YIELD: abc("YIELD", OpReg, OpNone, OpYield),
|
|
COSTOP: reg("COSTOP"),
|
|
CORUN: un("CORUN"),
|
|
EMIT: abx("EMIT", OpReg, OpSignal),
|
|
CONNECT: abx("CONNECT", OpReg, OpConnect),
|
|
DISCONNECT: reg("DISCONNECT"),
|
|
CONNECTED: un("CONNECTED"),
|
|
GETSCRIPT: abx("GETSCRIPT", OpReg, OpScriptRef),
|
|
GETXF: abc("GETXF", OpReg, OpReg, OpXField),
|
|
SETXF: abc("SETXF", OpReg, OpReg, OpXField),
|
|
CALLR: abx("CALLR", OpReg, OpXMethod),
|
|
SELFREF: reg("SELFREF"),
|
|
}
|
|
|
|
func (o Opcode) Valid() bool {
|
|
return o < opCount
|
|
}
|
|
|
|
func (o Opcode) Info() OpInfo {
|
|
if o < opCount {
|
|
return opInfo[o]
|
|
}
|
|
return OpInfo{Name: "OP" + strconv.Itoa(int(o))}
|
|
}
|
|
|
|
func (o Opcode) String() string {
|
|
return o.Info().Name
|
|
}
|
|
|
|
type Instr uint32
|
|
|
|
func ABC(op Opcode, a, b, c uint8) Instr {
|
|
return Instr(op) | Instr(a)<<8 | Instr(b)<<16 | Instr(c)<<24
|
|
}
|
|
|
|
func ABx(op Opcode, a uint8, bx uint16) Instr {
|
|
return Instr(op) | Instr(a)<<8 | Instr(bx)<<16
|
|
}
|
|
|
|
func AsBx(op Opcode, a uint8, sbx int16) Instr {
|
|
return ABx(op, a, uint16(sbx))
|
|
}
|
|
|
|
func (i Instr) Op() Opcode {
|
|
return Opcode(i)
|
|
}
|
|
|
|
func (i Instr) A() uint8 {
|
|
return uint8(i >> 8)
|
|
}
|
|
|
|
func (i Instr) B() uint8 {
|
|
return uint8(i >> 16)
|
|
}
|
|
|
|
func (i Instr) C() uint8 {
|
|
return uint8(i >> 24)
|
|
}
|
|
|
|
func (i Instr) Bx() uint16 {
|
|
return uint16(i >> 16)
|
|
}
|
|
|
|
func (i Instr) SBx() int16 {
|
|
return int16(i.Bx())
|
|
}
|
|
|
|
const (
|
|
WaitNext uint8 = iota
|
|
WaitTime
|
|
WaitFrames
|
|
WaitFixed
|
|
WaitAwait
|
|
MaxWait = WaitAwait
|
|
)
|
|
|
|
var WaitNames = [...]string{"next", "wait", "frames", "fixed", "await"}
|
|
|
|
const (
|
|
MaxRegisters = 255
|
|
MaxJumpOffset = 32767
|
|
MaxSliceElemSlots = 32
|
|
MaxComponentFields = 255
|
|
MaxScriptFieldRefs = 256
|
|
)
|