JS optimizer: properly minify special JS names like "constructor" (#11790)

Just checking minifiedNames["constructor"] always returns true, since
it's built into each JS object. We need to use hasOwnProperty to do it
properly, as it want to ignore stuff up the prototype chain.

Also remove an if in function name minification - we should not check if
there is a minified name, as if we are minifying, they must all be minified,
or that's a bug.

Fixes #11740 which is a codebase that has a function called "constructor".
This commit is contained in:
Alon Zakai 2020-08-04 14:24:54 -07:00 коммит произвёл GitHub
Родитель e84a56f931
Коммит 68f3899f2e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 142 добавлений и 11 удалений

Просмотреть файл

@ -0,0 +1,63 @@
// EMSCRIPTEN_START_ASM
function a(asmLibraryArg, wasmMemory, wasmTable) {
var scratchBuffer = new ArrayBuffer(16);
var b = new Int32Array(scratchBuffer);
var c = new Float32Array(scratchBuffer);
function d(index) {
return b[index];
}
function e(index, value) {
b[index] = value;
}
function f(value) {
c[2] = value;
}
function g() {
return c[2];
}
function h(global, env, buffer) {
var i = new global.Int8Array(buffer);
var j = env.emscripten_glVertexAttrib4fv;
var k = 6191184;
// EMSCRIPTEN_START_FUNCS
function n() {
return l(10, 20) + m(30);
}
function l(a, b) {
return m(a + b);
}
function m(a) {
return a + 1;
}
// EMSCRIPTEN_END_FUNCS
return {
"main": n
};
}
return h({
"Int8Array": Int8Array,
"Int16Array": Int16Array,
"Int32Array": Int32Array,
"Uint8Array": Uint8Array,
"Uint16Array": Uint16Array,
"Uint32Array": Uint32Array,
"Float32Array": Float32Array,
"Float64Array": Float64Array,
"NaN": NaN,
"Infinity": Infinity,
"Math": Math
}, asmLibraryArg, wasmMemory.buffer);
}
// EMSCRIPTEN_END_ASM
// EMSCRIPTEN_GENERATED_FUNCTIONS

Просмотреть файл

@ -0,0 +1,63 @@
// EMSCRIPTEN_START_ASM
function instantiate(asmLibraryArg, wasmMemory, wasmTable) {
var scratchBuffer = new ArrayBuffer(16);
var i32ScratchView = new Int32Array(scratchBuffer);
var f32ScratchView = new Float32Array(scratchBuffer);
function wasm2js_scratch_load_i32(index) {
return i32ScratchView[index];
}
function wasm2js_scratch_store_i32(index, value) {
i32ScratchView[index] = value;
}
function wasm2js_scratch_store_f32(value) {
f32ScratchView[2] = value;
}
function wasm2js_scratch_load_f32() {
return f32ScratchView[2];
}
function asmFunc(global, env, buffer) {
var HEAP8 = new global.Int8Array(buffer);
var emscripten_glVertexAttrib4fv = env.emscripten_glVertexAttrib4fv;
var global$0 = 6191184;
// EMSCRIPTEN_START_FUNCS
function foo(x, y) {
return constructor(x + y);
}
function constructor(foo) {
return foo + 1;
}
function mainey() {
return foo(10, 20) + constructor(30);
}
// EMSCRIPTEN_END_FUNCS
return {
"main": mainey
};
}
return asmFunc({
'Int8Array': Int8Array,
'Int16Array': Int16Array,
'Int32Array': Int32Array,
'Uint8Array': Uint8Array,
'Uint16Array': Uint16Array,
'Uint32Array': Uint32Array,
'Float32Array': Float32Array,
'Float64Array': Float64Array,
'NaN': NaN,
'Infinity': Infinity,
'Math': Math
},
asmLibraryArg,
wasmMemory.buffer
)
}// EMSCRIPTEN_END_ASM
// EMSCRIPTEN_GENERATED_FUNCTIONS

18
tests/test_other.py поставляемый
Просмотреть файл

@ -2209,12 +2209,18 @@ int f() {
check_js(output, expected)
@no_fastcomp('wasm2js-only')
def test_js_optimizer_wasm2js(self):
# run the js optimizer in a similar way as wasm2js does
shutil.copyfile(path_from_root('tests', 'optimizer', 'wasm2js.js'), 'wasm2js.js')
self.run_process([PYTHON, path_from_root('tools', 'js_optimizer.py'), 'wasm2js.js', 'minifyNames', 'last'])
with open(path_from_root('tests', 'optimizer', 'wasm2js-output.js')) as expected:
with open('wasm2js.js.jsopt.js') as actual:
@parameterized({
'wasm2js': ('wasm2js', ['minifyNames', 'last']),
'constructor': ('constructor', ['minifyNames'])
})
def test_js_optimizer_py(self, name, passes):
# run the js optimizer python script. this differs from test_js_optimizer
# which runs the internal js optimizer JS script directly (which the python
# script calls)
shutil.copyfile(path_from_root('tests', 'optimizer', name + '.js'), name + '.js')
self.run_process([PYTHON, path_from_root('tools', 'js_optimizer.py'), name + '.js'] + passes)
with open(path_from_root('tests', 'optimizer', name + '-output.js')) as expected:
with open(name + '.js.jsopt.js') as actual:
self.assertIdentical(expected.read(), actual.read())
def test_m_mm(self):

Просмотреть файл

@ -4580,7 +4580,7 @@ function minifyGlobals(ast) {
var minified = {};
var next = 0;
function getMinified(name) {
if (minified[name]) return minified[name];
if (minified.hasOwnProperty(name)) return minified[name];
ensureMinifiedNames(next);
return minified[name] = minifiedNames[next++];
}
@ -4706,10 +4706,9 @@ function minifyLocals(ast) {
}
// Traverse and minify all names.
if (fun[1] in extraInfo.globals) {
fun[1] = extraInfo.globals[fun[1]];
assert(fun[1]);
}
assert(extraInfo.globals.hasOwnProperty(fun[1]));
fun[1] = extraInfo.globals[fun[1]];
assert(fun[1] && typeof fun[1] === 'string');
if (fun[2]) {
for (var i = 0; i < fun[2].length; i++) {
var minified = getNextMinifiedName();