Skip to content

Linker: unresolved _perry_fn_..._render for V8-fallback modules referenced from main #678

@proggeramlug

Description

@proggeramlug

Summary

Surfaced during the #360 recheck on v0.5.796: compiling a TypeScript program that imports from a module Perry decided to keep on the V8 fallback (i.e. one of the 21 JavaScript modules in a `Found 67 module(s): 46 native, 21 JavaScript` split) fails at link time with unresolved native symbols:

```
Undefined symbols for architecture arm64:
"_perry_fn_node_modules_ink_build_render_js__render", referenced from:
_main in counter_tsx.o
"_perry_closure_node_modules_ink_build_measure_text_js__0", referenced from:
... in node_modules_ink_build_measure_text_js.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Error: Linking failed
```

The codegen is emitting native callsites to functions defined in a V8-fallback module, but the V8-fallback path of course doesn't emit those native symbols — they only exist for natively-compiled modules.

Environment

  • perry 0.5.796 (current main)
  • macOS arm64

Minimal repro

```tsx
// counter.tsx
import React, { useState } from "react";
import { render, Text, Box } from "ink";

function App() {
const [count] = useState(0);
return React.createElement(Box, null, React.createElement(Text, null, `count=${count}`));
}

render(React.createElement(App));
```

`package.json`:
```json
{ "perry": { "compilePackages": ["react", "ink"] } }
```

`perry compile counter.tsx -o counter` reports `46 native, 21 JavaScript` then fails at the link step as above.

Hypothesis

The codegen for the main module's `import { render } from "ink"` lowers the call to a native `_perry_fn_node_modules_ink_build_render_js__render` extern, assuming the symbol will exist. But `ink/build/render.js` got demoted to the V8 fallback (because of an unsupported feature — likely a transitive dep, e.g. yoga-layout, that Perry can't compile). The fallback module doesn't emit native symbols, so the linker fails.

The fix is either:

  1. Detect at codegen that the callee module is V8-fallback, and route the call through the V8 bridge instead of an extern; OR
  2. Emit weak stub symbols for V8-fallback modules that the V8 bridge can intercept at runtime; OR
  3. Promote the dependency-blocked module path to a hard compile error earlier so we don't reach link.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions