| Index: src/wasm/wasm-module.h
|
| diff --git a/src/wasm/wasm-module.h b/src/wasm/wasm-module.h
|
| index 0b9bc9762edec2834637c738356d4c160f5f6e71..79eee0a74b63bc15fc74d15d39c80c31b908aa66 100644
|
| --- a/src/wasm/wasm-module.h
|
| +++ b/src/wasm/wasm-module.h
|
| @@ -27,84 +27,73 @@ const size_t kMaxModuleSize = 1024 * 1024 * 1024;
|
| const size_t kMaxFunctionSize = 128 * 1024;
|
| const size_t kMaxStringSize = 256;
|
| const uint32_t kWasmMagic = 0x6d736100;
|
| -const uint32_t kWasmVersion = 0x0b;
|
| +const uint32_t kWasmVersion = 0x0c;
|
| const uint8_t kWasmFunctionTypeForm = 0x40;
|
| +const uint8_t kWasmAnyFunctionTypeForm = 0x20;
|
| +
|
| +enum WasmSectionCode {
|
| + kUnknownSectionCode = 0, // code for unknown sections
|
| + kTypeSectionCode = 1, // Function signature declarations
|
| + kImportSectionCode = 2, // Import declarations
|
| + kFunctionSectionCode = 3, // Function declarations
|
| + kTableSectionCode = 4, // Indirect function table and other tables
|
| + kMemorySectionCode = 5, // Memory attributes
|
| + kGlobalSectionCode = 6, // Global declarations
|
| + kExportSectionCode = 7, // Exports
|
| + kStartSectionCode = 8, // Start function declaration
|
| + kElementSectionCode = 9, // Elements section
|
| + kCodeSectionCode = 10, // Function code
|
| + kDataSectionCode = 11, // Data segments
|
| + kNameSectionCode = 12, // Name section (encoded as a string)
|
| +};
|
| +
|
| +inline bool IsValidSectionCode(uint8_t byte) {
|
| + return kTypeSectionCode <= byte && byte <= kDataSectionCode;
|
| +}
|
| +
|
| +const char* SectionName(WasmSectionCode code);
|
|
|
| -// WebAssembly sections are named as strings in the binary format, but
|
| -// internally V8 uses an enum to handle them.
|
| -//
|
| -// Entries have the form F(enumerator, string).
|
| -#define FOR_EACH_WASM_SECTION_TYPE(F) \
|
| - F(Signatures, 1, "type") \
|
| - F(ImportTable, 2, "import") \
|
| - F(FunctionSignatures, 3, "function") \
|
| - F(FunctionTable, 4, "table") \
|
| - F(Memory, 5, "memory") \
|
| - F(ExportTable, 6, "export") \
|
| - F(StartFunction, 7, "start") \
|
| - F(FunctionBodies, 8, "code") \
|
| - F(DataSegments, 9, "data") \
|
| - F(Names, 10, "name") \
|
| - F(Globals, 0, "global") \
|
| - F(End, 0, "end")
|
| -
|
| -// Contants for the above section types: {LEB128 length, characters...}.
|
| -#define WASM_SECTION_MEMORY 6, 'm', 'e', 'm', 'o', 'r', 'y'
|
| -#define WASM_SECTION_SIGNATURES 4, 't', 'y', 'p', 'e'
|
| -#define WASM_SECTION_GLOBALS 6, 'g', 'l', 'o', 'b', 'a', 'l'
|
| -#define WASM_SECTION_DATA_SEGMENTS 4, 'd', 'a', 't', 'a'
|
| -#define WASM_SECTION_FUNCTION_TABLE 5, 't', 'a', 'b', 'l', 'e'
|
| -#define WASM_SECTION_END 3, 'e', 'n', 'd'
|
| -#define WASM_SECTION_START_FUNCTION 5, 's', 't', 'a', 'r', 't'
|
| -#define WASM_SECTION_IMPORT_TABLE 6, 'i', 'm', 'p', 'o', 'r', 't'
|
| -#define WASM_SECTION_EXPORT_TABLE 6, 'e', 'x', 'p', 'o', 'r', 't'
|
| -#define WASM_SECTION_FUNCTION_SIGNATURES \
|
| - 8, 'f', 'u', 'n', 'c', 't', 'i', 'o', 'n'
|
| -#define WASM_SECTION_FUNCTION_BODIES 4, 'c', 'o', 'd', 'e'
|
| -#define WASM_SECTION_NAMES 4, 'n', 'a', 'm', 'e'
|
| -
|
| -// Constants for the above section headers' size (LEB128 + characters).
|
| -#define WASM_SECTION_MEMORY_SIZE ((size_t)7)
|
| -#define WASM_SECTION_SIGNATURES_SIZE ((size_t)5)
|
| -#define WASM_SECTION_GLOBALS_SIZE ((size_t)7)
|
| -#define WASM_SECTION_DATA_SEGMENTS_SIZE ((size_t)5)
|
| -#define WASM_SECTION_FUNCTION_TABLE_SIZE ((size_t)6)
|
| -#define WASM_SECTION_END_SIZE ((size_t)4)
|
| -#define WASM_SECTION_START_FUNCTION_SIZE ((size_t)6)
|
| -#define WASM_SECTION_IMPORT_TABLE_SIZE ((size_t)7)
|
| -#define WASM_SECTION_EXPORT_TABLE_SIZE ((size_t)7)
|
| -#define WASM_SECTION_FUNCTION_SIGNATURES_SIZE ((size_t)9)
|
| -#define WASM_SECTION_FUNCTION_BODIES_SIZE ((size_t)5)
|
| -#define WASM_SECTION_NAMES_SIZE ((size_t)5)
|
| +static const char* kNameString = "name";
|
| +static const size_t kNameStringLength = 4;
|
|
|
| class WasmDebugInfo;
|
|
|
| -struct WasmSection {
|
| - enum class Code : uint32_t {
|
| -#define F(enumerator, order, string) enumerator,
|
| - FOR_EACH_WASM_SECTION_TYPE(F)
|
| -#undef F
|
| - Max
|
| - };
|
| - static WasmSection::Code begin();
|
| - static WasmSection::Code end();
|
| - static WasmSection::Code next(WasmSection::Code code);
|
| - static const char* getName(Code code);
|
| - static int getOrder(Code code);
|
| - static size_t getNameLength(Code code);
|
| - static WasmSection::Code lookup(const byte* string, uint32_t length);
|
| +// Constants for fixed-size elements within a module.
|
| +static const uint32_t kMaxReturnCount = 1;
|
| +static const uint8_t kResizableMaximumFlag = 1;
|
| +static const int32_t kInvalidFunctionIndex = -1;
|
| +
|
| +enum WasmExternalKind {
|
| + kExternalFunction = 0,
|
| + kExternalTable = 1,
|
| + kExternalMemory = 2,
|
| + kExternalGlobal = 3
|
| };
|
|
|
| -enum WasmFunctionDeclBit {
|
| - kDeclFunctionName = 0x01,
|
| - kDeclFunctionExport = 0x08
|
| +// Representation of an initializer expression.
|
| +struct WasmInitExpr {
|
| + enum WasmInitKind {
|
| + kNone,
|
| + kGlobalIndex,
|
| + kI32Const,
|
| + kI64Const,
|
| + kF32Const,
|
| + kF64Const
|
| + } kind;
|
| +
|
| + union {
|
| + int32_t i32_const;
|
| + int64_t i64_const;
|
| + float f32_const;
|
| + double f64_const;
|
| + uint32_t global_index;
|
| + } val;
|
| };
|
|
|
| -// Constants for fixed-size elements within a module.
|
| -static const size_t kDeclMemorySize = 3;
|
| -static const size_t kDeclDataSegmentSize = 13;
|
| -
|
| -static const uint32_t kMaxReturnCount = 1;
|
| +#define NO_INIT \
|
| + { \
|
| + WasmInitExpr::kNone, { 0u } \
|
| + }
|
|
|
| // Static representation of a WASM function.
|
| struct WasmFunction {
|
| @@ -115,47 +104,59 @@ struct WasmFunction {
|
| uint32_t name_length; // length in bytes of the name.
|
| uint32_t code_start_offset; // offset in the module bytes of code start.
|
| uint32_t code_end_offset; // offset in the module bytes of code end.
|
| -};
|
| -
|
| -// Static representation of an imported WASM function.
|
| -struct WasmImport {
|
| - FunctionSig* sig; // signature of the function.
|
| - uint32_t sig_index; // index into the signature table.
|
| - uint32_t module_name_offset; // offset in module bytes of the module name.
|
| - uint32_t module_name_length; // length in bytes of the module name.
|
| - uint32_t function_name_offset; // offset in module bytes of the import name.
|
| - uint32_t function_name_length; // length in bytes of the import name.
|
| -};
|
| -
|
| -// Static representation of an exported WASM function.
|
| -struct WasmExport {
|
| - uint32_t func_index; // index into the function table.
|
| - uint32_t name_offset; // offset in module bytes of the name to export.
|
| - uint32_t name_length; // length in bytes of the exported name.
|
| + bool imported;
|
| + bool exported;
|
| };
|
|
|
| // Static representation of a wasm global variable.
|
| struct WasmGlobal {
|
| - uint32_t name_offset; // offset in the module bytes of the name, if any.
|
| - uint32_t name_length; // length in bytes of the global name.
|
| LocalType type; // type of the global.
|
| - uint32_t offset; // offset from beginning of globals area.
|
| - bool exported; // true if this global is exported.
|
| + bool mutability; // {true} if mutable.
|
| + WasmInitExpr init; // the initialization expression of the global.
|
| + uint32_t offset; // offset into global memory.
|
| + bool imported; // true if imported.
|
| + bool exported; // true if exported.
|
| };
|
|
|
| // Static representation of a wasm data segment.
|
| struct WasmDataSegment {
|
| - uint32_t dest_addr; // destination memory address of the data.
|
| + WasmInitExpr dest_addr; // destination memory address of the data.
|
| uint32_t source_offset; // start offset in the module bytes.
|
| uint32_t source_size; // end offset in the module bytes.
|
| - bool init; // true if loaded upon instantiation.
|
| };
|
|
|
| // Static representation of a wasm indirect call table.
|
| struct WasmIndirectFunctionTable {
|
| - uint32_t size; // initial table size.
|
| - uint32_t max_size; // maximum table size.
|
| - std::vector<uint16_t> values; // function table.
|
| + uint32_t size; // initial table size.
|
| + uint32_t max_size; // maximum table size.
|
| + std::vector<int32_t> values; // function table, -1 indicating invalid.
|
| + bool imported; // true if imported.
|
| + bool exported; // true if exported.
|
| +};
|
| +
|
| +// Static representation of how to initialize a table.
|
| +struct WasmTableInit {
|
| + uint32_t table_index;
|
| + WasmInitExpr offset;
|
| + std::vector<uint32_t> entries;
|
| +};
|
| +
|
| +// Static representation of a WASM import.
|
| +struct WasmImport {
|
| + uint32_t module_name_length; // length in bytes of the module name.
|
| + uint32_t module_name_offset; // offset in module bytes of the module name.
|
| + uint32_t field_name_length; // length in bytes of the import name.
|
| + uint32_t field_name_offset; // offset in module bytes of the import name.
|
| + WasmExternalKind kind; // kind of the import.
|
| + uint32_t index; // index into the respective space.
|
| +};
|
| +
|
| +// Static representation of a WASM export.
|
| +struct WasmExport {
|
| + uint32_t name_length; // length in bytes of the exported name.
|
| + uint32_t name_offset; // offset in module bytes of the name to export.
|
| + WasmExternalKind kind; // kind of the export.
|
| + uint32_t index; // index into the respective space.
|
| };
|
|
|
| enum ModuleOrigin { kWasmOrigin, kAsmJsOrigin };
|
| @@ -171,7 +172,6 @@ struct WasmModule {
|
| uint32_t min_mem_pages; // minimum size of the memory in 64k pages.
|
| uint32_t max_mem_pages; // maximum size of the memory in 64k pages.
|
| bool mem_export; // true if the memory is exported.
|
| - bool mem_external; // true if the memory is external.
|
| // TODO(wasm): reconcile start function index being an int with
|
| // the fact that we index on uint32_t, so we may technically not be
|
| // able to represent some start_function_index -es.
|
| @@ -180,12 +180,16 @@ struct WasmModule {
|
|
|
| std::vector<WasmGlobal> globals; // globals in this module.
|
| uint32_t globals_size; // size of globals table.
|
| + uint32_t num_imported_functions; // number of imported functions.
|
| + uint32_t num_declared_functions; // number of declared functions.
|
| + uint32_t num_exported_functions; // number of exported functions.
|
| std::vector<FunctionSig*> signatures; // signatures in this module.
|
| std::vector<WasmFunction> functions; // functions in this module.
|
| std::vector<WasmDataSegment> data_segments; // data segments in this module.
|
| std::vector<WasmIndirectFunctionTable> function_tables; // function tables.
|
| std::vector<WasmImport> import_table; // import table.
|
| std::vector<WasmExport> export_table; // export table.
|
| + std::vector<WasmTableInit> table_inits; // initializations of tables
|
| // We store the semaphore here to extend its lifetime. In <libc-2.21, which we
|
| // use on the try bots, semaphore::Wait() can return while some compilation
|
| // tasks are still executing semaphore::Signal(). If the semaphore is cleaned
|
| @@ -255,7 +259,6 @@ struct WasmModuleInstance {
|
| Handle<JSArrayBuffer> globals_buffer; // Handle to array buffer of globals.
|
| std::vector<Handle<FixedArray>> function_tables; // indirect function tables.
|
| std::vector<Handle<Code>> function_code; // code objects for each function.
|
| - std::vector<Handle<Code>> import_code; // code objects for each import.
|
| // -- raw memory ------------------------------------------------------------
|
| byte* mem_start; // start of linear memory.
|
| uint32_t mem_size; // size of the linear memory.
|
| @@ -266,7 +269,6 @@ struct WasmModuleInstance {
|
| : module(m),
|
| function_tables(m->function_tables.size()),
|
| function_code(m->functions.size()),
|
| - import_code(m->import_table.size()),
|
| mem_start(nullptr),
|
| mem_size(0),
|
| globals_start(nullptr) {}
|
| @@ -278,9 +280,6 @@ struct ModuleEnv {
|
| const WasmModule* module;
|
| WasmModuleInstance* instance;
|
| ModuleOrigin origin;
|
| - // TODO(mtrofin): remove this once we introduce WASM_DIRECT_CALL
|
| - // reloc infos.
|
| - std::vector<Handle<Code>> placeholders;
|
|
|
| bool IsValidGlobal(uint32_t index) const {
|
| return module && index < module->globals.size();
|
| @@ -291,9 +290,6 @@ struct ModuleEnv {
|
| bool IsValidSignature(uint32_t index) const {
|
| return module && index < module->signatures.size();
|
| }
|
| - bool IsValidImport(uint32_t index) const {
|
| - return module && index < module->import_table.size();
|
| - }
|
| bool IsValidTable(uint32_t index) const {
|
| return module && index < module->function_tables.size();
|
| }
|
| @@ -305,10 +301,6 @@ struct ModuleEnv {
|
| DCHECK(IsValidFunction(index));
|
| return module->functions[index].sig;
|
| }
|
| - FunctionSig* GetImportSignature(uint32_t index) {
|
| - DCHECK(IsValidImport(index));
|
| - return module->import_table[index].sig;
|
| - }
|
| FunctionSig* GetSignature(uint32_t index) {
|
| DCHECK(IsValidSignature(index));
|
| return module->signatures[index];
|
| @@ -320,8 +312,10 @@ struct ModuleEnv {
|
|
|
| bool asm_js() { return origin == kAsmJsOrigin; }
|
|
|
| - Handle<Code> GetCodeOrPlaceholder(uint32_t index) const;
|
| - Handle<Code> GetImportCode(uint32_t index);
|
| + Handle<Code> GetFunctionCode(uint32_t index) {
|
| + DCHECK_NOT_NULL(instance);
|
| + return instance->function_code[index];
|
| + }
|
|
|
| static compiler::CallDescriptor* GetWasmCallDescriptor(Zone* zone,
|
| FunctionSig* sig);
|
| @@ -408,6 +402,8 @@ MaybeHandle<JSObject> CreateModuleObjectFromBytes(Isolate* isolate,
|
| ErrorThrower* thrower,
|
| ModuleOrigin origin);
|
|
|
| +uint32_t GetNumImportedFunctions(Handle<JSObject> wasm_object);
|
| +
|
| // Assumed to be called with a code object associated to a wasm module instance.
|
| // Intended to be called from runtime functions.
|
| // Returns undefined if the runtime support was not setup, nullptr if the
|
|
|