LCOV - code coverage report
Current view: top level - core/wasm/exports - SPWasm.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 28 32 87.5 %
Date: 2024-05-12 00:16:13 Functions: 22 31 71.0 %

          Line data    Source code
       1             : /**
       2             :  Copyright (c) 2024 Stappler LLC <admin@stappler.dev>
       3             : 
       4             :  Permission is hereby granted, free of charge, to any person obtaining a copy
       5             :  of this software and associated documentation files (the "Software"), to deal
       6             :  in the Software without restriction, including without limitation the rights
       7             :  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       8             :  copies of the Software, and to permit persons to whom the Software is
       9             :  furnished to do so, subject to the following conditions:
      10             : 
      11             :  The above copyright notice and this permission notice shall be included in
      12             :  all copies or substantial portions of the Software.
      13             : 
      14             :  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      15             :  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      16             :  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      17             :  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      18             :  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      19             :  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      20             :  THE SOFTWARE.
      21             :  **/
      22             : 
      23             : #ifndef CORE_WASM_SPWASM_H_
      24             : #define CORE_WASM_SPWASM_H_
      25             : 
      26             : #include "SPMemory.h"
      27             : #include "SPRef.h"
      28             : 
      29             : #include <typeindex>
      30             : 
      31             : #include "wamr/wasm_export.h"
      32             : 
      33             : namespace stappler::wasm {
      34             : 
      35             : using namespace mem_std;
      36             : 
      37             : class ModuleInstance;
      38             : class ExecFunction;
      39             : 
      40             : struct ListOutput {
      41             :         uint32_t ptr;
      42             :         uint32_t len;
      43             : 
      44             :         template <typename T>
      45             :         void setData(ModuleInstance *, const T *, size_t count);
      46             : };
      47             : 
      48             : class Runtime final {
      49             : public:
      50             :         static Runtime *getInstance();
      51             : 
      52             :         ~Runtime();
      53             : 
      54             : protected:
      55             :         struct Data;
      56             : 
      57             :         Runtime();
      58             : 
      59             :         Data *_data;
      60             : };
      61             : 
      62             : struct NativeModule {
      63             :         NativeModule(StringView, NativeSymbol *, size_t count);
      64             :         ~NativeModule();
      65             : 
      66             :         String name;
      67             :         NativeSymbol *symbols;
      68             :         size_t symbolsCount;
      69             : };
      70             : 
      71             : class Module final : public Ref {
      72             : public:
      73             :         virtual ~Module();
      74             : 
      75             :         bool init(StringView name, BytesView);
      76             :         bool init(StringView name, Bytes &&);
      77             :         bool init(StringView name, FilePath);
      78             : 
      79          25 :         StringView getName() const { return _name; }
      80          25 :         wasm_module_t getModule() const { return _module; }
      81             : 
      82             : protected:
      83             :         String _name;
      84             :         Bytes _data;
      85             :         Runtime *_runtime = nullptr;
      86             :         wasm_module_t _module = nullptr;
      87             : };
      88             : 
      89             : class ModuleInstance final : public Ref {
      90             : public:
      91             :         static constexpr uint32_t InvalidHandle = maxOf<uint32_t>();
      92             : 
      93             :         virtual ~ModuleInstance();
      94             : 
      95             :         bool init(Module *, uint32_t stackSize = 16_KiB, uint32_t heapSize = 16_KiB);
      96             : 
      97          25 :         Module * getModule() const { return _module; }
      98         550 :         wasm_module_inst_t getInstance() const { return _inst; }
      99             : 
     100             :         void *appToNative(uint32_t offset) const;
     101             :         uint32_t nativeToApp(void *ptr) const;
     102             : 
     103             :         uint32_t allocate(uint32_t size, void ** = nullptr);
     104             :         uint32_t reallocate(uint32_t ptr, uint32_t size, void ** = nullptr);
     105             : 
     106             :         void free(uint32_t ptr);
     107             : 
     108             :         Rc<ExecFunction> lookup(StringView);
     109             : 
     110             :         template <typename T>
     111             :         uint32_t addHandle(T *, Function<void()> &&dtor = nullptr);
     112             : 
     113             :         template <typename T>
     114             :         uint32_t getHandle(T *) const;
     115             : 
     116             :         template <typename T = void>
     117             :         T *getObject(uint32_t) const;
     118             : 
     119             :         uint32_t getHandle(void *) const;
     120             : 
     121             :         void removeHandle(uint32_t);
     122             :         void removeObject(void *);
     123             : 
     124             : protected:
     125             :         uint32_t addHandleObject(void *, std::type_index &&, Function<void()> &&);
     126             :         uint32_t getHandleObject(void *, const std::type_index &) const;
     127             :         void *getObjectHandle(uint32_t, const std::type_index &) const;
     128             : 
     129             :         struct HandleSlot {
     130             :                 void *object = nullptr;
     131             :                 std::type_index type = std::type_index(typeid(void));
     132             :                 uint32_t index;
     133             :                 uint32_t nextIndex = InvalidHandle;
     134             :                 Function<void()> destructor;
     135             :         };
     136             : 
     137             :         Rc<Module> _module;
     138             :         wasm_module_inst_t _inst = nullptr;
     139             :         wasm_function_inst_t _finalize = nullptr;
     140             :         wasm_function_inst_t _realloc = nullptr;
     141             : 
     142             :         uint32_t _selfHandle = 0;
     143             :         uint32_t _freeHandleSlot = InvalidHandle;
     144             :         Vector<HandleSlot> _handles;
     145             :         HashMap<void *, uint32_t> _objects;
     146             : };
     147             : 
     148             : class ExecEnv final : public Ref {
     149             : public:
     150             :         static ExecEnv *get(wasm_exec_env_t);
     151             : 
     152             :         virtual ~ExecEnv();
     153             : 
     154             :         bool init(ModuleInstance *, uint32_t stackSize = 16_KiB);
     155             :         bool init(ModuleInstance *, wasm_exec_env_t);
     156             : 
     157          25 :         wasm_exec_env_t getEnv() const { return _env; }
     158         325 :         ModuleInstance *getInstance() const { return _instance; }
     159             : 
     160             :         template <typename T = void>
     161         375 :         auto appToNative(uint32_t offset) const -> T * {
     162         375 :                 return reinterpret_cast<T *>(_instance->appToNative(offset));
     163             :         }
     164             :         uint32_t nativeToApp(void *ptr) const;
     165             : 
     166             :         template <typename T = void>
     167         200 :         uint32_t allocate(uint32_t size, T **ptr = nullptr) {
     168         200 :                 return _instance->allocate(size, reinterpret_cast<void **>(ptr));
     169             :         }
     170             : 
     171          25 :         void free(uint32_t ptr) {
     172          25 :                 _instance->free(ptr);
     173          25 :         }
     174             : 
     175             :         bool callIndirect(uint32_t, uint32_t argc, uint32_t argv[]);
     176             : 
     177             : protected:
     178             :         Rc<ModuleInstance> _instance;
     179             :         wasm_exec_env_t _env = nullptr;
     180             :         bool _isSingleton = false;
     181             : };
     182             : 
     183             : class ExecFunction final : public Ref {
     184             : public:
     185             :         static constexpr uint32_t StaticArgumentsLimit = 28;
     186             :         static constexpr uint32_t StaticResultsLimit = 4;
     187             : 
     188         200 :         virtual ~ExecFunction() = default;
     189             : 
     190             :         bool init(ModuleInstance *, StringView name);
     191             : 
     192          25 :         StringView getName() const { return _name; }
     193          50 :         wasm_function_inst_t getFunc() const { return _func; }
     194             : 
     195          50 :         uint32_t getNumArgs() const { return _nArgs; }
     196          50 :         uint32_t getNumResults() const { return _nResults; }
     197             : 
     198             :         SpanView<wasm_valkind_t> getArgs() const { return makeSpanView(_argTypesStatic, std::max(_nArgs, StaticArgumentsLimit)); }
     199             :         SpanView<wasm_valkind_t> getResults() const { return makeSpanView(_resultTypesStatic, std::max(_nResults, StaticResultsLimit)); }
     200             : 
     201             :         // use when statics are out of limit
     202             :         Vector<wasm_valkind_t> getArgsFull() const;
     203             :         Vector<wasm_valkind_t> getResultsFull() const;
     204             : 
     205             :         bool call(ExecEnv *, SpanView<wasm_val_t> args = SpanView<wasm_val_t>(), VectorAdapter<wasm_val_t> *results = nullptr) const;
     206             : 
     207             :         wasm_val_t call1(ExecEnv *, SpanView<wasm_val_t> args = SpanView<wasm_val_t>()) const;
     208             : 
     209             : protected:
     210             :         String _name;
     211             :         wasm_function_inst_t _func = nullptr;
     212             :         Rc<ModuleInstance> _inst;
     213             :         uint32_t _nArgs = 0;
     214             :         uint32_t _nResults = 0;
     215             :         wasm_valkind_t _resultTypesStatic[StaticResultsLimit] = { 0 };
     216             :         wasm_valkind_t _argTypesStatic[StaticArgumentsLimit] = { 0 };
     217             : };
     218             : 
     219           0 : inline wasm_val_t MakeValue(uint32_t val) {
     220             :         wasm_val_t ret;
     221           0 :         ret.kind = WASM_I32;
     222           0 :         ret.of.i32 = val;
     223           0 :         return ret;
     224             : }
     225             : 
     226             : inline wasm_val_t MakeValue(int32_t val) {
     227             :         wasm_val_t ret;
     228             :         ret.kind = WASM_I32;
     229             :         ret.of.i32 = val;
     230             :         return ret;
     231             : }
     232             : 
     233             : inline wasm_val_t MakeValue(uint64_t val) {
     234             :         wasm_val_t ret;
     235             :         ret.kind = WASM_I64;
     236             :         ret.of.i64 = val;
     237             :         return ret;
     238             : }
     239             : 
     240             : inline wasm_val_t MakeValue(int64_t val) {
     241             :         wasm_val_t ret;
     242             :         ret.kind = WASM_I64;
     243             :         ret.of.i64 = val;
     244             :         return ret;
     245             : }
     246             : 
     247             : inline wasm_val_t MakeValue(float val) {
     248             :         wasm_val_t ret;
     249             :         ret.kind = WASM_F32;
     250             :         ret.of.f32 = val;
     251             :         return ret;
     252             : }
     253             : 
     254             : inline wasm_val_t MakeValue(double val) {
     255             :         wasm_val_t ret;
     256             :         ret.kind = WASM_F64;
     257             :         ret.of.f64 = val;
     258             :         return ret;
     259             : }
     260             : 
     261             : template <typename T>
     262         125 : void ListOutput::setData(ModuleInstance *inst, const T *data, size_t count) {
     263         125 :         uint8_t *buf = nullptr;
     264         125 :         ptr = inst->allocate(count * sizeof(T), (void **)&buf);
     265         125 :         len = count;
     266         125 :         memcpy(buf, data, count * sizeof(T));
     267         125 : }
     268             : 
     269             : template <typename T>
     270         100 : uint32_t ModuleInstance::addHandle(T *obj, Function<void()> &&dtor) {
     271             :         using Type = typename std::remove_reference<typename std::remove_cv<T>::type>::type;
     272         100 :         return addHandleObject((Type *)obj, std::type_index(typeid(Type)), move(dtor));
     273             : }
     274             : 
     275             : template <typename T>
     276             : uint32_t ModuleInstance::getHandle(T *obj) const {
     277             :         return getHandleObject(obj, std::type_index(typeid(typename std::remove_reference<typename std::remove_cv<T>::type>::type)));
     278             : }
     279             : 
     280             : template <typename T>
     281         275 : T *ModuleInstance::getObject(uint32_t idx) const {
     282         275 :         return reinterpret_cast<T *>(getObjectHandle(idx, std::type_index(typeid(typename std::remove_reference<typename std::remove_cv<T>::type>::type))));
     283             : }
     284             : 
     285             : }
     286             : 
     287             : #endif /* CORE_WASM_SPWASM_H_ */

Generated by: LCOV version 1.14