Beispiel #1
0
	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.
         }
      }
   }