summaryrefslogtreecommitdiff
path: root/src/asmjs/asmangle.cpp
diff options
context:
space:
mode:
authorDaniel Wirtz <dcode@dcode.io>2018-02-21 23:22:11 +0100
committerAlon Zakai <alonzakai@gmail.com>2018-02-21 14:22:11 -0800
commit3f5ee87d262080265b65a3789392b399c91f30ad (patch)
tree131b31b939cb6f0608e470fcb6d933cb9bb5016c /src/asmjs/asmangle.cpp
parent5578bb58402fde2bb2c932bfa08ab71045854a41 (diff)
downloadbinaryen-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.cpp252
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