diff options
author | Daniel Wirtz <dcode@dcode.io> | 2018-02-21 23:22:11 +0100 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2018-02-21 14:22:11 -0800 |
commit | 3f5ee87d262080265b65a3789392b399c91f30ad (patch) | |
tree | 131b31b939cb6f0608e470fcb6d933cb9bb5016c /src/asmjs/asmangle.cpp | |
parent | 5578bb58402fde2bb2c932bfa08ab71045854a41 (diff) | |
download | binaryen-3f5ee87d262080265b65a3789392b399c91f30ad.tar.gz binaryen-3f5ee87d262080265b65a3789392b399c91f30ad.tar.bz2 binaryen-3f5ee87d262080265b65a3789392b399c91f30ad.zip |
Improve name mangling of asm.js identifiers (#1433)
Also refactors mangling to its own file so it can be reused by generators and consumers, i.e., where it is important to know that an import must be named 'switch_' where it otherwise would be 'switch'.
* Update tests and JS dist files
Diffstat (limited to 'src/asmjs/asmangle.cpp')
-rw-r--r-- | src/asmjs/asmangle.cpp | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/src/asmjs/asmangle.cpp b/src/asmjs/asmangle.cpp new file mode 100644 index 000000000..0453139b3 --- /dev/null +++ b/src/asmjs/asmangle.cpp @@ -0,0 +1,252 @@ +/* + * Copyright 2018 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "asmjs/asmangle.h" +#include <assert.h> + + +namespace wasm { + +std::string asmangle(std::string name) { + bool mightBeKeyword = true; + size_t i = 1; + + assert(!name.empty()); + + // Names must start with a character, $ or _ + switch (auto ch = name[0]) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': { + name = "$" + name; + i = 2; + goto notKeyword; + } + notKeyword: + case '$': + case '_': { + mightBeKeyword = false; + break; + } + default: { + if ( + !(ch >= 'a' && ch <= 'z') && + !(ch >= 'A' && ch <= 'Z') + ) { + name = "$" + name.substr(1); + mightBeKeyword = false; + } + } + } + + // Names must contain only characters, digits, $ or _ + size_t len = name.length(); + for (; i < len; ++i) { + switch (char ch = name[i]) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '$': + case '_': { + mightBeKeyword = false; + break; + } + default: { + if ( + !(ch >= 'a' && ch <= 'z') && + !(ch >= 'A' && ch <= 'Z') + ) { + name = name.substr(0, i) + "_" + name.substr(i + 1); + mightBeKeyword = false; + } + } + } + } + + // Names must not collide with keywords + if (mightBeKeyword && len >= 2 && len <= 10) { + switch (name[0]) { + case 'a': { + if (name == "arguments") { + goto mangleKeyword; + } + break; + } + case 'b': { + if (name == "break") { + goto mangleKeyword; + } + break; + } + case 'c': { + if ( + name == "case" || + name == "continue" || + name == "catch" || + name == "const" || + name == "class" + ) { + goto mangleKeyword; + } + break; + } + case 'd': { + if ( + name == "do" || + name == "default" || + name == "debugger" + ) { + goto mangleKeyword; + } + break; + } + case 'e': { + if ( + name == "else" || + name == "enum" || + name == "eval" || // to be sure + name == "export" || + name == "extends" + ) { + goto mangleKeyword; + } + break; + } + case 'f': { + if ( + name == "for" || + name == "false" || + name == "finally" || + name == "function" + ) { + goto mangleKeyword; + } + break; + } + case 'i': { + if ( + name == "if" || + name == "in" || + name == "import" || + name == "interface" || + name == "implements" || + name == "instanceof" + ) { + goto mangleKeyword; + } + break; + } + case 'l': { + if (name == "let") { + goto mangleKeyword; + } + break; + } + case 'n': { + if ( + name == "new" || + name == "null" + ) { + goto mangleKeyword; + } + break; + } + case 'p': { + if ( + name == "public" || + name == "package" || + name == "private" || + name == "protected" + ) { + goto mangleKeyword; + } + break; + } + case 'r': { + if (name == "return") { + goto mangleKeyword; + } + break; + } + case 's': { + if ( + name == "super" || + name == "static" || + name == "switch" + ) { + goto mangleKeyword; + } + break; + } + case 't': { + if ( + name == "try" || + name == "this" || + name == "true" || + name == "throw" || + name == "typeof" + ) { + goto mangleKeyword; + } + break; + } + case 'v': { + if ( + name == "var" || + name == "void" + ) { + goto mangleKeyword; + } + break; + } + case 'w': { + if ( + name == "with" || + name == "while" + ) { + goto mangleKeyword; + } + break; + } + case 'y': { + if (name == "yield") { + goto mangleKeyword; + } + break; + } + mangleKeyword: { + name = name + "_"; + } + } + } + return name; +} + +} // namespace wasm |