From 797a506d81ad0f73d5e14e219208dd1a82887e66 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Wed, 30 Oct 2024 22:39:44 -0700 Subject: [PATCH] A bunch of improvements --- packages/@glimmer/runtime/lib/opcodes.ts | 217 +++++++++--------- packages/@glimmer/runtime/lib/vm/append.ts | 20 +- packages/@glimmer/runtime/lib/vm/low-level.ts | 4 +- vite.config.mts | 3 - 4 files changed, 125 insertions(+), 119 deletions(-) diff --git a/packages/@glimmer/runtime/lib/opcodes.ts b/packages/@glimmer/runtime/lib/opcodes.ts index 8f220e469..cf8559a75 100644 --- a/packages/@glimmer/runtime/lib/opcodes.ts +++ b/packages/@glimmer/runtime/lib/opcodes.ts @@ -53,6 +53,9 @@ export type DebugState = { export class AppendOpcodes { private evaluateOpcode: Evaluate[] = new Array(Op.Size).fill(null); + declare debugBefore?: (vm: VM, opcode: RuntimeOp) => DebugState; + declare debugAfter?: (vm: VM, pre: DebugState) => void; + add(name: Name, evaluate: Syscall): void; add(name: Name, evaluate: MachineOpcode, kind: 'machine'): void; add( @@ -66,111 +69,6 @@ export class AppendOpcodes { } as Evaluate; } - debugBefore(vm: VM, opcode: RuntimeOp): DebugState { - let params: Maybe = undefined; - let opName: string | undefined = undefined; - - if (LOCAL_TRACE_LOGGING) { - const lowlevel = unwrap(vm.debug).lowlevel; - let pos = lowlevel.fetchRegister($pc) - opcode.size; - - [opName, params] = debug(vm.constants, opcode, opcode.isMachine)!; - - // console.log(`${typePos(vm['pc'])}.`); - LOCAL_LOGGER.debug(`${pos}. ${logOpcode(opName, params)}`); - - let debugParams = []; - for (let prop in params) { - debugParams.push(prop, '=', params[prop]); - } - - LOCAL_LOGGER.debug(...debugParams); - } - - let sp: number; - - if (LOCAL_DEBUG) { - sp = vm.fetchValue($sp); - } - - recordStackSize(vm.fetchValue($sp)); - return { - sp: sp!, - pc: vm.fetchValue($pc), - name: opName, - params, - type: opcode.type, - isMachine: opcode.isMachine, - size: opcode.size, - state: undefined, - }; - } - - debugAfter(vm: VM, pre: DebugState) { - let { sp, type, isMachine, pc } = pre; - - if (LOCAL_DEBUG) { - const debug = unwrap(vm.debug); - - let meta = opcodeMetadata(type, isMachine); - let actualChange = vm.fetchValue($sp) - sp; - if ( - meta && - meta.check && - typeof meta.stackChange! === 'number' && - meta.stackChange !== actualChange - ) { - throw new Error( - `Error in ${pre.name}:\n\n${pc}. ${logOpcode( - pre.name!, - pre.params - )}\n\nStack changed by ${actualChange}, expected ${meta.stackChange}` - ); - } - - if (LOCAL_TRACE_LOGGING) { - const { lowlevel, registers } = unwrap(vm.debug); - LOCAL_LOGGER.debug( - '%c -> pc: %d, ra: %d, fp: %d, sp: %d, s0: %O, s1: %O, t0: %O, t1: %O, v0: %O', - 'color: orange', - lowlevel.registers[$pc], - lowlevel.registers[$ra], - lowlevel.registers[$fp], - lowlevel.registers[$sp], - registers[$s0], - registers[$s1], - registers[$t0], - registers[$t1], - registers[$v0] - ); - LOCAL_LOGGER.debug('%c -> eval stack', 'color: red', vm.stack.toArray()); - LOCAL_LOGGER.debug('%c -> block stack', 'color: magenta', vm.elements().debugBlocks()); - LOCAL_LOGGER.debug( - '%c -> destructor stack', - 'color: violet', - debug.destroyableStack.toArray() - ); - if (debug.stacks.scope.current === null) { - LOCAL_LOGGER.debug('%c -> scope', 'color: green', 'null'); - } else { - LOCAL_LOGGER.debug( - '%c -> scope', - 'color: green', - vm.scope().slots.map((s) => (isScopeReference(s) ? valueForRef(s) : s)) - ); - } - - LOCAL_LOGGER.debug( - '%c -> elements', - 'color: blue', - vm.elements()[CURSOR_STACK].current!.element - ); - - LOCAL_LOGGER.debug('%c -> constructing', 'color: aqua', vm.elements()['constructing']); - } - } - } - evaluate(vm: VM, opcode: RuntimeOp, type: number) { let operation = unwrap(this.evaluateOpcode[type]); @@ -190,4 +88,113 @@ export class AppendOpcodes { } } +if (import.meta.env.VM_LOCAL_DEV) { + Object.assign(AppendOpcodes.prototype, { + debugBefore(vm: VM, opcode: RuntimeOp): DebugState { + let params: Maybe = undefined; + let opName: string | undefined = undefined; + + if (LOCAL_TRACE_LOGGING) { + const lowlevel = unwrap(vm.debug).lowlevel; + let pos = lowlevel.fetchRegister($pc) - opcode.size; + + [opName, params] = debug(vm.constants, opcode, opcode.isMachine)!; + + // console.log(`${typePos(vm['pc'])}.`); + LOCAL_LOGGER.debug(`${pos}. ${logOpcode(opName, params)}`); + + let debugParams = []; + for (let prop in params) { + debugParams.push(prop, '=', params[prop]); + } + + LOCAL_LOGGER.debug(...debugParams); + } + + let sp: number; + + if (LOCAL_DEBUG) { + sp = vm.fetchValue($sp); + } + + recordStackSize(vm.fetchValue($sp)); + return { + sp: sp!, + pc: vm.fetchValue($pc), + name: opName, + params, + type: opcode.type, + isMachine: opcode.isMachine, + size: opcode.size, + state: undefined, + }; + }, + + debugAfter(vm: VM, pre: DebugState) { + let { sp, type, isMachine, pc } = pre; + + if (LOCAL_DEBUG) { + const debug = unwrap(vm.debug); + + let meta = opcodeMetadata(type, isMachine); + let actualChange = vm.fetchValue($sp) - sp; + if ( + meta && + meta.check && + typeof meta.stackChange! === 'number' && + meta.stackChange !== actualChange + ) { + throw new Error( + `Error in ${pre.name}:\n\n${pc}. ${logOpcode( + pre.name!, + pre.params + )}\n\nStack changed by ${actualChange}, expected ${meta.stackChange}` + ); + } + + if (LOCAL_TRACE_LOGGING) { + const { lowlevel, registers } = unwrap(vm.debug); + LOCAL_LOGGER.debug( + '%c -> pc: %d, ra: %d, fp: %d, sp: %d, s0: %O, s1: %O, t0: %O, t1: %O, v0: %O', + 'color: orange', + lowlevel.registers[$pc], + lowlevel.registers[$ra], + lowlevel.registers[$fp], + lowlevel.registers[$sp], + registers[$s0], + registers[$s1], + registers[$t0], + registers[$t1], + registers[$v0] + ); + LOCAL_LOGGER.debug('%c -> eval stack', 'color: red', vm.stack.toArray()); + LOCAL_LOGGER.debug('%c -> block stack', 'color: magenta', vm.elements().debugBlocks()); + LOCAL_LOGGER.debug( + '%c -> destructor stack', + 'color: violet', + debug.destroyableStack.toArray() + ); + if (debug.stacks.scope.current === null) { + LOCAL_LOGGER.debug('%c -> scope', 'color: green', 'null'); + } else { + LOCAL_LOGGER.debug( + '%c -> scope', + 'color: green', + vm.scope().slots.map((s) => (isScopeReference(s) ? valueForRef(s) : s)) + ); + } + + LOCAL_LOGGER.debug( + '%c -> elements', + 'color: blue', + vm.elements()[CURSOR_STACK].current!.element + ); + + LOCAL_LOGGER.debug('%c -> constructing', 'color: aqua', vm.elements()['constructing']); + } + } + }, + }); +} + export const APPEND_OPCODES = new AppendOpcodes(); diff --git a/packages/@glimmer/runtime/lib/vm/append.ts b/packages/@glimmer/runtime/lib/vm/append.ts index 4b38a445b..815d708ac 100644 --- a/packages/@glimmer/runtime/lib/vm/append.ts +++ b/packages/@glimmer/runtime/lib/vm/append.ts @@ -207,15 +207,17 @@ export class VM implements PublicVM { evalStack, this.#heap, runtime.program, - { - debugBefore: (opcode: RuntimeOpImpl): DebugState => { - return APPEND_OPCODES.debugBefore(this, opcode); - }, - - debugAfter: (state: DebugState): void => { - APPEND_OPCODES.debugAfter(this, state); - }, - }, + import.meta.env.VM_LOCAL_DEV + ? { + debugBefore: (opcode: RuntimeOpImpl): DebugState => { + return APPEND_OPCODES.debugBefore!(this, opcode); + }, + + debugAfter: (state: DebugState): void => { + APPEND_OPCODES.debugAfter!(this, state); + }, + } + : undefined, evalStack.registers ); diff --git a/packages/@glimmer/runtime/lib/vm/low-level.ts b/packages/@glimmer/runtime/lib/vm/low-level.ts index c620c2603..6bb2cbef9 100644 --- a/packages/@glimmer/runtime/lib/vm/low-level.ts +++ b/packages/@glimmer/runtime/lib/vm/low-level.ts @@ -49,7 +49,7 @@ export class LowLevelVM { public stack: VmStack, public heap: RuntimeHeap, public program: RuntimeProgram, - public externs: Externs, + public externs: Externs | undefined, readonly registers: LowLevelRegisters ) {} @@ -139,7 +139,7 @@ export class LowLevelVM { } evaluateOuter(opcode: RuntimeOp, vm: VM) { - if (LOCAL_DEBUG) { + if (LOCAL_DEBUG && this.externs) { let { externs: { debugBefore, debugAfter }, } = this; diff --git a/vite.config.mts b/vite.config.mts index f4bf811df..dec51f576 100644 --- a/vite.config.mts +++ b/vite.config.mts @@ -6,9 +6,6 @@ export default defineConfig({ }, mode: 'testing', plugins: [ - /** - * A similar plugin exists for our rollup builds - */ { name: 'define custom import.meta.env', async transform(code) {