31 KiB
Globals, Synthetic Module Init, and FRAME_RET Agenda
Status
Open
Purpose
Define how PBS should introduce runtime globals and lifecycle-driven executable bootstrap without changing the runtime contract in this phase.
This document is the umbrella agenda for topic 19.
It exists to:
- keep the full problem framed in one place;
- define the dependency order between discussions;
- prevent later discussions from re-opening earlier boundaries casually;
- and provide the parent reference for any follow-up agendas created under this topic.
This agenda must converge on:
- the source-level model for mutable module storage;
- the lifecycle model for module init, optional program init, and frame execution;
- the ownership of
FRAME_RETonce the published entrypoint stops being the user'sframe()directly; - the migration path from explicit
FrontendSpecentrypoint configuration to source-derived PBS entrypoint discovery.
Domain Owner
docs/compiler/pbs
Este tema pertence ao domínio PBS do compiler porque afeta diretamente:
- a surface language de declarações top-level;
- a detecção de entrypoints pelo frontend PBS;
- o modelo de inicialização de módulo e programa;
- o lowering de entrypoint de frame;
- a relação entre entrypoint lógico do usuário e entrypoint publicado no artefato;
- o contrato interno entre frontend,
IRBackend,IRVMlowering e bytecode final.
Nesta fase, o owner continua sendo compiler/pbs mesmo quando o resultado reutilizar capacidades já existentes da VM, porque a discussão é sobre como o compiler vai expor e orquestrar essas capacidades.
Problema
Hoje o PBS não expõe variáveis globais mutáveis de módulo.
O topo do arquivo aceita declare const, mas declare const é compile-time e não storage runtime. Isso impede formas como:
declare struct Vec2(x: int, y: int);
declare global origin: Vec2 = new Vec2(0, 0);
Ao mesmo tempo:
- a VM já tem suporte operacional para globals por slot;
- o compiler não modela globals no IR executável atual;
- o entrypoint de frame do usuário hoje coincide, na prática, com a função que delimita o frame lógico;
- o pipeline atual usa
FRAME_RETno final desse fluxo de frame lógico. - a seleção do entrypoint ainda depende de configuração explícita em
FrontendSpec, em vez de ser derivada da própria source language do PBS.
Se introduzirmos declare global, o compiler precisará definir:
- como globals são inicializados;
- quando essa inicialização roda;
- como garantir execução uma única vez;
- como conviver com um
init()custom do usuário; - como detectar de forma canônica quais funções do usuário exercem os papéis de
initeframe; - como preservar o contrato de frame lógico quando a função publicada deixar de ser a função
frame()original do usuário.
Contexto
O estado atual do sistema é:
- PBS proíbe
lettop-level e não expõe storage mutável de módulo; declare consté avaliado em compile time e pode ser inlinado/foldado;- inicializadores não constantes como
new, call sugar,some,none,if,switche outras formas executáveis não pertencem ao modelo dedeclare const; - a VM do runtime já possui
GetGlobaleSetGlobal; - o
IRBackendexecutável atual modela locals, calls, jumps e literais, mas não modela globals; - o entrypoint de frame hoje é tratado como raiz do frame lógico, inclusive para o ponto final onde
FRAME_RETé emitido; - o frontend PBS ainda depende de configuração explícita em
FrontendSpecpara saber qual callable é o entrypoint publicado; - hoje isso aparece como acoplamento a nomes/configuração que deveriam ser deduzidos pela própria linguagem.
O cenário motivador é permitir globals de módulo no PBS sem exigir, nesta fase, mudança de runtime.
Também queremos aproveitar essa discussão para mover a detecção de entrypoint para a source language do PBS, usando atributos explícitos:
[Init]
fn init() -> void {}
[Frame]
fn frame() -> void {}
Essa direção permitiria ao frontend PBS:
- localizar explicitamente o init do usuário;
- localizar explicitamente o frame root do usuário;
- montar o wrapper sintético final sem depender de configuração paralela em
FrontendSpec; - eliminar, nesta linha de evolução, a configuração explícita atual de entrypoint no registry/spec do frontend.
Esta agenda também cobre a extensão desse modelo para discutir:
- se
[Init]deve existir apenas como hook final de programa ou também como surface por módulo; - qual é exatamente o comportamento operacional de
[Frame]como root lógico de frame do usuário; - como
[Init]por módulo,[Init]final de programa, wrapper sintético eFRAME_RETse compõem sem ambiguidade.
Isso empurra a solução para o compiler:
- synth de init por módulo;
- synth de wrapper do frame published entrypoint;
- eventual símbolo privado
boot_done; - redefinição do ponto onde o frame lógico realmente termina;
- detecção de
init/framea partir de atributos de source; - remoção progressiva das configs explícitas atuais em
FrontendSpec.
Inputs
Relevant inputs already present in the repository:
docs/vm-arch/ISA_CORE.mdalready exposesGET_GLOBALandSET_GLOBAL;docs/compiler/pbs/specs/13. Lowering IRBackend Specification.mdcurrently requires a canonical executable entrypoint to be declared throughFrontendSpec;docs/compiler/pbs/specs/7. Cartridge Manifest and Runtime Capabilities Specification.mdcurrently expects PBS v1 manifestentrypointto align with frontend-declaredframe.
The discussion here must preserve compatibility with those contracts unless it explicitly proposes the propagation work needed to evolve them.
Core Questions
- PBS deve introduzir
declare globalcomo declaração top-level distinta dedeclare const? declare globaldeve aceitar inicializadores executáveis comonew Vec2(...), calls e outras expressões lowerables?- O compiler deve sintetizar um module init por módulo que contenha
declare global? - A inicialização deve rodar eager no boot lógico do programa ou lazy no primeiro frame?
- Deve existir um
init()custom do usuário que roda depois de todos os module inits e antes do primeiroframe()? - O PBS deve introduzir atributos explícitos
[Init]e[Frame]para identificar as funções corretas do usuário? - A descoberta de entrypoint no frontend PBS deve deixar de depender de configuração explícita em
FrontendSpec? [Init]deve poder existir também em escopo/módulo de forma declarativa para orientar module init explícito, ou o compiler deve manter module init sempre totalmente sintético?- Qual é o contrato preciso de comportamento de
[Frame]no PBS: callable obrigatório, assinatura fixa, frequência esperada e relação com o frame lógico publicado? - O published frame entrypoint deve passar a ser um wrapper sintético, por exemplo
__pbs_frame(), em vez doframe()do usuário? FRAME_RETdeve continuar significando "fim do frame lógico" e apenas mudar de owner, saindo da função do usuário para o wrapper sintético?- Como o compiler deve tratar ordem topológica, dependências e ciclos entre globals de módulos distintos?
- Qual política vale quando algum module init ou
init()do usuário falha: retry no próximo frame, fail-fast, ou outra forma? - Globals exportados por
mod.barreldevem se comportar como storage compartilhado de módulo ou como snapshot/importação por valor?
Inputs Already Fixed Elsewhere
Os seguintes pontos já parecem fixos ou fortemente estabelecidos e não devem ser contraditos nesta agenda:
- a VM já suporta globals em nível de bytecode/execução;
declare constnão é storage mutável/runtime-initialized;- o runtime já sabe executar um entrypoint published por frame;
FRAME_RETjá é usado como marcador do fim de um frame lógico;- o frontend PBS hoje ainda carrega configuração explícita de entrypoint fora da source language;
- nesta fase queremos evitar mudanças novas no runtime e concentrar a evolução no compiler.
Decisions To Produce
Como umbrella agenda, esta agenda não deve tentar fechar toda a solução normativa de uma vez.
Ela deve sair com:
- a decomposição oficial do tema em discussões derivadas;
- a ordem canônica dessas discussões;
- os inputs e outputs esperados de cada boundary;
- a lista de artefatos que não podem ser editados antes do boundary anterior fechar.
Depois que as discussões derivadas fecharem, o conjunto deve produzir direção suficiente para virar uma decision cobrindo pelo menos:
- a surface syntax e o modelo semântico de
declare global; - o modelo de bootstrap entre module init sintético,
[Init]de programa e[Frame]; - o owner real do frame lógico publicado e o ponto correto de emissão de
FRAME_RET; - a política de descoberta de entrypoint a partir da source language do PBS;
- a política de ordenação, ciclos e falhas para globals e module init;
- a política de imports/exports para globals entre módulos.
Options
Option A
Adicionar declare global, introduzir [Init] e [Frame] como superfícies explícitas para lifecycle/entrypoint, discutir [Init] final vs [Init] por módulo, gerar module init sintético por módulo, gerar wrapper sintético de frame published entrypoint e mover o FRAME_RET para esse wrapper.
Option B
Adicionar declare global, mas exigir init totalmente estático ou restrito, sem init() custom do usuário e sem wrapper published separado do frame() atual.
Option C
Não adicionar declare global agora; manter apenas declare const e postergar a discussão até existir um modelo maior de bootstrap/program lifecycle.
Option D
Adicionar declare global, mas exigir lazy materialization no primeiro acesso em vez de module init explícito por ordem topológica.
Tradeoffs
Option A
- Prós:
- modelo explícito e fácil de explicar;
- acomoda
declare globalcom inicializadores realmente executáveis; - faz o PBS declarar na própria linguagem quais são os callables de
initeframe; - abre espaço para discutir de forma unificada
initpor módulo,initfinal e root de frame; - permite
init()custom do usuário sem mudar o runtime; - preserva o significado de
FRAME_RETcomo fim do frame lógico; - remove um acoplamento indesejado entre frontend PBS e configuração manual de entrypoint em
FrontendSpec.
- Contras:
- exige nova modelagem no compiler para globals, init synthesis e published frame wrapper;
- exige regras novas de atributo e validação de unicidade para
[Init]e[Frame]; - obriga decisão clara sobre ordem, ciclos e falhas;
- muda a relação atual entre
frame()do usuário e entrypoint publicado.
Option B
- Prós:
- escopo menor;
- reduz a superfície de lifecycle;
- pode evitar parte da complexidade de wrapper e boot state.
- Contras:
- resolve mal o caso motivador com
new Vec2(...); - produz uma feature de globais com restrição semântica forte demais;
- deixa o
init()do usuário para outra rodada e pode forçar redesign posterior.
- resolve mal o caso motivador com
Option C
- Prós:
- nenhum risco imediato em pipeline/backend;
- preserva o estado atual do compiler.
- Contras:
- não resolve o caso desejado;
- mantém uma lacuna entre capacidade da VM e surface language do PBS;
- posterga um problema arquitetural que já apareceu de forma concreta.
Option D
- Prós:
- evita bootstrap eager explícito;
- pode reduzir custo de init em módulos não usados.
- Contras:
- complica determinismo e observabilidade;
- torna mais difícil explicar dependências entre módulos;
- aumenta risco semântico para reentrância, ciclos e ordem de efeitos;
- parece desnecessariamente sofisticado para v1.
Recommendation
Seguir com a Option A.
Direção recomendada para discussão:
- introduzir
declare globalcomo nova declaração top-level distinta dedeclare const; - permitir inicializadores executáveis lowerables, incluindo
newe calls compatíveis com o modelo de lowering executável; - sintetizar um module init por módulo owner de globals;
- ordenar os module inits de forma determinística e topológica;
- introduzir
[Init]e[Frame]como superfícies explícitas de detecção do init/frame do usuário; - remover da evolução do PBS a dependência de configuração explícita de entrypoint em
FrontendSpec, migrando a seleção para a análise da source language; - discutir explicitamente se
[Init]por módulo será uma surface do usuário ou se módulo continuará com init apenas sintético; - permitir um
init()custom opcional do usuário, executado depois de todos os module inits; - publicar um wrapper sintético de frame, por exemplo
__pbs_frame(), como verdadeiro frame root; - tratar
frame()do usuário como callable normal invocado por esse wrapper; - manter
FRAME_RETcomo marcador do fim do frame lógico, mas emitido no wrapper sintético publicado em vez de noframe()do usuário; - manter toda a primeira fase restrita ao compiler e ao backend pipeline, sem novos requisitos para o runtime além dos contratos já existentes.
Essa recomendação ainda deixa alguns pontos para fechamento na decision, mas já estabelece um shape arquitetural coerente:
- storage global pertence ao módulo owner;
- bootstrap observável pertence ao compiler, não ao runtime;
frame()do usuário deixa de ser o entrypoint publicado e passa a ser o root lógico invocado pelo wrapper;FRAME_RETcontinua significando fim do frame lógico, apenas com novo owner sintético;- a seleção de entrypoint deixa de ser configuração paralela e vira semântica explícita da linguagem.
Open Questions
- O nome surface deve ser exatamente
declare global, ou outra forma top-level? - Globals devem exigir initializer obrigatório em v1, ou existirão shells reservados parecidos com builtin const?
[Init]e[Frame]devem ser atributos reservados do PBS ou outra forma de marker surface?[Init]deve exigir assinatura fixafn init() -> void?[Frame]deve exigir assinatura fixafn frame() -> void?- Deve existir no máximo um
[Init]e um[Frame]por programa, por módulo owner, ou por outro escopo? - Module init deve permanecer sempre sintético em v1, ou o usuário pode anotar hooks por módulo em alguma forma futura?
- A política de falha de init deve ser fail-fast definitivo no boot, ou existe algum caso legítimo para retry controlado?
- Reexport de globals entre módulos deve preservar identidade de storage do owner original ou materializar aliases/import bindings sem storage próprio?
- O manifest
entrypointdeve continuar expondoframepor compatibilidade nominal ou passar a refletir o símbolo sintético publicado?
Main Difficulties
Os principais pontos de dificuldade desta agenda não são sintáticos; eles estão na composição entre contratos já existentes.
1. declare global colide com o recorte atual de declare const
Hoje a semântica estática do PBS fixa que:
declare constentra no value namespace;declare constnão materializa storage mutável runtime;- inicializadores de
declare constpertencem a um subset estritamente compile-time; - dependências entre
declare constsão acíclicas e resolvidas por análise de dependência, não por ordem textual.
Introduzir declare global exige decidir o que é reaproveitado desse modelo e o que deixa de valer:
- namespace e visibilidade podem reaproveitar parte do modelo atual;
- constant evaluation não pode ser reutilizada como está;
- o modelo de dependência deixa de ser apenas compile-time e passa a produzir efeitos runtime.
2. A surface de atributos hoje tem um conjunto reservado fechado
O PBS já trata atributos como metadata compile-time com lowering explícito apenas quando outra spec define esse efeito.
Isso é favorável para [Init] e [Frame], mas cria trabalho em três frentes:
- reservar novos atributos no conjunto normativo;
- definir targets válidos, unicidade e diagnóstico;
- definir o lowering sem deixar atributos "soltos" como metadata sem efeito operacional claro.
3. O entrypoint publicado hoje ainda está acoplado ao FrontendSpec
Existe uma obrigação atual em 13. Lowering IRBackend Specification.md para o frontend declarar um EntrypointRef canônico.
A agenda 19 quer mover a descoberta para a source language, mas isso abre uma transição delicada:
- PBS precisa derivar esse
EntrypointRefda source language; - o contrato de
IRBackendnão deve perder determinismo; - a migração não pode deixar coexistirem por muito tempo duas autoridades independentes para entrypoint.
4. O manifest ainda assume frame como callable publicado
7. Cartridge Manifest and Runtime Capabilities Specification.md hoje sugere alinhamento nominal entre manifest entrypoint e callable frame.
Se o compiler publicar __pbs_frame():
- ou o manifest passa a refletir o símbolo sintético real;
- ou o manifest preserva um nome lógico enquanto o símbolo real do artefato muda;
- ou a pipeline passa a distinguir entrypoint lógico e entrypoint físico.
Sem fechar isso, a solução de wrapper fica tecnicamente incompleta.
5. FRAME_RET hoje coincide com o fim do callable do usuário
O ponto difícil não é só "mover um opcode". É redefinir qual callable delimita semanticamente o frame lógico:
frame()do usuário continua sendo apenas código de frame;- o wrapper sintético vira o owner do frame published entrypoint;
FRAME_RETcontinua com o mesmo significado semântico, mas sua posição material muda.
Isso afeta lowering, testes de conformance e a forma de explicar o modelo da linguagem.
6. Globals intermodulares introduzem um problema novo de identidade e ordem
Hoje declare const exportado via mod.barrel é simples porque não há storage mutável compartilhado.
Com declare global, a agenda precisa fechar:
- quem é o owner real do storage;
- o que um import recebe: binding para o owner ou cópia/snapshot;
- como ciclos entre módulos são detectados;
- se init pode ler globals de módulos predecessores;
- qual é a ordem determinística entre módulos quando há efeitos de inicialização.
7. A política de falha deixa de ser apenas rejeição de build
Hoje boa parte do pipeline falha antes da emissão.
Com module init e init() do usuário, surge um problema runtime-observable:
- o que acontece quando o boot parcial falha;
- se o programa entra em estado terminal;
- se existe retry;
- como isso se relaciona com o fato de
FRAME_SYNCpermanecer o safepoint normativo.
Work Boundaries
Para manter a agenda executável e evitar mistura de artefatos, o trabalho pode ser separado nos seguintes boundaries.
Boundary A. Surface Language and AST
Owner principal: syntax + AST.
Inclui:
- gramática de
declare global; - superfície de atributos
[Init]e[Frame]; - targets permitidos desses atributos;
- novos nós ou flags obrigatórios no AST para globals e lifecycle markers.
Pergunta de fechamento:
- o parser apenas aceita as superfícies ou já impõe parte das restrições estruturais de target/shape?
Boundary B. Static Semantics and Linking
Owner principal: static semantics + linking.
Inclui:
- namespace e visibilidade de
declare global; - regras de initializer obrigatório ou opcional;
- compatibilidade de tipo do initializer;
- unicidade e assinatura válida para
[Init]e[Frame]; - regras de import/export/barrel para globals;
- detecção de ciclos de dependência entre globals;
- política de identidade do storage através de imports e reexports.
Pergunta de fechamento:
- globals entram no mesmo value namespace de
let/declare constou exigem distinção semântica adicional apesar do namespace compartilhado?
Boundary C. Dynamic Semantics and Lifecycle Model
Owner principal: dynamic semantics.
Inclui:
- ordem observável entre module init,
[Init]de programa e[Frame]; - definição de boot one-shot;
- política de falha de init;
- contrato semântico de
[Frame]como raiz lógica do tick/frame do usuário; - relação entre frame lógico do usuário e entrypoint efetivamente publicado.
Pergunta de fechamento:
- o programa tem dois conceitos distintos,
logical frame rootepublished runtime entrypoint, ou a spec tenta esconder essa distinção do usuário?
Boundary D. IR and Backend Lowering
Owner principal: lowering executável.
Inclui:
- representação de globals no
IRBackendou boundary imediatamente anterior; - synthesis de module init;
- synthesis de wrapper published entrypoint;
- materialização do guard one-shot de boot;
- reposicionamento do
FRAME_RET; - preservação do
EntrypointRefcanônico para o restante do backend.
Pergunta de fechamento:
- globals entram como primitivo explícito no IR ou aparecem apenas em lowering posterior antes de IRVM/bytecode?
Boundary E. Artifact and Manifest Publication
Owner principal: artifact contracts.
Inclui:
- nome do entrypoint exposto no manifest;
- relação entre callable do usuário, símbolo sintético e entrypoint published;
- compatibilidade com o contrato atual do cartridge manifest;
- possíveis ajustes na leitura de tooling sobre qual callable é o entrypoint "real".
Pergunta de fechamento:
- o manifest publica identidade lógica da linguagem ou identidade física do artefato executável?
Boundary F. Diagnostics and Conformance
Owner principal: diagnostics + fixture model.
Inclui:
- diagnósticos para target inválido de
[Init]e[Frame]; - duplicidade ou ausência de markers obrigatórios;
- initializer inválido de
declare global; - ciclos intra/inter-módulo;
- imports/reexports ilegais de globals;
- fixture coverage para init ordering, wrapper published entrypoint e
FRAME_RET.
Pergunta de fechamento:
- quais erros pertencem ao frontend/linking e quais só podem ser cobertos por fixtures de toolchain completo?
Discussion Order
As discussões derivadas desta umbrella agenda devem seguir a ordem abaixo.
O objetivo da ordem é simples:
- fechar primeiro autoridade semântica e surface;
- depois fechar comportamento observável;
- só então descer para lowering, artefato publicado e conformance.
Stage 1. Globals Surface and Static Identity
Boundary owner:
Boundary A. Surface Language and ASTBoundary B. Static Semantics and Linking
Esta discussão deve fechar primeiro porque todas as outras dependem da definição do que é um global no PBS.
Ela precisa decidir:
- a forma exata de
declare global; - initializer obrigatório ou opcional;
- namespace, visibilidade e barrel/export/import;
- identidade do storage owner;
- política de reexport;
- ciclos e dependências entre globals em nível de linking/static semantics.
Sem esse fechamento:
- lifecycle ainda não sabe o que precisa inicializar;
- lowering ainda não sabe que entidade precisa materializar;
- manifest ainda não sabe se está publicando símbolos que dependem de storage global importado.
Stage 2. Lifecycle Markers and Program Bootstrap Semantics
Boundary owner:
Boundary C. Dynamic Semantics and Lifecycle Model
Esta discussão vem depois de Stage 1 porque init e frame só fazem sentido quando o modelo de globals já estiver fixado.
Ela precisa decidir:
- se
[Init]e[Frame]entram como superfícies oficiais; - unicidade e assinatura desses markers;
- ordem entre module init,
[Init]de programa e[Frame]; - política de boot one-shot;
- política de falha;
- papel semântico exato de
frame()do usuário.
Sem esse fechamento:
- o wrapper sintético não tem contrato observável estável;
FRAME_RETnão tem owner definido;- qualquer modelagem de IR corre risco de materializar o comportamento errado.
Stage 3. Published Entrypoint, Wrapper Ownership, and FRAME_RET
Boundary owner:
Boundary C. Dynamic Semantics and Lifecycle ModelBoundary D. IR and Backend LoweringBoundary E. Artifact and Manifest Publication
Esta discussão depende de Stage 2 porque ela não decide mais "o que é lifecycle"; ela decide como lifecycle é publicado.
Ela precisa decidir:
- se o published entrypoint é um wrapper sintético;
- qual é a relação entre
frame()do usuário e esse wrapper; - onde
FRAME_RETpassa a ser emitido; - se o manifest expõe entrypoint lógico, entrypoint físico ou ambos;
- como o
EntrypointRefdo frontend continua determinístico durante a transição.
Sem esse fechamento:
- não existe contrato estável para lowering final;
- specs de manifest e
IRBackendficam em tensão; - o tooling pode continuar com duas autoridades concorrentes para entrypoint.
Stage 4. IR Representation and Lowering Mechanics
Boundary owner:
Boundary D. IR and Backend Lowering
Esta discussão vem depois de Stage 3 porque a forma do IR depende do que exatamente precisa ser publicado e executado.
Ela precisa decidir:
- se globals entram como primitivo explícito do IR ou apenas em lowering posterior;
- como module init é representado;
- como o guard de boot é materializado;
- como o wrapper published entrypoint é emitido;
- como
FRAME_RETé reposicionado mantendo o mesmo significado.
Sem esse fechamento:
- código pode ser implementado cedo demais sobre contratos ainda móveis;
- a propagação para specs gerais de lowering fica prematura;
- testes de backend podem congelar um shape errado.
Stage 5. Diagnostics, Gates, and Conformance Coverage
Boundary owner:
Boundary F. Diagnostics and Conformance
Esta discussão deve vir por último porque ela consolida o que as anteriores já fixaram.
Ela precisa decidir:
- catálogo mínimo de diagnósticos novos;
- divisão entre erro de syntax/AST, linking/static semantics, lowering e toolchain;
- fixtures obrigatórios para globals, lifecycle, wrapper e entrypoint publication;
- critérios de aceite para a migração de
FrontendSpecentrypoint config para source-derived entrypoint discovery.
Fazer isso antes cria dois riscos:
- congelar diagnósticos para regras ainda instáveis;
- ou escrever fixtures de conformance que depois precisam ser reabertas por mudança arquitetural.
Derived Agenda Outline
Se quisermos quebrar a umbrella agenda em agendas filhas, a ordem recomendada é:
19.1. PBS Globals Surface, Identity, and Module Boundaries Agenda19.2. PBS Lifecycle Markers, Program Init, and Frame Root Semantics Agenda19.3. Published Entrypoint, Synthetic Wrapper, and FRAME_RET Ownership Agenda19.4. Globals and Lifecycle Lowering to IRBackend/IRVM Agenda19.5. Diagnostics, Manifest Propagation, and Conformance Coverage Agenda
Cada agenda filha deve declarar explicitamente:
- que deriva da umbrella agenda
19; - quais stages anteriores já são input fixo;
- e quais outputs ela precisa entregar para a agenda seguinte.
Boundary Locking Rules
Para evitar que discussões posteriores prejudiquem as anteriores, esta umbrella agenda fixa as seguintes regras de sequenciamento:
19.2não redefine surface syntax ou identidade de globals já fechadas em19.1.19.3não redefine o significado semântico de[Init],[Frame]ou boot ordering já fechados em19.2.19.4não reabre decisões de linguagem ou de lifecycle; ela apenas escolhe a representação e o mecanismo de lowering compatíveis com elas.19.5não reabre arquitetura; ela consolida diagnostics, manifest propagation e coverage.- Qualquer ponto que force reabertura de stage anterior deve voltar explicitamente para a agenda filha owner correta, em vez de ser resolvido informalmente na etapa posterior.
Likely Propagation Targets
Mesmo sem virar decision ainda, esta agenda já mostra impacto provável nos seguintes artefatos.
PBS Specs
3. Core Syntax Specification.md4. Static Semantics Specification.md9. Dynamic Semantics Specification.md11. AST Specification.md12. Diagnostics Specification.md13. Lowering IRBackend Specification.md7. Cartridge Manifest and Runtime Capabilities Specification.md
Cross-Domain / VM Architecture
docs/vm-arch/ISA_CORE.mdprovavelmente não precisa mudar em capability, mas precisa ser referenciado explicitamente como base deGET_GLOBAL/SET_GLOBAL;- specs gerais de lowering fora de
docs/compiler/pbspodem precisar propagação posterior seIRBackendganhar representação explícita de globals ou novo contrato para entrypoint published.
Compiler / Implementation Areas
- parser e AST model;
- linking/resolution;
- static semantics;
- IR model do frontend PBS;
- executable lowering para
IRBackendeIRVM; - montagem do manifest/cartridge metadata;
- suites de fixture de frontend, lowering e toolchain.
Boundary Risks
Se os boundaries acima não forem respeitados, os riscos mais prováveis são:
- criar
declare globalcomo açúcar superficial sem lifecycle coerente; - introduzir
[Init]e[Frame]sem autoridade clara sobreFrontendSpec; - mover
FRAME_RETsem redefinir com precisão o owner do frame lógico; - resolver globals intra-módulo mas deixar imports/reexports semanticamente ambíguos;
- fechar a solução do compiler sem fechar o contrato do manifest;
- misturar nesta agenda decisões de produto/runtime que deveriam continuar fora de escopo.
Expected Spec Material
Se esta agenda virar decision, a propagação esperada deve atingir pelo menos:
- spec de declarações top-level do PBS para introduzir
declare global; - spec de lifecycle/entrypoint attributes para
[Init]e[Frame]; - spec de lowering executável/
IRBackendpara module init synthesis, wrapper published entrypoint e ownership deFRAME_RET; - spec de cartridge manifest para esclarecer a relação entre entrypoint lógico do usuário e entrypoint publicado no artefato;
- diagnósticos de validação para unicidade, assinatura inválida, ciclos de init e uso incorreto de globals.
Non-Goals
Esta agenda não deve:
- redesenhar o runtime ou introduzir novas instruções de VM;
- escrever a spec normativa final de globals e lifecycle;
- redefinir o modelo geral de módulos do compiler fora do necessário para globals/init;
- resolver todos os possíveis hooks futuros de programa além de
[Init]e[Frame]; - discutir otimizações de performance de init além do necessário para garantir semântica determinística.
Next Step
Usar esta agenda como parent reference e abrir as agendas filhas na ordem abaixo:
19.1. PBS Globals Surface, Identity, and Module Boundaries Agenda19.2. PBS Lifecycle Markers, Program Init, and Frame Root Semantics Agenda19.3. Published Entrypoint, Synthetic Wrapper, and FRAME_RET Ownership Agenda19.4. Globals and Lifecycle Lowering to IRBackend/IRVM Agenda19.5. Diagnostics, Manifest Propagation, and Conformance Coverage Agenda
Somente depois do fechamento dessas agendas derivadas esta linha deve virar uma decision consolidada em docs/compiler/pbs/decisions.