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; }
// - LuaValue::operator== --------------------------------------------------- bool LuaValue::operator== (const LuaValue& rhs) const { std::string lhsTypeName = typeName(); std::string rhsTypeName = rhs.typeName(); if (typeName() != rhs.typeName()) return false; else switch (type()) { case LUA_TNIL: return true; case LUA_TBOOLEAN: return asBoolean() == rhs.asBoolean(); case LUA_TNUMBER: return asNumber() == rhs.asNumber(); case LUA_TSTRING: return asString() == rhs.asString(); case LUA_TTABLE: return asTable() == rhs.asTable(); case LUA_TFUNCTION: return asFunction() == rhs.asFunction(); case LUA_TUSERDATA: return asUserData() == rhs.asUserData(); default: { assert( false && "Invalid type found in a call to 'LuaValue::operator==()'."); return 0; // make compilers happy } } }
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(); } }
// - LuaValue::operator> ---------------------------------------------------- bool LuaValue::operator> (const LuaValue& rhs) const { std::string lhsTypeName = typeName(); std::string rhsTypeName = rhs.typeName(); if (lhsTypeName > rhsTypeName) return true; else if (lhsTypeName < rhsTypeName) return false; else // lhsTypeName == rhsTypeName { if (lhsTypeName == "nil") return false; else if (lhsTypeName == "boolean") return asBoolean() > rhs.asBoolean(); else if (lhsTypeName == "number") return asNumber() > rhs.asNumber(); else if (lhsTypeName == "string") return asString() > rhs.asString(); else if (lhsTypeName == "function") return asFunction() > rhs.asFunction(); else if (lhsTypeName == "userdata") return asUserData() > rhs.asUserData(); else if (lhsTypeName == "table") { const LuaValueMap lhsMap = asTable(); const LuaValueMap rhsMap = rhs.asTable(); if (lhsMap.size() > rhsMap.size()) return true; else if (lhsMap.size() < rhsMap.size()) return false; else // lhsMap.size() == rhsMap.size() { typedef LuaValueMap::const_iterator iter_t; iter_t pLHS = lhsMap.begin(); iter_t pRHS = rhsMap.begin(); const iter_t end = lhsMap.end(); while (pLHS != end) { // check the key first if (pLHS->first > pRHS->first) return true; else if (pLHS->first < pRHS->first) return false; // then check the value if (pLHS->second > pRHS->second) return true; else if (pLHS->second < pRHS->second) return false; // make the iterators iterate ++pRHS; ++pLHS; } return false; } } else { assert (false && "Unsupported type found at a call " "to 'LuaValue::operator>()'"); return false; // make the compiler happy. } } }