From d137e7f8fb5ae943b115885f256ad57bfae67f6b Mon Sep 17 00:00:00 2001
From: Alon Zakai <azakai@google.com>
Date: Mon, 1 Mar 2021 20:48:30 +0000
Subject: Refactor code out of parsing.h NFC. (#3635)

Most of it goes in a new parsing.cpp. One method was only used in
the s-expression's parser, and has been moved there.
---
 src/wasm/parsing.cpp | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 141 insertions(+)
 create mode 100644 src/wasm/parsing.cpp

(limited to 'src/wasm/parsing.cpp')

diff --git a/src/wasm/parsing.cpp b/src/wasm/parsing.cpp
new file mode 100644
index 000000000..dc0d332d9
--- /dev/null
+++ b/src/wasm/parsing.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2021 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 "parsing.h"
+#include "ir/branch-utils.h"
+
+namespace wasm {
+
+void ParseException::dump(std::ostream& o) const {
+  Colors::magenta(o);
+  o << "[";
+  Colors::red(o);
+  o << "parse exception: ";
+  Colors::green(o);
+  o << text;
+  if (line != size_t(-1)) {
+    Colors::normal(o);
+    o << " (at " << line << ":" << col << ")";
+  }
+  Colors::magenta(o);
+  o << "]";
+  Colors::normal(o);
+}
+
+void MapParseException::dump(std::ostream& o) const {
+  Colors::magenta(o);
+  o << "[";
+  Colors::red(o);
+  o << "map parse exception: ";
+  Colors::green(o);
+  o << text;
+  Colors::magenta(o);
+  o << "]";
+  Colors::normal(o);
+}
+
+// UniqueNameMapper
+
+Name UniqueNameMapper::getPrefixedName(Name prefix) {
+  if (reverseLabelMapping.find(prefix) == reverseLabelMapping.end()) {
+    return prefix;
+  }
+  // make sure to return a unique name not already on the stack
+  while (1) {
+    Name ret = Name(prefix.str + std::to_string(otherIndex++));
+    if (reverseLabelMapping.find(ret) == reverseLabelMapping.end()) {
+      return ret;
+    }
+  }
+}
+
+Name UniqueNameMapper::pushLabelName(Name sName) {
+  Name name = getPrefixedName(sName);
+  labelStack.push_back(name);
+  labelMappings[sName].push_back(name);
+  reverseLabelMapping[name] = sName;
+  return name;
+}
+
+void UniqueNameMapper::popLabelName(Name name) {
+  assert(labelStack.back() == name);
+  labelStack.pop_back();
+  labelMappings[reverseLabelMapping[name]].pop_back();
+}
+
+Name UniqueNameMapper::sourceToUnique(Name sName) {
+  // DELEGATE_CALLER_TARGET is a fake target used to denote delegating to the
+  // caller. We do not need to modify it, as it has no definitions, only uses.
+  if (sName == DELEGATE_CALLER_TARGET) {
+    return DELEGATE_CALLER_TARGET;
+  }
+  if (labelMappings.find(sName) == labelMappings.end()) {
+    throw ParseException("bad label in sourceToUnique");
+  }
+  if (labelMappings[sName].empty()) {
+    throw ParseException("use of popped label in sourceToUnique");
+  }
+  return labelMappings[sName].back();
+}
+
+Name UniqueNameMapper::uniqueToSource(Name name) {
+  if (reverseLabelMapping.find(name) == reverseLabelMapping.end()) {
+    throw ParseException("label mismatch in uniqueToSource");
+  }
+  return reverseLabelMapping[name];
+}
+
+void UniqueNameMapper::clear() {
+  labelStack.clear();
+  labelMappings.clear();
+  reverseLabelMapping.clear();
+}
+
+void UniqueNameMapper::uniquify(Expression* curr) {
+  struct Walker
+    : public ControlFlowWalker<Walker, UnifiedExpressionVisitor<Walker>> {
+    UniqueNameMapper mapper;
+
+    static void doPreVisitControlFlow(Walker* self, Expression** currp) {
+      BranchUtils::operateOnScopeNameDefs(*currp, [&](Name& name) {
+        if (name.is()) {
+          name = self->mapper.pushLabelName(name);
+        }
+      });
+    }
+
+    static void doPostVisitControlFlow(Walker* self, Expression** currp) {
+      BranchUtils::operateOnScopeNameDefs(*currp, [&](Name& name) {
+        if (name.is()) {
+          self->mapper.popLabelName(name);
+        }
+      });
+    }
+
+    void visitExpression(Expression* curr) {
+      BranchUtils::operateOnScopeNameUses(curr, [&](Name& name) {
+        if (name.is()) {
+          name = mapper.sourceToUnique(name);
+        }
+      });
+    }
+  };
+
+  Walker walker;
+  walker.walk(curr);
+}
+
+} // namespace wasm
-- 
cgit v1.2.3