From 3768842373487f4b4e9fd651827de80b72889be0 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Wed, 11 Sep 2024 16:59:57 +0100 Subject: [PATCH] Fix production stripping in the production bundles (#1606) * Fix prod stripping * WIP - put utilities to be stripped in their own package, so we can inline the package * WIP: it turns out terser can't do what we want so we have to do a custom babel plugin... * Revert "WIP: it turns out terser can't do what we want so we have to do a custom babel plugin..." This reverts commit 5cddba2b0a4616350ba4d9da572863e77cad0ffe. * Revert "WIP - put utilities to be stripped in their own package, so we can inline the package" This reverts commit 57406f687a7991b8b35c907b1e7483bb40a4d521. * Add babel plugin that removes code from @glimmer/debug that terser couldn't figure out -- I also left some notes about the problem that terser is running in to -- it seems to be related to indirection of identity functions that 'passes' isn't smart enough to figure out We get big wins (side-wise) from sideEffects: false, but things break. This babel plugin is feeling more and more brittle, the more we want to strip. * Inline glimmer-debug and hide all the metadata * Convert more of the Checkers to the NoopChecker * Tell the Tests how to handle VM_LOCAL_DEV --- package.json | 4 +- packages/@glimmer-workspace/build/index.d.ts | 1 - packages/@glimmer-workspace/build/index.js | 1 - .../@glimmer-workspace/build/lib/config.js | 58 +- .../build/lib/import-meta.d.ts | 4 - .../build/lib/import-meta.js | 23 - .../@glimmer-workspace/build/package.json | 1 + packages/@glimmer/debug/index.ts | 54 +- .../@glimmer/debug/lib/opcode-metadata.ts | 2636 +++++++++-------- packages/@glimmer/debug/lib/stack-check.ts | 147 +- packages/@glimmer/debug/package.json | 1 + .../local-debug-babel-plugin/index.js | 110 + .../local-debug-babel-plugin/package.json | 13 + pnpm-lock.yaml | 177 +- vite.config.mts | 17 +- 15 files changed, 1697 insertions(+), 1550 deletions(-) delete mode 100644 packages/@glimmer-workspace/build/lib/import-meta.d.ts delete mode 100644 packages/@glimmer-workspace/build/lib/import-meta.js create mode 100644 packages/@glimmer/local-debug-babel-plugin/index.js create mode 100644 packages/@glimmer/local-debug-babel-plugin/package.json diff --git a/package.json b/package.json index 3ae7238df0..42de12a8e9 100644 --- a/package.json +++ b/package.json @@ -20,14 +20,14 @@ "build": "dotenv -- turbo build", "build:control": "rollup -c rollup.config.mjs", "build:flags": "RETAIN_FLAGS=true ember build --env production --suppress-sizes", - "link:all": "esyes ./bin/link-all.mts", "clean": "node ./bin/clean.mjs", + "link:all": "esyes ./bin/link-all.mts", "lint": "npm-run-all lint:*", "lint:files": "turbo lint", "lint:format": "prettier -c .", "lint:types": "tsc -b", "lintfix": "pnpm turbo test:lint -- --fix && prettier -w .", - "start": "ember serve --port=7357", + "start": "vite", "test": "node bin/run-tests.mjs", "test:babel-plugins": "yarn workspace @glimmer/vm-babel-plugins test", "test:browserstack": "ember test --test-port=7774 --host 127.0.0.1 --config-file=testem-browserstack.js", diff --git a/packages/@glimmer-workspace/build/index.d.ts b/packages/@glimmer-workspace/build/index.d.ts index 8442f97f0b..1315026703 100644 --- a/packages/@glimmer-workspace/build/index.d.ts +++ b/packages/@glimmer-workspace/build/index.d.ts @@ -4,4 +4,3 @@ export { type PackageJSON, type ViteConfig as ViteExport, } from './lib/config.js'; -export { default as importMeta } from './lib/import-meta.js'; diff --git a/packages/@glimmer-workspace/build/index.js b/packages/@glimmer-workspace/build/index.js index 480f7fba41..b16a2c80cf 100644 --- a/packages/@glimmer-workspace/build/index.js +++ b/packages/@glimmer-workspace/build/index.js @@ -1,3 +1,2 @@ export { Package } from './lib/config.js'; -export { default as importMeta } from './lib/import-meta.js'; export { default as inline } from './lib/inline.js'; diff --git a/packages/@glimmer-workspace/build/lib/config.js b/packages/@glimmer-workspace/build/lib/config.js index 316790b915..07945878ba 100644 --- a/packages/@glimmer-workspace/build/lib/config.js +++ b/packages/@glimmer-workspace/build/lib/config.js @@ -1,7 +1,7 @@ /* eslint-disable no-console */ // @ts-check - import { existsSync, readFileSync } from 'node:fs'; +import { createRequire } from 'node:module'; import { dirname, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; @@ -11,9 +11,10 @@ import * as insert from 'rollup-plugin-insert'; import rollupTS from 'rollup-plugin-ts'; import ts from 'typescript'; -import importMeta from './import-meta.js'; import inline from './inline.js'; +const require = createRequire(import.meta.url); + // eslint-disable-next-line import/no-named-as-default-member const { ModuleKind, ModuleResolutionKind, ScriptTarget, ImportsNotUsedAsValues } = ts; @@ -96,7 +97,10 @@ export function typescript(pkg, config) { return rollupTS({ transpiler: 'babel', transpileOnly: true, - babelConfig: { presets }, + babelConfig: { + presets, + plugins: [require.resolve('@glimmer/local-debug-babel-plugin')], + }, /** * This shouldn't be required, but it is. * If we use @rollup/plugin-babel, we can remove this. @@ -108,7 +112,7 @@ export function typescript(pkg, config) { /** @type {['is' | 'startsWith', string[], 'inline' | 'external'][]} */ const EXTERNAL_OPTIONS = [ - ['is', ['tslib', '@glimmer/local-debug-flags'], 'inline'], + ['is', ['tslib', '@glimmer/local-debug-flags', '@glimmer/debug'], 'inline'], ['is', ['@handlebars/parser', 'simple-html-tokenizer', 'babel-plugin-debug-macros'], 'external'], ['startsWith', ['.', '/', '#', '@babel/runtime/', process.cwd().replace(/\\/gu, '/')], 'inline'], ['startsWith', ['@glimmer/', '@simple-dom/', '@babel/', 'node:'], 'external'], @@ -315,7 +319,31 @@ export class Package { commonjs(), nodeResolve(), ...this.replacements(env), - ...(env === 'prod' ? [terser()] : []), + ...(env === 'prod' + ? [ + terser({ + module: true, + // to debug the output, uncomment this so you can read the + // identifiers, unchanged + // mangle: false, + compress: { + passes: 3, + }, + }), + ] + : [ + terser({ + module: true, + mangle: false, + compress: { + passes: 3, + }, + format: { + comments: 'all', + beautify: true, + }, + }), + ]), postcss(), typescript(this.#package, { target: ScriptTarget.ES2022, @@ -356,7 +384,20 @@ export class Package { */ replacements(env) { return env === 'prod' - ? [importMeta] + ? [ + replace({ + preventAssignment: true, + values: { + // Intended to be left in the build during publish + // currently compiled away to `@glimmer/debug` + 'import.meta.env.MODE': '"production"', + 'import.meta.env.DEV': 'false', + 'import.meta.env.PROD': 'true', + // Not exposed at publish, compiled away + 'import.meta.env.VM_LOCAL_DEV': 'false', + }, + }), + ] : [ replace({ preventAssignment: true, @@ -417,10 +458,15 @@ export class Package { return { input: resolve(root, ts), + treeshake: { + // moduleSideEffects: false, + moduleSideEffects: (id, external) => !external, + }, output: { file: resolve(root, 'dist', env, file), format, sourcemap: true, + hoistTransitiveImports: false, exports: format === 'cjs' ? 'named' : 'auto', }, onwarn: (warning, warn) => { diff --git a/packages/@glimmer-workspace/build/lib/import-meta.d.ts b/packages/@glimmer-workspace/build/lib/import-meta.d.ts deleted file mode 100644 index ecf41190e4..0000000000 --- a/packages/@glimmer-workspace/build/lib/import-meta.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/consistent-type-imports -declare const DEFAULT: import('rollup').Plugin; - -export default DEFAULT; diff --git a/packages/@glimmer-workspace/build/lib/import-meta.js b/packages/@glimmer-workspace/build/lib/import-meta.js deleted file mode 100644 index 922271f533..0000000000 --- a/packages/@glimmer-workspace/build/lib/import-meta.js +++ /dev/null @@ -1,23 +0,0 @@ -/// - -import { createReplacePlugin } from './replace.js'; - -const MODE = process.env['MODE'] ?? 'development'; -const DEV = MODE === 'development'; -const PROD = MODE === 'production'; -const STARBEAM_TRACE = process.env['STARBEAM_TRACE'] ?? false; - -export default createReplacePlugin( - (id) => /\.[jt]sx?$/u.test(id), - { - // Intended to be left in the build during publish - // currently compiled away to `@glimmer/debug` - 'import.meta.env.MODE': process.env['MODE'] ?? 'development', - 'import.meta.env.DEV': DEV ? 'true' : 'false', - 'import.meta.env.PROD': PROD ? 'true' : 'false', - // Not exposed at publish, compiled away - 'import.meta.env.VM_LOCAL_DEV': DEV ? 'true' : 'false', - 'import.meta.env.STARBEAM_TRACE': STARBEAM_TRACE ? 'true' : 'false', - }, - true -); diff --git a/packages/@glimmer-workspace/build/package.json b/packages/@glimmer-workspace/build/package.json index 3dd515f7c6..8705cec9ca 100644 --- a/packages/@glimmer-workspace/build/package.json +++ b/packages/@glimmer-workspace/build/package.json @@ -13,6 +13,7 @@ "test:types": "tsc --noEmit -p ../tsconfig.json" }, "dependencies": { + "@glimmer/local-debug-babel-plugin": "workspace:*", "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-replace": "^5.0.5", diff --git a/packages/@glimmer/debug/index.ts b/packages/@glimmer/debug/index.ts index b05cc97099..d8aa97aa18 100644 --- a/packages/@glimmer/debug/index.ts +++ b/packages/@glimmer/debug/index.ts @@ -1,4 +1,54 @@ export { debug, debugSlice, logOpcode } from './lib/debug'; -export * from './lib/metadata'; +export { + buildEnum, + buildMetas, + buildSingleMeta, + META_KIND, + normalize, + normalizeAll, + normalizeParsed, + OPERAND_TYPES, + strip, +} from './lib/metadata'; export { opcodeMetadata } from './lib/opcode-metadata'; -export * from './lib/stack-check'; +export { + check, + CheckArray, + CheckBlockSymbolTable, + CheckBoolean, + CheckDict, + CheckDocumentFragment, + CheckElement, + CheckFunction, + CheckHandle, + CheckInstanceof, + CheckInterface, + CheckMaybe, + CheckNode, + CheckNumber, + CheckObject, + CheckOption, + CheckOr, + CheckPrimitive, + CheckProgramSymbolTable, + CheckSafeString, + CheckString, + CheckUndefined, + CheckUnknown, + recordStackSize, + wrap, +} from './lib/stack-check'; + +// Types are optimized await automatically +export type { + NormalizedMetadata, + NormalizedOpcodes, + Operand, + OperandList, + OperandName, + OperandType, + RawOperandFormat, + RawOperandMetadata, + Stack, +} from './lib/metadata'; +export type { Checker } from './lib/stack-check'; diff --git a/packages/@glimmer/debug/lib/opcode-metadata.ts b/packages/@glimmer/debug/lib/opcode-metadata.ts index c559bf57d3..a05c52d149 100644 --- a/packages/@glimmer/debug/lib/opcode-metadata.ts +++ b/packages/@glimmer/debug/lib/opcode-metadata.ts @@ -1,6 +1,7 @@ /* This file is generated by build/debug.js */ import type { Nullable, VmMachineOp, VmOp } from '@glimmer/interfaces'; +import { LOCAL_DEBUG } from '@glimmer/local-debug-flags'; import { MachineOp, Op } from '@glimmer/vm'; import type { NormalizedMetadata } from './metadata'; @@ -9,6 +10,10 @@ export function opcodeMetadata( op: VmMachineOp | VmOp, isMachine: 0 | 1 ): Nullable { + if (!LOCAL_DEBUG) { + return null; + } + let value = isMachine ? MACHINE_METADATA[op] : METADATA[op]; return value || null; @@ -16,1317 +21,1320 @@ export function opcodeMetadata( const METADATA: Nullable[] = new Array(Op.Size).fill(null); const MACHINE_METADATA: Nullable[] = new Array(Op.Size).fill(null); -MACHINE_METADATA[MachineOp.PushFrame] = { - name: 'PushFrame', - mnemonic: 'pushf', - before: null, - stackChange: 2, - ops: [], - operands: 0, - check: true, -}; - -MACHINE_METADATA[MachineOp.PopFrame] = { - name: 'PopFrame', - mnemonic: 'popf', - before: null, - stackChange: -2, - ops: [], - operands: 0, - check: false, -}; - -MACHINE_METADATA[MachineOp.InvokeVirtual] = { - name: 'InvokeVirtual', - mnemonic: 'vcall', - before: null, - stackChange: -1, - ops: [], - operands: 0, - check: true, -}; - -MACHINE_METADATA[MachineOp.InvokeStatic] = { - name: 'InvokeStatic', - mnemonic: 'scall', - before: null, - stackChange: 0, - ops: [ - { - name: 'offset', - type: 'u32', - }, - ], - operands: 1, - check: true, -}; - -MACHINE_METADATA[MachineOp.Jump] = { - name: 'Jump', - mnemonic: 'goto', - before: null, - stackChange: 0, - ops: [ - { - name: 'to', - type: 'u32', - }, - ], - operands: 1, - check: true, -}; - -MACHINE_METADATA[MachineOp.Return] = { - name: 'Return', - mnemonic: 'ret', - before: null, - stackChange: 0, - ops: [], - operands: 0, - check: false, -}; - -MACHINE_METADATA[MachineOp.ReturnTo] = { - name: 'ReturnTo', - mnemonic: 'setra', - before: null, - stackChange: 0, - ops: [ - { - name: 'offset', - type: 'i32', - }, - ], - operands: 1, - check: true, -}; -METADATA[Op.Helper] = { - name: 'Helper', - mnemonic: 'ncall', - before: null, - stackChange: null, - ops: [ - { - name: 'helper', - type: 'handle', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.DynamicHelper] = { - name: 'DynamicHelper', - mnemonic: 'dynamiccall', - before: null, - stackChange: null, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.SetNamedVariables] = { - name: 'SetNamedVariables', - mnemonic: 'vsargs', - before: null, - stackChange: 0, - ops: [ - { - name: 'register', - type: 'u32', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.SetBlocks] = { - name: 'SetBlocks', - mnemonic: 'vbblocks', - before: null, - stackChange: 0, - ops: [ - { - name: 'register', - type: 'u32', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.SetVariable] = { - name: 'SetVariable', - mnemonic: 'sbvar', - before: null, - stackChange: -1, - ops: [ - { - name: 'symbol', - type: 'u32', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.SetBlock] = { - name: 'SetBlock', - mnemonic: 'sblock', - before: null, - stackChange: -3, - ops: [ - { - name: 'symbol', - type: 'u32', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.GetVariable] = { - name: 'GetVariable', - mnemonic: 'symload', - before: null, - stackChange: 1, - ops: [ - { - name: 'symbol', - type: 'u32', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.GetProperty] = { - name: 'GetProperty', - mnemonic: 'getprop', - before: null, - stackChange: 0, - ops: [ - { - name: 'property', - type: 'str', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.GetBlock] = { - name: 'GetBlock', - mnemonic: 'blockload', - before: null, - stackChange: 1, - ops: [ - { - name: 'block', - type: 'u32', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.SpreadBlock] = { - name: 'SpreadBlock', - mnemonic: 'blockspread', - before: null, - stackChange: 2, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.HasBlock] = { - name: 'HasBlock', - mnemonic: 'hasblockload', - before: null, - stackChange: 0, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.HasBlockParams] = { - name: 'HasBlockParams', - mnemonic: 'hasparamsload', - before: null, - stackChange: -2, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.Concat] = { - name: 'Concat', - mnemonic: 'concat', - before: null, - stackChange: null, - ops: [ - { - name: 'count', - type: 'u32', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.IfInline] = { - name: 'IfInline', - mnemonic: 'ifinline', - before: null, - stackChange: -2, - ops: [ - { - name: 'count', - type: 'u32', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.Not] = { - name: 'Not', - mnemonic: 'not', - before: null, - stackChange: 0, - ops: [ - { - name: 'count', - type: 'u32', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.Constant] = { - name: 'Constant', - mnemonic: 'rconstload', - before: null, - stackChange: 1, - ops: [ - { - name: 'constant', - type: 'unknown', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.ConstantReference] = { - name: 'ConstantReference', - mnemonic: 'rconstrefload', - before: null, - stackChange: 1, - ops: [ - { - name: 'constant', - type: 'unknown', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.Primitive] = { - name: 'Primitive', - mnemonic: 'pconstload', - before: null, - stackChange: 1, - ops: [ - { - name: 'constant', - type: 'primitive', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.PrimitiveReference] = { - name: 'PrimitiveReference', - mnemonic: 'ptoref', - before: null, - stackChange: 0, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.ReifyU32] = { - name: 'ReifyU32', - mnemonic: 'reifyload', - before: null, - stackChange: 1, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.Dup] = { - name: 'Dup', - mnemonic: 'dup', - before: null, - stackChange: 1, - ops: [ - { - name: 'register', - type: 'u32', - }, - { - name: 'offset', - type: 'u32', - }, - ], - operands: 2, - check: true, -}; - -METADATA[Op.Pop] = { - name: 'Pop', - mnemonic: 'pop', - before: null, - stackChange: 0, - ops: [ - { - name: 'count', - type: 'u32', - }, - ], - operands: 1, - check: false, -}; - -METADATA[Op.Load] = { - name: 'Load', - mnemonic: 'put', - before: null, - stackChange: -1, - ops: [ - { - name: 'register', - type: 'u32', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.Fetch] = { - name: 'Fetch', - mnemonic: 'regload', - before: null, - stackChange: 1, - ops: [ - { - name: 'register', - type: 'u32', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.RootScope] = { - name: 'RootScope', - mnemonic: 'rscopepush', - before: null, - stackChange: 0, - ops: [ - { - name: 'symbols', - type: 'u32', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.VirtualRootScope] = { - name: 'VirtualRootScope', - mnemonic: 'vrscopepush', - before: null, - stackChange: 0, - ops: [ - { - name: 'register', - type: 'u32', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.ChildScope] = { - name: 'ChildScope', - mnemonic: 'cscopepush', - before: null, - stackChange: 0, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.PopScope] = { - name: 'PopScope', - mnemonic: 'scopepop', - before: null, - stackChange: 0, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.Text] = { - name: 'Text', - mnemonic: 'apnd_text', - before: null, - stackChange: 0, - ops: [ - { - name: 'contents', - type: 'str', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.Comment] = { - name: 'Comment', - mnemonic: 'apnd_comment', - before: null, - stackChange: 0, - ops: [ - { - name: 'contents', - type: 'str', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.AppendHTML] = { - name: 'AppendHTML', - mnemonic: 'apnd_dynhtml', - before: null, - stackChange: -1, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.AppendSafeHTML] = { - name: 'AppendSafeHTML', - mnemonic: 'apnd_dynshtml', - before: null, - stackChange: -1, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.AppendDocumentFragment] = { - name: 'AppendDocumentFragment', - mnemonic: 'apnd_dynfrag', - before: null, - stackChange: -1, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.AppendNode] = { - name: 'AppendNode', - mnemonic: 'apnd_dynnode', - before: null, - stackChange: -1, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.AppendText] = { - name: 'AppendText', - mnemonic: 'apnd_dyntext', - before: null, - stackChange: -1, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.OpenElement] = { - name: 'OpenElement', - mnemonic: 'apnd_tag', - before: null, - stackChange: 0, - ops: [ - { - name: 'tag', - type: 'str', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.OpenDynamicElement] = { - name: 'OpenDynamicElement', - mnemonic: 'apnd_dyntag', - before: null, - stackChange: -1, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.PushRemoteElement] = { - name: 'PushRemoteElement', - mnemonic: 'apnd_remotetag', - before: null, - stackChange: -3, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.StaticAttr] = { - name: 'StaticAttr', - mnemonic: 'apnd_attr', - before: null, - stackChange: 0, - ops: [ - { - name: 'name', - type: 'str', - }, - { - name: 'value', - type: 'str', - }, - { - name: 'namespace', - type: 'option-str', - }, - ], - operands: 3, - check: true, -}; - -METADATA[Op.DynamicAttr] = { - name: 'DynamicAttr', - mnemonic: 'apnd_dynattr', - before: null, - stackChange: -1, - ops: [ - { - name: 'name', - type: 'str', - }, - { - name: 'trusting', - type: 'bool', - }, - { - name: 'namespace', - type: 'option-str', - }, - ], - operands: 3, - check: true, -}; - -METADATA[Op.ComponentAttr] = { - name: 'ComponentAttr', - mnemonic: 'apnd_cattr', - before: null, - stackChange: -1, - ops: [ - { - name: 'name', - type: 'str', - }, - { - name: 'trusting', - type: 'bool', - }, - { - name: 'namespace', - type: 'option-str', - }, - ], - operands: 3, - check: true, -}; - -METADATA[Op.FlushElement] = { - name: 'FlushElement', - mnemonic: 'apnd_flushtag', - before: null, - stackChange: 0, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.CloseElement] = { - name: 'CloseElement', - mnemonic: 'apnd_closetag', - before: null, - stackChange: 0, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.PopRemoteElement] = { - name: 'PopRemoteElement', - mnemonic: 'apnd_closeremotetag', - before: null, - stackChange: 0, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.Modifier] = { - name: 'Modifier', - mnemonic: 'apnd_modifier', - before: null, - stackChange: -1, - ops: [ - { - name: 'helper', - type: 'handle', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.BindDynamicScope] = { - name: 'BindDynamicScope', - mnemonic: 'setdynscope', - before: null, - stackChange: null, - ops: [ - { - name: 'names', - type: 'str-array', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.PushDynamicScope] = { - name: 'PushDynamicScope', - mnemonic: 'dynscopepush', - before: null, - stackChange: 0, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.PopDynamicScope] = { - name: 'PopDynamicScope', - mnemonic: 'dynscopepop', - before: null, - stackChange: 0, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.CompileBlock] = { - name: 'CompileBlock', - mnemonic: 'cmpblock', - before: null, - stackChange: 0, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.PushBlockScope] = { - name: 'PushBlockScope', - mnemonic: 'scopeload', - before: null, - stackChange: 1, - ops: [ - { - name: 'scope', - type: 'scope', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.PushSymbolTable] = { - name: 'PushSymbolTable', - mnemonic: 'dsymload', - before: null, - stackChange: 1, - ops: [ - { - name: 'table', - type: 'symbol-table', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.InvokeYield] = { - name: 'InvokeYield', - mnemonic: 'invokeyield', - before: null, - stackChange: null, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.JumpIf] = { - name: 'JumpIf', - mnemonic: 'iftrue', - before: null, - stackChange: -1, - ops: [ - { - name: 'to', - type: 'u32', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.JumpUnless] = { - name: 'JumpUnless', - mnemonic: 'iffalse', - before: null, - stackChange: -1, - ops: [ - { - name: 'to', - type: 'u32', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.JumpEq] = { - name: 'JumpEq', - mnemonic: 'ifeq', - before: null, - stackChange: 0, - ops: [ - { - name: 'to', - type: 'i32', - }, - { - name: 'comparison', - type: 'i32', - }, - ], - operands: 2, - check: true, -}; - -METADATA[Op.AssertSame] = { - name: 'AssertSame', - mnemonic: 'assert_eq', - before: null, - stackChange: 0, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.Enter] = { - name: 'Enter', - mnemonic: 'blk_start', - before: null, - stackChange: 0, - ops: [ - { - name: 'args', - type: 'u32', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.Exit] = { - name: 'Exit', - mnemonic: 'blk_end', - before: null, - stackChange: 0, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.ToBoolean] = { - name: 'ToBoolean', - mnemonic: 'anytobool', - before: null, - stackChange: 0, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.EnterList] = { - name: 'EnterList', - mnemonic: 'list_start', - before: null, - stackChange: null, - ops: [ - { - name: 'address', - type: 'u32', - }, - { - name: 'address', - type: 'u32', - }, - ], - operands: 2, - check: true, -}; - -METADATA[Op.ExitList] = { - name: 'ExitList', - mnemonic: 'list_end', - before: null, - stackChange: 0, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.Iterate] = { - name: 'Iterate', - mnemonic: 'iter', - before: null, - stackChange: 0, - ops: [ - { - name: 'end', - type: 'u32', - }, - ], - operands: 1, - check: false, -}; - -METADATA[Op.Main] = { - name: 'Main', - mnemonic: 'main', - before: null, - stackChange: -2, - ops: [ - { - name: 'state', - type: 'register', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.ContentType] = { - name: 'ContentType', - mnemonic: 'ctload', - before: null, - stackChange: 1, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.DynamicContentType] = { - name: 'DynamicContentType', - mnemonic: 'dctload', - before: null, - stackChange: 1, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.Curry] = { - name: 'Curry', - mnemonic: 'curry', - before: null, - stackChange: null, - ops: [ - { - name: 'type', - type: 'u32', - }, - { - name: 'is-strict', - type: 'bool', - }, - ], - operands: 2, - check: true, -}; - -METADATA[Op.PushComponentDefinition] = { - name: 'PushComponentDefinition', - mnemonic: 'cmload', - before: null, - stackChange: 1, - ops: [ - { - name: 'spec', - type: 'handle', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.PushDynamicComponentInstance] = { - name: 'PushDynamicComponentInstance', - mnemonic: 'dciload', - before: null, - stackChange: 0, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.ResolveDynamicComponent] = { - name: 'ResolveDynamicComponent', - mnemonic: 'cdload', - before: null, - stackChange: 0, - ops: [ - { - name: 'owner', - type: 'owner', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.PushArgs] = { - name: 'PushArgs', - mnemonic: 'argsload', - before: null, - stackChange: null, - ops: [ - { - name: 'names', - type: 'str-array', - }, - { - name: 'block-names', - type: 'str-array', - }, - { - name: 'flags', - type: 'u32', - }, - ], - operands: 3, - check: true, -}; - -METADATA[Op.PushEmptyArgs] = { - name: 'PushEmptyArgs', - mnemonic: 'emptyargsload', - before: null, - stackChange: 1, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.PopArgs] = { - name: 'PopArgs', - mnemonic: 'argspop', - before: null, - stackChange: null, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.PrepareArgs] = { - name: 'PrepareArgs', - mnemonic: 'argsprep', - before: null, - stackChange: 0, - ops: [ - { - name: 'state', - type: 'register', - }, - ], - operands: 1, - check: false, -}; - -METADATA[Op.CaptureArgs] = { - name: 'CaptureArgs', - mnemonic: 'argscapture', - before: null, - stackChange: 0, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.CreateComponent] = { - name: 'CreateComponent', - mnemonic: 'comp_create', - before: null, - stackChange: 0, - ops: [ - { - name: 'flags', - type: 'u32', - }, - { - name: 'state', - type: 'register', - }, - ], - operands: 2, - check: true, -}; - -METADATA[Op.RegisterComponentDestructor] = { - name: 'RegisterComponentDestructor', - mnemonic: 'comp_dest', - before: null, - stackChange: 0, - ops: [ - { - name: 'state', - type: 'register', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.PutComponentOperations] = { - name: 'PutComponentOperations', - mnemonic: 'comp_elops', - before: null, - stackChange: 0, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.GetComponentSelf] = { - name: 'GetComponentSelf', - mnemonic: 'comp_selfload', - before: null, - stackChange: 1, - ops: [ - { - name: 'state', - type: 'register', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.GetComponentTagName] = { - name: 'GetComponentTagName', - mnemonic: 'comp_tagload', - before: null, - stackChange: 1, - ops: [ - { - name: 'state', - type: 'register', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.GetComponentLayout] = { - name: 'GetComponentLayout', - mnemonic: 'comp_layoutload', - before: null, - stackChange: 2, - ops: [ - { - name: 'state', - type: 'register', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.BindEvalScope] = { - name: 'BindEvalScope', - mnemonic: 'eval_scope', - before: null, - stackChange: 0, - ops: [ - { - name: 'state', - type: 'register', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.SetupForEval] = { - name: 'SetupForEval', - mnemonic: 'eval_setup', - before: null, - stackChange: 0, - ops: [ - { - name: 'state', - type: 'register', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.PopulateLayout] = { - name: 'PopulateLayout', - mnemonic: 'comp_layoutput', - before: null, - stackChange: -2, - ops: [ - { - name: 'state', - type: 'register', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.InvokeComponentLayout] = { - name: 'InvokeComponentLayout', - mnemonic: 'comp_invokelayout', - before: null, - stackChange: 0, - ops: [ - { - name: 'state', - type: 'register', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.BeginComponentTransaction] = { - name: 'BeginComponentTransaction', - mnemonic: 'comp_begin', - before: null, - stackChange: 0, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.CommitComponentTransaction] = { - name: 'CommitComponentTransaction', - mnemonic: 'comp_commit', - before: null, - stackChange: 0, - ops: [], - operands: 0, - check: true, -}; - -METADATA[Op.DidCreateElement] = { - name: 'DidCreateElement', - mnemonic: 'comp_created', - before: null, - stackChange: 0, - ops: [ - { - name: 'state', - type: 'register', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.DidRenderLayout] = { - name: 'DidRenderLayout', - mnemonic: 'comp_rendered', - before: null, - stackChange: 0, - ops: [ - { - name: 'state', - type: 'register', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.ResolveMaybeLocal] = { - name: 'ResolveMaybeLocal', - mnemonic: 'eval_varload', - before: null, - stackChange: 1, - ops: [ - { - name: 'local', - type: 'str', - }, - ], - operands: 1, - check: true, -}; - -METADATA[Op.Debugger] = { - name: 'Debugger', - mnemonic: 'debugger', - before: null, - stackChange: 0, - ops: [ - { - name: 'symbols', - type: 'str-array', - }, - { - name: 'debugInfo', - type: 'array', - }, - ], - operands: 2, - check: true, -}; + +if (LOCAL_DEBUG) { + MACHINE_METADATA[MachineOp.PushFrame] = { + name: 'PushFrame', + mnemonic: 'pushf', + before: null, + stackChange: 2, + ops: [], + operands: 0, + check: true, + }; + + MACHINE_METADATA[MachineOp.PopFrame] = { + name: 'PopFrame', + mnemonic: 'popf', + before: null, + stackChange: -2, + ops: [], + operands: 0, + check: false, + }; + + MACHINE_METADATA[MachineOp.InvokeVirtual] = { + name: 'InvokeVirtual', + mnemonic: 'vcall', + before: null, + stackChange: -1, + ops: [], + operands: 0, + check: true, + }; + + MACHINE_METADATA[MachineOp.InvokeStatic] = { + name: 'InvokeStatic', + mnemonic: 'scall', + before: null, + stackChange: 0, + ops: [ + { + name: 'offset', + type: 'u32', + }, + ], + operands: 1, + check: true, + }; + + MACHINE_METADATA[MachineOp.Jump] = { + name: 'Jump', + mnemonic: 'goto', + before: null, + stackChange: 0, + ops: [ + { + name: 'to', + type: 'u32', + }, + ], + operands: 1, + check: true, + }; + + MACHINE_METADATA[MachineOp.Return] = { + name: 'Return', + mnemonic: 'ret', + before: null, + stackChange: 0, + ops: [], + operands: 0, + check: false, + }; + + MACHINE_METADATA[MachineOp.ReturnTo] = { + name: 'ReturnTo', + mnemonic: 'setra', + before: null, + stackChange: 0, + ops: [ + { + name: 'offset', + type: 'i32', + }, + ], + operands: 1, + check: true, + }; + METADATA[Op.Helper] = { + name: 'Helper', + mnemonic: 'ncall', + before: null, + stackChange: null, + ops: [ + { + name: 'helper', + type: 'handle', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.DynamicHelper] = { + name: 'DynamicHelper', + mnemonic: 'dynamiccall', + before: null, + stackChange: null, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.SetNamedVariables] = { + name: 'SetNamedVariables', + mnemonic: 'vsargs', + before: null, + stackChange: 0, + ops: [ + { + name: 'register', + type: 'u32', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.SetBlocks] = { + name: 'SetBlocks', + mnemonic: 'vbblocks', + before: null, + stackChange: 0, + ops: [ + { + name: 'register', + type: 'u32', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.SetVariable] = { + name: 'SetVariable', + mnemonic: 'sbvar', + before: null, + stackChange: -1, + ops: [ + { + name: 'symbol', + type: 'u32', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.SetBlock] = { + name: 'SetBlock', + mnemonic: 'sblock', + before: null, + stackChange: -3, + ops: [ + { + name: 'symbol', + type: 'u32', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.GetVariable] = { + name: 'GetVariable', + mnemonic: 'symload', + before: null, + stackChange: 1, + ops: [ + { + name: 'symbol', + type: 'u32', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.GetProperty] = { + name: 'GetProperty', + mnemonic: 'getprop', + before: null, + stackChange: 0, + ops: [ + { + name: 'property', + type: 'str', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.GetBlock] = { + name: 'GetBlock', + mnemonic: 'blockload', + before: null, + stackChange: 1, + ops: [ + { + name: 'block', + type: 'u32', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.SpreadBlock] = { + name: 'SpreadBlock', + mnemonic: 'blockspread', + before: null, + stackChange: 2, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.HasBlock] = { + name: 'HasBlock', + mnemonic: 'hasblockload', + before: null, + stackChange: 0, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.HasBlockParams] = { + name: 'HasBlockParams', + mnemonic: 'hasparamsload', + before: null, + stackChange: -2, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.Concat] = { + name: 'Concat', + mnemonic: 'concat', + before: null, + stackChange: null, + ops: [ + { + name: 'count', + type: 'u32', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.IfInline] = { + name: 'IfInline', + mnemonic: 'ifinline', + before: null, + stackChange: -2, + ops: [ + { + name: 'count', + type: 'u32', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.Not] = { + name: 'Not', + mnemonic: 'not', + before: null, + stackChange: 0, + ops: [ + { + name: 'count', + type: 'u32', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.Constant] = { + name: 'Constant', + mnemonic: 'rconstload', + before: null, + stackChange: 1, + ops: [ + { + name: 'constant', + type: 'unknown', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.ConstantReference] = { + name: 'ConstantReference', + mnemonic: 'rconstrefload', + before: null, + stackChange: 1, + ops: [ + { + name: 'constant', + type: 'unknown', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.Primitive] = { + name: 'Primitive', + mnemonic: 'pconstload', + before: null, + stackChange: 1, + ops: [ + { + name: 'constant', + type: 'primitive', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.PrimitiveReference] = { + name: 'PrimitiveReference', + mnemonic: 'ptoref', + before: null, + stackChange: 0, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.ReifyU32] = { + name: 'ReifyU32', + mnemonic: 'reifyload', + before: null, + stackChange: 1, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.Dup] = { + name: 'Dup', + mnemonic: 'dup', + before: null, + stackChange: 1, + ops: [ + { + name: 'register', + type: 'u32', + }, + { + name: 'offset', + type: 'u32', + }, + ], + operands: 2, + check: true, + }; + + METADATA[Op.Pop] = { + name: 'Pop', + mnemonic: 'pop', + before: null, + stackChange: 0, + ops: [ + { + name: 'count', + type: 'u32', + }, + ], + operands: 1, + check: false, + }; + + METADATA[Op.Load] = { + name: 'Load', + mnemonic: 'put', + before: null, + stackChange: -1, + ops: [ + { + name: 'register', + type: 'u32', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.Fetch] = { + name: 'Fetch', + mnemonic: 'regload', + before: null, + stackChange: 1, + ops: [ + { + name: 'register', + type: 'u32', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.RootScope] = { + name: 'RootScope', + mnemonic: 'rscopepush', + before: null, + stackChange: 0, + ops: [ + { + name: 'symbols', + type: 'u32', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.VirtualRootScope] = { + name: 'VirtualRootScope', + mnemonic: 'vrscopepush', + before: null, + stackChange: 0, + ops: [ + { + name: 'register', + type: 'u32', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.ChildScope] = { + name: 'ChildScope', + mnemonic: 'cscopepush', + before: null, + stackChange: 0, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.PopScope] = { + name: 'PopScope', + mnemonic: 'scopepop', + before: null, + stackChange: 0, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.Text] = { + name: 'Text', + mnemonic: 'apnd_text', + before: null, + stackChange: 0, + ops: [ + { + name: 'contents', + type: 'str', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.Comment] = { + name: 'Comment', + mnemonic: 'apnd_comment', + before: null, + stackChange: 0, + ops: [ + { + name: 'contents', + type: 'str', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.AppendHTML] = { + name: 'AppendHTML', + mnemonic: 'apnd_dynhtml', + before: null, + stackChange: -1, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.AppendSafeHTML] = { + name: 'AppendSafeHTML', + mnemonic: 'apnd_dynshtml', + before: null, + stackChange: -1, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.AppendDocumentFragment] = { + name: 'AppendDocumentFragment', + mnemonic: 'apnd_dynfrag', + before: null, + stackChange: -1, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.AppendNode] = { + name: 'AppendNode', + mnemonic: 'apnd_dynnode', + before: null, + stackChange: -1, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.AppendText] = { + name: 'AppendText', + mnemonic: 'apnd_dyntext', + before: null, + stackChange: -1, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.OpenElement] = { + name: 'OpenElement', + mnemonic: 'apnd_tag', + before: null, + stackChange: 0, + ops: [ + { + name: 'tag', + type: 'str', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.OpenDynamicElement] = { + name: 'OpenDynamicElement', + mnemonic: 'apnd_dyntag', + before: null, + stackChange: -1, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.PushRemoteElement] = { + name: 'PushRemoteElement', + mnemonic: 'apnd_remotetag', + before: null, + stackChange: -3, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.StaticAttr] = { + name: 'StaticAttr', + mnemonic: 'apnd_attr', + before: null, + stackChange: 0, + ops: [ + { + name: 'name', + type: 'str', + }, + { + name: 'value', + type: 'str', + }, + { + name: 'namespace', + type: 'option-str', + }, + ], + operands: 3, + check: true, + }; + + METADATA[Op.DynamicAttr] = { + name: 'DynamicAttr', + mnemonic: 'apnd_dynattr', + before: null, + stackChange: -1, + ops: [ + { + name: 'name', + type: 'str', + }, + { + name: 'trusting', + type: 'bool', + }, + { + name: 'namespace', + type: 'option-str', + }, + ], + operands: 3, + check: true, + }; + + METADATA[Op.ComponentAttr] = { + name: 'ComponentAttr', + mnemonic: 'apnd_cattr', + before: null, + stackChange: -1, + ops: [ + { + name: 'name', + type: 'str', + }, + { + name: 'trusting', + type: 'bool', + }, + { + name: 'namespace', + type: 'option-str', + }, + ], + operands: 3, + check: true, + }; + + METADATA[Op.FlushElement] = { + name: 'FlushElement', + mnemonic: 'apnd_flushtag', + before: null, + stackChange: 0, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.CloseElement] = { + name: 'CloseElement', + mnemonic: 'apnd_closetag', + before: null, + stackChange: 0, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.PopRemoteElement] = { + name: 'PopRemoteElement', + mnemonic: 'apnd_closeremotetag', + before: null, + stackChange: 0, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.Modifier] = { + name: 'Modifier', + mnemonic: 'apnd_modifier', + before: null, + stackChange: -1, + ops: [ + { + name: 'helper', + type: 'handle', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.BindDynamicScope] = { + name: 'BindDynamicScope', + mnemonic: 'setdynscope', + before: null, + stackChange: null, + ops: [ + { + name: 'names', + type: 'str-array', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.PushDynamicScope] = { + name: 'PushDynamicScope', + mnemonic: 'dynscopepush', + before: null, + stackChange: 0, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.PopDynamicScope] = { + name: 'PopDynamicScope', + mnemonic: 'dynscopepop', + before: null, + stackChange: 0, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.CompileBlock] = { + name: 'CompileBlock', + mnemonic: 'cmpblock', + before: null, + stackChange: 0, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.PushBlockScope] = { + name: 'PushBlockScope', + mnemonic: 'scopeload', + before: null, + stackChange: 1, + ops: [ + { + name: 'scope', + type: 'scope', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.PushSymbolTable] = { + name: 'PushSymbolTable', + mnemonic: 'dsymload', + before: null, + stackChange: 1, + ops: [ + { + name: 'table', + type: 'symbol-table', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.InvokeYield] = { + name: 'InvokeYield', + mnemonic: 'invokeyield', + before: null, + stackChange: null, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.JumpIf] = { + name: 'JumpIf', + mnemonic: 'iftrue', + before: null, + stackChange: -1, + ops: [ + { + name: 'to', + type: 'u32', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.JumpUnless] = { + name: 'JumpUnless', + mnemonic: 'iffalse', + before: null, + stackChange: -1, + ops: [ + { + name: 'to', + type: 'u32', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.JumpEq] = { + name: 'JumpEq', + mnemonic: 'ifeq', + before: null, + stackChange: 0, + ops: [ + { + name: 'to', + type: 'i32', + }, + { + name: 'comparison', + type: 'i32', + }, + ], + operands: 2, + check: true, + }; + + METADATA[Op.AssertSame] = { + name: 'AssertSame', + mnemonic: 'assert_eq', + before: null, + stackChange: 0, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.Enter] = { + name: 'Enter', + mnemonic: 'blk_start', + before: null, + stackChange: 0, + ops: [ + { + name: 'args', + type: 'u32', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.Exit] = { + name: 'Exit', + mnemonic: 'blk_end', + before: null, + stackChange: 0, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.ToBoolean] = { + name: 'ToBoolean', + mnemonic: 'anytobool', + before: null, + stackChange: 0, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.EnterList] = { + name: 'EnterList', + mnemonic: 'list_start', + before: null, + stackChange: null, + ops: [ + { + name: 'address', + type: 'u32', + }, + { + name: 'address', + type: 'u32', + }, + ], + operands: 2, + check: true, + }; + + METADATA[Op.ExitList] = { + name: 'ExitList', + mnemonic: 'list_end', + before: null, + stackChange: 0, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.Iterate] = { + name: 'Iterate', + mnemonic: 'iter', + before: null, + stackChange: 0, + ops: [ + { + name: 'end', + type: 'u32', + }, + ], + operands: 1, + check: false, + }; + + METADATA[Op.Main] = { + name: 'Main', + mnemonic: 'main', + before: null, + stackChange: -2, + ops: [ + { + name: 'state', + type: 'register', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.ContentType] = { + name: 'ContentType', + mnemonic: 'ctload', + before: null, + stackChange: 1, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.DynamicContentType] = { + name: 'DynamicContentType', + mnemonic: 'dctload', + before: null, + stackChange: 1, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.Curry] = { + name: 'Curry', + mnemonic: 'curry', + before: null, + stackChange: null, + ops: [ + { + name: 'type', + type: 'u32', + }, + { + name: 'is-strict', + type: 'bool', + }, + ], + operands: 2, + check: true, + }; + + METADATA[Op.PushComponentDefinition] = { + name: 'PushComponentDefinition', + mnemonic: 'cmload', + before: null, + stackChange: 1, + ops: [ + { + name: 'spec', + type: 'handle', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.PushDynamicComponentInstance] = { + name: 'PushDynamicComponentInstance', + mnemonic: 'dciload', + before: null, + stackChange: 0, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.ResolveDynamicComponent] = { + name: 'ResolveDynamicComponent', + mnemonic: 'cdload', + before: null, + stackChange: 0, + ops: [ + { + name: 'owner', + type: 'owner', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.PushArgs] = { + name: 'PushArgs', + mnemonic: 'argsload', + before: null, + stackChange: null, + ops: [ + { + name: 'names', + type: 'str-array', + }, + { + name: 'block-names', + type: 'str-array', + }, + { + name: 'flags', + type: 'u32', + }, + ], + operands: 3, + check: true, + }; + + METADATA[Op.PushEmptyArgs] = { + name: 'PushEmptyArgs', + mnemonic: 'emptyargsload', + before: null, + stackChange: 1, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.PopArgs] = { + name: 'PopArgs', + mnemonic: 'argspop', + before: null, + stackChange: null, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.PrepareArgs] = { + name: 'PrepareArgs', + mnemonic: 'argsprep', + before: null, + stackChange: 0, + ops: [ + { + name: 'state', + type: 'register', + }, + ], + operands: 1, + check: false, + }; + + METADATA[Op.CaptureArgs] = { + name: 'CaptureArgs', + mnemonic: 'argscapture', + before: null, + stackChange: 0, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.CreateComponent] = { + name: 'CreateComponent', + mnemonic: 'comp_create', + before: null, + stackChange: 0, + ops: [ + { + name: 'flags', + type: 'u32', + }, + { + name: 'state', + type: 'register', + }, + ], + operands: 2, + check: true, + }; + + METADATA[Op.RegisterComponentDestructor] = { + name: 'RegisterComponentDestructor', + mnemonic: 'comp_dest', + before: null, + stackChange: 0, + ops: [ + { + name: 'state', + type: 'register', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.PutComponentOperations] = { + name: 'PutComponentOperations', + mnemonic: 'comp_elops', + before: null, + stackChange: 0, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.GetComponentSelf] = { + name: 'GetComponentSelf', + mnemonic: 'comp_selfload', + before: null, + stackChange: 1, + ops: [ + { + name: 'state', + type: 'register', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.GetComponentTagName] = { + name: 'GetComponentTagName', + mnemonic: 'comp_tagload', + before: null, + stackChange: 1, + ops: [ + { + name: 'state', + type: 'register', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.GetComponentLayout] = { + name: 'GetComponentLayout', + mnemonic: 'comp_layoutload', + before: null, + stackChange: 2, + ops: [ + { + name: 'state', + type: 'register', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.BindEvalScope] = { + name: 'BindEvalScope', + mnemonic: 'eval_scope', + before: null, + stackChange: 0, + ops: [ + { + name: 'state', + type: 'register', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.SetupForEval] = { + name: 'SetupForEval', + mnemonic: 'eval_setup', + before: null, + stackChange: 0, + ops: [ + { + name: 'state', + type: 'register', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.PopulateLayout] = { + name: 'PopulateLayout', + mnemonic: 'comp_layoutput', + before: null, + stackChange: -2, + ops: [ + { + name: 'state', + type: 'register', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.InvokeComponentLayout] = { + name: 'InvokeComponentLayout', + mnemonic: 'comp_invokelayout', + before: null, + stackChange: 0, + ops: [ + { + name: 'state', + type: 'register', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.BeginComponentTransaction] = { + name: 'BeginComponentTransaction', + mnemonic: 'comp_begin', + before: null, + stackChange: 0, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.CommitComponentTransaction] = { + name: 'CommitComponentTransaction', + mnemonic: 'comp_commit', + before: null, + stackChange: 0, + ops: [], + operands: 0, + check: true, + }; + + METADATA[Op.DidCreateElement] = { + name: 'DidCreateElement', + mnemonic: 'comp_created', + before: null, + stackChange: 0, + ops: [ + { + name: 'state', + type: 'register', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.DidRenderLayout] = { + name: 'DidRenderLayout', + mnemonic: 'comp_rendered', + before: null, + stackChange: 0, + ops: [ + { + name: 'state', + type: 'register', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.ResolveMaybeLocal] = { + name: 'ResolveMaybeLocal', + mnemonic: 'eval_varload', + before: null, + stackChange: 1, + ops: [ + { + name: 'local', + type: 'str', + }, + ], + operands: 1, + check: true, + }; + + METADATA[Op.Debugger] = { + name: 'Debugger', + mnemonic: 'debugger', + before: null, + stackChange: 0, + ops: [ + { + name: 'symbols', + type: 'str-array', + }, + { + name: 'debugInfo', + type: 'array', + }, + ], + operands: 2, + check: true, + }; +} diff --git a/packages/@glimmer/debug/lib/stack-check.ts b/packages/@glimmer/debug/lib/stack-check.ts index f8abf5bbba..a0b81969a3 100644 --- a/packages/@glimmer/debug/lib/stack-check.ts +++ b/packages/@glimmer/debug/lib/stack-check.ts @@ -8,6 +8,7 @@ import type { SimpleElement, SimpleNode, } from '@glimmer/interfaces'; +import { LOCAL_DEBUG } from '@glimmer/local-debug-flags'; export interface Checker { type: T; @@ -16,7 +17,21 @@ export interface Checker { expected(): string; } +class NoopChecker implements Checker { + declare type: T; + validate(value: unknown): value is T { + return true; + } + expected(): string { + return ''; + } +} + export function wrap(checker: () => Checker): Checker { + if (!LOCAL_DEBUG) { + return new NoopChecker(); + } + class Wrapped { declare type: T; @@ -285,14 +300,26 @@ class SafeStringChecker implements Checker { } export function CheckInstanceof(Class: Constructor): Checker { + if (!LOCAL_DEBUG) { + return new NoopChecker(); + } + return new InstanceofChecker(Class); } export function CheckOption(checker: Checker): Checker> { + if (!LOCAL_DEBUG) { + return new NoopChecker(); + } + return new OptionChecker(checker, null); } export function CheckMaybe(checker: Checker): Checker> { + if (!LOCAL_DEBUG) { + return new NoopChecker(); + } + return new MaybeChecker(checker); } @@ -300,14 +327,24 @@ export function CheckInterface< I extends { [P in keyof O]: O[P]['type'] }, O extends Dict>, >(obj: O): Checker { + if (!LOCAL_DEBUG) { + return new NoopChecker(); + } + return new PropertyChecker(obj); } export function CheckArray(obj: Checker): Checker { + if (!LOCAL_DEBUG) { + return new NoopChecker(); + } return new ArrayChecker(obj); } export function CheckDict(obj: Checker): Checker> { + if (!LOCAL_DEBUG) { + return new NoopChecker(); + } return new DictChecker(obj); } @@ -326,6 +363,10 @@ export function check( checker: Checker | ((value: unknown) => void), message: (value: unknown, expected: string) => string = defaultMessage ): T { + if (!LOCAL_DEBUG) { + return value as T; + } + if (typeof checker === 'function') { checker(value); return value as T; @@ -344,6 +385,10 @@ export function recordStackSize(sp: number) { } export function expectStackChange(stack: { sp: number }, expected: number, name: string) { + if (LOCAL_DEBUG) { + return; + } + let actual = stack.sp - size; if (actual === expected) return; @@ -353,47 +398,79 @@ export function expectStackChange(stack: { sp: number }, expected: number, name: ); } -export const CheckPrimitive: Checker = new PrimitiveChecker(); -export const CheckFunction: Checker = new TypeofChecker('function'); -export const CheckNumber: Checker = new TypeofChecker('number'); -export const CheckBoolean: Checker = new TypeofChecker('boolean'); -export const CheckHandle: Checker = CheckNumber; -export const CheckString: Checker = new TypeofChecker('string'); -export const CheckNull: Checker = new NullChecker(); -export const CheckUndefined: Checker = new UndefinedChecker(); -export const CheckUnknown: Checker = new OpaqueChecker(); -export const CheckSafeString: Checker = new SafeStringChecker(); -export const CheckObject: Checker = new ObjectChecker(); +export const CheckPrimitive: Checker = !LOCAL_DEBUG + ? new NoopChecker() + : new PrimitiveChecker(); +export const CheckFunction: Checker = !LOCAL_DEBUG + ? new NoopChecker() + : new TypeofChecker('function'); +export const CheckNumber: Checker = !LOCAL_DEBUG + ? new NoopChecker() + : new TypeofChecker('number'); +export const CheckBoolean: Checker = !LOCAL_DEBUG + ? new NoopChecker() + : new TypeofChecker('boolean'); +export const CheckHandle: Checker = LOCAL_DEBUG ? CheckNumber : new NoopChecker(); +export const CheckString: Checker = !LOCAL_DEBUG + ? new NoopChecker() + : new TypeofChecker('string'); +export const CheckNull: Checker = !LOCAL_DEBUG ? new NoopChecker() : new NullChecker(); +export const CheckUndefined: Checker = !LOCAL_DEBUG + ? new NoopChecker() + : new UndefinedChecker(); +export const CheckUnknown: Checker = !LOCAL_DEBUG + ? new NoopChecker() + : new OpaqueChecker(); +export const CheckSafeString: Checker = !LOCAL_DEBUG + ? new NoopChecker() + : new SafeStringChecker(); +export const CheckObject: Checker = !LOCAL_DEBUG ? new NoopChecker() : new ObjectChecker(); export function CheckOr(left: Checker, right: Checker): Checker { + if (!LOCAL_DEBUG) { + return new NoopChecker(); + } return new OrChecker(left, right); } export function CheckValue(value: T, desc = String(value)): Checker { + if (!LOCAL_DEBUG) { + return new NoopChecker(); + } return new ExactValueChecker(value, desc); } -export const CheckBlockSymbolTable: Checker = CheckInterface({ - parameters: CheckArray(CheckNumber), -}); - -export const CheckProgramSymbolTable: Checker = CheckInterface({ - hasEval: CheckBoolean, - symbols: CheckArray(CheckString), -}); - -export const CheckElement: Checker = CheckInterface({ - nodeType: CheckValue(1), - tagName: CheckString, - nextSibling: CheckUnknown, -}); - -export const CheckDocumentFragment: Checker = CheckInterface({ - nodeType: CheckValue(11), - nextSibling: CheckUnknown, -}); - -export const CheckNode: Checker = CheckInterface({ - nodeType: CheckNumber, - nextSibling: CheckUnknown, -}); +export const CheckBlockSymbolTable: Checker = LOCAL_DEBUG + ? CheckInterface({ + parameters: CheckArray(CheckNumber), + }) + : new NoopChecker(); + +export const CheckProgramSymbolTable: Checker = LOCAL_DEBUG + ? CheckInterface({ + hasEval: CheckBoolean, + symbols: CheckArray(CheckString), + }) + : new NoopChecker(); + +export const CheckElement: Checker = LOCAL_DEBUG + ? CheckInterface({ + nodeType: CheckValue(1), + tagName: CheckString, + nextSibling: CheckUnknown, + }) + : new NoopChecker(); + +export const CheckDocumentFragment: Checker = LOCAL_DEBUG + ? CheckInterface({ + nodeType: CheckValue(11), + nextSibling: CheckUnknown, + }) + : new NoopChecker(); + +export const CheckNode: Checker = LOCAL_DEBUG + ? CheckInterface({ + nodeType: CheckNumber, + nextSibling: CheckUnknown, + }) + : new NoopChecker(); diff --git a/packages/@glimmer/debug/package.json b/packages/@glimmer/debug/package.json index 3d84e33e3c..13e553836d 100644 --- a/packages/@glimmer/debug/package.json +++ b/packages/@glimmer/debug/package.json @@ -2,6 +2,7 @@ "name": "@glimmer/debug", "version": "0.92.0", "license": "MIT", + "sideEffects": false, "repository": "https://github.com/glimmerjs/glimmer-vm/tree/main/packages/@glimmer/debug", "type": "module", "main": "index.ts", diff --git a/packages/@glimmer/local-debug-babel-plugin/index.js b/packages/@glimmer/local-debug-babel-plugin/index.js new file mode 100644 index 0000000000..c7be442030 --- /dev/null +++ b/packages/@glimmer/local-debug-babel-plugin/index.js @@ -0,0 +1,110 @@ +/** + * https://astexplorer.net/#/gist/c3f41b75af73006f64476775e73f7daa/e6e3e120df8404b1bff308bec3ed89eaaf0b05f2 + * + * This plugin exists because, _even when we inline @glimmer/debug_, + * we cannot get terser to remove/inline/unwrap identity functions. + * + * Repro here: https://try.terser.org/ + * + * ```js + function x(x) { return x; } + function y(x, y, z) { return x; }; + + function abc(a) { return x(a); } + function abc2(a) { return y(a); } + + export function example() { + return `${x(2)} ${y("2")} ${abc(3)} ${abc2("3")}`; + } + ``` + + With Options: + + { + module: true, + compress: { + passes: 6, + module: true, + inline: 3, // default + }, + mangle: {}, + output: {}, + parse: {}, + rename: {}, + } + */ +export default function (babel) { + let _removeCheck = removeChecks(babel); + + return { + name: 'Cleanup local-debug code that terser could not', + visitor: { + ImportDeclaration(path, state) { + _removeCheck.ImportDeclaration(path, state); + }, + CallExpression(path, state) { + _removeCheck.CallExpression(path, state); + }, + }, + }; +} + +function removeChecks({ template }) { + let stateKey = Symbol.for('removeChecks'); + + const unwrap = ['check']; + const trueFn = ['CheckInterface', 'wrap', 'CheckOr', 'CheckFunction', 'CheckObject']; + const removeEntirely = ['recordStackSize']; + + function isToBeRemoved(callPath, state) { + if (!state) return; + + let ourState = state[stateKey]; + + if (!ourState) return; + /** + * Do we want to support local aliasing / re-assignment? + * if so, this would break + */ + if (!ourState?.names?.has(callPath.node.callee.name)) return; + + return true; + } + + return { + ImportDeclaration(path, state) { + let node = path.node; + + if (!node.source) return; + if (node.source.value !== '@glimmer/debug') return; + + state[stateKey] ??= { names: new Set(), nodes: [] }; + + node.specifiers.forEach((specifier) => { + let name = specifier.local.name; + let relevant = + unwrap.includes(name) || removeEntirely.includes(name) || trueFn.includes(name); + if (!relevant) return; + + state[stateKey].names.add(name); + state[stateKey].nodes.push(specifier.local); + }); + }, + CallExpression(path, state) { + if (isToBeRemoved(path, state)) { + let name = path.node.callee.name; + if (removeEntirely.includes(name)) { + path.remove(); + return; + } + + if (trueFn.includes(name)) { + path.replaceWith(template(`() => true`)()); + return; + } + + path.replaceWith(path.node.arguments[0]); + } + }, + }; +} diff --git a/packages/@glimmer/local-debug-babel-plugin/package.json b/packages/@glimmer/local-debug-babel-plugin/package.json new file mode 100644 index 0000000000..c595d3a689 --- /dev/null +++ b/packages/@glimmer/local-debug-babel-plugin/package.json @@ -0,0 +1,13 @@ +{ + "name": "@glimmer/local-debug-babel-plugin", + "version": "0.92.0", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/glimmerjs/glimmer-vm.git", + "directory": "packages/@glimmer/local-debug-babel-plugin" + }, + "type": "module", + "private": true, + "main": "index.js" +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8bd4faf6c8..d68d48ff94 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -221,7 +221,7 @@ importers: version: 5.0.12(@types/node@20.9.4) xo: specifier: ^0.54.2 - version: 0.54.2(eslint-import-resolver-typescript@3.6.1)(webpack@5.89.0) + version: 0.54.2(@typescript-eslint/parser@6.12.0)(eslint-import-resolver-typescript@3.6.1)(webpack@5.89.0) zx: specifier: ^7.2.3 version: 7.2.3 @@ -349,6 +349,9 @@ importers: packages/@glimmer-workspace/build: dependencies: + '@glimmer/local-debug-babel-plugin': + specifier: workspace:* + version: link:../../@glimmer/local-debug-babel-plugin '@rollup/plugin-commonjs': specifier: ^25.0.7 version: 25.0.7(rollup@4.5.1) @@ -767,6 +770,8 @@ importers: specifier: ^5.0.4 version: 5.0.4 + packages/@glimmer/local-debug-babel-plugin: {} + packages/@glimmer/local-debug-flags: devDependencies: eslint: @@ -4356,34 +4361,6 @@ packages: '@types/node': 20.9.4 optional: true - /@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.54.0)(typescript@5.2.2): - resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 5.62.0(eslint@8.54.0)(typescript@5.2.2) - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/type-utils': 5.62.0(eslint@8.54.0)(typescript@5.2.2) - '@typescript-eslint/utils': 5.62.0(eslint@8.54.0)(typescript@5.2.2) - debug: 4.3.4(supports-color@8.1.1) - eslint: 8.54.0 - graphemer: 1.4.0 - ignore: 5.3.0 - natural-compare-lite: 1.4.0 - semver: 7.5.2 - tsutils: 3.21.0(typescript@5.2.2) - typescript: 5.2.2 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/eslint-plugin@6.12.0(@typescript-eslint/parser@6.12.0)(eslint@8.54.0)(typescript@5.0.4): resolution: {integrity: sha512-XOpZ3IyJUIV1b15M7HVOpgQxPPF7lGXgsfcEIu3yDxFPaf/xZKt7s9QO/pbk7vpWQyVulpJbu4E5LwpZiQo4kA==} engines: {node: ^16.0.0 || >=18.0.0} @@ -4441,26 +4418,6 @@ packages: transitivePeerDependencies: - supports-color - /@typescript-eslint/parser@5.62.0(eslint@8.54.0)(typescript@5.2.2): - resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.2.2) - debug: 4.3.4(supports-color@8.1.1) - eslint: 8.54.0 - typescript: 5.2.2 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/parser@6.12.0(eslint@8.54.0)(typescript@5.0.4): resolution: {integrity: sha512-s8/jNFPKPNRmXEnNXfuo1gemBdVmpQsK1pcu+QIvuNJuhFzGrpD7WjOcvDc/+uEdfzSYpNu7U/+MmbScjoQ6vg==} engines: {node: ^16.0.0 || >=18.0.0} @@ -4502,14 +4459,6 @@ packages: transitivePeerDependencies: - supports-color - /@typescript-eslint/scope-manager@5.62.0: - resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/visitor-keys': 5.62.0 - dev: true - /@typescript-eslint/scope-manager@6.12.0: resolution: {integrity: sha512-5gUvjg+XdSj8pcetdL9eXJzQNTl3RD7LgUiYTl8Aabdi8hFkaGSYnaS6BLc0BGNaDH+tVzVwmKtWvu0jLgWVbw==} engines: {node: ^16.0.0 || >=18.0.0} @@ -4517,26 +4466,6 @@ packages: '@typescript-eslint/types': 6.12.0 '@typescript-eslint/visitor-keys': 6.12.0 - /@typescript-eslint/type-utils@5.62.0(eslint@8.54.0)(typescript@5.2.2): - resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: '*' - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.2.2) - '@typescript-eslint/utils': 5.62.0(eslint@8.54.0)(typescript@5.2.2) - debug: 4.3.4(supports-color@8.1.1) - eslint: 8.54.0 - tsutils: 3.21.0(typescript@5.2.2) - typescript: 5.2.2 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/type-utils@6.12.0(eslint@8.54.0)(typescript@5.0.4): resolution: {integrity: sha512-WWmRXxhm1X8Wlquj+MhsAG4dU/Blvf1xDgGaYCzfvStP2NwPQh6KBvCDbiOEvaE0filhranjIlK/2fSTVwtBng==} engines: {node: ^16.0.0 || >=18.0.0} @@ -4576,36 +4505,10 @@ packages: transitivePeerDependencies: - supports-color - /@typescript-eslint/types@5.62.0: - resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true - /@typescript-eslint/types@6.12.0: resolution: {integrity: sha512-MA16p/+WxM5JG/F3RTpRIcuOghWO30//VEOvzubM8zuOOBYXsP+IfjoCXXiIfy2Ta8FRh9+IO9QLlaFQUU+10Q==} engines: {node: ^16.0.0 || >=18.0.0} - /@typescript-eslint/typescript-estree@5.62.0(typescript@5.2.2): - resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.3.4(supports-color@8.1.1) - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.5.2 - tsutils: 3.21.0(typescript@5.2.2) - typescript: 5.2.2 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/typescript-estree@6.12.0(typescript@5.0.4): resolution: {integrity: sha512-vw9E2P9+3UUWzhgjyyVczLWxZ3GuQNT7QpnIY3o5OMeLO/c8oHljGc8ZpryBMIyympiAAaKgw9e5Hl9dCWFOYw==} engines: {node: ^16.0.0 || >=18.0.0} @@ -4647,26 +4550,6 @@ packages: transitivePeerDependencies: - supports-color - /@typescript-eslint/utils@5.62.0(eslint@8.54.0)(typescript@5.2.2): - resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0) - '@types/json-schema': 7.0.15 - '@types/semver': 7.5.6 - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.2.2) - eslint: 8.54.0 - eslint-scope: 5.1.1 - semver: 7.5.2 - transitivePeerDependencies: - - supports-color - - typescript - dev: true - /@typescript-eslint/utils@6.12.0(eslint@8.54.0)(typescript@5.0.4): resolution: {integrity: sha512-LywPm8h3tGEbgfyjYnu3dauZ0U7R60m+miXgKcZS8c7QALO9uWJdvNoP+duKTk2XMWc7/Q3d/QiCuLN9X6SWyQ==} engines: {node: ^16.0.0 || >=18.0.0} @@ -4704,14 +4587,6 @@ packages: - supports-color - typescript - /@typescript-eslint/visitor-keys@5.62.0: - resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.62.0 - eslint-visitor-keys: 3.4.3 - dev: true - /@typescript-eslint/visitor-keys@6.12.0: resolution: {integrity: sha512-rg3BizTZHF1k3ipn8gfrzDXXSFKyOEB5zxYXInQ6z0hUvmQlhaZQzK+YmHmNViMA9HzW5Q9+bPPt90bU6GQwyw==} engines: {node: ^16.0.0 || >=18.0.0} @@ -8236,21 +8111,6 @@ packages: dependencies: eslint: 8.54.0 - /eslint-config-xo-typescript@0.57.0(@typescript-eslint/eslint-plugin@5.62.0)(@typescript-eslint/parser@5.62.0)(eslint@8.54.0)(typescript@5.2.2): - resolution: {integrity: sha512-u+qcTaADHn2/+hbDqZHRWiAps8JS6BcRsJKAADFxYHIPpYqQeQv9mXuhRe/1+ikfZAIz9hlG1V+Lkj8J7nf34A==} - engines: {node: '>=12'} - peerDependencies: - '@typescript-eslint/eslint-plugin': '>=5.57.0' - '@typescript-eslint/parser': '>=5.57.0' - eslint: '>=8.0.0' - typescript: ^5.0.4 || 5 - dependencies: - '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.54.0)(typescript@5.2.2) - '@typescript-eslint/parser': 5.62.0(eslint@8.54.0)(typescript@5.2.2) - eslint: 8.54.0 - typescript: 5.2.2 - dev: true - /eslint-config-xo@0.43.1(eslint@8.54.0): resolution: {integrity: sha512-azv1L2PysRA0NkZOgbndUpN+581L7wPqkgJOgxxw3hxwXAbJgD6Hqb/SjHRiACifXt/AvxCzE/jIKFAlI7XjvQ==} engines: {node: '>=12'} @@ -8339,7 +8199,7 @@ packages: array-find: 1.0.0 debug: 3.2.7 enhanced-resolve: 0.9.1 - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint-import-resolver-webpack@0.13.2)(eslint@8.54.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.12.0)(eslint-import-resolver-typescript@3.6.1)(eslint-import-resolver-webpack@0.13.2)(eslint@8.54.0) find-root: 1.1.0 has: 1.0.4 interpret: 1.4.0 @@ -8353,7 +8213,7 @@ packages: - supports-color dev: true - /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint-import-resolver-webpack@0.13.2)(eslint@8.54.0): + /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.12.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint-import-resolver-webpack@0.13.2)(eslint@8.54.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} peerDependencies: @@ -8374,7 +8234,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.54.0)(typescript@5.2.2) + '@typescript-eslint/parser': 6.12.0(eslint@8.54.0)(typescript@5.0.4) debug: 3.2.7 eslint: 8.54.0 eslint-import-resolver-node: 0.3.9 @@ -8533,7 +8393,7 @@ packages: - eslint-import-resolver-webpack - supports-color - /eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint-import-resolver-webpack@0.13.2)(eslint@8.54.0): + /eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.12.0)(eslint-import-resolver-typescript@3.6.1)(eslint-import-resolver-webpack@0.13.2)(eslint@8.54.0): resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} engines: {node: '>=4'} peerDependencies: @@ -8543,7 +8403,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.54.0)(typescript@5.2.2) + '@typescript-eslint/parser': 6.12.0(eslint@8.54.0)(typescript@5.0.4) array-includes: 3.1.7 array.prototype.findlastindex: 1.2.3 array.prototype.flat: 1.3.2 @@ -8552,7 +8412,7 @@ packages: doctrine: 2.1.0 eslint: 8.54.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint-import-resolver-webpack@0.13.2)(eslint@8.54.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.12.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint-import-resolver-webpack@0.13.2)(eslint@8.54.0) hasown: 2.0.0 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -12620,10 +12480,6 @@ packages: - supports-color dev: true - /natural-compare-lite@1.4.0: - resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} - dev: true - /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -16384,6 +16240,7 @@ packages: dependencies: tslib: 1.14.1 typescript: 5.2.2 + dev: false /tsx@3.14.0: resolution: {integrity: sha512-xHtFaKtHxM9LOklMmJdI3BEnQq/D5F73Of2E1GDrITi9sgoVkvIsrQUTY1G8FlmGtA+awCI4EBlTRRYxkL2sRg==} @@ -17324,7 +17181,7 @@ packages: engines: {node: '>=12'} dev: true - /xo@0.54.2(eslint-import-resolver-typescript@3.6.1)(webpack@5.89.0): + /xo@0.54.2(@typescript-eslint/parser@6.12.0)(eslint-import-resolver-typescript@3.6.1)(webpack@5.89.0): resolution: {integrity: sha512-1S3r+ecCg8OVPtu711as+cgwxOg+WQNRgSzqZ+OHzYlsa8CpW3ych0Ve9k8Q2QG6gqO3HSpaS5AXi9D0yPUffg==} engines: {node: '>=14.16'} hasBin: true @@ -17335,20 +17192,17 @@ packages: optional: true dependencies: '@eslint/eslintrc': 1.4.1 - '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.54.0)(typescript@5.2.2) - '@typescript-eslint/parser': 5.62.0(eslint@8.54.0)(typescript@5.2.2) arrify: 3.0.0 cosmiconfig: 8.3.6(typescript@5.2.2) define-lazy-prop: 3.0.0 eslint: 8.54.0 eslint-config-prettier: 8.10.0(eslint@8.54.0) eslint-config-xo: 0.43.1(eslint@8.54.0) - eslint-config-xo-typescript: 0.57.0(@typescript-eslint/eslint-plugin@5.62.0)(@typescript-eslint/parser@5.62.0)(eslint@8.54.0)(typescript@5.2.2) eslint-formatter-pretty: 5.0.0 eslint-import-resolver-webpack: 0.13.2(eslint-plugin-import@2.29.1)(webpack@5.89.0) eslint-plugin-ava: 14.0.0(eslint@8.54.0) eslint-plugin-eslint-comments: 3.2.0(eslint@8.54.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint-import-resolver-webpack@0.13.2)(eslint@8.54.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.12.0)(eslint-import-resolver-typescript@3.6.1)(eslint-import-resolver-webpack@0.13.2)(eslint@8.54.0) eslint-plugin-n: 15.7.0(eslint@8.54.0) eslint-plugin-no-use-extend-native: 0.5.0 eslint-plugin-prettier: 4.2.1(eslint-config-prettier@8.10.0)(eslint@8.54.0)(prettier@2.8.8) @@ -17372,6 +17226,7 @@ packages: typescript: 5.2.2 webpack: 5.89.0 transitivePeerDependencies: + - '@typescript-eslint/parser' - eslint-import-resolver-typescript - supports-color dev: true diff --git a/vite.config.mts b/vite.config.mts index 73a507649e..f4bf811dfe 100644 --- a/vite.config.mts +++ b/vite.config.mts @@ -1,10 +1,25 @@ -import { defineConfig } from 'vite'; +import { PluginOption, defineConfig } from 'vite'; export default defineConfig({ server: { open: '?hidepassed', }, mode: 'testing', + plugins: [ + /** + * A similar plugin exists for our rollup builds + */ + { + name: 'define custom import.meta.env', + async transform(code) { + if (code.includes('import.meta.env.VM_LOCAL_DEV')) { + return code.replace(/import.meta.env.VM_LOCAL_DEV/g, 'true'); + } + return undefined; + }, + enforce: 'pre', + }, + ], resolve: { extensions: ['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json', '.d.ts'], },