Skip to content

Commit df72746

Browse files
sbc100NickCarducci
andauthored
Remove str-to-func eval of named function factory (emscripten-core#18748)
For support for this feature see: https://caniuse.com/mdn-javascript_operators_object_initializer_computed_property_names Based on emscripten-core#17296 Co-authored-by: Nick Carducci <nmcarducci@gmail.com>
1 parent e0c513b commit df72746

3 files changed

Lines changed: 24 additions & 29 deletions

File tree

src/embind/embind.js

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -194,25 +194,16 @@ var LibraryEmbind = {
194194
},
195195

196196

197-
// from https://github.com/imvu/imvujs/blob/master/src/function.js
198197
$createNamedFunction__deps: ['$makeLegalFunctionName'],
199198
$createNamedFunction: function(name, body) {
200199
name = makeLegalFunctionName(name);
201-
#if DYNAMIC_EXECUTION == 0
202-
return function() {
203-
"use strict";
204-
return body.apply(this, arguments);
205-
};
206-
#else
207-
/*jshint evil:true*/
208-
return new Function(
209-
"body",
210-
"return function " + name + "() {\n" +
211-
" \"use strict\";" +
212-
" return body.apply(this, arguments);\n" +
213-
"};\n"
214-
)(body);
215-
#endif
200+
// Use an abject with a computed property name to create a new function with
201+
// a name specified at runtime, but without using `new Function` or `eval`.
202+
return {
203+
[name]: function() {
204+
return body.apply(this, arguments);
205+
}
206+
}[name];
216207
},
217208

218209
$embindRepr: function(v) {

test/embind/embind.test.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -162,17 +162,16 @@ module({
162162
});
163163

164164
test("setting and getting property on unrelated class throws error", function() {
165-
var className = cm['DYNAMIC_EXECUTION'] ? 'HasTwoBases' : '';
166165
var a = new cm.HasTwoBases;
167166
var e = assert.throws(cm.BindingError, function() {
168167
Object.getOwnPropertyDescriptor(cm.HeldBySmartPtr.prototype, 'i').set.call(a, 10);
169168
});
170-
assert.equal('HeldBySmartPtr.i setter incompatible with "this" of type ' + className, e.message);
169+
assert.equal('HeldBySmartPtr.i setter incompatible with "this" of type HasTwoBases', e.message);
171170

172171
var e = assert.throws(cm.BindingError, function() {
173172
Object.getOwnPropertyDescriptor(cm.HeldBySmartPtr.prototype, 'i').get.call(a);
174173
});
175-
assert.equal('HeldBySmartPtr.i getter incompatible with "this" of type ' + className, e.message);
174+
assert.equal('HeldBySmartPtr.i getter incompatible with "this" of type HasTwoBases', e.message);
176175

177176
a.delete();
178177
});
@@ -1766,8 +1765,7 @@ module({
17661765

17671766
test("smart pointer object has correct constructor name", function() {
17681767
var e = new cm.HeldBySmartPtr(10, "foo");
1769-
var expectedName = cm['DYNAMIC_EXECUTION'] ? "HeldBySmartPtr" : "";
1770-
assert.equal(expectedName, e.constructor.name);
1768+
assert.equal("HeldBySmartPtr", e.constructor.name);
17711769
e.delete();
17721770
});
17731771

@@ -2510,12 +2508,11 @@ module({
25102508
});
25112509

25122510
BaseFixture.extend("function names", function() {
2511+
assert.equal('ValHolder', cm.ValHolder.name);
25132512
if (!cm['DYNAMIC_EXECUTION']) {
2514-
assert.equal('', cm.ValHolder.name);
25152513
assert.equal('', cm.ValHolder.prototype.setVal.name);
25162514
assert.equal('', cm.ValHolder.makeConst.name);
25172515
} else {
2518-
assert.equal('ValHolder', cm.ValHolder.name);
25192516
assert.equal('ValHolder$setVal', cm.ValHolder.prototype.setVal.name);
25202517
assert.equal('ValHolder$makeConst', cm.ValHolder.makeConst.name);
25212518
}

test/test_other.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12370,6 +12370,13 @@ def test_es5_transpile(self, args):
1237012370
// arror funcs + const
1237112371
const bar = () => 2;
1237212372
err('bar: ' + bar());
12373+
12374+
// Computed property names
12375+
var key = 'mykey';
12376+
var obj2 = {
12377+
[key]: 42,
12378+
};
12379+
err('value: ' + obj2[key]);
1237312380
}
1237412381
});
1237512382
''')
@@ -12403,19 +12410,19 @@ def check_for_es6(filename, expect):
1240312410
print('with old browser')
1240412411
self.emcc_args.remove('-Werror')
1240512412
self.set_setting('MIN_CHROME_VERSION', '10')
12406-
self.do_runf('test.c', 'prop: 1\nbar: 2\n', output_basename='test2')
12407-
check_for_es6('test2.js', False)
12413+
self.do_runf('test.c', 'prop: 1\nbar: 2\n', output_basename='test_old')
12414+
check_for_es6('test_old.js', False)
1240812415

1240912416
# If we add `--closure=0` that transpiler (closure) is not run at all
1241012417
print('with old browser + --closure=0')
12411-
self.do_runf('test.c', 'prop: 1\nbar: 2\n', emcc_args=['--closure=0'], output_basename='test3')
12412-
check_for_es6('test3.js', True)
12418+
self.do_runf('test.c', 'prop: 1\nbar: 2\n', emcc_args=['--closure=0'], output_basename='test_no_closure')
12419+
check_for_es6('test_no_closure.js', True)
1241312420

1241412421
# If we use `--closure=1` closure will run in full optimization mode
1241512422
# and also transpile to ES5
1241612423
print('with old browser + --closure=1')
12417-
self.do_runf('test.c', 'prop: 1\nbar: 2\n', emcc_args=['--closure=1'], output_basename='test4')
12418-
check_for_es6('test4.js', False)
12424+
self.do_runf('test.c', 'prop: 1\nbar: 2\n', emcc_args=['--closure=1'], output_basename='test_closure')
12425+
check_for_es6('test_closure.js', False)
1241912426

1242012427
def test_gmtime_noleak(self):
1242112428
# Confirm that gmtime_r does not leak when called in isolation.

0 commit comments

Comments
 (0)