blob: 0453139b3863a0a1eaa6d877d8ef5ebe3d227364 [file] [log] [blame] [edit]
/*
* 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