Skip to content

Commit 6e54690

Browse files
authored
embind: Don't automatically destroy arguments passed into val calls. (#21022)
Before PR #20383 val's `call` and `operator()` had different behaviors where one would automatically destroy arguments after the call and the other didn't. After that PR, they both called destroy. The automatic destruction wasn't really documented anywhere and and led to some unexpected behavior. This changes it so neither automatically destroys the arguments which I think is more inline with the rest of embind where it's up to the user to handle object lifetimes. Fixes: #21016 and #20095
1 parent 49d5ece commit 6e54690

File tree

6 files changed

+30
-21
lines changed

6 files changed

+30
-21
lines changed

ChangeLog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ See docs/process.md for more on how version tagging works.
5050
`MIN_CHROME_VERSION` will now result in build-time error. All of these
5151
browser versions are at least 8 years old now so the hope is that nobody
5252
is intending to target them today. (#20924)
53+
- C++ objects passed into embind's val via constructors, methods, and call
54+
function will not be automatically destroyed after the function call. This
55+
makes the behavior consistent for invocations.
5356

5457
3.1.51 - 12/13/23
5558
-----------------

src/embind/embind.js

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -678,9 +678,6 @@ var LibraryEmbind = {
678678
'argPackAdvance': GenericWireTypeSize,
679679
'readValueFromPointer': simpleReadValueFromPointer,
680680
destructorFunction: null, // This type does not need a destructor
681-
682-
// TODO: do we need a deleteObject here? write a test where
683-
// emval is passed into JS via an interface
684681
});
685682
},
686683

@@ -1311,11 +1308,6 @@ var LibraryEmbind = {
13111308
},
13121309
'argPackAdvance': GenericWireTypeSize,
13131310
'readValueFromPointer': readPointer,
1314-
'deleteObject'(handle) {
1315-
if (handle !== null) {
1316-
handle['delete']();
1317-
}
1318-
},
13191311
'fromWireType': RegisteredPointer_fromWireType,
13201312
});
13211313
},

src/embind/emval.js

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -335,9 +335,6 @@ var LibraryEmVal = {
335335
offset += types[i]['argPackAdvance'];
336336
}
337337
var rv = kind === /* CONSTRUCTOR */ 1 ? reflectConstruct(func, argN) : func.apply(obj, argN);
338-
for (var i = 0; i < argCount; ++i) {
339-
types[i].deleteObject?.(argN[i]);
340-
}
341338
return emval_returnValue(retType, destructorsRef, rv);
342339
};
343340
#else
@@ -362,12 +359,6 @@ var LibraryEmVal = {
362359
var invoker = kind === /* CONSTRUCTOR */ 1 ? 'new func' : 'func.call';
363360
functionBody +=
364361
` var rv = ${invoker}(${argsList.join(", ")});\n`;
365-
for (var i = 0; i < argCount; ++i) {
366-
if (types[i]['deleteObject']) {
367-
functionBody +=
368-
` argType${i}.deleteObject(arg${i});\n`;
369-
}
370-
}
371362
if (!retType.isVoid) {
372363
params.push("emval_returnValue");
373364
args.push(emval_returnValue);

test/code_size/embind_val_wasm.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"a.html": 673,
33
"a.html.gz": 431,
4-
"a.js": 7426,
5-
"a.js.gz": 3122,
4+
"a.js": 7395,
5+
"a.js.gz": 3109,
66
"a.wasm": 11458,
77
"a.wasm.gz": 5733,
8-
"total": 19557,
9-
"total_gz": 9286
8+
"total": 19526,
9+
"total_gz": 9273
1010
}

test/embind/embind.test.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,10 @@ module({
707707
cm.emval_test_take_and_return_std_string_const_ref("foobar");
708708
});
709709

710+
test("val callback arguments are not destroyed", function() {
711+
cm.emval_test_callback_arg_lifetime(function() {});
712+
});
713+
710714
test("can get global", function(){
711715
/*jshint evil:true*/
712716
assert.equal((new Function("return this;"))(), cm.embind_test_getglobal());

test/embind/embind_test.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,22 @@ unsigned emval_test_sum(val v) {
127127
return rv;
128128
}
129129

130+
struct DestructorCounter {
131+
static int count;
132+
~DestructorCounter() {
133+
count++;
134+
};
135+
};
136+
137+
int DestructorCounter::count = 0;
138+
139+
void emval_test_callback_arg_lifetime(val callback) {
140+
DestructorCounter dc;
141+
int destructorCount = DestructorCounter::count;
142+
callback(dc);
143+
assert(destructorCount == DestructorCounter::count);
144+
}
145+
130146
std::string get_non_ascii_string(bool embindStdStringUTF8Support) {
131147
if(embindStdStringUTF8Support) {
132148
//ASCII
@@ -1828,6 +1844,9 @@ EMSCRIPTEN_BINDINGS(tests) {
18281844
function("const_ref_adder", &const_ref_adder);
18291845
function("emval_test_sum", &emval_test_sum);
18301846

1847+
class_<DestructorCounter>("DestructorCounter");
1848+
function("emval_test_callback_arg_lifetime", &emval_test_callback_arg_lifetime);
1849+
18311850
function("get_non_ascii_string", &get_non_ascii_string);
18321851
function("get_non_ascii_wstring", &get_non_ascii_wstring);
18331852
function("get_literal_wstring", &get_literal_wstring);

0 commit comments

Comments
 (0)