lyng/bytecode_migration_plan.md

3.1 KiB

Bytecode Migration Plan

Goal: migrate the compiler so all values live in frames/bytecode, keeping JVM tests green after each step.

Steps

  • Step 1: Module/import slots seeded into module frame; bytecode module resolution works across closures.
  • Step 2: Allow implicit/qualified this member refs to compile to bytecode.
    • Enable bytecode for ImplicitThisMethodCallRef, QualifiedThisMethodSlotCallRef, QualifiedThisFieldSlotRef.
    • Keep unsupported cases blocked: ClassScopeMemberRef, dynamic receivers, delegated members.
    • JVM tests must be green before commit.
  • Step 3: Bytecode support for try/catch/finally.
    • Implement bytecode emission for try/catch and finally blocks.
    • Preserve existing error/stack semantics.
    • JVM tests must be green before commit.

Remaining Migration (prioritized)

  • Step 4: Allow bytecode wrapping for supported declaration statements.
    • Enable DestructuringVarDeclStatement and ExtensionPropertyDeclStatement in containsUnsupportedForBytecode.
    • Keep JVM tests green before commit.
  • Step 5: Enable bytecode for delegated var declarations.
    • Revisit containsDelegatedRefs guard for DelegatedVarDeclStatement.
    • Ensure delegate binding uses explicit Statement objects (no inline suspend lambdas).
    • Keep JVM tests green before commit.
  • Step 6: Map literal spread in bytecode.
    • Replace MapLiteralEntry.Spread bytecode exception with runtime putAll/merge logic.
  • Step 7: Class-scope member refs in bytecode.
    • Support ClassScopeMemberRef without scope-map fallback.
  • Step 8: ObjDynamic member access in bytecode.
    • Allow dynamic receiver field/method lookup without falling back to interpreter.
  • Step 9: Module-level bytecode execution.
    • Compile Script bodies to bytecode instead of interpreting at module scope.
    • Keep import/module slot seeding in frame-only flow.
  • Step 10: Bytecode for declaration statements in module scripts.
    • Support ClassDeclStatement, FunctionDeclStatement, EnumDeclStatement in bytecode compilation.
    • Keep a mixed execution path for declarations (module bytecode calls statement bodies via CALL_SLOT).
    • Ensure module object member refs compile as instance access (not class-scope).
  • Step 11: Destructuring assignment bytecode.
    • Handle [a, b] = expr (AssignRef target ListLiteralRef) without interpreter fallback.
  • Step 12: Optional member assign-ops and inc/dec in bytecode.
    • Support a?.b += 1 and a?.b++ for FieldRef targets.
    • Fix post-inc return value for object slots stored in scope frames.
    • Handle optional receivers for member assign-ops and inc/dec without evaluating operands on null.
    • Support class-scope and index optional inc/dec paths in bytecode.

Notes

  • Keep imports bound to module frame slots; no scope map writes for imports.
  • Avoid inline suspend lambdas in compiler hot paths; use explicit object : Statement().
  • Do not reintroduce bytecode fallback opcodes; all symbol resolution remains compile-time only.