emscripten-core / emscripten-core/emscripten
Unexpected release of a managed pointer in `wrapper.call`
- 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
Assessment
This issue has not been assessed yet.