Runtime::ModuleInstance* instantiateModule( Runtime::Compartment* compartment, const Intrinsics::Module& moduleRef, std::string&& debugName, const HashMap<std::string,Runtime::Object*>& extraExports) { auto moduleInstance = new Runtime::ModuleInstance(compartment,{},{},{},{},{},std::move(debugName)); if(moduleRef.impl) { for(const auto& pair : moduleRef.impl->functionMap) { auto functionInstance = pair.value->instantiate(compartment); moduleInstance->functions.push_back(functionInstance); errorUnless(moduleInstance->exportMap.add(pair.key, functionInstance)); } for(const auto& pair : moduleRef.impl->tableMap) { auto tableInstance = pair.value->instantiate(compartment); moduleInstance->tables.push_back(tableInstance); errorUnless(moduleInstance->exportMap.add(pair.key, tableInstance)); } for(const auto& pair : moduleRef.impl->memoryMap) { auto memoryInstance = pair.value->instantiate(compartment); moduleInstance->memories.push_back(memoryInstance); errorUnless(moduleInstance->exportMap.add(pair.key, memoryInstance)); } for(const auto& pair : moduleRef.impl->globalMap) { auto globalInstance = pair.value->instantiate(compartment); moduleInstance->globals.push_back(globalInstance); errorUnless(moduleInstance->exportMap.add(pair.key, globalInstance)); } for(const auto& pair : extraExports) { Runtime::Object* object = pair.value; moduleInstance->exportMap.set(pair.key, object); switch(object->kind) { case Runtime::ObjectKind::function: moduleInstance->functions.push_back(asFunction(object)); break; case Runtime::ObjectKind::table: moduleInstance->tables.push_back(asTable(object)); break; case Runtime::ObjectKind::memory: moduleInstance->memories.push_back(asMemory(object)); break; case Runtime::ObjectKind::global: moduleInstance->globals.push_back(asGlobal(object)); break; case Runtime::ObjectKind::exceptionTypeInstance: moduleInstance->exceptionTypeInstances.push_back(asExceptionTypeInstance(object)); break; default: Errors::unreachable(); }; } } return moduleInstance; }
bool isA(Object* object,const ObjectType& type) { if(type.kind != object->kind) { return false; } switch(type.kind) { case ObjectKind::function: return type.function == asFunction(object)->type; case ObjectKind::global: return type.global == asGlobal(object)->type; case ObjectKind::table: { auto table = asTable(object); return type.table.elementType == table->type.elementType && isSubset(type.table.size,table->type.size); } case ObjectKind::memory: { auto memory = asMemory(object); return isSubset(type.memory.size,memory->type.size); } default: Core::unreachable(); } }