Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed constv
Binary file not shown.
47 changes: 2 additions & 45 deletions crates/perry-codegen/src/codegen/artifacts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1348,47 +1348,6 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> {
namespace_key_globals.push((gname, byte_len));
}
}
let mut namespace_extern_prefixes = std::collections::BTreeSet::new();
for entry in &cross_module.namespace_entries {
if let super::opts::NamespaceEntryKind::NestedNamespace { source_prefix } = &entry.kind {
if source_prefix != module_prefix {
namespace_extern_prefixes.insert(source_prefix.clone());
}
}
}
for source_prefix in cross_module.namespace_import_prefixes.values() {
if source_prefix != module_prefix {
namespace_extern_prefixes.insert(source_prefix.clone());
}
}
for source_prefix in cross_module.namespace_member_namespace_prefixes.values() {
if source_prefix != module_prefix {
namespace_extern_prefixes.insert(source_prefix.clone());
}
}
let mut emitted_namespace_extern_prefixes = std::collections::BTreeSet::new();
for source_prefix in namespace_extern_prefixes {
if emitted_namespace_extern_prefixes.insert(source_prefix.clone()) {
llmod.add_external_global(&format!("__perry_ns_{}", source_prefix), DOUBLE);
}
}
for export in &hir.exports {
let perry_hir::Export::Named { local, exported } = export else {
continue;
};
let Some(source_prefix) = cross_module.namespace_import_prefixes.get(local) else {
continue;
};
let getter_name = format!("perry_fn_{}__{}", module_prefix, sanitize(exported));
if llmod.has_function(&getter_name) {
continue;
}
let getter = llmod.define_function(&getter_name, DOUBLE, vec![]);
let _ = getter.create_block("entry");
let blk = getter.block_mut(0).unwrap();
let value = blk.load(DOUBLE, &format!("@__perry_ns_{}", source_prefix));
blk.ret(DOUBLE, &value);
}
// For each `Expr::DynamicImport` target this module dispatches to,
// declare the foreign module's `@__perry_ns_<target_prefix>` as an
// extern global so the dispatch site can load it. Deduped via
Expand All @@ -1415,10 +1374,8 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> {
if prefix.starts_with("__native_mod__") || prefix.starts_with("__node_submod__") {
continue;
}
if emitted_namespace_extern_prefixes.insert(prefix.clone()) {
let ns_name = format!("__perry_ns_{}", prefix);
llmod.add_external_global(&ns_name, DOUBLE);
}
let ns_name = format!("__perry_ns_{}", prefix);
llmod.add_external_global(&ns_name, DOUBLE);
// Issue #753: declare each dynamic-import target's `__init`
// so the dispatch site in `Expr::DynamicImport` can call it
// before loading the namespace. The wrapper-side init is
Expand Down
3 changes: 0 additions & 3 deletions crates/perry-codegen/src/codegen/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -780,9 +780,6 @@ pub(super) fn compile_closure(
namespace_reexport_named_imports: &cross_module.namespace_reexport_named_imports,
namespace_member_prefixes: &cross_module.namespace_member_prefixes,
namespace_member_origin_names: &cross_module.namespace_member_origin_names,
namespace_member_vars: &cross_module.namespace_member_vars,
namespace_member_namespace_prefixes: &cross_module.namespace_member_namespace_prefixes,
namespace_import_prefixes: &cross_module.namespace_import_prefixes,
imported_async_funcs: &cross_module.imported_async_funcs,
local_async_funcs: &cross_module.local_async_funcs,
local_generator_funcs: &cross_module.local_generator_funcs,
Expand Down
6 changes: 0 additions & 6 deletions crates/perry-codegen/src/codegen/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -613,9 +613,6 @@ pub(super) fn compile_module_entry(
namespace_reexport_named_imports: &cross_module.namespace_reexport_named_imports,
namespace_member_prefixes: &cross_module.namespace_member_prefixes,
namespace_member_origin_names: &cross_module.namespace_member_origin_names,
namespace_member_vars: &cross_module.namespace_member_vars,
namespace_member_namespace_prefixes: &cross_module.namespace_member_namespace_prefixes,
namespace_import_prefixes: &cross_module.namespace_import_prefixes,
imported_async_funcs: &cross_module.imported_async_funcs,
local_async_funcs: &cross_module.local_async_funcs,
local_generator_funcs: &cross_module.local_generator_funcs,
Expand Down Expand Up @@ -1148,9 +1145,6 @@ pub(super) fn compile_module_entry(
namespace_reexport_named_imports: &cross_module.namespace_reexport_named_imports,
namespace_member_prefixes: &cross_module.namespace_member_prefixes,
namespace_member_origin_names: &cross_module.namespace_member_origin_names,
namespace_member_vars: &cross_module.namespace_member_vars,
namespace_member_namespace_prefixes: &cross_module.namespace_member_namespace_prefixes,
namespace_import_prefixes: &cross_module.namespace_import_prefixes,
imported_async_funcs: &cross_module.imported_async_funcs,
local_async_funcs: &cross_module.local_async_funcs,
local_generator_funcs: &cross_module.local_generator_funcs,
Expand Down
3 changes: 0 additions & 3 deletions crates/perry-codegen/src/codegen/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -516,9 +516,6 @@ pub(super) fn compile_function(
namespace_reexport_named_imports: &cross_module.namespace_reexport_named_imports,
namespace_member_prefixes: &cross_module.namespace_member_prefixes,
namespace_member_origin_names: &cross_module.namespace_member_origin_names,
namespace_member_vars: &cross_module.namespace_member_vars,
namespace_member_namespace_prefixes: &cross_module.namespace_member_namespace_prefixes,
namespace_import_prefixes: &cross_module.namespace_import_prefixes,
imported_async_funcs: &cross_module.imported_async_funcs,
local_async_funcs: &cross_module.local_async_funcs,
local_generator_funcs: &cross_module.local_generator_funcs,
Expand Down
2 changes: 1 addition & 1 deletion crates/perry-codegen/src/codegen/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1145,7 +1145,7 @@ pub(super) fn emit_namespace_populator(
let wrapper_name = format!(
"__perry_wrap_perry_fn_{}__{}",
source_prefix,
sanitize_member(source_local)
sanitize(source_local)
);
let arity = (*param_count).min(16);
let mut wrapper_params: Vec<crate::types::LlvmType> = vec![I64];
Expand Down
56 changes: 0 additions & 56 deletions crates/perry-codegen/src/codegen/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,31 +235,6 @@ fn node_stream_parent_kind(
None
}

fn map_set_default_super_kind<'a>(
classes: &HashMap<String, &'a perry_hir::Class>,
mut parent: Option<&'a str>,
) -> Option<i32> {
let mut depth = 0usize;
while let Some(name) = parent {
match name {
"Map" => return Some(0),
"Set" => return Some(1),
_ => {}
}
let class = classes.get(name).copied()?;
if class.constructor.is_some() {
return None;
}
parent = class.extends_name.as_deref();
depth += 1;
// Keep this bound in sync with the twin in lower_call/new_helpers.rs.
if depth > 64 {
break;
}
}
None
}

/// Compile a class instance method as a top-level LLVM function with the
/// signature `perry_method_<class>_<name>(this_box: double, args: double…)
/// -> double`. The first parameter (`this`) is stored in a slot whose
Expand Down Expand Up @@ -425,9 +400,6 @@ pub(super) fn compile_method(
namespace_reexport_named_imports: &cross_module.namespace_reexport_named_imports,
namespace_member_prefixes: &cross_module.namespace_member_prefixes,
namespace_member_origin_names: &cross_module.namespace_member_origin_names,
namespace_member_vars: &cross_module.namespace_member_vars,
namespace_member_namespace_prefixes: &cross_module.namespace_member_namespace_prefixes,
namespace_import_prefixes: &cross_module.namespace_import_prefixes,
imported_async_funcs: &cross_module.imported_async_funcs,
local_async_funcs: &cross_module.local_async_funcs,
local_generator_funcs: &cross_module.local_generator_funcs,
Expand Down Expand Up @@ -745,31 +717,6 @@ pub(super) fn compile_method(
ctx.block()
.call(DOUBLE, runtime_fn, &[(DOUBLE, &this_box), (DOUBLE, &opts)]);
}
if let Some(kind) = map_set_default_super_kind(classes, class.extends_name.as_deref()) {
let undef_lit =
crate::nanbox::double_literal(f64::from_bits(crate::nanbox::TAG_UNDEFINED));
let iterable = method
.params
.first()
.and_then(|param| ctx.locals.get(&param.id).cloned())
.map(|slot| ctx.block().load(DOUBLE, &slot))
.unwrap_or_else(|| undef_lit.clone());
let this_box = ctx
.this_stack
.last()
.cloned()
.map(|slot| ctx.block().load(DOUBLE, &slot))
.unwrap_or_else(|| undef_lit.clone());
ctx.block().call(
DOUBLE,
"js_map_set_subclass_init",
&[
(DOUBLE, &this_box),
(I32, &kind.to_string()),
(DOUBLE, &iterable),
],
);
}

// Wall 51: a no-own-ctor class with a DYNAMIC / cross-module parent
// (`class X extends _mod.Parent {}`, captured as `extends_expr`) that
Expand Down Expand Up @@ -1326,9 +1273,6 @@ pub(super) fn compile_static_method(
namespace_reexport_named_imports: &cross_module.namespace_reexport_named_imports,
namespace_member_prefixes: &cross_module.namespace_member_prefixes,
namespace_member_origin_names: &cross_module.namespace_member_origin_names,
namespace_member_vars: &cross_module.namespace_member_vars,
namespace_member_namespace_prefixes: &cross_module.namespace_member_namespace_prefixes,
namespace_import_prefixes: &cross_module.namespace_import_prefixes,
imported_async_funcs: &cross_module.imported_async_funcs,
local_async_funcs: &cross_module.local_async_funcs,
local_generator_funcs: &cross_module.local_generator_funcs,
Expand Down
4 changes: 0 additions & 4 deletions crates/perry-codegen/src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1457,9 +1457,6 @@ pub fn compile_module(hir: &HirModule, opts: CompileOptions) -> Result<Vec<u8>>
namespace_reexport_named_imports: opts.namespace_reexport_named_imports.clone(),
namespace_member_prefixes: opts.namespace_member_prefixes,
namespace_member_origin_names: opts.namespace_member_origin_names,
namespace_member_vars: opts.namespace_member_vars,
namespace_member_namespace_prefixes: opts.namespace_member_namespace_prefixes,
namespace_import_prefixes: opts.namespace_import_prefixes,
imported_async_funcs: opts.imported_async_funcs,
local_async_funcs,
local_generator_funcs,
Expand Down Expand Up @@ -1493,7 +1490,6 @@ pub fn compile_module(hir: &HirModule, opts: CompileOptions) -> Result<Vec<u8>>
symbol: ctor_name,
param_count: ic.constructor_param_count,
has_own_constructor: ic.has_own_constructor,
uses_new_target: ic.constructor_uses_new_target,
has_instance_fields: ic.has_instance_fields,
has_rest: ic.constructor_has_rest,
},
Expand Down
8 changes: 1 addition & 7 deletions crates/perry-codegen/src/codegen/module_globals_emit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,13 +270,7 @@ pub(crate) fn emit_module_globals(
// semantically wrong (it'd return the closure value instead
// of invoking it).
let is_function_alias = hir.exported_functions.iter().any(|(exp, _)| exp == name);
let is_exported_alias_source = hir.exports.iter().any(|export| {
matches!(export, perry_hir::Export::Named { local, .. } if local == name)
});
if (is_exported || is_exported_alias_source)
&& !is_also_function
&& !is_function_alias
{
if is_exported && !is_also_function && !is_function_alias {
let fn_name = format!("perry_fn_{}__{}", module_prefix, sanitize(name),);
let getter = llmod.define_function(&fn_name, DOUBLE, vec![]);
let _ = getter.create_block("entry");
Expand Down
49 changes: 11 additions & 38 deletions crates/perry-codegen/src/codegen/opts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,35 +175,16 @@ pub struct CompileOptions {
/// it dispatched `tracer.make(Math.random())` instead of
/// `random.make(Math.random())`.
pub namespace_member_prefixes: std::collections::HashMap<(String, String), String>,
/// Issue #680 / #5924 follow-up: per-namespace member origin-name overrides.
/// `namespace_member_prefixes` picks the producer module, but re-exported
/// members can be stored under a different origin export name; without this
/// `ns.alias` calls the right module with the wrong symbol name. Keyed by
/// `(namespace_local_name, exported_member_name)` → `origin_export_name`.
/// Being per-namespace also fixes #5924: `import_function_origin_names` is a
/// flat map, so two namespaces imported into the same file that both expose
/// a member with the same name (only one of them a re-export rename) would
/// clobber each other — `import { Effect, Context } from "effect"` broke
/// `Context.Service` because `Effect`'s own re-exported `Service` clobbered
/// the flat map first.
/// Issue #5924 (companion to #680/#678): per-namespace origin-name
/// resolution. Keyed by `(namespace_local_name, member_name)` →
/// `origin_name`. `import_function_origin_names` is a flat map, so when
/// two namespaces imported into the same file both have a member with
/// the same name and only one of them is a re-export rename, the
/// rename's origin-name override clobbers the other namespace's
/// (correct, unrenamed) suffix — `import { Effect, Context } from
/// "effect"` broke `Context.Service` because `Effect`'s own re-exported
/// `Service` clobbered the flat map first.
pub namespace_member_origin_names: std::collections::HashMap<(String, String), String>,
/// Issue #680 follow-up: per-namespace exported-variable members. Namespace
/// member calls need to know when `ns.member` is a getter returning a
/// closure rather than a direct function symbol; otherwise codegen emits a
/// direct call to the zero-arg getter. Keyed by `(namespace_local_name,
/// exported_member_name)`.
pub namespace_member_vars: std::collections::HashSet<(String, String)>,
/// Issue #680 follow-up: per-namespace nested namespace re-exports.
/// `export * as child` members are namespace objects, not callable/value
/// exports from the parent prefix; this map preserves the nested target
/// prefix. Keyed by `(namespace_local_name, exported_member_name)` →
/// nested module prefix.
pub namespace_member_namespace_prefixes: std::collections::HashMap<(String, String), String>,
/// Issue #680 follow-up: namespace import local → target module prefix.
/// Member-specific maps are insufficient when the namespace binding itself
/// is read as a value; codegen must return the producer's real module
/// namespace object, including nested `export * as` members.
pub namespace_import_prefixes: std::collections::HashMap<String, String>,
/// When true, `compile_module` returns the textual LLVM IR (`.ll`)
/// as bytes instead of invoking `clang -c` to produce an object file.
/// Used by the bitcode-link path (`PERRY_LLVM_BITCODE_LINK=1`).
Expand Down Expand Up @@ -494,8 +475,6 @@ pub struct ImportedClass {
pub constructor_param_count: usize,
/// Whether the source class declared its own constructor body.
pub has_own_constructor: bool,
/// Whether the source constructor symbol may read `new.target`.
pub constructor_uses_new_target: bool,
/// Whether the source class's constructor's last declared parameter is
/// `...rest`. Symmetric to `method_has_rest` but for the constructor: the
/// source module compiled `<class>_constructor(this, arg0, …)` expecting
Expand Down Expand Up @@ -570,7 +549,6 @@ pub(crate) struct ImportedCtor {
pub symbol: String,
pub param_count: usize,
pub has_own_constructor: bool,
pub uses_new_target: bool,
pub has_instance_fields: bool,
/// True when the constructor's last declared param is `...rest`. Tells
/// the cross-module `new` dispatch to pack the trailing args into an
Expand All @@ -596,14 +574,9 @@ pub(crate) struct CrossModuleCtx {
/// Issue #680: per-namespace member resolution. See doc on
/// `CompileOptions::namespace_member_prefixes`.
pub namespace_member_prefixes: std::collections::HashMap<(String, String), String>,
/// See `CompileOptions::namespace_member_origin_names` (#680 / #5924).
/// Issue #5924: per-namespace origin-name resolution. See doc on
/// `CompileOptions::namespace_member_origin_names`.
pub namespace_member_origin_names: std::collections::HashMap<(String, String), String>,
/// See `CompileOptions::namespace_member_vars`.
pub namespace_member_vars: std::collections::HashSet<(String, String)>,
/// See `CompileOptions::namespace_member_namespace_prefixes`.
pub namespace_member_namespace_prefixes: std::collections::HashMap<(String, String), String>,
/// See `CompileOptions::namespace_import_prefixes`.
pub namespace_import_prefixes: std::collections::HashMap<String, String>,
pub imported_async_funcs: std::collections::HashSet<String>,
/// FuncIds of locally-defined async functions in this module. Populated
/// from `hir.functions.is_async`. Used by `is_promise_expr` to refine
Expand Down
Loading