@@ -6,12 +6,10 @@ use std::collections::{HashMap, HashSet};
66use std:: time:: Instant ;
77
88use anyhow:: { Context , Result } ;
9- use perry_hir:: Module as HirModule ;
109
11- use crate :: module:: LlModule ;
12- use crate :: strings:: StringPool ;
1310use crate :: types:: { LlvmType , DOUBLE , I64 , VOID } ;
1411
12+ use super :: artifact_context:: { ModuleArtifactsCtx , OptsView } ;
1513use super :: closure:: {
1614 compile_closure, compile_typed_f64_closure, compile_typed_i1_closure,
1715 compile_typed_i32_closure, compile_typed_string_closure,
@@ -27,78 +25,9 @@ use super::method::{
2725 compile_typed_string_method,
2826} ;
2927use super :: native_namespace_exports:: emit_native_namespace_reexport_getters;
30- use super :: opts:: CrossModuleCtx ;
3128use super :: spec_function_length;
32- use super :: typed_abi:: TypedFunctionTrampolineKind ;
33-
34- /// Read-only view of the `CompileOptions` fields that the artifact
35- /// emission step references via `opts.X`. Bundled into a struct so the
36- /// moved block (originally written against `let opts = …;` of type
37- /// `CompileOptions`) can keep its `opts.X` syntax without holding a
38- /// `&CompileOptions` borrow — that borrow is unavailable at the call
39- /// site, because `compile_module`'s prelude moves several `opts`
40- /// fields into `CrossModuleCtx` before invoking this function.
41- struct OptsView < ' a > {
42- import_function_prefixes : & ' a std:: collections:: HashMap < String , String > ,
43- imported_classes : & ' a [ super :: opts:: ImportedClass ] ,
44- is_entry_module : bool ,
45- non_entry_module_prefixes : & ' a [ String ] ,
46- output_type : & ' a str ,
47- }
4829use super :: string_pool:: emit_string_pool;
49-
50- /// All the data computed by the prelude of `compile_module` that the
51- /// tail half (this file) needs. Bundled so the call from
52- /// `compile_module` stays a single line; field names mirror the
53- /// in-prelude local names so the moved block reads unchanged once
54- /// destructured.
55- pub ( super ) struct ModuleArtifactsCtx < ' a > {
56- pub progress : & ' a super :: CompileProgress ,
57- pub llmod : & ' a mut LlModule ,
58- pub target_triple : & ' a str ,
59- pub strings : & ' a mut StringPool ,
60- pub hir : & ' a HirModule ,
61- pub import_function_prefixes : & ' a std:: collections:: HashMap < String , String > ,
62- pub imported_classes : & ' a [ super :: opts:: ImportedClass ] ,
63- pub is_entry_module : bool ,
64- pub non_entry_module_prefixes : & ' a [ String ] ,
65- pub output_type : & ' a str ,
66- pub module_prefix : & ' a String ,
67- pub class_table : & ' a HashMap < String , & ' a perry_hir:: Class > ,
68- pub class_ids : & ' a HashMap < String , u32 > ,
69- pub enum_table : & ' a HashMap < ( String , String ) , perry_hir:: EnumValue > ,
70- pub module_globals : & ' a HashMap < u32 , String > ,
71- pub module_global_types : & ' a HashMap < u32 , perry_hir:: types:: Type > ,
72- pub static_field_globals : & ' a HashMap < ( String , String ) , String > ,
73- pub method_names : & ' a HashMap < ( String , String ) , String > ,
74- pub func_names : & ' a HashMap < u32 , String > ,
75- pub func_signatures : & ' a HashMap < u32 , ( usize , bool , bool , bool ) > ,
76- pub func_synthetic_arguments : & ' a std:: collections:: HashSet < u32 > ,
77- pub module_boxed_vars : & ' a std:: collections:: HashSet < u32 > ,
78- /// Typed-ABI capture-representation oracle: module-wide `Stmt::Let` types
79- /// MINUS boxed ids (#5869). Only the typed closure clones read this.
80- pub module_local_types : & ' a HashMap < u32 , perry_hir:: types:: Type > ,
81- /// #6369: receiver-type oracle for closure bodies — the same module-wide
82- /// `Stmt::Let` types with no representation filtering, mirroring the
83- /// `module_global_types` seed that `compile_function` / `compile_method`
84- /// already use. Feeds `FnCtx.local_types` only.
85- pub module_receiver_types : & ' a HashMap < u32 , perry_hir:: types:: Type > ,
86- pub closure_rest_params : & ' a HashMap < u32 , usize > ,
87- pub closure_synthetic_arguments : & ' a std:: collections:: HashSet < u32 > ,
88- pub closure_rest_and_arguments : & ' a std:: collections:: HashSet < u32 > ,
89- pub closure_arities : & ' a HashMap < u32 , u32 > ,
90- pub closure_lengths : & ' a HashMap < u32 , u32 > ,
91- pub closure_arrow_functions : & ' a std:: collections:: HashSet < u32 > ,
92- pub trusted_box_closures :
93- & ' a std:: collections:: HashMap < u32 , super :: closure_collect:: TrustedBoxClosure > ,
94- pub closures : & ' a [ ( perry_hir:: types:: FuncId , perry_hir:: Expr ) ] ,
95- pub class_keys_init_data : & ' a [ ( String , String , u32 , Vec < u64 > , Vec < u64 > ) ] ,
96- /// #8122: keys global → (class id, packed GcHeader word) for the classes
97- /// whose inline-`new` header image module init must compose.
98- pub class_header_image_inits : & ' a std:: collections:: HashMap < String , ( u32 , u64 ) > ,
99- pub imported_class_stubs : & ' a [ perry_hir:: Class ] ,
100- pub cross_module : & ' a CrossModuleCtx ,
101- }
30+ use super :: typed_abi:: TypedFunctionTrampolineKind ;
10231
10332/// Emit the artifact tail: bodies, wrappers, namespace globals, entry
10433/// function, string pool. Mirrors the in-prelude execution order of
@@ -393,6 +322,7 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> {
393322 None ,
394323 Some ( nonnegative_index_params) ,
395324 false ,
325+ false ,
396326 )
397327 . with_context ( || {
398328 format ! (
@@ -427,8 +357,46 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> {
427357 None ,
428358 None ,
429359 false ,
360+ false ,
430361 )
431362 . with_context ( || format ! ( "lowering method '{}::{}'" , class. name, method. name) ) ?;
363+ if cross_module
364+ . guarded_undefined_method_params
365+ . contains_key ( & ( class. name . clone ( ) , method. name . clone ( ) ) )
366+ {
367+ compile_method (
368+ llmod,
369+ class,
370+ method,
371+ func_names,
372+ strings,
373+ class_table,
374+ method_names,
375+ module_globals,
376+ module_global_types,
377+ opts. import_function_prefixes ,
378+ enum_table,
379+ static_field_globals,
380+ class_ids,
381+ func_signatures,
382+ func_synthetic_arguments,
383+ module_boxed_vars,
384+ closure_rest_params,
385+ cross_module,
386+ None ,
387+ false ,
388+ None ,
389+ None ,
390+ false ,
391+ true ,
392+ )
393+ . with_context ( || {
394+ format ! (
395+ "lowering exact-undefined clone of method '{}::{}'" ,
396+ class. name, method. name
397+ )
398+ } ) ?;
399+ }
432400 // Representation-selection Phase 5a: the additive `internal`
433401 // proven-`this` clone. Same HIR, same ABI, same shadow-bound
434402 // tagged-at-rest receiver slot — only `this.field` lowering
@@ -464,13 +432,51 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> {
464432 Some ( fact. clone ( ) ) ,
465433 None ,
466434 false ,
435+ false ,
467436 )
468437 . with_context ( || {
469438 format ! (
470439 "lowering proven-`this` clone of method '{}::{}'" ,
471440 class. name, method. name
472441 )
473442 } ) ?;
443+ if cross_module
444+ . guarded_undefined_method_params
445+ . contains_key ( & ( class. name . clone ( ) , method. name . clone ( ) ) )
446+ {
447+ compile_method (
448+ llmod,
449+ class,
450+ method,
451+ func_names,
452+ strings,
453+ class_table,
454+ method_names,
455+ module_globals,
456+ module_global_types,
457+ opts. import_function_prefixes ,
458+ enum_table,
459+ static_field_globals,
460+ class_ids,
461+ func_signatures,
462+ func_synthetic_arguments,
463+ module_boxed_vars,
464+ closure_rest_params,
465+ cross_module,
466+ None ,
467+ false ,
468+ Some ( fact. clone ( ) ) ,
469+ None ,
470+ false ,
471+ true ,
472+ )
473+ . with_context ( || {
474+ format ! (
475+ "lowering proven-`this` exact-undefined clone of method '{}::{}'" ,
476+ class. name, method. name
477+ )
478+ } ) ?;
479+ }
474480
475481 // #8607: a second, stricter clone for the Phase 3b
476482 // provenance+containment route. Its synthetic immutable
@@ -505,6 +511,7 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> {
505511 Some ( fact. clone ( ) ) ,
506512 None ,
507513 true ,
514+ false ,
508515 )
509516 . with_context ( || {
510517 format ! (
@@ -544,6 +551,7 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> {
544551 None ,
545552 None ,
546553 false ,
554+ false ,
547555 )
548556 . with_context ( || {
549557 format ! (
@@ -611,6 +619,7 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> {
611619 None ,
612620 None ,
613621 false ,
622+ false ,
614623 )
615624 . with_context ( || format ! ( "lowering getter '{}::{}'" , class. name, prop) ) ?;
616625 }
@@ -666,6 +675,7 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> {
666675 None ,
667676 None ,
668677 false ,
678+ false ,
669679 )
670680 . with_context ( || format ! ( "lowering setter '{}::{}'" , class. name, prop) ) ?;
671681 }
@@ -763,6 +773,7 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> {
763773 None ,
764774 None ,
765775 false ,
776+ false ,
766777 )
767778 . with_context ( || format ! ( "lowering constructor for '{}'" , class. name) ) ?;
768779 }
0 commit comments