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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions