Skip to content

When calling a function across modules, calling methods of the passed-in object instance within the function does not take effect. #392

@codehz

Description

@codehz

What happened

As title

What you expected

it should works

Minimal reproduction

Multiple files:

perry-repro-ecs-direct.ts

import { processCommands } from "./perry-repro-modules/commands";
import { Changeset } from "./perry-repro-modules/shared";

const changeset = new Changeset();
processCommands([{ type: "set", componentType: 1, component: { x: 1 } }], changeset);

console.log("adds size", changeset.adds.size);
console.log("has component", changeset.adds.has(1));

perry-repro-modules/commands.ts:

export function processCommands(
  commands: { type: string; componentType: number; component: unknown }[],
  changeset: { set(componentType: number, component: unknown): void },
): void {
  for (const command of commands) {
    if (command.type === "set") {
      changeset.set(command.componentType, command.component);
    }
  }
}

perry-repro-modules/shared.ts:

export class Changeset {
  readonly adds = new Map<number, unknown>();

  set(componentType: number, component: unknown): void {
    this.adds.set(componentType, component);
  }
}

Command you ran:

perry perry-repro-ecs-direct.ts && ./perry-repro-ecs-direct

output:

adds size 0
has component false

expected:

adds size 1
has component true

Environment

  • Perry version:
  • Host OS:
  • Target:
  • Rust toolchain (if building from source):
  • Installed via:

Diagnostic output

Perry Doctor

Environment Checks
──────────────────
  ✓ perry version: 0.5.455
  ✓ update status: up to date
  ✓ clang (LLVM codegen): clang version 22.1.3
  ✓ system linker (cc): cc (GCC) 15.2.1 20260209
  ✓ runtime library: /home/codehz/Projects/perry/target/release/libperry_runtime.a
  ⚠ project config (perry.toml): not found - run: perry init

All critical checks passed with some warnings.

Anything else

Found a compile/link bug
if I rename those files as a.ts, b.ts, c.ts and rewrite a.ts to

import { processCommands } from "./b.ts";
import { Changeset } from "./c.ts";

const changeset = new Changeset();
processCommands([{ type: "set", componentType: 1, component: { x: 1 } }], changeset);

console.log("adds size", changeset.adds.size);
console.log("has component", changeset.adds.has(1));

I got a link error like

Collecting modules...
  Compile package: @codehz/pipeline
Found 3 module(s): 3 native, 0 JavaScript
Generating code...
Wrote object file: a_ts.o
Wrote object file: b_ts.o
Wrote object file: c_ts.o
Linking (runtime-only)...
/usr/bin/ld: a_ts.o: in function `main':
perry_llvm_19546_1777593693465021409.ll:(.text+0x71): undefined reference to `b_ts__init'
/usr/bin/ld: perry_llvm_19546_1777593693465021409.ll:(.text+0x76): undefined reference to `c_ts__init'
/usr/bin/ld: perry_llvm_19546_1777593693465021409.ll:(.text+0x10f): undefined reference to `c_ts__Changeset_constructor'
/usr/bin/ld: perry_llvm_19546_1777593693465021409.ll:(.text+0x255): undefined reference to `perry_fn_b_ts__processCommands'
collect2: 错误:ld 返回 1
Error: Linking failed

its seems to be cache poisoning... same content file hit same cache in .perry-cache

objdump --syms b_ts.o

b_ts.o:     文件格式 elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    df *ABS*	0000000000000000 perry_llvm_18891_1777593312870011022.ll
0000000000000000 l    d  .text	0000000000000000 .text
0000000000000000 l       .rodata.cst8	0000000000000000 .LCPI0_0
0000000000000008 l       .rodata.cst8	0000000000000000 .LCPI0_1
0000000000000000 l     O .rodata.cst4	0000000000000004 perry_null_guard_zero
0000000000000048 l     O .bss	0000000000000008 perry_repro_modules_commands_ts_.str.3.handle
0000000000000005 l     O .rodata.str1.1	0000000000000004 .Lperry_repro_modules_commands_ts_.str.1.bytes
0000000000000030 l     O .bss	0000000000000008 perry_repro_modules_commands_ts_.str.0.handle
0000000000000038 l     O .bss	0000000000000008 perry_repro_modules_commands_ts_.str.1.handle
0000000000000040 l     O .bss	0000000000000008 perry_repro_modules_commands_ts_.str.2.handle
0000000000000010 l       .rodata.cst8	0000000000000000 .LCPI1_0
0000000000000018 l       .rodata.cst8	0000000000000000 .LCPI1_1
0000000000000020 l       .rodata.cst8	0000000000000000 .LCPI2_0
0000000000000000 l     O .rodata.str1.1	0000000000000005 .Lperry_repro_modules_commands_ts_.str.0.bytes
0000000000000009 l     O .rodata.str1.1	000000000000000e .Lperry_repro_modules_commands_ts_.str.2.bytes
0000000000000017 l     O .rodata.str1.1	000000000000000a .Lperry_repro_modules_commands_ts_.str.3.bytes
0000000000000000 l    d  .bss	0000000000000000 .bss
0000000000000000 g     F .text	0000000000000353 perry_fn_perry_repro_modules_commands_ts__processCommands
0000000000000000         *UND*	0000000000000000 js_shadow_frame_push
0000000000000000         *UND*	0000000000000000 js_shadow_slot_set
0000000000000000         *UND*	0000000000000000 js_value_length_f64
0000000000000000         *UND*	0000000000000000 js_object_get_field_by_name_f64
0000000000000000         *UND*	0000000000000000 js_native_call_method
0000000000000000         *UND*	0000000000000000 js_array_get_f64
0000000000000000         *UND*	0000000000000000 js_object_get_field_ic_miss
0000000000000000         *UND*	0000000000000000 js_get_string_pointer_unified
0000000000000000         *UND*	0000000000000000 js_string_equals
0000000000000000         *UND*	0000000000000000 js_shadow_frame_pop
0000000000000360 g     F .text	0000000000000353 __perry_wrap_perry_fn_perry_repro_modules_commands_ts__processCommands
00000000000006c0 g     F .text	0000000000000009 __perry_wrap_perry_unknown_func
00000000000006d0 g     F .text	0000000000000005 perry_repro_modules_commands_ts__init
00000000000006e0 g     F .text	00000000000000b6 __perry_init_strings_perry_repro_modules_commands_ts
0000000000000000         *UND*	0000000000000000 js_string_from_bytes
0000000000000000         *UND*	0000000000000000 js_nanbox_string
0000000000000000         *UND*	0000000000000000 js_gc_register_global_root

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions