-
-
Notifications
You must be signed in to change notification settings - Fork 158
perf(codegen): specialize undefined loop filters #8740
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| Versioned eligible instance methods for an exact `undefined` optional argument. | ||
| The public boxed-ABI wrapper validates the live argument bits once and sends only | ||
| that value to a private specialized body; functions and every other falsey or | ||
| non-callable value retain the ordinary JavaScript path. Mutation, closure capture, | ||
| async/generator bodies, and oversized methods are conservatively excluded. | ||
|
|
||
| This removes the per-entity optional-filter truthiness and callback arm from | ||
| codehz/ecs's 10k-entity accumulation loop. On an Apple M1 Mac mini, 11 | ||
| alternating process pairs measured 0.179437 ms versus 0.195817 ms on the exact | ||
| parent, an 8.376% median paired improvement with 11/11 wins and all output | ||
| oracles passing. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| //! Borrowed inputs for the module artifact-emission phase. | ||
|
|
||
| use std::collections::{HashMap, HashSet}; | ||
|
|
||
| use perry_hir::Module as HirModule; | ||
|
|
||
| use crate::module::LlModule; | ||
| use crate::strings::StringPool; | ||
|
|
||
| use super::opts::CrossModuleCtx; | ||
|
|
||
| /// Read-only view of the `CompileOptions` fields that artifact emission still | ||
| /// references after the pipeline has moved other fields into `CrossModuleCtx`. | ||
| pub(super) struct OptsView<'a> { | ||
| pub(super) import_function_prefixes: &'a HashMap<String, String>, | ||
| pub(super) imported_classes: &'a [super::opts::ImportedClass], | ||
| pub(super) is_entry_module: bool, | ||
| pub(super) non_entry_module_prefixes: &'a [String], | ||
| pub(super) output_type: &'a str, | ||
| } | ||
|
|
||
| /// Data computed by the `compile_module` prelude and borrowed by the artifact | ||
| /// tail. Keeping it together avoids a second oversized compiler entry module. | ||
| pub(super) struct ModuleArtifactsCtx<'a> { | ||
| pub progress: &'a super::CompileProgress, | ||
| pub llmod: &'a mut LlModule, | ||
| pub target_triple: &'a str, | ||
| pub strings: &'a mut StringPool, | ||
| pub hir: &'a HirModule, | ||
| pub import_function_prefixes: &'a HashMap<String, String>, | ||
| pub imported_classes: &'a [super::opts::ImportedClass], | ||
| pub is_entry_module: bool, | ||
| pub non_entry_module_prefixes: &'a [String], | ||
| pub output_type: &'a str, | ||
| pub module_prefix: &'a String, | ||
| pub class_table: &'a HashMap<String, &'a perry_hir::Class>, | ||
| pub class_ids: &'a HashMap<String, u32>, | ||
| pub enum_table: &'a HashMap<(String, String), perry_hir::EnumValue>, | ||
| pub module_globals: &'a HashMap<u32, String>, | ||
| pub module_global_types: &'a HashMap<u32, perry_hir::types::Type>, | ||
| pub static_field_globals: &'a HashMap<(String, String), String>, | ||
| pub method_names: &'a HashMap<(String, String), String>, | ||
| pub func_names: &'a HashMap<u32, String>, | ||
| pub func_signatures: &'a HashMap<u32, (usize, bool, bool, bool)>, | ||
| pub func_synthetic_arguments: &'a HashSet<u32>, | ||
| pub module_boxed_vars: &'a HashSet<u32>, | ||
| /// Typed-ABI capture oracle: module-wide local types minus boxed ids. | ||
| pub module_local_types: &'a HashMap<u32, perry_hir::types::Type>, | ||
| /// Source-type metadata for closure receivers; not a representation proof. | ||
| pub module_receiver_types: &'a HashMap<u32, perry_hir::types::Type>, | ||
| pub closure_rest_params: &'a HashMap<u32, usize>, | ||
| pub closure_synthetic_arguments: &'a HashSet<u32>, | ||
| pub closure_rest_and_arguments: &'a HashSet<u32>, | ||
| pub closure_arities: &'a HashMap<u32, u32>, | ||
| pub closure_lengths: &'a HashMap<u32, u32>, | ||
| pub closure_arrow_functions: &'a HashSet<u32>, | ||
| pub trusted_box_closures: &'a HashMap<u32, super::closure_collect::TrustedBoxClosure>, | ||
| pub closures: &'a [(perry_hir::types::FuncId, perry_hir::Expr)], | ||
| pub class_keys_init_data: &'a [(String, String, u32, Vec<u64>, Vec<u64>)], | ||
| /// Keys global to `(class id, packed GcHeader word)` for inline `new`. | ||
| pub class_header_image_inits: &'a HashMap<String, (u32, u64)>, | ||
| pub imported_class_stubs: &'a [perry_hir::Class], | ||
| pub cross_module: &'a CrossModuleCtx, | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,12 +6,10 @@ use std::collections::{HashMap, HashSet}; | |
| use std::time::Instant; | ||
|
|
||
| use anyhow::{Context, Result}; | ||
| use perry_hir::Module as HirModule; | ||
|
|
||
| use crate::module::LlModule; | ||
| use crate::strings::StringPool; | ||
| use crate::types::{LlvmType, DOUBLE, I64, VOID}; | ||
|
|
||
| use super::artifact_context::{ModuleArtifactsCtx, OptsView}; | ||
| use super::closure::{ | ||
| compile_closure, compile_typed_f64_closure, compile_typed_i1_closure, | ||
| compile_typed_i32_closure, compile_typed_string_closure, | ||
|
|
@@ -27,78 +25,9 @@ use super::method::{ | |
| compile_typed_string_method, | ||
| }; | ||
| use super::native_namespace_exports::emit_native_namespace_reexport_getters; | ||
| use super::opts::CrossModuleCtx; | ||
| use super::spec_function_length; | ||
| use super::typed_abi::TypedFunctionTrampolineKind; | ||
|
|
||
| /// Read-only view of the `CompileOptions` fields that the artifact | ||
| /// emission step references via `opts.X`. Bundled into a struct so the | ||
| /// moved block (originally written against `let opts = …;` of type | ||
| /// `CompileOptions`) can keep its `opts.X` syntax without holding a | ||
| /// `&CompileOptions` borrow — that borrow is unavailable at the call | ||
| /// site, because `compile_module`'s prelude moves several `opts` | ||
| /// fields into `CrossModuleCtx` before invoking this function. | ||
| struct OptsView<'a> { | ||
| import_function_prefixes: &'a std::collections::HashMap<String, String>, | ||
| imported_classes: &'a [super::opts::ImportedClass], | ||
| is_entry_module: bool, | ||
| non_entry_module_prefixes: &'a [String], | ||
| output_type: &'a str, | ||
| } | ||
| use super::string_pool::emit_string_pool; | ||
|
|
||
| /// All the data computed by the prelude of `compile_module` that the | ||
| /// tail half (this file) needs. Bundled so the call from | ||
| /// `compile_module` stays a single line; field names mirror the | ||
| /// in-prelude local names so the moved block reads unchanged once | ||
| /// destructured. | ||
| pub(super) struct ModuleArtifactsCtx<'a> { | ||
| pub progress: &'a super::CompileProgress, | ||
| pub llmod: &'a mut LlModule, | ||
| pub target_triple: &'a str, | ||
| pub strings: &'a mut StringPool, | ||
| pub hir: &'a HirModule, | ||
| pub import_function_prefixes: &'a std::collections::HashMap<String, String>, | ||
| pub imported_classes: &'a [super::opts::ImportedClass], | ||
| pub is_entry_module: bool, | ||
| pub non_entry_module_prefixes: &'a [String], | ||
| pub output_type: &'a str, | ||
| pub module_prefix: &'a String, | ||
| pub class_table: &'a HashMap<String, &'a perry_hir::Class>, | ||
| pub class_ids: &'a HashMap<String, u32>, | ||
| pub enum_table: &'a HashMap<(String, String), perry_hir::EnumValue>, | ||
| pub module_globals: &'a HashMap<u32, String>, | ||
| pub module_global_types: &'a HashMap<u32, perry_hir::types::Type>, | ||
| pub static_field_globals: &'a HashMap<(String, String), String>, | ||
| pub method_names: &'a HashMap<(String, String), String>, | ||
| pub func_names: &'a HashMap<u32, String>, | ||
| pub func_signatures: &'a HashMap<u32, (usize, bool, bool, bool)>, | ||
| pub func_synthetic_arguments: &'a std::collections::HashSet<u32>, | ||
| pub module_boxed_vars: &'a std::collections::HashSet<u32>, | ||
| /// Typed-ABI capture-representation oracle: module-wide `Stmt::Let` types | ||
| /// MINUS boxed ids (#5869). Only the typed closure clones read this. | ||
| pub module_local_types: &'a HashMap<u32, perry_hir::types::Type>, | ||
| /// #6369: receiver-type oracle for closure bodies — the same module-wide | ||
| /// `Stmt::Let` types with no representation filtering, mirroring the | ||
| /// `module_global_types` seed that `compile_function` / `compile_method` | ||
| /// already use. Feeds `FnCtx.local_types` only. | ||
| pub module_receiver_types: &'a HashMap<u32, perry_hir::types::Type>, | ||
| pub closure_rest_params: &'a HashMap<u32, usize>, | ||
| pub closure_synthetic_arguments: &'a std::collections::HashSet<u32>, | ||
| pub closure_rest_and_arguments: &'a std::collections::HashSet<u32>, | ||
| pub closure_arities: &'a HashMap<u32, u32>, | ||
| pub closure_lengths: &'a HashMap<u32, u32>, | ||
| pub closure_arrow_functions: &'a std::collections::HashSet<u32>, | ||
| pub trusted_box_closures: | ||
| &'a std::collections::HashMap<u32, super::closure_collect::TrustedBoxClosure>, | ||
| pub closures: &'a [(perry_hir::types::FuncId, perry_hir::Expr)], | ||
| pub class_keys_init_data: &'a [(String, String, u32, Vec<u64>, Vec<u64>)], | ||
| /// #8122: keys global → (class id, packed GcHeader word) for the classes | ||
| /// whose inline-`new` header image module init must compose. | ||
| pub class_header_image_inits: &'a std::collections::HashMap<String, (u32, u64)>, | ||
| pub imported_class_stubs: &'a [perry_hir::Class], | ||
| pub cross_module: &'a CrossModuleCtx, | ||
| } | ||
| use super::typed_abi::TypedFunctionTrampolineKind; | ||
|
|
||
| /// Emit the artifact tail: bodies, wrappers, namespace globals, entry | ||
| /// function, string pool. Mirrors the in-prelude execution order of | ||
|
|
@@ -393,6 +322,7 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> { | |
| None, | ||
| Some(nonnegative_index_params), | ||
| false, | ||
| false, | ||
| ) | ||
| .with_context(|| { | ||
| format!( | ||
|
|
@@ -427,8 +357,46 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> { | |
| None, | ||
| None, | ||
| false, | ||
| false, | ||
| ) | ||
| .with_context(|| format!("lowering method '{}::{}'", class.name, method.name))?; | ||
| if cross_module | ||
| .guarded_undefined_method_params | ||
| .contains_key(&(class.name.clone(), method.name.clone())) | ||
| { | ||
| compile_method( | ||
| llmod, | ||
| class, | ||
| method, | ||
| func_names, | ||
| strings, | ||
| class_table, | ||
| method_names, | ||
| module_globals, | ||
| module_global_types, | ||
| opts.import_function_prefixes, | ||
| enum_table, | ||
| static_field_globals, | ||
| class_ids, | ||
| func_signatures, | ||
| func_synthetic_arguments, | ||
| module_boxed_vars, | ||
| closure_rest_params, | ||
| cross_module, | ||
| None, | ||
| false, | ||
| None, | ||
| None, | ||
| false, | ||
| true, | ||
| ) | ||
| .with_context(|| { | ||
| format!( | ||
| "lowering exact-undefined clone of method '{}::{}'", | ||
| class.name, method.name | ||
| ) | ||
| })?; | ||
| } | ||
|
Comment on lines
+363
to
+399
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Description: Locate the population sites of `guarded_undefined_method_params` and confirm the key source.
set -euo pipefail
rg -n -C 12 'guarded_undefined_method_params' --type=rust
rg -n -C 8 'guarded_undefined_method_candidate' --type=rustRepository: PerryTS/perry Length of output: 151 🏁 Script executed: set -euo pipefail
printf '%s\n' '--- tracked Rust files containing the map or candidate ---'
rg -n -C 12 'guarded_undefined_method_params|guarded_undefined_method_candidate' --glob '*.rs' . || true
printf '%s\n' '--- candidate artifacts file ---'
fd -i 'artifacts.rs' .Repository: PerryTS/perry Length of output: 22700 🏁 Script executed: set -euo pipefail
printf '%s\n' '--- tracked files ---'
git ls-files '*.rs' | sed -n '1,120p'
printf '%s\n' '--- all textual references ---'
rg -n -C 10 'guarded_undefined|undefined_method_candidate' . || true
printf '%s\n' '--- target file ---'
fd -i 'artifacts.rs' . -x sh -c 'wc -l "$1"; rg -n -C 8 "compile_method|computed|getter|setter" "$1" | sed -n "1,260p"' sh {}Repository: PerryTS/perry Length of output: 50369 🏁 Script executed: set -euo pipefail
rg -n -C 12 'guarded_undefined_method_params|guarded_undefined_method_candidate|guarded_undefined' . || true
fd -i 'artifacts.rs' . -x wc -lRepository: PerryTS/perry Length of output: 50369 🏁 Script executed: set -euo pipefail
printf '%s\n' '--- every assignment or transfer of guarded_undefined_method_params ---'
rg -n 'guarded_undefined_method_params|guarded_undefined_method_candidates' crates/perry-codegen/src --glob '*.rs'
printf '%s\n' '--- candidate collection and CrossModuleCtx construction ---'
sed -n '1748,1790p' crates/perry-codegen/src/codegen/mod.rs
sed -n '1998,2024p' crates/perry-codegen/src/codegen/mod.rs
sed -n '2280,2310p' crates/perry-codegen/src/codegen/mod.rs
printf '%s\n' '--- artifacts lowering regions ---'
sed -n '300,475p' crates/perry-codegen/src/codegen/artifacts.rs
sed -n '500,680p' crates/perry-codegen/src/codegen/artifacts.rsRepository: PerryTS/perry Length of output: 18955 🏁 Script executed: set -euo pipefail
rg -n 'guarded_undefined_method_params|guarded_undefined_method_candidates' crates/perry-codegen/src --glob '*.rs'
sed -n '1748,1790p' crates/perry-codegen/src/codegen/mod.rs
sed -n '1998,2024p' crates/perry-codegen/src/codegen/mod.rs
sed -n '2280,2310p' crates/perry-codegen/src/codegen/mod.rs
sed -n '300,475p' crates/perry-codegen/src/codegen/artifacts.rs
sed -n '500,680p' crates/perry-codegen/src/codegen/artifacts.rsRepository: PerryTS/perry Length of output: 18787 🏁 Script executed: set -euo pipefail
printf '%s\n' '--- compile_method naming and guarded wrapper emission ---'
sed -n '90,140p' crates/perry-codegen/src/codegen/method.rs
sed -n '1148,1170p' crates/perry-codegen/src/codegen/method.rs
sed -n '200,270p' crates/perry-codegen/src/codegen/method_trampolines.rs
printf '%s\n' '--- HIR class and member definitions ---'
rg -n -C 8 'struct Class|pub struct Class|computed_members|getters:|setters:|pub methods:' crates --glob '*.rs' | sed -n '1,300p'
printf '%s\n' '--- member function name construction and method registry ---'
rg -n -C 8 'computed_members|static_accessor_fn_ids|class\.methods|methods\.insert|method_registry' crates/perry-* --glob '*.rs' | sed -n '1,420p'Repository: PerryTS/perry Length of output: 50369 🏁 Script executed: set -euo pipefail
sed -n '90,140p' crates/perry-codegen/src/codegen/method.rs
sed -n '1148,1170p' crates/perry-codegen/src/codegen/method.rs
sed -n '200,270p' crates/perry-codegen/src/codegen/method_trampolines.rs
rg -n -C 8 'struct Class|pub struct Class|computed_members|getters:|setters:|pub methods:' crates --glob '*.rs' | sed -n '1,300p'
rg -n -C 8 'computed_members|static_accessor_fn_ids|class\.methods|methods\.insert|method_registry' crates/perry-* --glob '*.rs' | sed -n '1,420p'Repository: PerryTS/perry Length of output: 50369 🏁 Script executed: set -euo pipefail
printf '%s\n' '--- exact HIR declarations ---'
rg -n -C 12 'ClassComputedMember|pub struct Class|struct Class' crates/perry-hir --glob '*.rs' | sed -n '1,260p'
printf '%s\n' '--- declaration lowering writes to member containers ---'
rg -n -C 10 'computed_members\.push|class\.computed_members|computed_members:|getters\.push|setters\.push|methods\.push' crates/perry-hir/src --glob '*.rs' | sed -n '1,500p'
printf '%s\n' '--- function name assignments near class-member lowering ---'
rg -n -C 8 'name\s*=|name:' crates/perry-hir/src/lower_decl --glob '*.rs' | sed -n '1,500p'
printf '%s\n' '--- method registry construction ---'
rg -n -C 12 'fn .*method|methods\.insert|method_names|class\.methods|computed_members' crates/perry-codegen/src/codegen/method_registry.rs crates/perry-codegen/src/codegen/artifacts.rs crates/perry-codegen/src/codegen/mod.rs | sed -n '1,500p'Repository: PerryTS/perry Length of output: 50370 🏁 Script executed: set -euo pipefail
rg -n -C 12 'ClassComputedMember|pub struct Class|struct Class' crates/perry-hir --glob '*.rs' | sed -n '1,260p'
rg -n -C 10 'computed_members\.push|class\.computed_members|computed_members:|getters\.push|setters\.push|methods\.push' crates/perry-hir/src --glob '*.rs' | sed -n '1,500p'
rg -n -C 8 'name\s*=|name:' crates/perry-hir/src/lower_decl --glob '*.rs' | sed -n '1,500p'
rg -n -C 12 'methods\.insert|method_names|class\.methods|computed_members' crates/perry-codegen/src/codegen/method_registry.rs crates/perry-codegen/src/codegen/artifacts.rs crates/perry-codegen/src/codegen/mod.rs | sed -n '1,500p'Repository: PerryTS/perry Length of output: 50370 🏁 Script executed: set -euo pipefail
printf '%s\n' '--- computed-member naming helpers ---'
rg -n -C 20 'computed_member_name|lower_getter_method_with_name|lower_setter_method_with_name|lower_class_method_with_name|fn lower_getter_method|fn lower_setter_method' crates/perry-hir/src/lower_decl --glob '*.rs'
printf '%s\n' '--- exact class lowering name range ---'
sed -n '100,190p' crates/perry-hir/src/lower_decl/class_decl.rs
sed -n '760,875p' crates/perry-hir/src/lower_decl/class_decl.rs
printf '%s\n' '--- method registry implementation ---'
cat -n crates/perry-codegen/src/codegen/method_registry.rs | sed -n '1,280p'
printf '%s\n' '--- registry call sites ---'
rg -n -C 10 'build_method|register.*method|MethodRegistry|method_names\.insert|methods\.insert' crates/perry-codegen/src/codegen --glob '*.rs' | sed -n '1,500p'Repository: PerryTS/perry Length of output: 50370 🏁 Script executed: set -euo pipefail
rg -n -C 20 'computed_member_name|lower_getter_method_with_name|lower_setter_method_with_name|lower_class_method_with_name|fn lower_getter_method|fn lower_setter_method' crates/perry-hir/src/lower_decl --glob '*.rs'
sed -n '100,190p' crates/perry-hir/src/lower_decl/class_decl.rs
sed -n '760,875p' crates/perry-hir/src/lower_decl/class_decl.rs
cat -n crates/perry-codegen/src/codegen/method_registry.rs | sed -n '1,280p'
rg -n -C 10 'build_method|register.*method|MethodRegistry|method_names\.insert|methods\.insert' crates/perry-codegen/src/codegen --glob '*.rs' | sed -n '1,500p'Repository: PerryTS/perry Length of output: 50370 🏁 Script executed: python3 - <<'PY'
from pathlib import Path
import re
mod = Path("crates/perry-codegen/src/codegen/mod.rs").read_text()
artifacts = Path("crates/perry-codegen/src/codegen/artifacts.rs").read_text()
class_decl = Path("crates/perry-hir/src/lower_decl/class_decl.rs").read_text()
producer = re.search(
r"let mut guarded_undefined_method_candidates.*?\.collect\(\);",
mod,
re.S,
)
assert producer, "candidate producer not found"
assert "class.methods.iter()" in producer.group(0)
assert "(class.name.clone(), method.name.clone())" in producer.group(0)
assert 'renamed.name = format!("__get_{}", prop);' in artifacts
assert 'renamed.name = format!("__set_{}", prop);' in artifacts
assert 'ast::MethodKind::Method => "__computed_method"' in class_decl
assert 'ast::MethodKind::Getter => "__computed_getter"' in class_decl
assert 'ast::MethodKind::Setter => "__computed_setter"' in class_decl
# These are valid Function.name values for ordinary instance methods.
for name in ("__get_value", "__set_value", "__computed_method_10_20"):
assert re.fullmatch(r"[A-Za-z_$][A-Za-z0-9_$]*", name), name
print("producer_keys_source=class.methods")
print("accessor_collision=__get_value / __set_value")
print("computed_collision=__computed_method_10_20")
print("compile_method_lookup=class.name + method.name")
print("invariant_status=producer_restricted_but_name_collision_unexcluded")
PYRepository: PerryTS/perry Length of output: 388 🏁 Script executed: python3 - <<'PY'
from pathlib import Path
import re
mod = Path("crates/perry-codegen/src/codegen/mod.rs").read_text()
artifacts = Path("crates/perry-codegen/src/codegen/artifacts.rs").read_text()
class_decl = Path("crates/perry-hir/src/lower_decl/class_decl.rs").read_text()
producer = re.search(r"let mut guarded_undefined_method_candidates.*?\.collect\(\);", mod, re.S)
assert producer and "class.methods.iter()" in producer.group(0)
assert "(class.name.clone(), method.name.clone())" in producer.group(0)
assert 'renamed.name = format!("__get_{}", prop);' in artifacts
assert 'renamed.name = format!("__set_{}", prop);' in artifacts
assert 'ast::MethodKind::Method => "__computed_method"' in class_decl
for name in ("__get_value", "__set_value", "__computed_method_10_20"):
assert re.fullmatch(r"[A-Za-z_$][A-Za-z0-9_$]*", name)
print("producer_keys_source=class.methods")
print("collision_names=__get_value,__set_value,__computed_method_10_20")
print("invariant_status=producer_restricted_but_name_collision_unexcluded")
PYRepository: PerryTS/perry Length of output: 317 🏁 Script executed: set -euo pipefail
cat -n crates/perry-codegen/src/codegen/method_registry.rs | sed -n '68,220p'
rg -n -C 8 'computed_members|class\.getters|class\.setters|scoped_method_name|method_names\.insert' crates/perry-codegen/src/codegen/method_registry.rsRepository: PerryTS/perry Length of output: 14824 Avoid name-only guarded-undefined lookup for computed members and accessors. A valid instance method can collide with 🤖 Prompt for AI Agents |
||
| // Representation-selection Phase 5a: the additive `internal` | ||
| // proven-`this` clone. Same HIR, same ABI, same shadow-bound | ||
| // tagged-at-rest receiver slot — only `this.field` lowering | ||
|
|
@@ -464,13 +432,51 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> { | |
| Some(fact.clone()), | ||
| None, | ||
| false, | ||
| false, | ||
| ) | ||
| .with_context(|| { | ||
| format!( | ||
| "lowering proven-`this` clone of method '{}::{}'", | ||
| class.name, method.name | ||
| ) | ||
| })?; | ||
| if cross_module | ||
| .guarded_undefined_method_params | ||
| .contains_key(&(class.name.clone(), method.name.clone())) | ||
| { | ||
| compile_method( | ||
| llmod, | ||
| class, | ||
| method, | ||
| func_names, | ||
| strings, | ||
| class_table, | ||
| method_names, | ||
| module_globals, | ||
| module_global_types, | ||
| opts.import_function_prefixes, | ||
| enum_table, | ||
| static_field_globals, | ||
| class_ids, | ||
| func_signatures, | ||
| func_synthetic_arguments, | ||
| module_boxed_vars, | ||
| closure_rest_params, | ||
| cross_module, | ||
| None, | ||
| false, | ||
| Some(fact.clone()), | ||
| None, | ||
| false, | ||
| true, | ||
| ) | ||
| .with_context(|| { | ||
| format!( | ||
| "lowering proven-`this` exact-undefined clone of method '{}::{}'", | ||
| class.name, method.name | ||
| ) | ||
| })?; | ||
| } | ||
|
|
||
| // #8607: a second, stricter clone for the Phase 3b | ||
| // provenance+containment route. Its synthetic immutable | ||
|
|
@@ -505,6 +511,7 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> { | |
| Some(fact.clone()), | ||
| None, | ||
| true, | ||
| false, | ||
| ) | ||
| .with_context(|| { | ||
| format!( | ||
|
|
@@ -544,6 +551,7 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> { | |
| None, | ||
| None, | ||
| false, | ||
| false, | ||
| ) | ||
| .with_context(|| { | ||
| format!( | ||
|
|
@@ -611,6 +619,7 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> { | |
| None, | ||
| None, | ||
| false, | ||
| false, | ||
| ) | ||
| .with_context(|| format!("lowering getter '{}::{}'", class.name, prop))?; | ||
| } | ||
|
|
@@ -666,6 +675,7 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> { | |
| None, | ||
| None, | ||
| false, | ||
| false, | ||
| ) | ||
| .with_context(|| format!("lowering setter '{}::{}'", class.name, prop))?; | ||
| } | ||
|
|
@@ -763,6 +773,7 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> { | |
| None, | ||
| None, | ||
| false, | ||
| false, | ||
| ) | ||
| .with_context(|| format!("lowering constructor for '{}'", class.name))?; | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Use "falsy" for consistency with the rest of this PR.
The standard spelling is "falsy". This PR already uses it in
scripts/local_binding_type_allowlist.json(Line 346, "A falsy-local fold") and incrates/perry-codegen/src/codegen/guarded_undefined_method_tests.rs(Line 167, "known-falsy filter"). Use one term for one concept in the released notes.✏️ Proposed fix
📝 Committable suggestion
🧰 Tools
🪛 LanguageTool
[grammar] ~3-~3: Ensure spelling is correct
Context: ...ialized body; functions and every other falsey or non-callable value retain the ordina...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🤖 Prompt for AI Agents
Source: Linters/SAST tools