WasmBuiltinModule.h (5719B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * 4 * Copyright 2021 Mozilla Foundation 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 #ifndef wasm_builtin_module_h 20 #define wasm_builtin_module_h 21 22 #include "mozilla/EnumeratedArray.h" 23 #include "mozilla/Maybe.h" 24 #include "mozilla/Span.h" 25 26 #include "wasm/WasmBuiltins.h" 27 #include "wasm/WasmCompileArgs.h" 28 #include "wasm/WasmConstants.h" 29 #include "wasm/WasmSerialize.h" 30 #include "wasm/WasmTypeDecls.h" 31 #include "wasm/WasmTypeDef.h" 32 33 namespace js { 34 namespace wasm { 35 36 struct ImportValues; 37 struct Import; 38 39 struct MOZ_STACK_CLASS BuiltinModuleInstances { 40 explicit BuiltinModuleInstances(JSContext* cx) 41 : selfTest(cx), intGemm(cx), jsString(cx) {} 42 43 Rooted<JSObject*> selfTest; 44 Rooted<JSObject*> intGemm; 45 Rooted<JSObject*> jsString; 46 47 MutableHandle<JSObject*> operator[](BuiltinModuleId module) { 48 switch (module) { 49 case BuiltinModuleId::SelfTest: { 50 return &selfTest; 51 } 52 case BuiltinModuleId::IntGemm: { 53 return &intGemm; 54 } 55 case BuiltinModuleId::JSString: { 56 return &jsString; 57 } 58 default: { 59 MOZ_CRASH(); 60 } 61 } 62 } 63 }; 64 65 // An builtin module func is a natively implemented function that may be 66 // compiled into a 'builtin module', which may be instantiated with a provided 67 // memory yielding an exported WebAssembly function wrapping the builtin module. 68 class BuiltinModuleFunc { 69 private: 70 SharedRecGroup recGroup_; 71 const char* exportName_; 72 const SymbolicAddressSignature* sig_; 73 bool usesMemory_; 74 BuiltinInlineOp inlineOp_; 75 76 public: 77 // Default constructor so this can be used in an EnumeratedArray. 78 BuiltinModuleFunc() = default; 79 80 // Initialize this builtin. Must only be called once. 81 [[nodiscard]] bool init(const RefPtr<TypeContext>& types, 82 mozilla::Span<const ValType> params, 83 mozilla::Maybe<ValType> result, bool usesMemory, 84 const SymbolicAddressSignature* sig, 85 BuiltinInlineOp inlineOp, const char* exportName); 86 87 // The rec group for the function type for this builtin. 88 const RecGroup* recGroup() const { return recGroup_.get(); } 89 // The type definition for the function type for this builtin. 90 const TypeDef* typeDef() const { return &recGroup_->type(0); } 91 // The function type for this builtin. 92 const FuncType* funcType() const { return &typeDef()->funcType(); } 93 94 // The name of the func as it is exported 95 const char* exportName() const { return exportName_; } 96 // The signature of the builtin that implements this function. 97 const SymbolicAddressSignature* sig() const { return sig_; } 98 // Whether this function takes a pointer to the memory base as a hidden final 99 // parameter. This parameter will show up in the SymbolicAddressSignature, 100 // but not the function type. Compilers must pass the memoryBase to the 101 // function call as the last parameter. 102 bool usesMemory() const { return usesMemory_; } 103 // An optional inline operation that can be used for this function instead of 104 // calling `sig`. 105 BuiltinInlineOp inlineOp() const { return inlineOp_; } 106 }; 107 108 // Static storage for all builtin module funcs in the system. 109 class BuiltinModuleFuncs { 110 using Storage = 111 mozilla::EnumeratedArray<BuiltinModuleFuncId, BuiltinModuleFunc, 112 size_t(BuiltinModuleFuncId::Limit)>; 113 Storage funcs_; 114 115 static BuiltinModuleFuncs* singleton_; 116 117 public: 118 [[nodiscard]] static bool init(); 119 static void destroy(); 120 121 // Get the BuiltinModuleFunc for an BuiltinModuleFuncId. BuiltinModuleFuncId 122 // must be validated. 123 static const BuiltinModuleFunc& getFromId(BuiltinModuleFuncId id) { 124 return singleton_->funcs_[id]; 125 } 126 }; 127 128 mozilla::Maybe<BuiltinModuleId> ImportMatchesBuiltinModule( 129 mozilla::Span<const char> importName, 130 const BuiltinModuleIds& enabledBuiltins); 131 bool ImportMatchesBuiltinModuleFunc(mozilla::Span<const char> importName, 132 BuiltinModuleId module, 133 const BuiltinModuleFunc** matchedFunc, 134 BuiltinModuleFuncId* matchedFuncId); 135 136 // Compile and return the builtin module for a particular 137 // builtin module. The `moduleMemoryImport` can be used if the builtin module 138 // requires memory to set the import name that it will need when it is 139 // instantiated, otherwise ("" "memory") is used instead. 140 [[nodiscard]] bool CompileBuiltinModule( 141 JSContext* cx, BuiltinModuleId module, const Import* moduleMemoryImport, 142 MutableHandle<WasmModuleObject*> result); 143 144 // Compile, instantiate and return the builtin module instance for a particular 145 // builtin module. 146 [[nodiscard]] bool InstantiateBuiltinModule(JSContext* cx, 147 BuiltinModuleId module, 148 const Import* moduleMemoryImport, 149 Handle<JSObject*> importObj, 150 MutableHandle<JSObject*> result); 151 152 } // namespace wasm 153 } // namespace js 154 155 #endif // wasm_builtin_module_h