From 99d023278bb25d5e06324cd12f1562bf3c858912 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Tue, 19 Nov 2024 12:50:25 -0800 Subject: [PATCH] Remove eval infrastructure This commit eliminates debugger infrastructure that derived from the old partial/eval infrastructure. Instead, it passes the in-scope values as a constant to the `debugger` wire format opcode and uses it directly in the scope inspector. This will be followed up with support for accessing strict-mode lexical variables. --- .../integration-tests/lib/suites/debugger.ts | 8 +++- .../test/compiler/compile-options-test.ts | 8 ++-- .../passes/1-normalization/keywords/append.ts | 1 - .../compiler/lib/passes/2-encoding/content.ts | 2 +- .../compiler/lib/passes/2-encoding/index.ts | 7 +-- .../@glimmer/compiler/lib/wire-encoding.md | 6 +-- .../compiler/lib/wire-format-debug.ts | 2 +- .../@glimmer/compiler/test/compiler-test.ts | 7 +-- .../@glimmer/constants/lib/syscall-ops.ts | 4 -- .../@glimmer/debug-util/lib/debug-brand.ts | 1 - packages/@glimmer/debug/lib/dism/opcode.ts | 5 +- .../@glimmer/debug/lib/opcode-metadata.ts | 18 +------- packages/@glimmer/debug/lib/stack-check.ts | 1 - .../interfaces/lib/compile/operands.d.ts | 6 ++- .../lib/compile/wire-format/api.d.ts | 13 ++++-- .../interfaces/lib/runtime/scope.d.ts | 4 +- .../@glimmer/interfaces/lib/template.d.ts | 7 ++- .../interfaces/lib/tier1/symbol-table.d.ts | 1 - .../@glimmer/interfaces/lib/vm-opcodes.d.ts | 4 -- .../lib/compilable-template.ts | 3 +- .../lib/opcode-builder/encoder.ts | 2 +- .../lib/opcode-builder/helpers/components.ts | 6 +-- .../lib/opcode-builder/helpers/shared.ts | 10 +--- .../lib/opcode-builder/helpers/stdlib.ts | 1 - .../lib/opcode-builder/operands.ts | 8 +++- .../opcode-compiler/lib/syntax/statements.ts | 6 +-- .../opcode-compiler/lib/wrapped-component.ts | 3 +- .../program/lib/util/default-template.ts | 7 +-- .../runtime/lib/compiled/opcodes/component.ts | 10 ---- .../runtime/lib/compiled/opcodes/debugger.ts | 32 +++++-------- packages/@glimmer/runtime/lib/scope.ts | 22 ++------- packages/@glimmer/syntax/lib/symbol-table.ts | 46 +++++++++---------- 32 files changed, 94 insertions(+), 167 deletions(-) diff --git a/packages/@glimmer-workspace/integration-tests/lib/suites/debugger.ts b/packages/@glimmer-workspace/integration-tests/lib/suites/debugger.ts index c446b6a503..466d19a575 100644 --- a/packages/@glimmer-workspace/integration-tests/lib/suites/debugger.ts +++ b/packages/@glimmer-workspace/integration-tests/lib/suites/debugger.ts @@ -28,8 +28,12 @@ export class DebuggerSuite extends RenderTest { callbackExecuted++; this.assert.strictEqual(context.foo, expectedContext.foo, 'reading from the context'); this.assert.strictEqual(get('foo'), expectedContext.foo, 'reading from a local'); - this.assert.strictEqual(get('@a'), expectedContext.a, 'reading from an unused named args'); - this.assert.strictEqual(get('@used'), expectedContext.used, 'reading from a used named args'); + this.assert.strictEqual( + get('this.args.a'), + expectedContext.a, + 'reading from an unused named arg (available on this.args)' + ); + this.assert.strictEqual(get('@used'), expectedContext.used, 'reading from a used named arg'); }); this.registerComponent( diff --git a/packages/@glimmer-workspace/integration-tests/test/compiler/compile-options-test.ts b/packages/@glimmer-workspace/integration-tests/test/compiler/compile-options-test.ts index 8c84c02b4c..59a512bde4 100644 --- a/packages/@glimmer-workspace/integration-tests/test/compiler/compile-options-test.ts +++ b/packages/@glimmer-workspace/integration-tests/test/compiler/compile-options-test.ts @@ -116,7 +116,7 @@ module('[glimmer-compiler] precompile', ({ test }) => { `component name is a free variable lookup` ); - let componentName = block[3][componentNameExpr[1]]; + let componentName = block[2][componentNameExpr[1]]; assert.strictEqual(componentName, 'ooFX', 'customized component name was used'); }); @@ -140,7 +140,7 @@ module('[glimmer-compiler] precompile', ({ test }) => { `component name is a free variable lookup` ); - let componentName = block[3][componentNameExpr[1]]; + let componentName = block[2][componentNameExpr[1]]; assert.strictEqual(componentName, 'rental', 'customized component name was used'); }); @@ -163,7 +163,7 @@ module('[glimmer-compiler] precompile', ({ test }) => { `component name is a free variable lookup` ); - let componentName = block[3][componentNameExpr[1]]; + let componentName = block[2][componentNameExpr[1]]; assert.strictEqual(componentName, 'my-component', 'original component name was used'); }); @@ -186,7 +186,7 @@ module('[glimmer-compiler] precompile', ({ test }) => { `component name is a free variable lookup` ); - let componentName = block[3][componentNameExpr[1]]; + let componentName = block[2][componentNameExpr[1]]; assert.strictEqual(componentName, 'MyComponent', 'original component name was used'); }); diff --git a/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/append.ts b/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/append.ts index a0a8c6991d..14023c4a62 100644 --- a/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/append.ts +++ b/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/append.ts @@ -98,7 +98,6 @@ export const APPEND_KEYWORDS = keywords('Append') node: ASTv2.AppendContent; state: NormalizationState; }): Result { - scope.setHasDebugger(); return Ok(new mir.Debugger({ loc: node.loc, scope })); }, }) diff --git a/packages/@glimmer/compiler/lib/passes/2-encoding/content.ts b/packages/@glimmer/compiler/lib/passes/2-encoding/content.ts index c8ca14246b..15720bcd6b 100644 --- a/packages/@glimmer/compiler/lib/passes/2-encoding/content.ts +++ b/packages/@glimmer/compiler/lib/passes/2-encoding/content.ts @@ -56,7 +56,7 @@ export class ContentEncoder { private visitContent(stmt: mir.Statement): WireFormat.Statement | WireStatements { switch (stmt.type) { case 'Debugger': - return [SexpOpcodes.Debugger, stmt.scope.getDebugInfo()]; + return [SexpOpcodes.Debugger, ...stmt.scope.getDebugInfo(), {}]; case 'AppendComment': return this.AppendComment(stmt); case 'AppendTextNode': diff --git a/packages/@glimmer/compiler/lib/passes/2-encoding/index.ts b/packages/@glimmer/compiler/lib/passes/2-encoding/index.ts index 715946773e..ab82fd0218 100644 --- a/packages/@glimmer/compiler/lib/passes/2-encoding/index.ts +++ b/packages/@glimmer/compiler/lib/passes/2-encoding/index.ts @@ -10,12 +10,7 @@ import { CONTENT } from './content'; export function visit(template: mir.Template): WireFormat.SerializedTemplateBlock { let statements = CONTENT.list(template.body); let scope = template.scope; - let block: WireFormat.SerializedTemplateBlock = [ - statements, - scope.symbols, - scope.hasDebugger, - scope.upvars, - ]; + let block: WireFormat.SerializedTemplateBlock = [statements, scope.symbols, scope.upvars]; if (LOCAL_TRACE_LOGGING) { let debug = new WireFormatDebugger(block); diff --git a/packages/@glimmer/compiler/lib/wire-encoding.md b/packages/@glimmer/compiler/lib/wire-encoding.md index a01940de7a..f2cea78996 100644 --- a/packages/@glimmer/compiler/lib/wire-encoding.md +++ b/packages/@glimmer/compiler/lib/wire-encoding.md @@ -130,9 +130,9 @@ when otherwise explicitly stated. ## Flags -| 0 | 1 | 2 | 3 | 4 | 5 | -| -------- | -------- | -------- | -------- | ---------- | ----------- | -| reserved | reserved | reserved | reserved | has upvars | hasDebugger | +| 0 | 1 | 2 | 3 | 4 | +| -------- | -------- | -------- | -------- | ---------- | +| reserved | reserved | reserved | reserved | has upvars | # Expression diff --git a/packages/@glimmer/compiler/lib/wire-format-debug.ts b/packages/@glimmer/compiler/lib/wire-format-debug.ts index 0688d6c5dc..43dc026ea2 100644 --- a/packages/@glimmer/compiler/lib/wire-format-debug.ts +++ b/packages/@glimmer/compiler/lib/wire-format-debug.ts @@ -16,7 +16,7 @@ export default class WireFormatDebugger { private upvars: string[]; private symbols: string[]; - constructor([_statements, symbols, _hasDebugger, upvars]: SerializedTemplateBlock) { + constructor([_statements, symbols, upvars]: SerializedTemplateBlock) { this.upvars = upvars; this.symbols = symbols; } diff --git a/packages/@glimmer/compiler/test/compiler-test.ts b/packages/@glimmer/compiler/test/compiler-test.ts index 555fabb2b2..c79cb992a7 100644 --- a/packages/@glimmer/compiler/test/compiler-test.ts +++ b/packages/@glimmer/compiler/test/compiler-test.ts @@ -36,12 +36,7 @@ function test(desc: string, template: string, ...expectedStatements: BuilderStat let statements = buildStatements(expectedStatements, symbols); - let expected: SerializedTemplateBlock = [ - statements, - symbols.toSymbols(), - false, - symbols.toUpvars(), - ]; + let expected: SerializedTemplateBlock = [statements, symbols.toSymbols(), symbols.toUpvars()]; let debugExpected = new WireFormatDebugger(expected).format(expected); let debugActual = new WireFormatDebugger(actual.block).format(actual.block); diff --git a/packages/@glimmer/constants/lib/syscall-ops.ts b/packages/@glimmer/constants/lib/syscall-ops.ts index 6056637470..22e49360b8 100644 --- a/packages/@glimmer/constants/lib/syscall-ops.ts +++ b/packages/@glimmer/constants/lib/syscall-ops.ts @@ -6,7 +6,6 @@ import type { VmAppendText, VmAssertSame, VmBeginComponentTransaction, - VmBindDebuggerScope, VmBindDynamicScope, VmCaptureArgs, VmChildScope, @@ -86,7 +85,6 @@ import type { VmSetBlock, VmSetBlocks, VmSetNamedVariables, - VmSetupForDebugger, VmSetVariable, VmSize, VmSpreadBlock, @@ -174,8 +172,6 @@ export const VM_PUT_COMPONENT_OPERATIONS_OP = 89 satisfies VmPutComponentOperati export const VM_GET_COMPONENT_SELF_OP = 90 satisfies VmGetComponentSelf; export const VM_GET_COMPONENT_TAG_NAME_OP = 91 satisfies VmGetComponentTagName; export const VM_GET_COMPONENT_LAYOUT_OP = 92 satisfies VmGetComponentLayout; -export const VM_BIND_DEBUGGER_SCOPE_OP = 93 satisfies VmBindDebuggerScope; -export const VM_SETUP_FOR_DEBUGGER_OP = 94 satisfies VmSetupForDebugger; export const VM_POPULATE_LAYOUT_OP = 95 satisfies VmPopulateLayout; export const VM_INVOKE_COMPONENT_LAYOUT_OP = 96 satisfies VmInvokeComponentLayout; export const VM_BEGIN_COMPONENT_TRANSACTION_OP = 97 satisfies VmBeginComponentTransaction; diff --git a/packages/@glimmer/debug-util/lib/debug-brand.ts b/packages/@glimmer/debug-util/lib/debug-brand.ts index e2d54f5ea0..3b013ac43a 100644 --- a/packages/@glimmer/debug-util/lib/debug-brand.ts +++ b/packages/@glimmer/debug-util/lib/debug-brand.ts @@ -80,7 +80,6 @@ export interface DebugProgramSymbolTable { readonly upvars: readonly string[]; readonly named: Dict; readonly blocks: Dict; - readonly hasDebugger: boolean; } export type LocalDebugType = keyof LocalDebugMap; diff --git a/packages/@glimmer/debug/lib/dism/opcode.ts b/packages/@glimmer/debug/lib/dism/opcode.ts index caf0222c47..840127e228 100644 --- a/packages/@glimmer/debug/lib/dism/opcode.ts +++ b/packages/@glimmer/debug/lib/dism/opcode.ts @@ -272,15 +272,12 @@ function describeProgramSymbolTable( ) { const debug = dev(classified.options.debug); - const hasDebugger = debug.hasDebugger - ? frag`(${as.kw('has debugger')})` - : frag`(${as.dim('no debugger')})`.subtle(); const keywords = labelledList('keywords', debug.keywords); const upvars = labelledList('upvars', debug.upvars); const atNames = labelledList('@-names', Object.keys(debug.named)); const blocks = labelledList('blocks', Object.keys(debug.blocks)); - const fields = join([hasDebugger, keywords, atNames, upvars, blocks], ' '); + const fields = join([keywords, atNames, upvars, blocks], ' '); const full = frag` ${value(debug, { ref: 'debug' })}`.subtle(); diff --git a/packages/@glimmer/debug/lib/opcode-metadata.ts b/packages/@glimmer/debug/lib/opcode-metadata.ts index 85df9827ec..1ca832e8d3 100644 --- a/packages/@glimmer/debug/lib/opcode-metadata.ts +++ b/packages/@glimmer/debug/lib/opcode-metadata.ts @@ -10,7 +10,6 @@ import { VM_APPEND_TEXT_OP, VM_ASSERT_SAME_OP, VM_BEGIN_COMPONENT_TRANSACTION_OP, - VM_BIND_DEBUGGER_SCOPE_OP, VM_BIND_DYNAMIC_SCOPE_OP, VM_CAPTURE_ARGS_OP, VM_CHILD_SCOPE_OP, @@ -94,7 +93,6 @@ import { VM_SET_BLOCKS_OP, VM_SET_NAMED_VARIABLES_OP, VM_SET_VARIABLE_OP, - VM_SETUP_FOR_DEBUGGER_OP, VM_SPREAD_BLOCK_OP, VM_STATIC_ATTR_OP, VM_SYSCALL_SIZE, @@ -693,20 +691,6 @@ if (LOCAL_DEBUG) { ops: ['state:register'], }; - METADATA[VM_BIND_DEBUGGER_SCOPE_OP] = { - name: 'BindDebuggerScope', - mnemonic: 'debugger_scope', - stackChange: 0, - ops: ['state:register'], - }; - - METADATA[VM_SETUP_FOR_DEBUGGER_OP] = { - name: 'SetupForDebugger', - mnemonic: 'debugger_setup', - stackChange: 0, - ops: ['state:register'], - }; - METADATA[VM_POPULATE_LAYOUT_OP] = { name: 'PopulateLayout', mnemonic: 'comp_layoutput', @@ -751,6 +735,6 @@ if (LOCAL_DEBUG) { name: 'Debugger', mnemonic: 'debugger', stackChange: 0, - ops: ['symbols:const/any', 'debugInfo:const/i32[]'], + ops: ['symbols:const/any'], }; } diff --git a/packages/@glimmer/debug/lib/stack-check.ts b/packages/@glimmer/debug/lib/stack-check.ts index 4300065e5c..27f53278cb 100644 --- a/packages/@glimmer/debug/lib/stack-check.ts +++ b/packages/@glimmer/debug/lib/stack-check.ts @@ -511,7 +511,6 @@ export const CheckBlockSymbolTable: Checker = LOCAL_DEBUG export const CheckProgramSymbolTable: Checker = LOCAL_DEBUG ? CheckInterface({ - hasDebugger: CheckBoolean, symbols: CheckArray(CheckString), }) : new NoopChecker(); diff --git a/packages/@glimmer/interfaces/lib/compile/operands.d.ts b/packages/@glimmer/interfaces/lib/compile/operands.d.ts index e7c359da04..36e491371a 100644 --- a/packages/@glimmer/interfaces/lib/compile/operands.d.ts +++ b/packages/@glimmer/interfaces/lib/compile/operands.d.ts @@ -33,7 +33,11 @@ export interface IsStrictModeOperand { export interface DebugSymbolsOperand { type: DebugSymbolsOperandType; - value: undefined; + value: { + locals: Record; + upvars: Record; + lexical: Record; + }; } export interface BlockOperand { diff --git a/packages/@glimmer/interfaces/lib/compile/wire-format/api.d.ts b/packages/@glimmer/interfaces/lib/compile/wire-format/api.d.ts index b30d38d35c..6db2138eb8 100644 --- a/packages/@glimmer/interfaces/lib/compile/wire-format/api.d.ts +++ b/packages/@glimmer/interfaces/lib/compile/wire-format/api.d.ts @@ -72,6 +72,8 @@ export type SexpOpcode = keyof SexpOpcodeMap; export namespace Core { export type Expression = Expressions.Expression; + export type DebugSymbols = [locals: Record, upvars: Record]; + export type CallArgs = [Params, Hash]; export type Path = [string, ...string[]]; export type ConcatParams = PresentArray; @@ -80,10 +82,9 @@ export namespace Core { export type Blocks = Nullable<[string[], SerializedInlineBlock[]]>; export type Args = [Params, Hash]; export type NamedBlock = [string, SerializedInlineBlock]; - export type DebugInfo = number[]; export type ElementParameters = Nullable>; - export type Syntax = Path | Params | ConcatParams | Hash | Blocks | Args | DebugInfo; + export type Syntax = Path | Params | ConcatParams | Hash | Blocks | Args; } export type CoreSyntax = Core.Syntax; @@ -254,7 +255,12 @@ export namespace Statements { | TrustingDynamicAttr | TrustingComponentAttr; - export type Debugger = [DebuggerOpcode, Core.DebugInfo]; + export type Debugger = [ + op: DebuggerOpcode, + locals: Record, + upvars: Record, + lexical: Record, + ]; export type InElement = [ op: InElementOpcode, block: SerializedInlineBlock, @@ -366,7 +372,6 @@ export type SerializedInlineBlock = [statements: Statements.Statement[], paramet export type SerializedTemplateBlock = [ statements: Statements.Statement[], locals: string[], - hasDebugger: boolean, upvars: string[], lexicalSymbols?: string[], ]; diff --git a/packages/@glimmer/interfaces/lib/runtime/scope.d.ts b/packages/@glimmer/interfaces/lib/runtime/scope.d.ts index 825aec0737..86966d8ac3 100644 --- a/packages/@glimmer/interfaces/lib/runtime/scope.d.ts +++ b/packages/@glimmer/interfaces/lib/runtime/scope.d.ts @@ -1,4 +1,4 @@ -import type { Dict, Nullable } from '../core.js'; +import type { Nullable } from '../core.js'; import type { Reference } from '../references.js'; import type { CompilableBlock } from '../template.js'; import type { BlockSymbolTable } from '../tier1/symbol-table.js'; @@ -25,8 +25,6 @@ export interface Scope { getSelf(): Reference; getSymbol(symbol: number): Reference; getBlock(symbol: number): Nullable; - getDebuggerScope(): Nullable>; - bindDebuggerScope(map: Nullable>): void; bind(symbol: number, value: ScopeSlot): void; bindSelf(self: Reference): void; bindSymbol(symbol: number, value: Reference): void; diff --git a/packages/@glimmer/interfaces/lib/template.d.ts b/packages/@glimmer/interfaces/lib/template.d.ts index ddbb0336b6..35a8afd6a1 100644 --- a/packages/@glimmer/interfaces/lib/template.d.ts +++ b/packages/@glimmer/interfaces/lib/template.d.ts @@ -110,11 +110,16 @@ export interface BlockSymbolNames { upvars: Nullable; } +export interface DebuggerInfo { + locals: Record; + lexical: Record; + upvars: Record; +} + export interface BlockMetadata { symbols: BlockSymbolNames; scopeValues: unknown[] | null; isStrictMode: boolean; - hasDebugger: boolean; moduleName: string; owner: Owner | null; size: number; diff --git a/packages/@glimmer/interfaces/lib/tier1/symbol-table.d.ts b/packages/@glimmer/interfaces/lib/tier1/symbol-table.d.ts index f81303b3cd..254896532c 100644 --- a/packages/@glimmer/interfaces/lib/tier1/symbol-table.d.ts +++ b/packages/@glimmer/interfaces/lib/tier1/symbol-table.d.ts @@ -1,5 +1,4 @@ export interface ProgramSymbolTable { - hasDebugger: boolean; symbols: string[]; } diff --git a/packages/@glimmer/interfaces/lib/vm-opcodes.d.ts b/packages/@glimmer/interfaces/lib/vm-opcodes.d.ts index c42c97f3cd..53058efcdd 100644 --- a/packages/@glimmer/interfaces/lib/vm-opcodes.d.ts +++ b/packages/@glimmer/interfaces/lib/vm-opcodes.d.ts @@ -96,8 +96,6 @@ export type VmPutComponentOperations = 89; export type VmGetComponentSelf = 90; export type VmGetComponentTagName = 91; export type VmGetComponentLayout = 92; -export type VmBindDebuggerScope = 93; -export type VmSetupForDebugger = 94; export type VmPopulateLayout = 95; export type VmInvokeComponentLayout = 96; export type VmBeginComponentTransaction = 97; @@ -193,8 +191,6 @@ export type VmOp = | VmGetComponentSelf | VmGetComponentTagName | VmGetComponentLayout - | VmBindDebuggerScope - | VmSetupForDebugger | VmPopulateLayout | VmInvokeComponentLayout | VmBeginComponentTransaction diff --git a/packages/@glimmer/opcode-compiler/lib/compilable-template.ts b/packages/@glimmer/opcode-compiler/lib/compilable-template.ts index f89b661191..06f15882d0 100644 --- a/packages/@glimmer/opcode-compiler/lib/compilable-template.ts +++ b/packages/@glimmer/opcode-compiler/lib/compilable-template.ts @@ -55,13 +55,12 @@ class CompilableTemplateImpl implements CompilableTemplat } export function compilable(layout: LayoutWithContext, moduleName: string): CompilableProgram { - let [statements, symbols, hasDebugger] = layout.block; + let [statements, symbols] = layout.block; return new CompilableTemplateImpl( statements, meta(layout), { symbols, - hasDebugger, }, moduleName ); diff --git a/packages/@glimmer/opcode-compiler/lib/opcode-builder/encoder.ts b/packages/@glimmer/opcode-compiler/lib/opcode-builder/encoder.ts index a6fd2cf488..0a9eb4c100 100644 --- a/packages/@glimmer/opcode-compiler/lib/opcode-builder/encoder.ts +++ b/packages/@glimmer/opcode-compiler/lib/opcode-builder/encoder.ts @@ -193,7 +193,7 @@ export class EncoderImpl implements Encoder { return encodeHandle(constants.value(this.meta.isStrictMode)); case HighLevelOperands.DebugSymbols: - return encodeHandle(constants.value(this.meta.symbols)); + return encodeHandle(constants.value(operand.value)); case HighLevelOperands.Block: return encodeHandle(constants.value(compilableBlock(operand.value, this.meta))); diff --git a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/components.ts b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/components.ts index f28e762078..067c6b8581 100644 --- a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/components.ts +++ b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/components.ts @@ -51,7 +51,6 @@ import { VM_SET_BLOCKS_OP, VM_SET_NAMED_VARIABLES_OP, VM_SET_VARIABLE_OP, - VM_SETUP_FOR_DEBUGGER_OP, VM_VIRTUAL_ROOT_SCOPE_OP, } from '@glimmer/constants'; import { unwrap } from '@glimmer/debug-util'; @@ -195,9 +194,7 @@ function InvokeStaticComponent( ): void { let { symbolTable } = layout; - let bailOut = - symbolTable.hasDebugger || - hasCapability(capabilities, InternalComponentCapabilities.prepareArgs); + let bailOut = hasCapability(capabilities, InternalComponentCapabilities.prepareArgs); if (bailOut) { InvokeNonStaticComponent(op, { @@ -464,7 +461,6 @@ export function invokePreparedComponent( op(VM_VIRTUAL_ROOT_SCOPE_OP, $s0); op(VM_SET_VARIABLE_OP, 0); - op(VM_SETUP_FOR_DEBUGGER_OP, $s0); if (bindableAtNames) op(VM_SET_NAMED_VARIABLES_OP, $s0); if (bindableBlocks) op(VM_SET_BLOCKS_OP, $s0); diff --git a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/shared.ts b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/shared.ts index fa8230f55d..7015d77527 100644 --- a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/shared.ts +++ b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/shared.ts @@ -106,7 +106,7 @@ export function CompilePositional( } export function meta(layout: LayoutWithContext): BlockMetadata { - let [, locals, hasDebugger, upvars, lexicalSymbols] = layout.block; + let [, locals, upvars, lexicalSymbols] = layout.block; return { symbols: { @@ -114,7 +114,6 @@ export function meta(layout: LayoutWithContext): BlockMetadata { upvars, lexical: lexicalSymbols, }, - hasDebugger, scopeValues: layout.scope?.() ?? null, isStrictMode: layout.isStrictMode, moduleName: layout.moduleName, @@ -122,10 +121,3 @@ export function meta(layout: LayoutWithContext): BlockMetadata { size: locals.length, }; } - -export function getDebuggerSymbols(layout: LayoutWithContext): Nullable { - let { block } = layout; - let [, symbols, hasDebugger] = block; - - return hasDebugger ? symbols : null; -} diff --git a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/stdlib.ts b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/stdlib.ts index 58d3747234..1f9ee02ecc 100644 --- a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/stdlib.ts +++ b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/stdlib.ts @@ -121,7 +121,6 @@ export const STDLIB_META: BlockMetadata = { locals: null, upvars: null, }, - hasDebugger: false, moduleName: 'stdlib', // TODO: ?? diff --git a/packages/@glimmer/opcode-compiler/lib/opcode-builder/operands.ts b/packages/@glimmer/opcode-compiler/lib/opcode-builder/operands.ts index a21481c552..4abfabf53b 100644 --- a/packages/@glimmer/opcode-compiler/lib/opcode-builder/operands.ts +++ b/packages/@glimmer/opcode-compiler/lib/opcode-builder/operands.ts @@ -38,8 +38,12 @@ export function labelOperand(value: string): LabelOperand { return { type: HighLevelOperands.Label, value }; } -export function debugSymbolsOperand(): DebugSymbolsOperand { - return { type: HighLevelOperands.DebugSymbols, value: undefined }; +export function debugSymbolsOperand( + locals: Record, + upvars: Record, + lexical: Record +): DebugSymbolsOperand { + return { type: HighLevelOperands.DebugSymbols, value: { locals, upvars, lexical } }; } export function isStrictMode(): IsStrictModeOperand { diff --git a/packages/@glimmer/opcode-compiler/lib/syntax/statements.ts b/packages/@glimmer/opcode-compiler/lib/syntax/statements.ts index f5d6b45824..300fd5bf36 100644 --- a/packages/@glimmer/opcode-compiler/lib/syntax/statements.ts +++ b/packages/@glimmer/opcode-compiler/lib/syntax/statements.ts @@ -163,9 +163,9 @@ STATEMENTS.add(SexpOpcodes.Yield, (op, [, to, params]) => YieldBlock(op, to, par STATEMENTS.add(SexpOpcodes.AttrSplat, (op, [, to]) => YieldBlock(op, to, null)); -STATEMENTS.add(SexpOpcodes.Debugger, (op, [, debugInfo]) => - op(VM_DEBUGGER_OP, debugSymbolsOperand(), debugInfo) -); +STATEMENTS.add(SexpOpcodes.Debugger, (op, [, locals, upvars, lexical]) => { + op(VM_DEBUGGER_OP, debugSymbolsOperand(locals, upvars, lexical)); +}); STATEMENTS.add(SexpOpcodes.Append, (op, [, value]) => { // Special case for static values diff --git a/packages/@glimmer/opcode-compiler/lib/wrapped-component.ts b/packages/@glimmer/opcode-compiler/lib/wrapped-component.ts index c400a8da18..733f50fe52 100644 --- a/packages/@glimmer/opcode-compiler/lib/wrapped-component.ts +++ b/packages/@glimmer/opcode-compiler/lib/wrapped-component.ts @@ -30,7 +30,7 @@ export class WrappedBuilder implements CompilableProgram { public moduleName: string ) { let { block } = layout; - let [, symbols, hasDebugger] = block; + let [, symbols] = block; symbols = symbols.slice(); @@ -43,7 +43,6 @@ export class WrappedBuilder implements CompilableProgram { } this.symbolTable = { - hasDebugger, symbols, }; diff --git a/packages/@glimmer/program/lib/util/default-template.ts b/packages/@glimmer/program/lib/util/default-template.ts index 5139be859c..2539b52f87 100644 --- a/packages/@glimmer/program/lib/util/default-template.ts +++ b/packages/@glimmer/program/lib/util/default-template.ts @@ -4,12 +4,7 @@ import { SexpOpcodes as op } from '@glimmer/wire-format'; /** * Default component template, which is a plain yield */ -const DEFAULT_TEMPLATE_BLOCK: SerializedTemplateBlock = [ - [[op.Yield, 1, null]], - ['&default'], - false, - [], -]; +const DEFAULT_TEMPLATE_BLOCK: SerializedTemplateBlock = [[[op.Yield, 1, null]], ['&default'], []]; export const DEFAULT_TEMPLATE: SerializedTemplateWithLazyBlock = { // random uuid diff --git a/packages/@glimmer/runtime/lib/compiled/opcodes/component.ts b/packages/@glimmer/runtime/lib/compiled/opcodes/component.ts index 2d9c099403..f3bd6efb20 100644 --- a/packages/@glimmer/runtime/lib/compiled/opcodes/component.ts +++ b/packages/@glimmer/runtime/lib/compiled/opcodes/component.ts @@ -51,7 +51,6 @@ import { VM_RESOLVE_DYNAMIC_COMPONENT_OP, VM_SET_BLOCKS_OP, VM_SET_NAMED_VARIABLES_OP, - VM_SETUP_FOR_DEBUGGER_OP, VM_STATIC_COMPONENT_ATTR_OP, VM_VIRTUAL_ROOT_SCOPE_OP, } from '@glimmer/constants'; @@ -840,15 +839,6 @@ APPEND_OPCODES.add(VM_VIRTUAL_ROOT_SCOPE_OP, (vm, { op1: register }) => { vm.pushRootScope(table.symbols.length + 1, owner); }); -APPEND_OPCODES.add(VM_SETUP_FOR_DEBUGGER_OP, (vm, { op1: register }) => { - let state = check(vm.fetchValue(check(register, CheckRegister)), CheckFinishedComponentInstance); - - if (state.table.hasDebugger) { - let lookup = (state.lookup = dict()); - vm.scope().bindDebuggerScope(lookup); - } -}); - APPEND_OPCODES.add(VM_SET_NAMED_VARIABLES_OP, (vm, { op1: register }) => { let state = check(vm.fetchValue(check(register, CheckRegister)), CheckFinishedComponentInstance); let scope = vm.scope(); diff --git a/packages/@glimmer/runtime/lib/compiled/opcodes/debugger.ts b/packages/@glimmer/runtime/lib/compiled/opcodes/debugger.ts index 60351cf137..ce0a167d82 100644 --- a/packages/@glimmer/runtime/lib/compiled/opcodes/debugger.ts +++ b/packages/@glimmer/runtime/lib/compiled/opcodes/debugger.ts @@ -1,9 +1,8 @@ -import type { BlockSymbolNames, Scope } from '@glimmer/interfaces'; +import type { DebuggerInfo, Scope } from '@glimmer/interfaces'; import type { Reference } from '@glimmer/reference'; import { decodeHandle, VM_DEBUGGER_OP } from '@glimmer/constants'; import { unwrap } from '@glimmer/debug-util'; import { childRefFor, valueForRef } from '@glimmer/reference'; -import { dict } from '@glimmer/util'; import { APPEND_OPCODES } from '../../opcodes'; @@ -34,34 +33,28 @@ export function resetDebuggerCallback() { } class ScopeInspector { - private locals = dict(); + #symbols: DebuggerInfo; constructor( private scope: Scope, - symbols: BlockSymbolNames, - debugInfo: number[] + symbols: DebuggerInfo ) { - for (const slot of debugInfo) { - let name = unwrap(symbols.locals?.[slot - 1]); - let ref = scope.getSymbol(slot); - this.locals[name] = ref; - } + this.#symbols = symbols; } get(path: string): Reference { - let { scope, locals } = this; + let { scope } = this; + let symbols = this.#symbols; + let parts = path.split('.'); let [head, ...tail] = path.split('.') as [string, ...string[]]; - let debuggerScope = scope.getDebuggerScope()!; let ref: Reference; if (head === 'this') { ref = scope.getSelf(); - } else if (locals[head]) { - ref = unwrap(locals[head]); - } else if (head.indexOf('@') === 0 && debuggerScope[head]) { - ref = debuggerScope[head] as Reference; + } else if (symbols.locals[head]) { + ref = unwrap(scope.getSymbol(symbols.locals[head]!)); } else { ref = this.scope.getSelf(); tail = parts; @@ -71,9 +64,8 @@ class ScopeInspector { } } -APPEND_OPCODES.add(VM_DEBUGGER_OP, (vm, { op1: _symbols, op2: _debugInfo }) => { - let symbols = vm.constants.getValue(_symbols); - let debugInfo = vm.constants.getArray(decodeHandle(_debugInfo)); - let inspector = new ScopeInspector(vm.scope(), symbols, debugInfo); +APPEND_OPCODES.add(VM_DEBUGGER_OP, (vm, { op1: _debugInfo }) => { + let debuggerInfo = vm.constants.getValue(decodeHandle(_debugInfo)); + let inspector = new ScopeInspector(vm.scope(), debuggerInfo); callback(valueForRef(vm.getSelf()), (path) => valueForRef(inspector.get(path))); }); diff --git a/packages/@glimmer/runtime/lib/scope.ts b/packages/@glimmer/runtime/lib/scope.ts index 928a3f4205..6c9d8441c8 100644 --- a/packages/@glimmer/runtime/lib/scope.ts +++ b/packages/@glimmer/runtime/lib/scope.ts @@ -52,34 +52,30 @@ export class ScopeImpl implements Scope { static root(owner: Owner, { self, size = 0 }: ScopeOptions): Scope { let refs: Reference[] = new Array(size + 1).fill(UNDEFINED_REFERENCE); - return new ScopeImpl(owner, refs, null, null).init({ self }); + return new ScopeImpl(owner, refs, null).init({ self }); } static sized(owner: Owner, size = 0): Scope { let refs: Reference[] = new Array(size + 1).fill(UNDEFINED_REFERENCE); - return new ScopeImpl(owner, refs, null, null); + return new ScopeImpl(owner, refs, null); } readonly owner: Owner; private slots: ScopeSlot[]; - private callerScope: Scope | null; - private debuggerScope: Dict | null; + private callerScope: Nullable; constructor( owner: Owner, // the 0th slot is `self` slots: Array, // a single program can mix owners via curried components, and the state lives on root scopes - callerScope: Scope | null, - // named arguments and blocks passed to a layout that uses eval - debuggerScope: Dict | null + callerScope: Nullable ) { this.owner = owner; this.slots = slots; this.callerScope = callerScope; - this.debuggerScope = debuggerScope; } init({ self }: { self: Reference }): this { @@ -107,10 +103,6 @@ export class ScopeImpl implements Scope { return block === UNDEFINED_REFERENCE ? null : (block as ScopeBlock); } - getDebuggerScope(): Nullable> { - return this.debuggerScope; - } - bind(symbol: number, value: ScopeSlot) { this.set(symbol, value); } @@ -127,10 +119,6 @@ export class ScopeImpl implements Scope { this.set>(symbol, value); } - bindDebuggerScope(map: Nullable>) { - this.debuggerScope = map; - } - bindCallerScope(scope: Nullable): void { this.callerScope = scope; } @@ -140,7 +128,7 @@ export class ScopeImpl implements Scope { } child(): Scope { - return new ScopeImpl(this.owner, this.slots.slice(), this.callerScope, this.debuggerScope); + return new ScopeImpl(this.owner, this.slots.slice(), this.callerScope); } private get(index: number): T { diff --git a/packages/@glimmer/syntax/lib/symbol-table.ts b/packages/@glimmer/syntax/lib/symbol-table.ts index 286f8c0258..714b355168 100644 --- a/packages/@glimmer/syntax/lib/symbol-table.ts +++ b/packages/@glimmer/syntax/lib/symbol-table.ts @@ -24,6 +24,8 @@ export abstract class SymbolTable { return new ProgramSymbolTable(locals, keywords, options); } + abstract root(): ProgramSymbolTable; + abstract has(name: string): boolean; abstract get(name: string): [symbol: number, isRoot: boolean]; @@ -33,8 +35,7 @@ export abstract class SymbolTable { abstract hasLexical(name: string): boolean; abstract getLocalsMap(): Dict; - abstract getDebugInfo(): Core.DebugInfo; - abstract setHasDebugger(): void; + abstract getDebugInfo(): Core.DebugSymbols; abstract allocateFree(name: string, resolution: ASTv2.FreeVarResolution): number; abstract allocateNamed(name: string): number; @@ -63,20 +64,21 @@ export class ProgramSymbolTable extends SymbolTable { upvars: this.upvars, named: this.named, blocks: this.blocks, - hasDebugger: this.hasDebugger, }), }); } - public symbols: string[] = []; - public upvars: string[] = []; + readonly symbols: string[] = []; + readonly upvars: string[] = []; private size = 1; - private named = dict(); - private blocks = dict(); - private usedTemplateLocals: string[] = []; + readonly named = dict(); + readonly blocks = dict(); + readonly usedTemplateLocals: string[] = []; - #hasDebugger = false; + root(): ProgramSymbolTable { + return this; + } hasLexical(name: string): boolean { return this.options.lexicalScope(name); @@ -94,14 +96,6 @@ export class ProgramSymbolTable extends SymbolTable { return this.usedTemplateLocals; } - setHasDebugger(): void { - this.#hasDebugger = true; - } - - get hasDebugger(): boolean { - return this.#hasDebugger; - } - has(name: string): boolean { return this.templateLocals.includes(name); } @@ -122,8 +116,8 @@ export class ProgramSymbolTable extends SymbolTable { return dict(); } - getDebugInfo(): Core.DebugInfo { - return Object.values(this.getLocalsMap()); + getDebugInfo(): Core.DebugSymbols { + return [this.getLocalsMap(), this.named]; } allocateFree(name: string, resolution: ASTv2.FreeVarResolution): number { @@ -186,6 +180,10 @@ export class BlockSymbolTable extends SymbolTable { super(); } + root(): ProgramSymbolTable { + return this.parent.root(); + } + get locals(): string[] { return this.symbols; } @@ -222,12 +220,12 @@ export class BlockSymbolTable extends SymbolTable { return dict; } - getDebugInfo(): Core.DebugInfo { - return Object.values(this.getLocalsMap()); - } + getDebugInfo(): [locals: Record, upvars: Record] { + const locals = this.getLocalsMap(); + const root = this.root(); + const named = root.named; - setHasDebugger(): void { - this.parent.setHasDebugger(); + return [{ ...locals, ...named }, Object.fromEntries(root.upvars.map((s, i) => [s, i]))]; } allocateFree(name: string, resolution: ASTv2.FreeVarResolution): number {