@@ -237,22 +237,22 @@ std::optional<uint32_t> find_export(const Module& module, ExternalKind kind, std
237237
238238} // namespace
239239
240- std::unique_ptr<Instance> instantiate (Module module ,
240+ std::unique_ptr<Instance> instantiate (std::unique_ptr< Module>&& module ,
241241 std::vector<ExternalFunction> imported_functions, std::vector<ExternalTable> imported_tables,
242242 std::vector<ExternalMemory> imported_memories, std::vector<ExternalGlobal> imported_globals,
243243 uint32_t memory_pages_limit /* = DefaultMemoryPagesLimit*/ )
244244{
245- assert (module . funcsec .size () == module . codesec .size ());
245+ assert (module -> funcsec .size () == module -> codesec .size ());
246246
247- match_imported_functions (module . imported_function_types , imported_functions);
248- match_imported_tables (module . imported_table_types , imported_tables);
249- match_imported_memories (module . imported_memory_types , imported_memories);
250- match_imported_globals (module . imported_global_types , imported_globals);
247+ match_imported_functions (module -> imported_function_types , imported_functions);
248+ match_imported_tables (module -> imported_table_types , imported_tables);
249+ match_imported_memories (module -> imported_memory_types , imported_memories);
250+ match_imported_globals (module -> imported_global_types , imported_globals);
251251
252252 // Init globals
253253 std::vector<Value> globals;
254- globals.reserve (module . globalsec .size ());
255- for (auto const & global : module . globalsec )
254+ globals.reserve (module -> globalsec .size ());
255+ for (auto const & global : module -> globalsec )
256256 {
257257 // Constraint to use global.get only with imported globals is checked at validation.
258258 assert (global.expression .kind != ConstantExpression::Kind::GlobalGet ||
@@ -262,10 +262,10 @@ std::unique_ptr<Instance> instantiate(Module module,
262262 globals.emplace_back (value);
263263 }
264264
265- auto [table, table_limits] = allocate_table (module . tablesec , imported_tables);
265+ auto [table, table_limits] = allocate_table (module -> tablesec , imported_tables);
266266
267267 auto [memory, memory_limits] =
268- allocate_memory (module . memorysec , imported_memories, memory_pages_limit);
268+ allocate_memory (module -> memorysec , imported_memories, memory_pages_limit);
269269 // In case upper limit for local/imported memory is defined,
270270 // we adjust the hard memory limit, to ensure memory.grow will fail when exceeding it.
271271 // Note: allocate_memory ensures memory's max limit is always below memory_pages_limit.
@@ -278,8 +278,8 @@ std::unique_ptr<Instance> instantiate(Module module,
278278 // Before starting to fill memory and table,
279279 // check that data and element segments are within bounds.
280280 std::vector<uint64_t > datasec_offsets;
281- datasec_offsets.reserve (module . datasec .size ());
282- for (const auto & data : module . datasec )
281+ datasec_offsets.reserve (module -> datasec .size ());
282+ for (const auto & data : module -> datasec )
283283 {
284284 // Offset is validated to be i32, but it's used in 64-bit calculation below.
285285 const uint64_t offset =
@@ -291,10 +291,10 @@ std::unique_ptr<Instance> instantiate(Module module,
291291 datasec_offsets.emplace_back (offset);
292292 }
293293
294- assert (module . elementsec .empty () || table != nullptr );
294+ assert (module -> elementsec .empty () || table != nullptr );
295295 std::vector<ptrdiff_t > elementsec_offsets;
296- elementsec_offsets.reserve (module . elementsec .size ());
297- for (const auto & element : module . elementsec )
296+ elementsec_offsets.reserve (module -> elementsec .size ());
297+ for (const auto & element : module -> elementsec )
298298 {
299299 // Offset is validated to be i32, but it's used in 64-bit calculation below.
300300 const uint64_t offset =
@@ -307,10 +307,10 @@ std::unique_ptr<Instance> instantiate(Module module,
307307 }
308308
309309 // Fill out memory based on data segments
310- for (size_t i = 0 ; i < module . datasec .size (); ++i)
310+ for (size_t i = 0 ; i < module -> datasec .size (); ++i)
311311 {
312312 // NOTE: these instructions can overlap
313- std::copy (module . datasec [i].init .begin (), module . datasec [i].init .end (),
313+ std::copy (module -> datasec [i].init .begin (), module -> datasec [i].init .end (),
314314 memory->data () + datasec_offsets[i]);
315315 }
316316
@@ -321,41 +321,41 @@ std::unique_ptr<Instance> instantiate(Module module,
321321 std::move (imported_functions), std::move (imported_globals));
322322
323323 // Fill the table based on elements segment
324- for (size_t i = 0 ; i < instance->module . elementsec .size (); ++i)
324+ for (size_t i = 0 ; i < instance->module -> elementsec .size (); ++i)
325325 {
326326 // Overwrite table[offset..] with element.init
327327 auto it_table = instance->table ->begin () + elementsec_offsets[i];
328- for (const auto idx : instance->module . elementsec [i].init )
328+ for (const auto idx : instance->module -> elementsec [i].init )
329329 {
330330 auto func = [idx, &instance_ref = *instance](fizzy::Instance&, span<const Value> args,
331331 int depth) { return execute (instance_ref, idx, args, depth); };
332332
333333 *it_table++ =
334- ExternalFunction{std::move (func), instance->module . get_function_type (idx)};
334+ ExternalFunction{std::move (func), instance->module -> get_function_type (idx)};
335335 }
336336 }
337337
338338 // Run start function if present
339- if (instance->module . startfunc )
339+ if (instance->module -> startfunc )
340340 {
341- const auto funcidx = *instance->module . startfunc ;
342- assert (funcidx < instance->imported_functions .size () + instance->module . funcsec .size ());
341+ const auto funcidx = *instance->module -> startfunc ;
342+ assert (funcidx < instance->imported_functions .size () + instance->module -> funcsec .size ());
343343 if (execute (*instance, funcidx, {}).trapped )
344344 {
345345 // When element section modified imported table, and then start function trapped,
346346 // modifications to the table are not rolled back.
347347 // Instance in this case is not being returned to the user, so it needs to be kept alive
348348 // as long as functions using it are alive in the table.
349- if (!imported_tables.empty () && !instance->module . elementsec .empty ())
349+ if (!imported_tables.empty () && !instance->module -> elementsec .empty ())
350350 {
351351 // Instance may be used by several functions added to the table,
352352 // so we need a shared ownership here.
353353 std::shared_ptr<Instance> shared_instance = std::move (instance);
354354
355- for (size_t i = 0 ; i < shared_instance->module . elementsec .size (); ++i)
355+ for (size_t i = 0 ; i < shared_instance->module -> elementsec .size (); ++i)
356356 {
357357 auto it_table = shared_instance->table ->begin () + elementsec_offsets[i];
358- for ([[maybe_unused]] auto _ : shared_instance->module . elementsec [i].init )
358+ for ([[maybe_unused]] auto _ : shared_instance->module -> elementsec [i].init )
359359 {
360360 // Wrap the function with the lambda capturing shared instance
361361 auto & table_function = (*it_table)->function ;
@@ -373,6 +373,16 @@ std::unique_ptr<Instance> instantiate(Module module,
373373 return instance;
374374}
375375
376+ std::unique_ptr<Instance> instantiate (const std::unique_ptr<Module>& module ,
377+ std::vector<ExternalFunction> imported_functions, std::vector<ExternalTable> imported_tables,
378+ std::vector<ExternalMemory> imported_memories, std::vector<ExternalGlobal> imported_globals,
379+ uint32_t memory_pages_limit)
380+ {
381+ return instantiate (std::make_unique<Module>(*module ), std::move (imported_functions),
382+ std::move (imported_tables), std::move (imported_memories), std::move (imported_globals),
383+ memory_pages_limit);
384+ }
385+
376386std::vector<ExternalFunction> resolve_imported_functions (
377387 const Module& module , std::vector<ImportedFunction> imported_functions)
378388{
@@ -427,7 +437,7 @@ std::optional<FuncIdx> find_exported_function(const Module& module, std::string_
427437
428438std::optional<ExternalFunction> find_exported_function (Instance& instance, std::string_view name)
429439{
430- const auto opt_index = find_export (instance.module , ExternalKind::Function, name);
440+ const auto opt_index = find_export (* instance.module , ExternalKind::Function, name);
431441 if (!opt_index.has_value ())
432442 return std::nullopt ;
433443
@@ -436,12 +446,12 @@ std::optional<ExternalFunction> find_exported_function(Instance& instance, std::
436446 return execute (instance, idx, args, depth);
437447 };
438448
439- return ExternalFunction{std::move (func), instance.module . get_function_type (idx)};
449+ return ExternalFunction{std::move (func), instance.module -> get_function_type (idx)};
440450}
441451
442452std::optional<ExternalGlobal> find_exported_global (Instance& instance, std::string_view name)
443453{
444- const auto opt_index = find_export (instance.module , ExternalKind::Global, name);
454+ const auto opt_index = find_export (* instance.module , ExternalKind::Global, name);
445455 if (!opt_index.has_value ())
446456 return std::nullopt ;
447457
@@ -457,27 +467,23 @@ std::optional<ExternalGlobal> find_exported_global(Instance& instance, std::stri
457467 // global owned by instance
458468 const auto module_global_idx = global_idx - instance.imported_globals .size ();
459469 return ExternalGlobal{&instance.globals [module_global_idx],
460- instance.module . globalsec [module_global_idx].type };
470+ instance.module -> globalsec [module_global_idx].type };
461471 }
462472}
463473
464474std::optional<ExternalTable> find_exported_table (Instance& instance, std::string_view name)
465475{
466- const auto & module = instance.module ;
467-
468476 // Index returned from find_export is discarded, because there's no more than 1 table
469- if (!find_export (module , ExternalKind::Table, name))
477+ if (!find_export (*instance. module , ExternalKind::Table, name))
470478 return std::nullopt ;
471479
472480 return ExternalTable{instance.table .get (), instance.table_limits };
473481}
474482
475483std::optional<ExternalMemory> find_exported_memory (Instance& instance, std::string_view name)
476484{
477- const auto & module = instance.module ;
478-
479485 // Index returned from find_export is discarded, because there's no more than 1 memory
480- if (!find_export (module , ExternalKind::Memory, name))
486+ if (!find_export (*instance. module , ExternalKind::Memory, name))
481487 return std::nullopt ;
482488
483489 return ExternalMemory{instance.memory .get (), instance.memory_limits };
0 commit comments