Skip to content

Commit 99bb5ae

Browse files
committed
embind: Don't automatically destroy arguments passed into val calls.
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 67ce331 commit 99bb5ae

File tree

5 files changed

+26
-17
lines changed

5 files changed

+26
-17
lines changed

ChangeLog.md

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

5053
3.1.51 - 12/13/23
5154
-----------------

src/embind/embind.js

-8
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

-9
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/embind/embind.test.js

+4
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

+19
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)