emscripten-core / emscripten-core/emscripten

Unexpected release of a managed pointer in `wrapper.call`

Open
#20,095 7 comments 1 reaction 0 assignees View on GitHub
Dominant language
C++
Stars
27.6k
Forks
3.6k
Avg merge
1d 1h
Merged PRs (30d)
105

Description

Please include the following in your bug report:

**Version of emscripten/emsdk:**

emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.44-git
clang version 17.0.0 (https://github.com/llvm/llvm-project.git a8cbd27d1f238e104a5d5ca345d93bc1f4d4ab1f)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /opt/homebrew/Cellar/emscripten/3.1.44/libexec/llvm/bin

**The Problem**

In my C++ library there's a class that manages a list (vector) of `std::unique_ptr` and hence manages the life time of the objects (in this case instances of a `Token` class). When any of the tokens is needed the raw pointer is passed around, but of course must not be managed elsewhere.

One of the consumers of a token pointer is a listener class, which is bound with embind and its methods can be overriden in JS. The wrapper is defined as:

```cpp
class ANTLRErrorListenerWrapper : public wrapper {
public:
EMSCRIPTEN_WRAPPER(ANTLRErrorListenerWrapper);

virtual ~ANTLRErrorListenerWrapper() noexcept override {
}

virtual void syntaxError(Recognizer *recognizer, Token *offendingSymbol, size_t line, size_t charPositionInLine,
const std::string &msg, const RecognitionException &e) override {
call("syntaxError", recognizer, offendingSymbol, line, charPositionInLine, msg, e);
}
```

This listener is overridden in JS:

```typescript
import {
ANTLRErrorListener as AEL
} from "../../src/antlr4-runtime.js";

const ANTLRErrorListener = AEL.extend("AEL", {});
type ANTLRErrorListener = InstanceType;

export class MySQLErrorListener extends ANTLRErrorListener {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public syntaxError(recognizer: Recognizer, offendingSymbol: T | null,
line: number, charPositionInLine: number, msg: string, e: RecognitionException | null): void {

}


}
```

When the `syntaxError` method is called (from the wrapper code) it does everything nicely, but when it returns, the token value is deleted, even though it is managed by a unique_ptr. Is that a bug, a gotcha or an error on my side and how can I prevent the premature release?

**Work Around**

I just found a work around to avoid the premature release, by calling `offendingSymbol.clone()` in the `syntaxError` method body, though that looks a bit hackish to me...

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.