Changeset 273962 in webkit


Ignore:
Timestamp:
Mar 5, 2021 4:16:49 AM (17 months ago)
Author:
commit-queue@webkit.org
Message:

[WASM-Function-References] Update ref.func to produce (ref $t)
https://bugs.webkit.org/show_bug.cgi?id=222779

Patch by Dmitry Bezhetskov <dbezhetskov> on 2021-03-05
Reviewed by Yusuke Suzuki.

Make ref.func to produce non nullable reference type which
incorporates signature index. Since in JSC signature index represents
type of the function from Type section we use it instead of type_idx
for representing type of function references.

JSTests:

  • wasm/wasm.json:

Source/JavaScriptCore:

  • runtime/OptionsList.h:
  • wasm/WasmAirIRGenerator.cpp:

(JSC::Wasm::AirIRGenerator::addTableGrow):
(JSC::Wasm::AirIRGenerator::addTableFill):
(JSC::Wasm::AirIRGenerator::unify):

  • wasm/WasmFormat.h:

(JSC::Wasm::isValueType):
(JSC::Wasm::isSubtype):
(JSC::Wasm::isRefType):

  • wasm/WasmFunctionParser.h:

(JSC::Wasm::FunctionParser<Context>::checkBranchTarget):
(JSC::Wasm::FunctionParser<Context>::unify):
(JSC::Wasm::FunctionParser<Context>::parseExpression):

  • wasm/WasmLLIntGenerator.cpp:

(JSC::Wasm::LLIntGenerator::callInformationForCaller):
(JSC::Wasm::LLIntGenerator::callInformationForCallee):
(JSC::Wasm::LLIntGenerator::addArguments):

  • wasm/WasmSectionParser.cpp:

(JSC::Wasm::SectionParser::parseGlobal):

  • wasm/generateWasmOpsHeader.py:
  • wasm/js/WasmToJS.cpp:

(JSC::Wasm::wasmToJS):

  • wasm/js/WebAssemblyFunction.cpp:

(JSC::JSC_DEFINE_HOST_FUNCTION):

  • wasm/wasm.json:
Location:
trunk
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r273931 r273962  
     12021-03-05  Dmitry Bezhetskov  <dbezhetskov@igalia.com>
     2
     3        [WASM-Function-References] Update ref.func to produce (ref $t)
     4        https://bugs.webkit.org/show_bug.cgi?id=222779
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        Make ref.func to produce non nullable reference type which
     9        incorporates signature index. Since in JSC signature index represents
     10        type of the function from Type section we use it instead of type_idx
     11        for representing type of function references.
     12
     13        * wasm/wasm.json:
     14
    1152021-03-04  Saam Barati  <sbarati@apple.com>
    216
  • trunk/JSTests/wasm/wasm.json

    r272933 r273962  
    88    ],
    99    "type" : {
    10         "i32":       { "type": "varint7", "value":  -1, "b3type": "B3::Int32" },
    11         "i64":       { "type": "varint7", "value":  -2, "b3type": "B3::Int64" },
    12         "f32":       { "type": "varint7", "value":  -3, "b3type": "B3::Float" },
    13         "f64":       { "type": "varint7", "value":  -4, "b3type": "B3::Double" },
    14         "funcref":   { "type": "varint7", "value": -16, "b3type": "B3::Int64" },
    15         "externref": { "type": "varint7", "value": -17, "b3type": "B3::Int64" },
    16         "func":      { "type": "varint7", "value": -32, "b3type": "B3::Void" },
    17         "void":      { "type": "varint7", "value": -64, "b3type": "B3::Void" }
     10        "i32":       { "type": "varint7", "value":   -1, "b3type": "B3::Int32" },
     11        "i64":       { "type": "varint7", "value":   -2, "b3type": "B3::Int64" },
     12        "f32":       { "type": "varint7", "value":   -3, "b3type": "B3::Float" },
     13        "f64":       { "type": "varint7", "value":   -4, "b3type": "B3::Double" },
     14        "funcref":   { "type": "varint7", "value":  -16, "b3type": "B3::Int64" },
     15        "externref": { "type": "varint7", "value":  -17, "b3type": "B3::Int64" },
     16        "func":      { "type": "varint7", "value":  -32, "b3type": "B3::Void" },
     17        "void":      { "type": "varint7", "value":  -64, "b3type": "B3::Void" },
     18        "type_idx":  { "type": "varint7", "value": -128, "b3type": "B3::Int64" }
    1819    },
    1920    "value_type": ["i32", "i64", "f32", "f64", "externref", "funcref"],
    2021    "block_type": ["i32", "i64", "f32", "f64", "void", "externref", "funcref"],
    21     "ref_type": ["funcref","externref"],
     22    "ref_type": ["funcref", "externref", "type_idx"],
    2223    "external_kind": {
    2324        "Function": { "type": "uint8", "value": 0 },
  • trunk/Source/JavaScriptCore/ChangeLog

    r273940 r273962  
     12021-03-05  Dmitry Bezhetskov  <dbezhetskov@igalia.com>
     2
     3        [WASM-Function-References] Update ref.func to produce (ref $t)
     4        https://bugs.webkit.org/show_bug.cgi?id=222779
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        Make ref.func to produce non nullable reference type which
     9        incorporates signature index. Since in JSC signature index represents
     10        type of the function from Type section we use it instead of type_idx
     11        for representing type of function references.
     12
     13
     14        * runtime/OptionsList.h:
     15        * wasm/WasmAirIRGenerator.cpp:
     16        (JSC::Wasm::AirIRGenerator::addTableGrow):
     17        (JSC::Wasm::AirIRGenerator::addTableFill):
     18        (JSC::Wasm::AirIRGenerator::unify):
     19        * wasm/WasmFormat.h:
     20        (JSC::Wasm::isValueType):
     21        (JSC::Wasm::isSubtype):
     22        (JSC::Wasm::isRefType):
     23        * wasm/WasmFunctionParser.h:
     24        (JSC::Wasm::FunctionParser<Context>::checkBranchTarget):
     25        (JSC::Wasm::FunctionParser<Context>::unify):
     26        (JSC::Wasm::FunctionParser<Context>::parseExpression):
     27        * wasm/WasmLLIntGenerator.cpp:
     28        (JSC::Wasm::LLIntGenerator::callInformationForCaller):
     29        (JSC::Wasm::LLIntGenerator::callInformationForCallee):
     30        (JSC::Wasm::LLIntGenerator::addArguments):
     31        * wasm/WasmSectionParser.cpp:
     32        (JSC::Wasm::SectionParser::parseGlobal):
     33        * wasm/generateWasmOpsHeader.py:
     34        * wasm/js/WasmToJS.cpp:
     35        (JSC::Wasm::wasmToJS):
     36        * wasm/js/WebAssemblyFunction.cpp:
     37        (JSC::JSC_DEFINE_HOST_FUNCTION):
     38        * wasm/wasm.json:
     39
    1402021-03-04  Alex Christensen  <achristensen@webkit.org>
    241
  • trunk/Source/JavaScriptCore/runtime/OptionsList.h

    r273225 r273962  
    521521    v(Bool, useWebAssemblyStreaming, true, Normal, "Allow to run WebAssembly's Streaming API") \
    522522    v(Bool, useWebAssemblyReferences, true, Normal, "Allow types from the wasm references spec.") \
     523    v(Bool, useWebAssemblyTypedFunctionReferences, false, Normal, "Allow function types from the wasm typed function references spec.") \
    523524    v(Bool, useWebAssemblyMultiValues, true, Normal, "Allow types from the wasm mulit-values spec.") \
    524525    v(Bool, useWebAssemblyThreading, true, Normal, "Allow instructions from the wasm threading spec.") \
  • trunk/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp

    r273813 r273962  
    11771177{
    11781178    ASSERT(fill.tmp());
    1179     ASSERT(fill.type() == m_info.tables[tableIndex].wasmType());
     1179    ASSERT(isSubtype(fill.type(), m_info.tables[tableIndex].wasmType()));
    11801180    ASSERT(delta.tmp());
    11811181    ASSERT(delta.type().isI32());
     
    11901190{
    11911191    ASSERT(fill.tmp());
    1192     ASSERT(fill.type() == m_info.tables[tableIndex].wasmType());
     1192    ASSERT(isSubtype(fill.type(), m_info.tables[tableIndex].wasmType()));
    11931193    ASSERT(offset.tmp());
    11941194    ASSERT(offset.type().isI32());
     
    34203420void AirIRGenerator::unify(const ExpressionType dst, const ExpressionType source)
    34213421{
    3422     ASSERT(source.type() == dst.type());
     3422    ASSERT(isSubtype(source.type(), dst.type()));
    34233423    append(moveOpForValueType(dst.type()), source, dst);
    34243424}
  • trunk/Source/JavaScriptCore/wasm/WasmFormat.h

    r273813 r273962  
    7171    case TypeKind::Funcref:
    7272        return Options::useWebAssemblyReferences();
     73    case TypeKind::TypeIdx:
     74        return Options::useWebAssemblyTypedFunctionReferences();
    7375    default:
    7476        break;
     
    7779}
    7880
     81inline bool isSubtype(Type sub, Type parent)
     82{
     83    if (sub.isTypeIdx() && parent.isFuncref())
     84        return true;
     85
     86    return sub == parent;
     87}
     88
    7989inline bool isRefType(Type type)
    8090{
    81     return type.isFuncref() || type.isExternref();
    82 }
    83    
     91    return type.isFuncref() || type.isExternref() || type.isTypeIdx();
     92}
     93
    8494enum class ExternalKind : uint8_t {
    8595    // FIXME auto-generate this. https://bugs.webkit.org/show_bug.cgi?id=165231
  • trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h

    r273813 r273962  
    700700    unsigned offset = m_expressionStack.size() - target.branchTargetArity();
    701701    for (unsigned i = 0; i < target.branchTargetArity(); ++i)
    702         WASM_VALIDATOR_FAIL_IF(target.branchTargetType(i) != m_expressionStack[offset + i].type(), "branch's stack type is not a block's type branch target type. Stack value has type", m_expressionStack[offset + i].type().kind, " but branch target expects a value of ", target.branchTargetType(i).kind, " at index ", i);
     702        WASM_VALIDATOR_FAIL_IF(!isSubtype(target.branchTargetType(i), m_expressionStack[offset + i].type()), "branch's stack type is not a block's type branch target type. Stack value has type", m_expressionStack[offset + i].type().kind, " but branch target expects a value of ", target.branchTargetType(i).kind, " at index ", i);
    703703
    704704    return { };
     
    710710    WASM_VALIDATOR_FAIL_IF(controlData.signature()->returnCount() != m_expressionStack.size(), " block with type: ", controlData.signature()->toString(), " returns: ", controlData.signature()->returnCount(), " but stack has: ", m_expressionStack.size(), " values");
    711711    for (unsigned i = 0; i < controlData.signature()->returnCount(); ++i)
    712         WASM_VALIDATOR_FAIL_IF(m_expressionStack[i].type() != controlData.signature()->returnType(i), "control flow returns with unexpected type. ", m_expressionStack[i].type().kind, " is not a ", controlData.signature()->returnType(i).kind);
     712        WASM_VALIDATOR_FAIL_IF(!isSubtype(m_expressionStack[i].type(), controlData.signature()->returnType(i)), "control flow returns with unexpected type. ", m_expressionStack[i].type().kind, " is not a ", controlData.signature()->returnType(i).kind);
    713713
    714714    return { };
     
    837837        WASM_VALIDATOR_FAIL_IF(TypeKind::I32 != index.type().kind, "table.set index to type ", index.type().kind, " expected ", TypeKind::I32);
    838838        Type type = m_info.tables[tableIndex].wasmType();
    839         WASM_VALIDATOR_FAIL_IF(value.type() != type, "table.set value to type ", value.type().kind, " expected ", type.kind);
     839        WASM_VALIDATOR_FAIL_IF(!isSubtype(value.type(), type), "table.set value to type ", value.type().kind, " expected ", type.kind);
    840840        RELEASE_ASSERT(m_info.tables[tableIndex].type() == TableElementType::Externref || m_info.tables[tableIndex].type() == TableElementType::Funcref);
    841841        WASM_TRY_ADD_TO_CONTEXT(addTableSet(tableIndex, index, value));
     
    900900            WASM_TRY_POP_EXPRESSION_STACK_INTO(fill, "table.grow");
    901901
    902             WASM_VALIDATOR_FAIL_IF(fill.type() != m_info.tables[tableIndex].wasmType(), "table.grow expects fill value of type ", m_info.tables[tableIndex].wasmType().kind, " got ", fill.type().kind);
     902            Type tableType = m_info.tables[tableIndex].wasmType();
     903            WASM_VALIDATOR_FAIL_IF(!isSubtype(fill.type(), tableType), "table.grow expects fill value of type ", tableType.kind, " got ", fill.type().kind);
    903904            WASM_VALIDATOR_FAIL_IF(TypeKind::I32 != delta.type().kind, "table.grow expects an i32 delta value, got ", delta.type().kind);
    904905
     
    919920            WASM_TRY_POP_EXPRESSION_STACK_INTO(offset, "table.fill");
    920921
    921             WASM_VALIDATOR_FAIL_IF(fill.type() != m_info.tables[tableIndex].wasmType(), "table.fill expects fill value of type ", m_info.tables[tableIndex].wasmType().kind, " got ", fill.type().kind);
     922            Type tableType = m_info.tables[tableIndex].wasmType();
     923            WASM_VALIDATOR_FAIL_IF(!isSubtype(fill.type(), tableType), "table.fill expects fill value of type ", tableType.kind, " got ", fill.type().kind);
    922924            WASM_VALIDATOR_FAIL_IF(TypeKind::I32 != offset.type().kind, "table.fill expects an i32 offset value, got ", offset.type().kind);
    923925            WASM_VALIDATOR_FAIL_IF(TypeKind::I32 != count.type().kind, "table.fill expects an i32 count value, got ", count.type().kind);
     
    11051107        ExpressionType result;
    11061108        WASM_TRY_ADD_TO_CONTEXT(addRefFunc(index, result));
     1109
     1110        if (Options::useWebAssemblyTypedFunctionReferences()) {
     1111            SignatureIndex signatureIndex = m_info.signatureIndexFromFunctionIndexSpace(index);
     1112            m_expressionStack.constructAndAppend(Type {TypeKind::TypeIdx, signatureIndex}, result);
     1113            return { };
     1114        }
     1115
    11071116        m_expressionStack.constructAndAppend(Types::Funcref, result);
    11081117        return { };
     
    11261135        WASM_TRY_POP_EXPRESSION_STACK_INTO(value, "set_local");
    11271136        WASM_VALIDATOR_FAIL_IF(index >= m_locals.size(), "attempt to set unknown local ", index, " last one is ", m_locals.size());
    1128         WASM_VALIDATOR_FAIL_IF(value.type() != m_locals[index], "set_local to type ", value.type().kind, " expected ", m_locals[index].kind);
     1137        WASM_VALIDATOR_FAIL_IF(!isSubtype(value.type(), m_locals[index]), "set_local to type ", value.type().kind, " expected ", m_locals[index].kind);
    11291138        WASM_TRY_ADD_TO_CONTEXT(setLocal(index, value));
    11301139        return { };
     
    11381147        TypedExpression value = m_expressionStack.last();
    11391148        WASM_VALIDATOR_FAIL_IF(index >= m_locals.size(), "attempt to tee unknown local ", index, " last one is ", m_locals.size());
    1140         WASM_VALIDATOR_FAIL_IF(value.type() != m_locals[index], "set_local to type ", value.type().kind, " expected ", m_locals[index].kind);
     1149        WASM_VALIDATOR_FAIL_IF(!isSubtype(value.type(), m_locals[index]), "set_local to type ", value.type().kind, " expected ", m_locals[index].kind);
    11411150        WASM_TRY_ADD_TO_CONTEXT(setLocal(index, value));
    11421151        return { };
     
    11661175        Type globalType = m_info.globals[index].type;
    11671176        ASSERT(isValueType(globalType));
    1168         WASM_VALIDATOR_FAIL_IF(globalType != value.type(), "set_global ", index, " with type ", globalType.kind, " with a variable of type ", value.type().kind);
     1177        WASM_VALIDATOR_FAIL_IF(!isSubtype(value.type(), globalType), "set_global ", index, " with type ", globalType.kind, " with a variable of type ", value.type().kind);
    11691178
    11701179        WASM_TRY_ADD_TO_CONTEXT(setGlobal(index, value));
     
    11851194        for (size_t i = firstArgumentIndex; i < m_expressionStack.size(); ++i) {
    11861195            TypedExpression arg = m_expressionStack.at(i);
    1187             WASM_VALIDATOR_FAIL_IF(arg.type() != calleeSignature.argument(i - firstArgumentIndex), "argument type mismatch in call, got ", arg.type().kind, ", expected ", calleeSignature.argument(i - firstArgumentIndex).kind);
     1196            WASM_VALIDATOR_FAIL_IF(!isSubtype(arg.type(), calleeSignature.argument(i - firstArgumentIndex)), "argument type mismatch in call, got ", arg.type().kind, ", expected ", calleeSignature.argument(i - firstArgumentIndex).kind);
    11881197            args.uncheckedAppend(arg);
    11891198            m_context.didPopValueFromStack();
     
    12261235            TypedExpression arg = m_expressionStack.at(i);
    12271236            if (i < m_expressionStack.size() - 1)
    1228                 WASM_VALIDATOR_FAIL_IF(arg.type() != calleeSignature.argument(i - firstArgumentIndex), "argument type mismatch in call_indirect, got ", arg.type().kind, ", expected ", calleeSignature.argument(i - firstArgumentIndex).kind);
     1237                WASM_VALIDATOR_FAIL_IF(!isSubtype(arg.type(), calleeSignature.argument(i - firstArgumentIndex)), "argument type mismatch in call_indirect, got ", arg.type().kind, ", expected ", calleeSignature.argument(i - firstArgumentIndex).kind);
    12291238            args.uncheckedAppend(arg);
    12301239            m_context.didPopValueFromStack();
  • trunk/Source/JavaScriptCore/wasm/WasmLLIntGenerator.cpp

    r273813 r273962  
    540540        case TypeKind::Externref:
    541541        case TypeKind::Funcref:
     542        case TypeKind::TypeIdx:
    542543            if (gprIndex < gprCount)
    543544                ++gprIndex;
     
    595596        case TypeKind::Externref:
    596597        case TypeKind::Funcref:
     598        case TypeKind::TypeIdx:
    597599            if (gprIndex > gprLimit)
    598600                arguments[i] = virtualRegisterForLocal(--gprIndex);
     
    622624        case TypeKind::Externref:
    623625        case TypeKind::Funcref:
     626        case TypeKind::TypeIdx:
    624627            if (gprIndex > gprLimit)
    625628                temporaryResults[i] = virtualRegisterForLocal(--gprIndex);
     
    677680        case TypeKind::Externref:
    678681        case TypeKind::Funcref:
     682        case TypeKind::TypeIdx:
    679683            if (gprIndex < maxGPRIndex)
    680684                m_results.append(virtualRegisterForLocal(numberOfLLIntCalleeSaveRegisters + gprIndex++));
     
    731735        case TypeKind::Externref:
    732736        case TypeKind::Funcref:
     737        case TypeKind::TypeIdx:
    733738            addArgument(i, gprIndex, maxGPRIndex);
    734739            break;
  • trunk/Source/JavaScriptCore/wasm/WasmModule.h

    r273662 r273962  
    3131#include "WasmEmbedder.h"
    3232#include "WasmMemory.h"
     33#include "WasmOps.h"
    3334#include <wtf/Expected.h>
    3435#include <wtf/Lock.h>
     
    4142struct Context;
    4243struct ModuleInformation;
    43 
    44 using SignatureIndex = uintptr_t;
    4544
    4645class Module : public ThreadSafeRefCounted<Module> {
  • trunk/Source/JavaScriptCore/wasm/WasmSectionParser.cpp

    r273813 r273962  
    305305        else
    306306            global.initializationType = GlobalInformation::FromExpression;
    307         WASM_PARSER_FAIL_IF(typeForInitOpcode != global.type, "Global init_expr opcode of type ", typeForInitOpcode.kind, " doesn't match global's type ", global.type.kind);
     307        WASM_PARSER_FAIL_IF(!isSubtype(typeForInitOpcode, global.type), "Global init_expr opcode of type ", typeForInitOpcode.kind, " doesn't match global's type ", global.type.kind);
    308308
    309309        if (initOpcode == RefFunc)
  • trunk/Source/JavaScriptCore/wasm/WasmSignature.h

    r273813 r273962  
    4545
    4646using SignatureArgCount = uint32_t;
    47 using SignatureIndex = uintptr_t;
    4847
    4948class Signature : public ThreadSafeRefCounted<Signature> {
  • trunk/Source/JavaScriptCore/wasm/generateWasmOpsHeader.py

    r273813 r273962  
    213213#undef CREATE_ENUM_VALUE
    214214
     215using SignatureIndex = uintptr_t;
     216
    215217struct Type {
    216218    TypeKind kind;
    217     unsigned index;
     219    SignatureIndex index;
    218220
    219221    bool operator==(const Type& other) const
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h

    r273662 r273962  
    3131#include "JSObject.h"
    3232#include "WasmMemoryMode.h"
     33#include "WasmOps.h"
    3334#include <wtf/Bag.h>
    3435#include <wtf/Expected.h>
     
    4344struct ModuleInformation;
    4445class Plan;
    45 using SignatureIndex = uintptr_t;
    4646}
    4747
  • trunk/Source/JavaScriptCore/wasm/js/WasmToJS.cpp

    r273813 r273962  
    106106            case TypeKind::Func:
    107107                RELEASE_ASSERT_NOT_REACHED(); // Handled above.
     108            case TypeKind::TypeIdx:
    108109            case TypeKind::Externref:
    109110            case TypeKind::Funcref:
     
    178179            case TypeKind::Func:
    179180                RELEASE_ASSERT_NOT_REACHED(); // Handled above.
     181            case TypeKind::TypeIdx:
    180182            case TypeKind::Externref:
    181183            case TypeKind::Funcref:
     
    320322        case TypeKind::Funcref:
    321323        case TypeKind::Externref:
     324        case TypeKind::TypeIdx:
    322325            jit.move(GPRInfo::returnValueGPR, wasmCallInfo.results[0].gpr());
    323326            break;
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp

    r273813 r273962  
    8484            arg = JSValue::decode(arg.toInt32(globalObject));
    8585            break;
     86        case Wasm::TypeKind::TypeIdx:
    8687        case Wasm::TypeKind::Funcref: {
    8788            if (!isWebAssemblyHostFunction(vm, arg) && !arg.isNull())
  • trunk/Source/JavaScriptCore/wasm/wasm.json

    r272933 r273962  
    88    ],
    99    "type" : {
    10         "i32":       { "type": "varint7", "value":  -1, "b3type": "B3::Int32" },
    11         "i64":       { "type": "varint7", "value":  -2, "b3type": "B3::Int64" },
    12         "f32":       { "type": "varint7", "value":  -3, "b3type": "B3::Float" },
    13         "f64":       { "type": "varint7", "value":  -4, "b3type": "B3::Double" },
    14         "funcref":   { "type": "varint7", "value": -16, "b3type": "B3::Int64" },
    15         "externref": { "type": "varint7", "value": -17, "b3type": "B3::Int64" },
    16         "func":      { "type": "varint7", "value": -32, "b3type": "B3::Void" },
    17         "void":      { "type": "varint7", "value": -64, "b3type": "B3::Void" }
     10        "i32":       { "type": "varint7", "value":   -1, "b3type": "B3::Int32" },
     11        "i64":       { "type": "varint7", "value":   -2, "b3type": "B3::Int64" },
     12        "f32":       { "type": "varint7", "value":   -3, "b3type": "B3::Float" },
     13        "f64":       { "type": "varint7", "value":   -4, "b3type": "B3::Double" },
     14        "funcref":   { "type": "varint7", "value":  -16, "b3type": "B3::Int64" },
     15        "externref": { "type": "varint7", "value":  -17, "b3type": "B3::Int64" },
     16        "func":      { "type": "varint7", "value":  -32, "b3type": "B3::Void" },
     17        "void":      { "type": "varint7", "value":  -64, "b3type": "B3::Void" },
     18        "type_idx":  { "type": "varint7", "value": -128, "b3type": "B3::Int64" }
    1819    },
    1920    "value_type": ["i32", "i64", "f32", "f64", "externref", "funcref"],
    2021    "block_type": ["i32", "i64", "f32", "f64", "void", "externref", "funcref"],
    21     "ref_type": ["funcref","externref"],
     22    "ref_type": ["funcref", "externref", "type_idx"],
    2223    "external_kind": {
    2324        "Function": { "type": "uint8", "value": 0 },
Note: See TracChangeset for help on using the changeset viewer.