WebAssembly JS API: add Module.sections
[WebKit-https.git] / Source / JavaScriptCore / wasm / WasmFormat.h
index e49a891..dc63474 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,8 +36,9 @@
 #include "WasmMemoryInformation.h"
 #include "WasmOps.h"
 #include "WasmPageCount.h"
+#include "WasmSignature.h"
+#include <limits>
 #include <memory>
-#include <wtf/FastMalloc.h>
 #include <wtf/Optional.h>
 #include <wtf/Vector.h>
 
@@ -100,11 +101,6 @@ static inline const char* makeString(ExternalKind kind)
     return "?";
 }
 
-struct Signature {
-    Type returnType;
-    Vector<Type> arguments;
-};
-
 struct Import {
     Identifier module;
     Identifier field;
@@ -142,34 +138,54 @@ struct FunctionLocationInBinary {
     size_t end;
 };
 
-struct Segment {
-    uint32_t offset;
-    uint32_t sizeInBytes;
-    // Bytes are allocated at the end.
-    static Segment* make(uint32_t offset, uint32_t sizeInBytes)
+class I32InitExpr {
+    enum Type : uint8_t {
+        Global,
+        Const
+    };
+
+    I32InitExpr(Type type, uint32_t bits)
+        : m_bits(bits)
+        , m_type(type)
+    { }
+
+public:
+    I32InitExpr() = delete;
+
+    static I32InitExpr globalImport(uint32_t globalImportNumber) { return I32InitExpr(Global, globalImportNumber); }
+    static I32InitExpr constValue(uint32_t constValue) { return I32InitExpr(Const, constValue); }
+
+    bool isConst() const { return m_type == Const; }
+    bool isGlobalImport() const { return m_type == Global; }
+    uint32_t constValue() const
     {
-        auto allocated = tryFastCalloc(sizeof(Segment) + sizeInBytes, 1);
-        Segment* segment;
-        if (!allocated.getValue(segment))
-            return nullptr;
-        segment->offset = offset;
-        segment->sizeInBytes = sizeInBytes;
-        return segment;
+        RELEASE_ASSERT(isConst());
+        return m_bits;
     }
-    static void destroy(Segment *segment)
+    uint32_t globalImportIndex() const
     {
-        fastFree(segment);
+        RELEASE_ASSERT(isGlobalImport());
+        return m_bits;
     }
+
+private:
+    uint32_t m_bits;
+    Type m_type;
+};
+
+struct Segment {
+    uint32_t sizeInBytes;
+    I32InitExpr offset;
+    // Bytes are allocated at the end.
     uint8_t& byte(uint32_t pos)
     {
         ASSERT(pos < sizeInBytes);
-        return *reinterpret_cast<uint8_t*>(reinterpret_cast<char*>(this) + sizeof(offset) + sizeof(sizeInBytes) + pos);
+        return *reinterpret_cast<uint8_t*>(reinterpret_cast<char*>(this) + sizeof(Segment) + pos);
     }
+    static Segment* create(I32InitExpr, uint32_t);
+    static void destroy(Segment*);
     typedef std::unique_ptr<Segment, decltype(&Segment::destroy)> Ptr;
-    static Ptr makePtr(Segment* segment)
-    {
-        return Ptr(segment, &Segment::destroy);
-    }
+    static Ptr adoptPtr(Segment*);
 };
 
 struct Element {
@@ -204,13 +220,19 @@ private:
     bool m_isImport { false };
     bool m_isValid { false };
 };
+    
+struct CustomSection {
+    String name;
+    Vector<uint8_t> payload;
+};
 
 struct ModuleInformation {
-    Vector<Signature> signatures;
     Vector<Import> imports;
-    Vector<Signature*> importFunctions;
-    Vector<Signature*> internalFunctionSignatures;
+    Vector<SignatureIndex> importFunctionSignatureIndices;
+    Vector<SignatureIndex> internalFunctionSignatureIndices;
+
     MemoryInformation memory;
+
     Vector<Export> exports;
     std::optional<uint32_t> startFunctionIndexSpace;
     Vector<Segment::Ptr> data;
@@ -218,6 +240,23 @@ struct ModuleInformation {
     TableInformation tableInformation;
     Vector<Global> globals;
     unsigned firstInternalGlobal { 0 };
+    Vector<CustomSection> customSections;
+
+    size_t functionIndexSpaceSize() const { return importFunctionSignatureIndices.size() + internalFunctionSignatureIndices.size(); }
+    bool isImportedFunctionFromFunctionIndexSpace(size_t functionIndex) const
+    {
+        ASSERT(functionIndex < functionIndexSpaceSize());
+        return functionIndex < importFunctionSignatureIndices.size();
+    }
+    SignatureIndex signatureIndexFromFunctionIndexSpace(size_t functionIndex) const
+    {
+        return isImportedFunctionFromFunctionIndexSpace(functionIndex)
+            ? importFunctionSignatureIndices[functionIndex]
+            : internalFunctionSignatureIndices[functionIndex - importFunctionSignatureIndices.size()];
+    }
+
+    uint32_t importFunctionCount() const { return importFunctionSignatureIndices.size(); }
+    bool hasMemory() const { return !!memory; }
 
     ~ModuleInformation();
 };
@@ -225,6 +264,10 @@ struct ModuleInformation {
 struct UnlinkedWasmToWasmCall {
     CodeLocationCall callLocation;
     size_t functionIndex;
+    enum class Target : uint8_t {
+        ToJs,
+        ToWasm,
+    } target;
 };
 
 struct Entrypoint {
@@ -240,32 +283,28 @@ struct WasmInternalFunction {
     Entrypoint jsToWasmEntrypoint;
 };
 
-typedef MacroAssemblerCodeRef WasmToJSStub;
+struct WasmExitStubs {
+    MacroAssemblerCodeRef wasmToJs;
+    MacroAssemblerCodeRef wasmToWasm;
+};
 
 // WebAssembly direct calls and call_indirect use indices into "function index space". This space starts with all imports, and then all internal functions.
 // CallableFunction and FunctionIndexSpace are only meant as fast lookup tables for these opcodes, and do not own code.
 struct CallableFunction {
     CallableFunction() = default;
 
-    CallableFunction(Signature* signature, void* code = nullptr)
-        : signature(signature)
+    CallableFunction(SignatureIndex signatureIndex, void* code = nullptr)
+        : signatureIndex(signatureIndex)
         , code(code)
     {
     }
 
-    // FIXME pack this inside a (uniqued) integer (for correctness the parser should unique Signatures),
-    // and then pack that integer into the code pointer. https://bugs.webkit.org/show_bug.cgi?id=165511
-    Signature* signature { nullptr }; 
+    // FIXME pack the SignatureIndex and the code pointer into one 64-bit value. https://bugs.webkit.org/show_bug.cgi?id=165511
+    SignatureIndex signatureIndex { Signature::invalidIndex };
     void* code { nullptr };
 };
 typedef Vector<CallableFunction> FunctionIndexSpace;
 
-
-struct ImmutableFunctionIndexSpace {
-    MallocPtr<CallableFunction> buffer;
-    size_t size;
-};
-
 } } // namespace JSC::Wasm
 
 #endif // ENABLE(WEBASSEMBLY)