OSDN Git Service

[WebAssembly] Add minor helper functions to WasmObjectFile
authorSam Clegg <sbc@chromium.org>
Wed, 24 Jan 2018 01:27:17 +0000 (01:27 +0000)
committerSam Clegg <sbc@chromium.org>
Wed, 24 Jan 2018 01:27:17 +0000 (01:27 +0000)
Also, fix crash when exporting an imported function.

Differential Revision: https://reviews.llvm.org/D42454

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@323290 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Object/Wasm.h
lib/Object/WasmObjectFile.cpp

index 22e19a1..f0a85b2 100644 (file)
@@ -205,6 +205,9 @@ public:
 
 private:
   bool isValidFunctionIndex(uint32_t Index) const;
+  bool isDefinedFunctionIndex(uint32_t Index) const;
+  wasm::WasmFunction& getDefinedFunction(uint32_t Index);
+
   const WasmSection &getWasmSection(DataRefImpl Ref) const;
   const wasm::WasmRelocation &getWasmRelocation(DataRefImpl Ref) const;
 
index 132471a..2bba662 100644 (file)
@@ -292,10 +292,10 @@ Error WasmObjectFile::parseNameSection(const uint8_t *Ptr, const uint8_t *End) {
           return make_error<GenericBinaryError>("Invalid name entry",
                                                 object_error::parse_failed);
         DebugNames.push_back(wasm::WasmFunctionName{Index, Name});
-        if (Index >= NumImportedFunctions) {
+        if (isDefinedFunctionIndex(Index)) {
           // Override any existing name; the name specified by the "names"
           // section is the Function's canonical name.
-          Functions[Index - NumImportedFunctions].Name = Name;
+          getDefinedFunction(Index).Name = Name;
         }
       }
       break;
@@ -369,8 +369,9 @@ void WasmObjectFile::populateSymbolTable() {
                      << " sym index:" << SymIndex << "\n");
       }
     }
-    if (Export.Kind == wasm::WASM_EXTERNAL_FUNCTION) {
-      auto &Function = Functions[Export.Index - NumImportedFunctions];
+    if (Export.Kind == wasm::WASM_EXTERNAL_FUNCTION &&
+        isDefinedFunctionIndex(Export.Index)) {
+      auto &Function = getDefinedFunction(Export.Index);
       if (Function.Name.empty()) {
         // Use the export's name to set a name for the Function, but only if one
         // hasn't already been set.
@@ -501,14 +502,13 @@ Error WasmObjectFile::parseLinkingSectionComdat(const uint8_t *&Ptr,
         DataSegments[Index].Data.Comdat = Name;
         break;
       case wasm::WASM_COMDAT_FUNCTION:
-        if (Index < NumImportedFunctions || !isValidFunctionIndex(Index))
+        if (!isDefinedFunctionIndex(Index))
           return make_error<GenericBinaryError>("COMDAT function index out of range",
                                                 object_error::parse_failed);
-        Index -= NumImportedFunctions;
-        if (!Functions[Index].Comdat.empty())
+        if (!getDefinedFunction(Index).Comdat.empty())
           return make_error<GenericBinaryError>("Function in two COMDATs",
                                                 object_error::parse_failed);
-        Functions[Index].Comdat = Name;
+        getDefinedFunction(Index).Comdat = Name;
         break;
       }
     }
@@ -736,7 +736,7 @@ Error WasmObjectFile::parseExportSection(const uint8_t *Ptr, const uint8_t *End)
     Ex.Index = readVaruint32(Ptr);
     switch (Ex.Kind) {
     case wasm::WASM_EXTERNAL_FUNCTION:
-      if (Ex.Index >= FunctionTypes.size() + NumImportedFunctions)
+      if (!isValidFunctionIndex(Ex.Index))
         return make_error<GenericBinaryError>("Invalid function export",
                                               object_error::parse_failed);
       break;
@@ -765,6 +765,15 @@ bool WasmObjectFile::isValidFunctionIndex(uint32_t Index) const {
   return Index < FunctionTypes.size() + NumImportedFunctions;
 }
 
+bool WasmObjectFile::isDefinedFunctionIndex(uint32_t Index) const {
+  return Index >= NumImportedFunctions && isValidFunctionIndex(Index);
+}
+
+wasm::WasmFunction& WasmObjectFile::getDefinedFunction(uint32_t Index) {
+  assert(isDefinedFunctionIndex(Index));
+  return Functions[Index - NumImportedFunctions];
+}
+
 Error WasmObjectFile::parseStartSection(const uint8_t *Ptr, const uint8_t *End) {
   StartFunction = readVaruint32(Ptr);
   if (!isValidFunctionIndex(StartFunction))