https://bugs.webkit.org/show_bug.cgi?id=239666
Reviewed by Justin Michaud.
Add support for the Wasm GC proposal's recursion groups. These are
a new kind of TypeDefinition that allows for recursive type
definitions. Recursive type index references are only allowed with
recursion group definitions.
Recursion groups can be stored hash-consed like other type
definitions, but to successfully compare them they must store several
definitions in the type store:
- The recursion group itself (rec (type ...) ...)
- Each type component in the group (type ...), where any potential
recursive references are represented as a special value type.
- Projections into the recursion group ((rec ...).<i>)
Projections can be expanded into the underlying function/struct/etc
type when the validator needs to examine the structure of the type.
This operation exposes the type component in the group, and replaces
recursive references with the appropriate projection (which can then
be expanded if required, and so on).
If expansion becomes a bottleneck, it is easy to memoize it with the
addition of a TypeIndex to TypeIndex mapping in the type store.
Generally, the expansion operation is needed when code relies on the
structure of the underlying type. For functions, these uses usually
look like `signature.as<FunctionSignature>()`. The signature *must* be
expanded before such a conversion is called.
When signatures need to be compared for equality, such as for
call_indirect or for matching function import/export, the comparison
should generally be done by the type index of the projection. That is,
*not* by equality of the underlying/expanded type.
Recursive references are not represented in the binary format and are
internal to the semantics and implementation. To avoid using extra
opcodes, they are internally represented as a type that uses the
opcode for recursion group (TypeKind::Rec), which cannot normally be
used for value types in the binary format, with a heap type that
encodes the index into the recursion group's type list.
* JSTests/wasm/gc/rec.js: Added.
(module):
(testRecDeclaration):
* JSTests/wasm/wasm.json:
* Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::AirIRGenerator):
(JSC::Wasm::AirIRGenerator::addCallIndirect):
* Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::addCallIndirect):
* Source/JavaScriptCore/wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::work):
(JSC::Wasm::BBQPlan::compileFunction):
* Source/JavaScriptCore/wasm/WasmCallee.h:
* Source/JavaScriptCore/wasm/WasmFormat.h:
(JSC::Wasm::isValueType):
* Source/JavaScriptCore/wasm/WasmFunctionCodeBlockGenerator.cpp:
(JSC::Wasm::FunctionCodeBlockGenerator::addSignature):
* Source/JavaScriptCore/wasm/WasmFunctionCodeBlockGenerator.h:
* Source/JavaScriptCore/wasm/WasmFunctionParser.h:
(JSC::Wasm::splitStack):
(JSC::Wasm::FunctionParser<Context>::FunctionParser):
(JSC::Wasm::FunctionParser<Context>::parse):
(JSC::Wasm::FunctionParser<Context>::parseExpression):
(JSC::Wasm::FunctionParser<Context>::parseUnreachableExpression):
* Source/JavaScriptCore/wasm/WasmInstance.cpp:
(JSC::Wasm::Instance::initElementSegment):
* Source/JavaScriptCore/wasm/WasmLLIntGenerator.cpp:
(JSC::Wasm::LLIntGenerator::callInformationForCaller):
(JSC::Wasm::LLIntGenerator::callInformationForCallee):
(JSC::Wasm::LLIntGenerator::addArguments):
(JSC::Wasm::LLIntGenerator::addCallIndirect):
(JSC::Wasm::LLIntGenerator::addCallRef):
* Source/JavaScriptCore/wasm/WasmLLIntPlan.cpp:
(JSC::Wasm::LLIntPlan::didCompleteCompilation):
* Source/JavaScriptCore/wasm/WasmLimits.h:
* Source/JavaScriptCore/wasm/WasmParser.h:
(JSC::Wasm::Parser<SuccessType>::Parser):
(JSC::Wasm::Parser<SuccessType>::parseHeapType):
(JSC::Wasm::Parser<SuccessType>::parseValueType):
* Source/JavaScriptCore/wasm/WasmSectionParser.cpp:
(JSC::Wasm::SectionParser::parseType):
(JSC::Wasm::SectionParser::parseElement):
(JSC::Wasm::SectionParser::parseRecursionGroup):
* Source/JavaScriptCore/wasm/WasmSectionParser.h:
* Source/JavaScriptCore/wasm/WasmSlowPaths.cpp:
(JSC::LLInt::doWasmCallIndirect):
(JSC::LLInt::doWasmCallRef):
* Source/JavaScriptCore/wasm/WasmTypeDefinition.cpp:
(JSC::Wasm::TypeDefinition::dump const):
(JSC::Wasm::RecursionGroup::toString const):
(JSC::Wasm::RecursionGroup::dump const):
(JSC::Wasm::Projection::toString const):
(JSC::Wasm::Projection::dump const):
(JSC::Wasm::computeRecursionGroupHash):
(JSC::Wasm::computeProjectionHash):
(JSC::Wasm::TypeDefinition::hash const):
(JSC::Wasm::TypeDefinition::tryCreateFunctionSignature):
(JSC::Wasm::TypeDefinition::tryCreateStructType):
(JSC::Wasm::TypeDefinition::tryCreateRecursionGroup):
(JSC::Wasm::TypeDefinition::tryCreateProjection):
(JSC::Wasm::TypeDefinition::substitute):
(JSC::Wasm::TypeDefinition::replacePlaceholders const):
(JSC::Wasm::TypeDefinition::expand const):
(JSC::Wasm::FunctionParameterTypes::equal):
(JSC::Wasm::StructParameterTypes::equal):
(JSC::Wasm::RecursionGroupParameterTypes::hash):
(JSC::Wasm::RecursionGroupParameterTypes::equal):
(JSC::Wasm::RecursionGroupParameterTypes::translate):
(JSC::Wasm::ProjectionParameterTypes::hash):
(JSC::Wasm::ProjectionParameterTypes::equal):
(JSC::Wasm::ProjectionParameterTypes::translate):
(JSC::Wasm::TypeInformation::typeDefinitionForRecursionGroup):
(JSC::Wasm::TypeInformation::typeDefinitionForProjection):
* Source/JavaScriptCore/wasm/WasmTypeDefinition.h:
(JSC::Wasm::RecursionGroup::RecursionGroup):
(JSC::Wasm::RecursionGroup::typeCount const):
(JSC::Wasm::RecursionGroup::type const):
(JSC::Wasm::RecursionGroup::getType):
(JSC::Wasm::RecursionGroup::storage):
(JSC::Wasm::RecursionGroup::storage const):
(JSC::Wasm::Projection::Projection):
(JSC::Wasm::Projection::recursionGroup const):
(JSC::Wasm::Projection::index const):
(JSC::Wasm::Projection::getRecursionGroup):
(JSC::Wasm::Projection::getIndex):
(JSC::Wasm::Projection::storage):
(JSC::Wasm::Projection::storage const):
(JSC::Wasm::TypeDefinition::TypeDefinition):
(JSC::Wasm::TypeDefinition::allocatedRecursionGroupSize):
(JSC::Wasm::TypeDefinition::allocatedProjectionSize):
* Source/JavaScriptCore/wasm/WasmTypeDefinitionInlines.h:
(JSC::Wasm::TypeInformation::getFunctionSignature):
* Source/JavaScriptCore/wasm/js/WasmToJS.cpp:
(JSC::Wasm::wasmToJS):
* Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::initializeExports):
* Source/JavaScriptCore/wasm/wasm.json:
Canonical link: https://commits.webkit.org/253491@main