diff --git a/src/parser/WASMComponentParser.cpp b/src/parser/WASMComponentParser.cpp index 20ed9af0a..703217742 100644 --- a/src/parser/WASMComponentParser.cpp +++ b/src/parser/WASMComponentParser.cpp @@ -745,7 +745,6 @@ class WASMComponentBinaryReader : public wabt::WASMComponentBinaryReaderDelegate ComponentTypeInfo* info = m_currentInfo; m_current = m_currentInfo->parentComponentType; m_currentComponent = m_currentInfo->parentComponent; - ASSERT(m_currentComponent == nullptr || m_currentComponent->type() == m_current); m_currentInfo = m_currentInfo->parent; delete info; } @@ -764,7 +763,6 @@ class WASMComponentBinaryReader : public wabt::WASMComponentBinaryReaderDelegate ComponentTypeInfo* info = m_currentInfo; m_current = m_currentInfo->parentComponentType; m_currentComponent = m_currentInfo->parentComponent; - ASSERT(m_currentComponent == nullptr || m_currentComponent->type() == m_current); m_currentInfo = m_currentInfo->parent; delete info; } @@ -806,7 +804,7 @@ class WASMComponentBinaryReader : public wabt::WASMComponentBinaryReaderDelegate nonstd::string_view* versionSuffix, const ComponentExternalInfo& externalInfo) { - if (m_currentComponent != nullptr) { + if (m_currentComponent->type() == m_current) { m_currentComponent->pushDeclaration(new Walrus::ComponentImport(static_cast(m_current->imports().size()))); } m_current->imports().push_back(Walrus::ComponentType::External{ name.str.to_string(), pushExternalType(externalInfo), getSort(externalInfo.sort), kInvalidIndex }); @@ -823,8 +821,34 @@ class WASMComponentBinaryReader : public wabt::WASMComponentBinaryReaderDelegate return; } - ComponentExternalInfo info{ exportInfo->sort, ComponentExternalDesc::Unused, exportInfo->index }; - m_current->exports().push_back(Walrus::ComponentType::External{ name.str.to_string(), pushExternalType(info), getSort(exportInfo->sort), exportInfo->index.index }); + ASSERT(m_currentComponent->type() == m_current); + Walrus::ComponentRefCounted* type; + + switch (exportInfo->sort) { + case ComponentSort::Func: + type = m_currentInfo->funcTypes[exportInfo->index.index]; + m_currentInfo->funcTypes.push_back(type->asTypeFunc()); + break; + case ComponentSort::Type: + type = m_current->getType(exportInfo->index.index); + type->addRef(); + m_current->pushType(type); + break; + case ComponentSort::Component: + type = m_currentInfo->componentTypes[exportInfo->index.index]; + m_currentInfo->componentTypes.push_back(type->asComponentType()); + break; + case ComponentSort::Instance: + type = m_currentInfo->instanceTypes[exportInfo->index.index]; + m_currentInfo->instanceTypes.push_back(type->asComponentType()); + break; + default: + RELEASE_ASSERT_NOT_REACHED(); + return; + } + + type->addRef(); + m_current->exports().push_back(Walrus::ComponentType::External{ name.str.to_string(), type, getSort(exportInfo->sort), exportInfo->index.index }); } Walrus::Component* parsingResult() diff --git a/src/runtime/Store.cpp b/src/runtime/Store.cpp index a57b28135..18729fb3f 100644 --- a/src/runtime/Store.cpp +++ b/src/runtime/Store.cpp @@ -155,6 +155,20 @@ FunctionType* Store::createDefinedFunctionType(DefinedFunctionType type) param->setType(0, Value::Type::I32); param->setType(1, Value::Type::I32); break; + case I32I32I32R: + functionType = new FunctionType(3, 0, 0, 0, true, noIndex); + param = functionType->initParam(); + param->setType(0, Value::Type::I32); + param->setType(1, Value::Type::I32); + param->setType(2, Value::Type::I32); + break; + case I32I64I32R: + functionType = new FunctionType(3, 0, 0, 0, true, noIndex); + param = functionType->initParam(); + param->setType(0, Value::Type::I32); + param->setType(1, Value::Type::I64); + param->setType(2, Value::Type::I32); + break; case I32I32I32I32R: functionType = new FunctionType(4, 0, 0, 0, true, noIndex); param = functionType->initParam(); @@ -260,6 +274,17 @@ FunctionType* Store::createDefinedFunctionType(DefinedFunctionType type) param->setType(5, Value::Type::I32); result->setType(0, Value::Type::I32); break; + case I32I32I32I32I32I32I32R: + functionType = new FunctionType(7, 0, 0, 0, true, noIndex); + param = functionType->initParam(); + param->setType(0, Value::Type::I32); + param->setType(1, Value::Type::I32); + param->setType(2, Value::Type::I32); + param->setType(3, Value::Type::I32); + param->setType(4, Value::Type::I32); + param->setType(5, Value::Type::I32); + param->setType(6, Value::Type::I32); + break; case I32I32I32I32I64I64I32_RI32: functionType = new FunctionType(7, 0, 1, 0, true, noIndex); param = functionType->initParam(); @@ -298,6 +323,18 @@ FunctionType* Store::createDefinedFunctionType(DefinedFunctionType type) param = functionType->initParam(); param->setType(0, Value::Type::I64); break; + case I64_RI32: + functionType = new FunctionType(1, 0, 1, 0, true, noIndex); + param = functionType->initParam(); + param->setType(0, Value::Type::I64); + result = functionType->initResult(); + result->setType(0, Value::Type::I32); + break; + case RI64: + functionType = new FunctionType(0, 0, 1, 0, true, noIndex); + result = functionType->initResult(); + result->setType(0, Value::Type::I64); + break; case F32R: functionType = new FunctionType(1, 0, 0, 0, true, noIndex); param = functionType->initParam(); diff --git a/src/runtime/Store.h b/src/runtime/Store.h index e1cd6a76b..1ebb564b9 100644 --- a/src/runtime/Store.h +++ b/src/runtime/Store.h @@ -61,6 +61,8 @@ class Store { NONE = 0, I32R, I32I32R, + I32I32I32R, + I32I64I32R, I32I32I32I32R, I32_RI32, I32I32_RI32, @@ -72,10 +74,13 @@ class Store { I32I32I32I32I32_RI32, I32I32I32I64I32_RI32, I32I32I32I32I32I32_RI32, + I32I32I32I32I32I32I32R, I32I32I32I32I64I64I32_RI32, I32I32I32I32I32I64I64I32I32_RI32, RI32, I64R, + I64_RI32, + RI64, F32R, F64R, I32F32R, diff --git a/src/runtime/TypeStore.cpp b/src/runtime/TypeStore.cpp index b679348da..0363c8899 100644 --- a/src/runtime/TypeStore.cpp +++ b/src/runtime/TypeStore.cpp @@ -379,12 +379,9 @@ void TypeStore::updateTypes(Vector& types) } } -void TypeStore::releaseRecursiveType(RecursiveType* recType) +void TypeStore::destroyRecursiveType(RecursiveType* recType) { - recType->m_refCount--; - if (recType->m_refCount != 0) { - return; - } + ASSERT(recType->m_refCount == 0); if (recType->m_prev == nullptr) { m_first = recType->m_next; @@ -434,7 +431,7 @@ void TypeStore::ReleaseRef(const CompositeType** typeInfo) ASSERT(index > 0); RecursiveType* recType = typeInfo[index]->getRecursiveType(); if (--recType->m_refCount == 0) { - recType->m_typeStore->releaseRecursiveType(recType); + recType->m_typeStore->destroyRecursiveType(recType); } } diff --git a/src/runtime/TypeStore.h b/src/runtime/TypeStore.h index 8f77a73a2..f74e99d72 100644 --- a/src/runtime/TypeStore.h +++ b/src/runtime/TypeStore.h @@ -133,7 +133,14 @@ class TypeStore { #endif static const CompositeType** updateRefs(CompositeType* type, const Vector& types, const CompositeType** nextSubType); - void releaseRecursiveType(RecursiveType* recType); + void destroyRecursiveType(RecursiveType* recType); + + void releaseRecursiveType(RecursiveType* recType) + { + if (--recType->m_refCount == 0) { + destroyRecursiveType(recType); + } + } #ifdef ENABLE_GC void insertRootRef(GCBase* object); diff --git a/src/shell/Shell.cpp b/src/shell/Shell.cpp index 2fc594a93..82a492735 100644 --- a/src/shell/Shell.cpp +++ b/src/shell/Shell.cpp @@ -388,7 +388,7 @@ static Trap::TrapResult executeWASMComponent(Store* store, const std::string& fi RunData* data = reinterpret_cast(d); ComponentInstance* instance = ComponentInstance::instantiate(state, data->store, data->component); for (auto& it : instance->type()->exports()) { - if (it.sort == ComponentSort::Instance && it.name == "wasi:cli/run@0.2.6") { + if (it.sort == ComponentSort::Instance && it.name.length() >= 17 && memcmp(it.name.data(), "wasi:cli/run@0.2.", 17) == 0) { instance = instance->getInstance(it.exportIndex); break; } diff --git a/src/wasi/WASI02.cpp b/src/wasi/WASI02.cpp index e7e333033..6bf88555a 100644 --- a/src/wasi/WASI02.cpp +++ b/src/wasi/WASI02.cpp @@ -24,19 +24,24 @@ namespace Walrus { enum WasiNamedInstances : size_t { - instanceUnknown, - instanceIoError02, - instanceIoPoll02, - instanceIoStreams02, - instanceCliExit02, - instanceCliStdin02, - instanceCliStdout02, - instanceCliStderr02, - instanceCliTerminalInput02, - instanceCliTerminalOutput02, - instanceCliTerminalStdin02, - instanceCliTerminalStdout02, - instanceCliTerminalStderr02, + InstanceUnknown, + InstanceIoError02, + InstanceIoPoll02, + InstanceIoStreams02, + InstanceCliEnvironment02, + InstanceCliExit02, + InstanceCliStdin02, + InstanceCliStdout02, + InstanceCliStderr02, + InstanceCliTerminalInput02, + InstanceCliTerminalOutput02, + InstanceCliTerminalStdin02, + InstanceCliTerminalStdout02, + InstanceCliTerminalStderr02, + InstanceClockMonotonic02, + InstanceClockWall02, + InstanceFileSystemTypes02, + InstanceFileSystemPreOpens02, }; class ComponentResourceWasiStream : public ComponentResource { @@ -116,17 +121,33 @@ class LiftedWasiFunction : public LiftedFunction { enum Type { cliExit02, ioPollableBlock02, + ioPoll02, + ioInputStreamRead02, + ioInputStreamSubscribe02, ioOutputStreamCheckWrite02, ioOutputStreamWrite02, ioOutputStreamBlockingWriteAndFlush02, ioOutputStreamBlockingFlush02, ioOutputStreamSubscribe02, + cliGetEnvironment02, + cliGetArguments02, cliGetStdin02, cliGetStdout02, cliGetStderr02, cliGetTerminalStdin02, cliGetTerminalStdout02, cliGetTerminalStderr02, + clockMonotonicNow02, + clockSubscribeDuration02, + clockWallNow02, + fileSystemDescriptorReadViaStream02, + fileSystemDescriptorWriteViaStream02, + fileSystemDescriptorAppendViaStream02, + fileSystemDescriptorGetFlags02, + fileSystemDescriptorStat02, + fileSystemDescriptorOpenAt02, + fileSystemDescriptorMetadataHash02, + fileSystemGetDirectories02, }; LiftedWasiFunction(Type type, ComponentInstance* instance, FunctionType* functionType) @@ -237,30 +258,31 @@ ComponentInstance* ComponentInstanceWasi02::loadInstance(size_t instanceId, bool } switch (instanceId) { - case instanceIoError02: { + case InstanceIoError02: { m_type = new ComponentType(ComponentType::ComponentTypeKind); ComponentInstance* instance = ComponentInstance::createInstance(m_store, m_type); addResourceExport(instance, "error"); /* 0 */ return instance; } - case instanceIoPoll02: { + case InstanceIoPoll02: { m_type = new ComponentType(ComponentType::ComponentTypeKind); ComponentInstance* instance = ComponentInstance::createInstance(m_store, m_type); addResourceExport(instance, "pollable"); /* 0 */ addExport(instance, "[method]pollable.block", LiftedWasiFunction::ioPollableBlock02, getType(Store::I32R)); + addExport(instance, "poll", LiftedWasiFunction::ioPoll02, getType(Store::I32I32I32R)); return instance; } - case instanceIoStreams02: { + case InstanceIoStreams02: { m_type = new ComponentType(ComponentType::ComponentTypeKind); ComponentInstance* instance = ComponentInstance::createInstance(m_store, m_type); addResourceExport(instance, "input-stream"); /* 0 */ addResourceExport(instance, "output-stream"); /* 1 */ - ComponentInstance* errorIntance = loadInstance(instanceIoError02); + ComponentInstance* errorIntance = loadInstance(InstanceIoError02); instance->m_instances.push_back(errorIntance); ComponentRefCounted* errorType = errorIntance->type()->getType(0); aliasTypeExport(instance, "error", errorType); /* 2 */ - ComponentInstance* pollIntance = loadInstance(instanceIoPoll02); + ComponentInstance* pollIntance = loadInstance(InstanceIoPoll02); instance->m_instances.push_back(pollIntance); aliasTypeExport(instance, "pollable", pollIntance->type()->getType(0)); /* 3 */ ComponentRefCounted* ownErrorType = new ComponentTypeResourceRef(ComponentRefCounted::OwnKind, errorType); @@ -270,6 +292,8 @@ ComponentInstance* ComponentInstanceWasi02::loadInstance(size_t instanceId, bool variant->items().push_back(ComponentTypeItems::Item{ "last-operation-failed", ComponentTypeRef(ownErrorType) }); variant->items().push_back(ComponentTypeItems::Item{ "closed", ComponentTypeRef() }); addTypeExport(instance, "stream-error", variant); + addExport(instance, "[method]input-stream.read", LiftedWasiFunction::ioInputStreamRead02, getType(Store::I32I64I32R)); + addExport(instance, "[method]input-stream.subscribe", LiftedWasiFunction::ioInputStreamSubscribe02, getType(Store::I32_RI32)); addExport(instance, "[method]output-stream.check-write", LiftedWasiFunction::ioOutputStreamCheckWrite02, getType(Store::I32I32R)); addExport(instance, "[method]output-stream.write", LiftedWasiFunction::ioOutputStreamWrite02, getType(Store::I32I32I32I32R)); addExport(instance, "[method]output-stream.blocking-write-and-flush", LiftedWasiFunction::ioOutputStreamBlockingWriteAndFlush02, getType(Store::I32I32I32I32R)); @@ -277,84 +301,236 @@ ComponentInstance* ComponentInstanceWasi02::loadInstance(size_t instanceId, bool addExport(instance, "[method]output-stream.subscribe", LiftedWasiFunction::ioOutputStreamSubscribe02, getType(Store::I32_RI32)); return instance; } - case instanceCliExit02: { + case InstanceCliEnvironment02: { + m_type = new ComponentType(ComponentType::ComponentTypeKind); + ComponentInstance* instance = ComponentInstance::createInstance(m_store, m_type); + addExport(instance, "get-environment", LiftedWasiFunction::cliGetEnvironment02, getType(Store::I32R)); + addExport(instance, "get-arguments", LiftedWasiFunction::cliGetArguments02, getType(Store::I32R)); + return instance; + } + case InstanceCliExit02: { m_type = new ComponentType(ComponentType::ComponentTypeKind); ComponentInstance* instance = ComponentInstance::createInstance(m_store, m_type); addExport(instance, "exit", LiftedWasiFunction::cliExit02, getType(Store::I32R)); return instance; } - case instanceCliStdin02: { + case InstanceCliStdin02: { m_type = new ComponentType(ComponentType::ComponentTypeKind); ComponentInstance* instance = ComponentInstance::createInstance(m_store, m_type); - ComponentInstance* streamsIntance = loadInstance(instanceIoStreams02); + ComponentInstance* streamsIntance = loadInstance(InstanceIoStreams02); instance->m_instances.push_back(streamsIntance); aliasTypeExport(instance, "input-stream", streamsIntance->type()->getType(0)); /* 0 */ addExport(instance, "get-stdin", LiftedWasiFunction::cliGetStdin02, getType(Store::RI32)); return instance; } - case instanceCliStdout02: { + case InstanceCliStdout02: { m_type = new ComponentType(ComponentType::ComponentTypeKind); ComponentInstance* instance = ComponentInstance::createInstance(m_store, m_type); - ComponentInstance* streamsIntance = loadInstance(instanceIoStreams02); + ComponentInstance* streamsIntance = loadInstance(InstanceIoStreams02); instance->m_instances.push_back(streamsIntance); aliasTypeExport(instance, "output-stream", streamsIntance->type()->getType(1)); /* 0 */ addExport(instance, "get-stdout", LiftedWasiFunction::cliGetStdout02, getType(Store::RI32)); return instance; } - case instanceCliStderr02: { + case InstanceCliStderr02: { m_type = new ComponentType(ComponentType::ComponentTypeKind); ComponentInstance* instance = ComponentInstance::createInstance(m_store, m_type); - ComponentInstance* streamsIntance = loadInstance(instanceIoStreams02); + ComponentInstance* streamsIntance = loadInstance(InstanceIoStreams02); instance->m_instances.push_back(streamsIntance); aliasTypeExport(instance, "output-stream", streamsIntance->type()->getType(1)); /* 0 */ addExport(instance, "get-stderr", LiftedWasiFunction::cliGetStderr02, getType(Store::RI32)); return instance; } - case instanceCliTerminalInput02: { + case InstanceCliTerminalInput02: { m_type = new ComponentType(ComponentType::ComponentTypeKind); ComponentInstance* instance = ComponentInstance::createInstance(m_store, m_type); addResourceExport(instance, "terminal-input"); /* 0 */ return instance; } - case instanceCliTerminalOutput02: { + case InstanceCliTerminalOutput02: { m_type = new ComponentType(ComponentType::ComponentTypeKind); ComponentInstance* instance = ComponentInstance::createInstance(m_store, m_type); addResourceExport(instance, "terminal-output"); /* 0 */ return instance; } - case instanceCliTerminalStdin02: { + case InstanceCliTerminalStdin02: { m_type = new ComponentType(ComponentType::ComponentTypeKind); ComponentInstance* instance = ComponentInstance::createInstance(m_store, m_type); - ComponentInstance* inputIntance = loadInstance(instanceCliTerminalInput02); + ComponentInstance* inputIntance = loadInstance(InstanceCliTerminalInput02); instance->m_instances.push_back(inputIntance); aliasTypeExport(instance, "terminal-input", inputIntance->type()->getType(0)); /* 0 */ addExport(instance, "get-terminal-stdin", LiftedWasiFunction::cliGetTerminalStdin02, getType(Store::I32R)); return instance; } - case instanceCliTerminalStdout02: { + case InstanceCliTerminalStdout02: { m_type = new ComponentType(ComponentType::ComponentTypeKind); ComponentInstance* instance = ComponentInstance::createInstance(m_store, m_type); - ComponentInstance* outputIntance = loadInstance(instanceCliTerminalOutput02); + ComponentInstance* outputIntance = loadInstance(InstanceCliTerminalOutput02); instance->m_instances.push_back(outputIntance); aliasTypeExport(instance, "terminal-output", outputIntance->type()->getType(0)); /* 0 */ addExport(instance, "get-terminal-stdout", LiftedWasiFunction::cliGetTerminalStdout02, getType(Store::I32R)); return instance; } - case instanceCliTerminalStderr02: { + case InstanceCliTerminalStderr02: { m_type = new ComponentType(ComponentType::ComponentTypeKind); ComponentInstance* instance = ComponentInstance::createInstance(m_store, m_type); - ComponentInstance* outputIntance = loadInstance(instanceCliTerminalOutput02); + ComponentInstance* outputIntance = loadInstance(InstanceCliTerminalOutput02); instance->m_instances.push_back(outputIntance); aliasTypeExport(instance, "terminal-output", outputIntance->type()->getType(0)); /* 0 */ addExport(instance, "get-terminal-stderr", LiftedWasiFunction::cliGetTerminalStderr02, getType(Store::I32R)); return instance; } + case InstanceClockMonotonic02: { + m_type = new ComponentType(ComponentType::ComponentTypeKind); + ComponentInstance* instance = ComponentInstance::createInstance(m_store, m_type); + + ComponentValueType* timeType = new ComponentValueType(ComponentTypeRef::U64); + addTypeExport(instance, "instant", timeType); /* 0 */ + aliasTypeExport(instance, "duration", timeType); /* 1 */ + ComponentInstance* pollIntance = loadInstance(InstanceIoPoll02); + instance->m_instances.push_back(pollIntance); + aliasTypeExport(instance, "pollable", pollIntance->type()->getType(0)); /* 2 */ + addExport(instance, "now", LiftedWasiFunction::clockMonotonicNow02, getType(Store::RI64)); + addExport(instance, "subscribe-duration", LiftedWasiFunction::clockSubscribeDuration02, getType(Store::I64_RI32)); + return instance; + } + case InstanceClockWall02: { + m_type = new ComponentType(ComponentType::ComponentTypeKind); + ComponentInstance* instance = ComponentInstance::createInstance(m_store, m_type); + + ComponentTypeItems* dateTime = new ComponentTypeItems(ComponentRefCounted::RecordKind); + dateTime->items().push_back(ComponentTypeItems::Item{ "seconds", ComponentTypeRef(ComponentTypeRef::U64) }); + dateTime->items().push_back(ComponentTypeItems::Item{ "nanoseconds", ComponentTypeRef(ComponentTypeRef::U32) }); + addTypeExport(instance, "datetime", dateTime); + addExport(instance, "now", LiftedWasiFunction::clockWallNow02, getType(Store::I32R)); + return instance; + } + case InstanceFileSystemTypes02: { + m_type = new ComponentType(ComponentType::ComponentTypeKind); + ComponentInstance* instance = ComponentInstance::createInstance(m_store, m_type); + + addResourceExport(instance, "descriptor"); /* 0 */ + ComponentValueType* u64Type = new ComponentValueType(ComponentTypeRef::U64); + addTypeExport(instance, "filesize", u64Type); /* 1 */ + ComponentInstance* streamsIntance = loadInstance(InstanceIoStreams02); + instance->m_instances.push_back(streamsIntance); + aliasTypeExport(instance, "input-stream", streamsIntance->type()->getType(0)); /* 2 */ + aliasTypeExport(instance, "output-stream", streamsIntance->type()->getType(1)); /* 3 */ + ComponentTypeLabels* errorCode = new ComponentTypeLabels(ComponentRefCounted::EnumKind); + errorCode->labels().push_back("access"); + errorCode->labels().push_back("would-block"); + errorCode->labels().push_back("already"); + errorCode->labels().push_back("bad-descriptor"); + errorCode->labels().push_back("busy"); + errorCode->labels().push_back("deadlock"); + errorCode->labels().push_back("quota"); + errorCode->labels().push_back("exist"); + errorCode->labels().push_back("file-too-large"); + errorCode->labels().push_back("illegal-byte-sequence"); + errorCode->labels().push_back("in-progress"); + errorCode->labels().push_back("interrupted"); + errorCode->labels().push_back("invalid"); + errorCode->labels().push_back("io"); + errorCode->labels().push_back("is-directory"); + errorCode->labels().push_back("loop"); + errorCode->labels().push_back("too-many-links"); + errorCode->labels().push_back("message-size"); + errorCode->labels().push_back("name-too-long"); + errorCode->labels().push_back("no-device"); + errorCode->labels().push_back("no-entry"); + errorCode->labels().push_back("no-lock"); + errorCode->labels().push_back("insufficient-memory"); + errorCode->labels().push_back("insufficient-space"); + errorCode->labels().push_back("not-directory"); + errorCode->labels().push_back("not-empty"); + errorCode->labels().push_back("not-recoverable"); + errorCode->labels().push_back("unsupported"); + errorCode->labels().push_back("no-tty"); + errorCode->labels().push_back("no-such-device"); + errorCode->labels().push_back("overflow"); + errorCode->labels().push_back("not-permitted"); + errorCode->labels().push_back("pipe"); + errorCode->labels().push_back("read-only"); + errorCode->labels().push_back("invalid-seek"); + errorCode->labels().push_back("text-file-busy"); + errorCode->labels().push_back("cross-device"); + addTypeExport(instance, "error-code", errorCode); /* 4 */ + ComponentTypeLabels* descriptorFlags = new ComponentTypeLabels(ComponentRefCounted::FlagsKind); + descriptorFlags->labels().push_back("read"); + descriptorFlags->labels().push_back("write"); + descriptorFlags->labels().push_back("file-integrity-sync"); + descriptorFlags->labels().push_back("data-integrity-sync"); + descriptorFlags->labels().push_back("requested-write-sync"); + descriptorFlags->labels().push_back("mutate-directory"); + addTypeExport(instance, "descriptor-flags", descriptorFlags); /* 5 */ + ComponentTypeLabels* descriptorType = new ComponentTypeLabels(ComponentRefCounted::EnumKind); + descriptorType->labels().push_back("unknown"); + descriptorType->labels().push_back("block-device"); + descriptorType->labels().push_back("character-device"); + descriptorType->labels().push_back("directory"); + descriptorType->labels().push_back("fifo"); + descriptorType->labels().push_back("symbolic-link"); + descriptorType->labels().push_back("regular-file"); + descriptorType->labels().push_back("socket"); + addTypeExport(instance, "descriptor-type", descriptorType); /* 6 */ + aliasTypeExport(instance, "link-count", u64Type); /* 7 */ + ComponentTypeItems* dateTime = new ComponentTypeItems(ComponentRefCounted::RecordKind); + dateTime->items().push_back(ComponentTypeItems::Item{ "seconds", ComponentTypeRef(ComponentTypeRef::U64) }); + dateTime->items().push_back(ComponentTypeItems::Item{ "nanoseconds", ComponentTypeRef(ComponentTypeRef::U32) }); + addTypeExport(instance, "datetime", dateTime); /* 8 */ + ComponentTypeItems* descriptorStat = new ComponentTypeItems(ComponentRefCounted::RecordKind); + descriptorType->addRef(); + descriptorStat->items().push_back(ComponentTypeItems::Item{ "type", ComponentTypeRef(descriptorType) }); + u64Type->addRef(); + descriptorStat->items().push_back(ComponentTypeItems::Item{ "link-count", ComponentTypeRef(u64Type) }); + u64Type->addRef(); + descriptorStat->items().push_back(ComponentTypeItems::Item{ "size", ComponentTypeRef(u64Type) }); + dateTime->addRef(); + ComponentValueTypeRef* optionalDateTime = new ComponentValueTypeRef(ComponentRefCounted::OptionKind, ComponentTypeRef(dateTime)); + descriptorStat->items().push_back(ComponentTypeItems::Item{ "data-access-timestamp", ComponentTypeRef(optionalDateTime) }); + optionalDateTime->addRef(); + descriptorStat->items().push_back(ComponentTypeItems::Item{ "data-modification-timestamp", ComponentTypeRef(optionalDateTime) }); + optionalDateTime->addRef(); + descriptorStat->items().push_back(ComponentTypeItems::Item{ "status-change-timestamp", ComponentTypeRef(optionalDateTime) }); + addTypeExport(instance, "descriptor-stat", descriptorStat); /* 9 */ + ComponentTypeLabels* pathFlags = new ComponentTypeLabels(ComponentRefCounted::FlagsKind); + pathFlags->labels().push_back("symlink-follow"); + addTypeExport(instance, "path-flags", pathFlags); /* 10 */ + ComponentTypeLabels* openFlags = new ComponentTypeLabels(ComponentRefCounted::FlagsKind); + openFlags->labels().push_back("create"); + openFlags->labels().push_back("directory"); + openFlags->labels().push_back("exclusive"); + openFlags->labels().push_back("truncate"); + addTypeExport(instance, "open-flags", openFlags); /* 11 */ + ComponentTypeItems* metadataHashValue = new ComponentTypeItems(ComponentRefCounted::RecordKind); + metadataHashValue->items().push_back(ComponentTypeItems::Item{ "lower", ComponentTypeRef(ComponentTypeRef::U64) }); + metadataHashValue->items().push_back(ComponentTypeItems::Item{ "upper", ComponentTypeRef(ComponentTypeRef::U64) }); + addTypeExport(instance, "metadata-hash-value", metadataHashValue); /* 12 */ + addExport(instance, "[method]descriptor.read-via-stream", LiftedWasiFunction::fileSystemDescriptorReadViaStream02, getType(Store::I32I64I32R)); + addExport(instance, "[method]descriptor.write-via-stream", LiftedWasiFunction::fileSystemDescriptorWriteViaStream02, getType(Store::I32I64I32R)); + addExport(instance, "[method]descriptor.append-via-stream", LiftedWasiFunction::fileSystemDescriptorAppendViaStream02, getType(Store::I32I32R)); + addExport(instance, "[method]descriptor.get-flags", LiftedWasiFunction::fileSystemDescriptorGetFlags02, getType(Store::I32I32R)); + addExport(instance, "[method]descriptor.stat", LiftedWasiFunction::fileSystemDescriptorStat02, getType(Store::I32I32R)); + addExport(instance, "[method]descriptor.open-at", LiftedWasiFunction::fileSystemDescriptorOpenAt02, getType(Store::I32I32I32I32I32I32I32R)); + addExport(instance, "[method]descriptor.metadata-hash", LiftedWasiFunction::fileSystemDescriptorMetadataHash02, getType(Store::I32I32R)); + return instance; + } + case InstanceFileSystemPreOpens02: { + m_type = new ComponentType(ComponentType::ComponentTypeKind); + ComponentInstance* instance = ComponentInstance::createInstance(m_store, m_type); + + ComponentInstance* typesIntance = loadInstance(InstanceFileSystemTypes02); + instance->m_instances.push_back(typesIntance); + aliasTypeExport(instance, "descriptor", typesIntance->type()->getType(0)); /* 0 */ + addExport(instance, "get-directories", LiftedWasiFunction::fileSystemGetDirectories02, getType(Store::I32R)); + return instance; + } default: RELEASE_ASSERT_NOT_REACHED(); return nullptr; @@ -390,45 +566,65 @@ ComponentInstance* wasi02LoadInstance(Store* store, std::string& name) } length -= 5; - size_t instanceId = instanceUnknown; + size_t instanceId = InstanceUnknown; if (length > 8 && memcmp(charData, "wasi:io/", 8) == 0) { charData += 8; length -= 8; if (compareName(charData, length, "error")) { - instanceId = instanceIoError02; + instanceId = InstanceIoError02; } else if (compareName(charData, length, "poll")) { - instanceId = instanceIoPoll02; + instanceId = InstanceIoPoll02; } else if (compareName(charData, length, "streams")) { - instanceId = instanceIoStreams02; + instanceId = InstanceIoStreams02; } } else if (length > 9 && memcmp(charData, "wasi:cli/", 9) == 0) { charData += 9; length -= 9; - if (compareName(charData, length, "exit")) { - instanceId = instanceCliExit02; + if (compareName(charData, length, "environment")) { + instanceId = InstanceCliEnvironment02; + } else if (compareName(charData, length, "exit")) { + instanceId = InstanceCliExit02; } else if (compareName(charData, length, "stdin")) { - instanceId = instanceCliStdin02; + instanceId = InstanceCliStdin02; } else if (compareName(charData, length, "stdout")) { - instanceId = instanceCliStdout02; + instanceId = InstanceCliStdout02; } else if (compareName(charData, length, "stderr")) { - instanceId = instanceCliStderr02; + instanceId = InstanceCliStderr02; } else if (compareName(charData, length, "terminal-input")) { - instanceId = instanceCliTerminalInput02; + instanceId = InstanceCliTerminalInput02; } else if (compareName(charData, length, "terminal-output")) { - instanceId = instanceCliTerminalOutput02; + instanceId = InstanceCliTerminalOutput02; } else if (compareName(charData, length, "terminal-stdin")) { - instanceId = instanceCliTerminalStdin02; + instanceId = InstanceCliTerminalStdin02; } else if (compareName(charData, length, "terminal-stdout")) { - instanceId = instanceCliTerminalStdout02; + instanceId = InstanceCliTerminalStdout02; } else if (compareName(charData, length, "terminal-stderr")) { - instanceId = instanceCliTerminalStderr02; + instanceId = InstanceCliTerminalStderr02; + } + } else if (length > 9 && memcmp(charData, "wasi:clocks/", 12) == 0) { + charData += 12; + length -= 12; + + if (compareName(charData, length, "monotonic-clock")) { + instanceId = InstanceClockMonotonic02; + } else if (compareName(charData, length, "wall-clock")) { + instanceId = InstanceClockWall02; + } + } else if (length > 9 && memcmp(charData, "wasi:filesystem/", 16) == 0) { + charData += 16; + length -= 16; + + if (compareName(charData, length, "types")) { + instanceId = InstanceFileSystemTypes02; + } else if (compareName(charData, length, "preopens")) { + instanceId = InstanceFileSystemPreOpens02; } } - if (instanceId == instanceUnknown) { + if (instanceId == InstanceUnknown) { return nullptr; }