| 527 | } |
| 528 | |
| 529 | std::shared_ptr<WasmHandleBase> createWasm(const std::string &vm_key, const std::string &code, |
| 530 | const std::shared_ptr<PluginBase> &plugin, |
| 531 | const WasmHandleFactory &factory, |
| 532 | const WasmHandleCloneFactory &clone_factory, |
| 533 | bool allow_precompiled) { |
| 534 | std::shared_ptr<WasmHandleBase> wasm_handle; |
| 535 | { |
| 536 | std::lock_guard<std::mutex> guard(base_wasms_mutex); |
| 537 | if (base_wasms == nullptr) { |
| 538 | base_wasms = new std::remove_reference<decltype(*base_wasms)>::type; |
| 539 | } |
| 540 | auto it = base_wasms->find(vm_key); |
| 541 | if (it != base_wasms->end()) { |
| 542 | wasm_handle = it->second.lock(); |
| 543 | if (!wasm_handle) { |
| 544 | base_wasms->erase(it); |
| 545 | } |
| 546 | } |
| 547 | if (!wasm_handle) { |
| 548 | // If no cached base_wasm, creates a new base_wasm, loads the code and initializes it. |
| 549 | wasm_handle = factory(vm_key); |
| 550 | if (!wasm_handle) { |
| 551 | return nullptr; |
| 552 | } |
| 553 | if (!wasm_handle->wasm()->load(code, allow_precompiled)) { |
| 554 | wasm_handle->wasm()->fail(FailState::UnableToInitializeCode, "Failed to load Wasm code"); |
| 555 | return nullptr; |
| 556 | } |
| 557 | if (!wasm_handle->wasm()->initialize()) { |
| 558 | wasm_handle->wasm()->fail(FailState::UnableToInitializeCode, |
| 559 | "Failed to initialize Wasm code"); |
| 560 | return nullptr; |
| 561 | } |
| 562 | (*base_wasms)[vm_key] = wasm_handle; |
| 563 | } |
| 564 | } |
| 565 | |
| 566 | // Either creating new one or reusing the existing one, apply canary for each plugin. |
| 567 | if (!wasm_handle->canary(plugin, clone_factory)) { |
| 568 | return nullptr; |
| 569 | } |
| 570 | return wasm_handle; |
| 571 | }; |
| 572 | |
| 573 | std::shared_ptr<WasmHandleBase> getThreadLocalWasm(std::string_view vm_key) { |
| 574 | auto it = local_wasms.find(std::string(vm_key)); |