Skip to content

embind: Val call invokers delete object arguments #21016

Closed
@brendandahl

Description

@brendandahl

This is a regression from #20383. Before the patch the destructor of objects passed into a val functions were not automatically run, but now they are. While this is a regression, I think it's actually just copying the strange(broken?) behavior of the other code. There was another issue filed about this as #20095 related to val::call which used the optimized code that val::operator() now uses.

I did a bit of digging and it appears that automatically destroying the object arguments was the originally intended behavior in this patch and that the user should call clone to avoid this.

I'm still thinking about the best approach here, but my initial thought is that the user should handle explicitly deleting the object if they need to.

Output before:

>>> constructor
>>> before callback
branch [object Object]
>>> after callback
>>> destructor

After:

>>> constructor
>>> before callback
branch [object Object]
>>> destructor
>>> after callback
>>> destructor
#include <stdio.h>
#include <emscripten.h>
#include <emscripten/bind.h>

using namespace emscripten;

struct Branch {
  Branch() {
    printf(">>> constructor\n");
  }
  ~Branch() {
    printf(">>> destructor\n");
  }
};

class Editor {
public:
  void WithBranch(std::function<void(Branch*)> callback) {
    Branch b;
    printf(">>> before callback\n");
    callback(&b);  // This pointer should not be deleted!
    printf(">>> after callback\n");
  }
};

void EditorWithBranch(Editor& editor, val callback) {
  editor.WithBranch([callback](Branch* branch) { callback(branch); });
}

int main() {
EM_ASM(
  var editor = new Module.Editor();
  editor.withBranch((branch) => {
    console.log("branch " + branch);
  });
);
  
}

EMSCRIPTEN_BINDINGS(xxx) {
  class_<Editor>("Editor").constructor<>().function("withBranch", &EditorWithBranch);
  class_<Branch>("Branch");
}

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