This commit is contained in:
bQUARKz 2026-02-10 10:09:23 +00:00
parent 07e9871b13
commit 7eb2e5d75b
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
6 changed files with 92 additions and 64 deletions

View File

@ -293,8 +293,8 @@ impl BytecodeEmitter {
stack_height = (stack_height - (*arg_count as i32)).max(0);
}
}
InstrKind::ImportCall { dep_alias, module_path, symbol_name, arg_count } => {
let label = format!("@{}::{}:{}", dep_alias, module_path, symbol_name);
InstrKind::ImportCall { dep_alias, module_path, base_name, sig, arg_count } => {
let label = format!("@{}::{}:{}#sig{}", dep_alias, module_path, base_name, sig.0);
asm_instrs.push(Asm::Op(OpCode::Call, vec![Operand::Label(label)]));
stack_height = (stack_height - (*arg_count as i32)).max(0);
}

View File

@ -4,8 +4,9 @@ use crate::frontends::pbs::ast::*;
use crate::frontends::pbs::contracts::ContractRegistry;
use crate::frontends::pbs::symbols::*;
use crate::frontends::pbs::types::PbsType;
use crate::ir_core::ids::{FieldId, FunctionId, TypeId, ValueId};
use crate::ir_core::{Block, ConstPool, Function, Instr, InstrKind, Module, Param, Program, Terminator, Type, Signature, global_signature_interner};
use crate::ir_core::ids::{FieldId, FunctionId, TypeId, ValueId, SigId};
use crate::ir_core::{Block, ConstPool, Function, Instr, InstrKind, Module, Param, Program, Terminator, Type};
use crate::ir_core::signature::{Signature, global_signature_interner};
use prometeu_analysis::{NameInterner, NodeId};
use std::collections::HashMap;
@ -44,6 +45,21 @@ pub struct Lowerer<'a> {
}
impl<'a> Lowerer<'a> {
fn sig_from_pbs_fn(&self, pbs: &PbsType) -> Option<SigId> {
if let PbsType::Function { params, return_type } = pbs {
let mut core_params = Vec::with_capacity(params.len());
for p in params {
core_params.push(self.convert_pbs_type(p));
}
let core_ret = self.convert_pbs_type(return_type);
let sig = Signature { params: core_params, return_type: core_ret };
// Global, deterministic interner across the compiler process
let mut guard = global_signature_interner().lock().unwrap();
Some(guard.intern(sig))
} else {
None
}
}
#[inline]
fn hash_tag_u16(s: &str) -> u16 {
// FNV-1a 16-bit (simple, deterministic, allows small collisions)
@ -1133,18 +1149,28 @@ impl<'a> Lowerer<'a> {
if parts.len() == 2 {
let dep_alias = parts[0].to_string();
let module_path = parts[1].to_string();
// Encode arity to disambiguate overloads at link time: symbol/arity
let base = self.interner.resolve(sym.name).to_string();
let symbol_with_arity = format!("{}/{}", base, n.args.len());
self.emit(InstrKind::ImportCall(
// Compute signature id from symbol type
let base_name = self.interner.resolve(sym.name).to_string();
if let Some(ty) = &sym.ty {
if let Some(sig) = self.sig_from_pbs_fn(ty) {
self.emit(InstrKind::ImportCall {
dep_alias,
module_path,
symbol_with_arity,
n.args.len() as u32,
));
base_name,
sig,
arg_count: n.args.len() as u32,
});
return Ok(());
}
}
self.error(
"E_LOWER_SIGNATURE",
format!("Missing or non-function type for imported symbol '{}' to compute signature id", base_name),
self.arena.span(n.callee),
);
return Err(());
}
}
}
self.error(
@ -1292,14 +1318,37 @@ impl<'a> Lowerer<'a> {
// Usar o binding real do import para este Service (ex.: Log -> (sdk, log))
let obj_name_str = obj_name.to_string();
if let Some((dep_alias, module_path)) = self.import_bindings.get(&obj_name_str).cloned() {
// Encode arity to disambiguate overloads at link time: symbol/arity
let symbol_name = format!("{}/{}", member_name, n.args.len());
self.emit(InstrKind::ImportCall(
// Try to find the function symbol in imported value symbols using `Service.method`
let qualified = format!("{}.{}", obj_name, member_name);
let sig_opt = self
.imported_symbols
.value_symbols
.symbols
.values()
.find(|s| self.interner.resolve(s.name) == qualified)
.and_then(|s| s.ty.as_ref())
.and_then(|t| self.sig_from_pbs_fn(t));
if let Some(sig) = sig_opt {
self.emit(InstrKind::ImportCall {
dep_alias,
module_path,
symbol_name,
n.args.len() as u32,
));
base_name: member_name.to_string(),
sig,
arg_count: n.args.len() as u32,
});
} else {
// Fallback: attempt to compute from service method type if exposed in type_constants or error deterministically
self.error(
"E_LOWER_SIGNATURE",
format!(
"Unable to determine signature for imported service method '{}.{}' (missing type info)",
obj_name, member_name
),
self.arena.span(n.callee),
);
return Err(());
}
} else {
// Sem binding de import conhecido: erro claro de serviço não importado
self.error(

View File

@ -1,4 +1,4 @@
use super::ids::{ConstId, FieldId, FunctionId, TypeId, ValueId};
use super::ids::{ConstId, FieldId, FunctionId, TypeId, ValueId, SigId};
use crate::common::spans::Span;
use serde::{Deserialize, Serialize};
@ -23,8 +23,15 @@ pub enum InstrKind {
PushBounded(u32),
/// Placeholder for function calls.
Call(FunctionId, u32),
/// External calls (imports). (dep_alias, module_path, symbol_name, arg_count)
ImportCall(String, String, String, u32),
/// External calls (imports).
/// Carries dependency alias, module path, base function name, precise signature id, and arg count.
ImportCall {
dep_alias: String,
module_path: String,
base_name: String,
sig: SigId,
arg_count: u32,
},
/// Host calls (syscalls). (id, return_slots)
HostCall(u32, u32),
/// Variable access.

View File

@ -5,7 +5,7 @@
//! easy to lower into VM-specific bytecode.
use crate::common::spans::Span;
use crate::ir_core::ids::FunctionId;
use crate::ir_core::ids::{FunctionId, SigId};
use crate::ir_vm::types::{ConstId, TypeId};
/// An `Instruction` combines an instruction's behavior (`kind`) with its
@ -134,7 +134,8 @@ pub enum InstrKind {
ImportCall {
dep_alias: String,
module_path: String,
symbol_name: String,
base_name: String,
sig: SigId,
arg_count: u32,
},
/// Returns from the current function. The return value (if any) should be on top of the stack.
@ -248,7 +249,8 @@ mod tests {
InstrKind::ImportCall {
dep_alias: "std".to_string(),
module_path: "math".to_string(),
symbol_name: "abs".to_string(),
base_name: "abs".to_string(),
sig: SigId(1),
arg_count: 1,
},
InstrKind::Ret,
@ -341,7 +343,8 @@ mod tests {
"ImportCall": {
"dep_alias": "std",
"module_path": "math",
"symbol_name": "abs",
"base_name": "abs",
"sig": 1,
"arg_count": 1
}
},

View File

@ -124,18 +124,17 @@ pub fn lower_function(
arg_count: *arg_count
}, None));
}
ir_core::InstrKind::ImportCall(dep_alias, module_path, symbol_name, arg_count) => {
ir_core::InstrKind::ImportCall { dep_alias, module_path, base_name, sig, arg_count } => {
// Pop arguments from type stack
for _ in 0..*arg_count {
stack_types.pop();
}
// Push return type (Assume Int for v0 imports if unknown)
stack_types.push(ir_core::Type::Int);
// Do not assume a return type here; VM semantics should be verified elsewhere.
vm_func.body.push(ir_vm::Instruction::new(ir_vm::InstrKind::ImportCall {
dep_alias: dep_alias.clone(),
module_path: module_path.clone(),
symbol_name: symbol_name.clone(),
base_name: base_name.clone(),
sig: *sig,
arg_count: *arg_count,
}, None));
}

View File

@ -15,36 +15,6 @@
## Phase 3 — JVM-like Symbol Identity: Signature-based Overload & Constant-Pool Mindset
### PR-07 (5 pts) — Introduce Signature interning (`SigId`) and descriptor canonicalization
**Briefing**
Overload must be by signature, not by `name/arity`.
**Target**
Create a canonical function descriptor system (JVM-like) and intern signatures.
**Scope**
* Add `Signature` model:
* params types + return type
* Add `SignatureInterner` -> `SigId`
* Add `descriptor()` canonical representation (stable, deterministic).
**Requirements Checklist**
* [ ] `SigId` is used as identity in compiler IR.
* [ ] Descriptor is stable and round-trippable.
**Completion Tests**
* [ ] `debug(int)->void` and `debug(string)->void` produce different descriptors.
* [ ] Descriptor stability tests.
---
### PR-08 (5 pts) — Replace `name/arity` import/export keys with `(name, SigId)`
**Briefing**