Changeset 279265 in webkit
- Timestamp:
- Jun 24, 2021 7:23:28 PM (13 months ago)
- Location:
- trunk
- Files:
-
- 1 added
- 18 edited
-
JSTests/ChangeLog (modified) (1 diff)
-
JSTests/wasm/function-references/ref_types.js (added)
-
JSTests/wasm/wasm.json (modified) (1 diff)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp (modified) (8 diffs)
-
Source/JavaScriptCore/wasm/WasmCallingConvention.h (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/WasmFormat.h (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/WasmFunctionParser.h (modified) (5 diffs)
-
Source/JavaScriptCore/wasm/WasmGlobal.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/WasmLLIntGenerator.cpp (modified) (5 diffs)
-
Source/JavaScriptCore/wasm/WasmParser.h (modified) (4 diffs)
-
Source/JavaScriptCore/wasm/WasmSectionParser.cpp (modified) (9 diffs)
-
Source/JavaScriptCore/wasm/WasmSignature.cpp (modified) (1 diff)
-
Source/JavaScriptCore/wasm/generateWasmOpsHeader.py (modified) (3 diffs)
-
Source/JavaScriptCore/wasm/js/WasmToJS.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp (modified) (5 diffs)
-
Source/JavaScriptCore/wasm/js/WebAssemblyFunctionBase.h (modified) (1 diff)
-
Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/wasm/wasm.json (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r279243 r279265 1 2021-06-24 Asumu Takikawa <asumu@igalia.com> 2 3 [WASM-Function-References] Add support for (ref null? $t) type constructor 4 https://bugs.webkit.org/show_bug.cgi?id=226296 5 6 Adds additional tests for uses of `(ref $t)` and `(ref null $t)` 7 types, including with non-null extern/funcrefs. 8 9 Reviewed by Yusuke Suzuki. 10 11 * wasm/function-references/ref_types.js: Added. 12 (module): 13 (async testRefTypeLocal): 14 (async testNonNullRefTypeLocal): 15 (async testRefTypeInSignature): 16 (async testRefTypeParamCheck): 17 (async testRefGlobalCheck): 18 (async testExternFuncrefNonNullCheck): 19 (async testExternrefCompatibility): 20 (async testNonNullExternrefIncompatible): 21 (async testFuncrefCompatibility): 22 (async testNonNullFuncrefIncompatible): 23 * wasm/wasm.json: 24 1 25 2021-06-24 Guillaume Emont <guijemont@igalia.com> 2 26 -
trunk/JSTests/wasm/wasm.json
r276896 r279265 14 14 "funcref": { "type": "varint7", "value": -16, "b3type": "B3::Int64" }, 15 15 "externref": { "type": "varint7", "value": -17, "b3type": "B3::Int64" }, 16 "ref_null": { "type": "varint7", "value": -20, "b3type": "B3::Int64" }, 17 "ref": { "type": "varint7", "value": -21, "b3type": "B3::Int64" }, 16 18 "func": { "type": "varint7", "value": -32, "b3type": "B3::Void" }, 17 19 "void": { "type": "varint7", "value": -64, "b3type": "B3::Void" }, -
trunk/Source/JavaScriptCore/ChangeLog
r279256 r279265 1 2021-06-24 Asumu Takikawa <asumu@igalia.com> 2 3 [WASM-Function-References] Add support for (ref null? $t) type constructor 4 https://bugs.webkit.org/show_bug.cgi?id=226296 5 6 Reviewed by Yusuke Suzuki. 7 8 Adds the `ref` type constructor from the typed function references proposal: 9 10 https://github.com/WebAssembly/function-references/blob/master/proposals/function-references/Overview.md 11 12 It's also required for the type imports and GC proposals as well. Ref types represent 13 references to any heap type (including existing funcref and externref) with a specified 14 nullability. 15 16 This requires a new isNullable flag in the type representation. This flag also enables 17 non-null externref and funcrefs, and hence this commit also adds the necessary checks 18 at Wasm/JS boundaries. 19 20 Non-null reference types also generally cannot be used as function locals. 21 22 * wasm/WasmAirIRGenerator.cpp: 23 (JSC::Wasm::AirIRGenerator::gTypeIdx): 24 (JSC::Wasm::AirIRGenerator::tmpForType): 25 (JSC::Wasm::AirIRGenerator::emitCCall): 26 (JSC::Wasm::AirIRGenerator::moveOpForValueType): 27 (JSC::Wasm::AirIRGenerator::AirIRGenerator): 28 (JSC::Wasm::AirIRGenerator::addLocal): 29 (JSC::Wasm::AirIRGenerator::addConstant): 30 (JSC::Wasm::AirIRGenerator::addRefFunc): 31 * wasm/WasmCallingConvention.h: 32 (JSC::Wasm::WasmCallingConvention::marshallLocation const): 33 (JSC::Wasm::JSCallingConvention::marshallLocation const): 34 * wasm/WasmFormat.h: 35 (JSC::Wasm::isSubtype): 36 (JSC::Wasm::isValidHeapTypeKind): 37 (JSC::Wasm::isDefaultableType): 38 * wasm/WasmFunctionParser.h: 39 (JSC::Wasm::FunctionParser<Context>::parse): 40 (JSC::Wasm::FunctionParser<Context>::parseAnnotatedSelectImmediates): 41 (JSC::Wasm::FunctionParser<Context>::checkBranchTarget): 42 (JSC::Wasm::FunctionParser<Context>::parseExpression): 43 * wasm/WasmGlobal.cpp: 44 (JSC::Wasm::Global::get const): 45 (JSC::Wasm::Global::set): 46 * wasm/WasmLLIntGenerator.cpp: 47 (JSC::Wasm::LLIntGenerator::callInformationForCaller): 48 (JSC::Wasm::LLIntGenerator::callInformationForCallee): 49 (JSC::Wasm::LLIntGenerator::addArguments): 50 * wasm/WasmParser.h: 51 (JSC::Wasm::Parser<SuccessType>::parseBlockSignature): 52 (JSC::Wasm::Parser<SuccessType>::parseValueType): 53 (JSC::Wasm::Parser<SuccessType>::parseRefType): 54 * wasm/WasmSectionParser.cpp: 55 (JSC::Wasm::SectionParser::parseType): 56 (JSC::Wasm::SectionParser::parseElement): 57 (JSC::Wasm::SectionParser::parseInitExpr): 58 (JSC::Wasm::SectionParser::parseElementSegmentVectorOfExpressions): 59 (JSC::Wasm::SectionParser::parseGlobalType): 60 * wasm/WasmSignature.cpp: 61 (JSC::Wasm::computeHash): 62 * wasm/generateWasmOpsHeader.py: 63 * wasm/js/WasmToJS.cpp: 64 (JSC::Wasm::wasmToJS): 65 * wasm/js/WebAssemblyFunction.cpp: 66 (JSC::JSC_DEFINE_HOST_FUNCTION): 67 (JSC::WebAssemblyFunction::jsCallEntrypointSlow): 68 * wasm/js/WebAssemblyFunctionBase.h: 69 (JSC::WebAssemblyFunctionBase::offsetOfSignatureIndex): 70 * wasm/js/WebAssemblyModuleRecord.cpp: 71 (JSC::WebAssemblyModuleRecord::linkImpl): 72 * wasm/wasm.json: 73 1 74 2021-06-24 Mark Lam <mark.lam@apple.com> 2 75 -
trunk/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp
r279256 r279265 414 414 TypedTmp gExternref() { return { newTmp(B3::GP), Types::Externref }; } 415 415 TypedTmp gFuncref() { return { newTmp(B3::GP), Types::Funcref }; } 416 TypedTmp gTypeIdx(Type type) { return { newTmp(B3::GP), type }; } 416 417 TypedTmp f32() { return { newTmp(B3::FP), Types::F32 }; } 417 418 TypedTmp f64() { return { newTmp(B3::FP), Types::F64 }; } … … 426 427 case TypeKind::Funcref: 427 428 return gFuncref(); 429 case TypeKind::TypeIdx: 430 return gTypeIdx(type); 428 431 case TypeKind::Externref: 429 432 return gExternref(); … … 602 605 case TypeKind::Externref: 603 606 case TypeKind::Funcref: 607 case TypeKind::TypeIdx: 604 608 resultType = B3::Int64; 605 609 break; … … 651 655 case TypeKind::Externref: 652 656 case TypeKind::Funcref: 657 case TypeKind::TypeIdx: 653 658 return Move; 654 659 case TypeKind::F32: … … 908 913 case TypeKind::Externref: 909 914 case TypeKind::Funcref: 915 case TypeKind::TypeIdx: 910 916 append(Move, arg, m_locals[i]); 911 917 break; … … 1010 1016 case TypeKind::Externref: 1011 1017 case TypeKind::Funcref: 1018 case TypeKind::TypeIdx: 1012 1019 append(Move, Arg::imm(JSValue::encode(jsNull())), local); 1013 1020 break; … … 1045 1052 case TypeKind::Externref: 1046 1053 case TypeKind::Funcref: 1054 case TypeKind::TypeIdx: 1047 1055 append(block, Move, Arg::bigImm(value), result); 1048 1056 break; … … 1089 1097 { 1090 1098 // FIXME: Emit this inline <https://bugs.webkit.org/show_bug.cgi?id=198506>. 1091 result = tmpForType(Types::Funcref); 1099 if (Options::useWebAssemblyTypedFunctionReferences()) { 1100 SignatureIndex signatureIndex = m_info.signatureIndexFromFunctionIndexSpace(index); 1101 result = tmpForType(Type { TypeKind::TypeIdx, Nullable::No, signatureIndex }); 1102 } else 1103 result = tmpForType(Types::Funcref); 1092 1104 emitCCall(&operationWasmRefFunc, result, instanceValue(), addConstant(Types::I32, index)); 1093 1105 -
trunk/Source/JavaScriptCore/wasm/WasmCallingConvention.h
r273813 r279265 108 108 case TypeKind::Funcref: 109 109 case TypeKind::Externref: 110 case TypeKind::TypeIdx: 110 111 return marshallLocationImpl(role, gprArgs, gpArgumentCount, stackOffset); 111 112 case TypeKind::F32: … … 196 197 case TypeKind::Funcref: 197 198 case TypeKind::Externref: 199 case TypeKind::TypeIdx: 198 200 return marshallLocationImpl(role, gprArgs, gpArgumentCount, stackOffset); 199 201 case TypeKind::F32: -
trunk/Source/JavaScriptCore/wasm/WasmFormat.h
r278340 r279265 80 80 inline bool isSubtype(Type sub, Type parent) 81 81 { 82 if (sub.isNullable() && !parent.isNullable()) 83 return false; 84 82 85 if (sub.isTypeIdx() && parent.isFuncref()) 83 86 return true; … … 89 92 { 90 93 return type.isFuncref() || type.isExternref() || type.isTypeIdx(); 94 } 95 96 inline bool isValidHeapTypeKind(TypeKind kind) 97 { 98 switch (kind) { 99 case TypeKind::Funcref: 100 case TypeKind::Externref: 101 return true; 102 default: 103 break; 104 } 105 return false; 106 } 107 108 inline bool isDefaultableType(Type type) 109 { 110 return !isRefType(type) || type.isNullable(); 91 111 } 92 112 -
trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h
r276896 r279265 244 244 totalNumberOfLocals += numberOfLocals; 245 245 WASM_PARSER_FAIL_IF(totalNumberOfLocals > maxFunctionLocals, "Function's number of locals is too big ", totalNumberOfLocals, " maximum ", maxFunctionLocals); 246 WASM_PARSER_FAIL_IF(!parseValueType(typeOfLocal), "can't get Function local's type in group ", i); 246 WASM_PARSER_FAIL_IF(!parseValueType(m_info, typeOfLocal), "can't get Function local's type in group ", i); 247 WASM_PARSER_FAIL_IF(!isDefaultableType(typeOfLocal), "Function locals must have a defaultable type"); 247 248 248 249 WASM_PARSER_FAIL_IF(!m_locals.tryReserveCapacity(totalNumberOfLocals), "can't allocate enough memory for function's ", totalNumberOfLocals, " locals"); … … 645 646 646 647 Type targetType; 647 WASM_PARSER_FAIL_IF(!parseValueType( targetType), "select can't parse annotations");648 WASM_PARSER_FAIL_IF(!parseValueType(m_info, targetType), "select can't parse annotations"); 648 649 649 650 result.sizeOfAnnotationVector = sizeOfAnnotationVector; … … 700 701 unsigned offset = m_expressionStack.size() - target.branchTargetArity(); 701 702 for (unsigned i = 0; i < target.branchTargetArity(); ++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);703 WASM_VALIDATOR_FAIL_IF(!isSubtype(m_expressionStack[offset + i].type(), target.branchTargetType(i)), "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); 703 704 704 705 return { }; … … 1080 1081 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyReferences(), "references are not enabled"); 1081 1082 Type typeOfNull; 1082 WASM_PARSER_FAIL_IF(!parseRefType( typeOfNull), "ref.null type must be a reference type");1083 WASM_PARSER_FAIL_IF(!parseRefType(m_info, typeOfNull), "ref.null type must be a reference type"); 1083 1084 m_expressionStack.constructAndAppend(typeOfNull, m_context.addConstant(typeOfNull, JSValue::encode(jsNull()))); 1084 1085 return { }; … … 1110 1111 if (Options::useWebAssemblyTypedFunctionReferences()) { 1111 1112 SignatureIndex signatureIndex = m_info.signatureIndexFromFunctionIndexSpace(index); 1112 m_expressionStack.constructAndAppend(Type {TypeKind::TypeIdx, signatureIndex}, result);1113 m_expressionStack.constructAndAppend(Type {TypeKind::TypeIdx, Nullable::No, signatureIndex}, result); 1113 1114 return { }; 1114 1115 } -
trunk/Source/JavaScriptCore/wasm/WasmGlobal.cpp
r273813 r279265 49 49 case TypeKind::Externref: 50 50 case TypeKind::Funcref: 51 case TypeKind::TypeIdx: 51 52 return m_value.m_externref.get(); 52 53 default: … … 87 88 case TypeKind::Externref: { 88 89 RELEASE_ASSERT(m_owner); 90 if (!m_type.isNullable() && argument.isNull()) { 91 throwException(globalObject, throwScope, createJSWebAssemblyRuntimeError(globalObject, vm, "Non-null Externref cannot be null")); 92 return; 93 } 89 94 m_value.m_externref.set(m_owner->vm(), m_owner, argument); 90 95 break; 91 96 } 97 case TypeKind::TypeIdx: 92 98 case TypeKind::Funcref: { 93 99 RELEASE_ASSERT(m_owner); 94 if (!isWebAssemblyHostFunction(vm, argument) && !argument.isNull()) { 100 bool isNullable = m_type.isNullable(); 101 WebAssemblyFunction* wasmFunction = nullptr; 102 WebAssemblyWrapperFunction* wasmWrapperFunction = nullptr; 103 if (!isWebAssemblyHostFunction(vm, argument, wasmFunction, wasmWrapperFunction) && (!isNullable || !argument.isNull())) { 95 104 throwException(globalObject, throwScope, createJSWebAssemblyRuntimeError(globalObject, vm, "Funcref must be an exported wasm function")); 96 105 return; 106 } 107 if (m_type.kind == TypeKind::TypeIdx && (wasmFunction || wasmWrapperFunction)) { 108 Wasm::SignatureIndex paramIndex = m_type.index; 109 Wasm::SignatureIndex argIndex; 110 if (wasmFunction) 111 argIndex = wasmFunction->signatureIndex(); 112 else 113 argIndex = wasmWrapperFunction->signatureIndex(); 114 if (paramIndex != argIndex) { 115 throwException(globalObject, throwScope, createJSWebAssemblyRuntimeError(globalObject, vm, "Argument function did not match the reference type")); 116 return; 117 } 97 118 } 98 119 m_value.m_externref.set(m_owner->vm(), m_owner, argument); -
trunk/Source/JavaScriptCore/wasm/WasmLLIntGenerator.cpp
r279082 r279265 563 563 case TypeKind::Void: 564 564 case TypeKind::Func: 565 case TypeKind::RefNull: 566 case TypeKind::Ref: 565 567 RELEASE_ASSERT_NOT_REACHED(); 566 568 } … … 619 621 case TypeKind::Void: 620 622 case TypeKind::Func: 623 case TypeKind::RefNull: 624 case TypeKind::Ref: 621 625 RELEASE_ASSERT_NOT_REACHED(); 622 626 } … … 647 651 case TypeKind::Void: 648 652 case TypeKind::Func: 653 case TypeKind::RefNull: 654 case TypeKind::Ref: 649 655 RELEASE_ASSERT_NOT_REACHED(); 650 656 } … … 703 709 case TypeKind::Void: 704 710 case TypeKind::Func: 711 case TypeKind::RefNull: 712 case TypeKind::Ref: 705 713 RELEASE_ASSERT_NOT_REACHED(); 706 714 } … … 752 760 case TypeKind::Void: 753 761 case TypeKind::Func: 762 case TypeKind::RefNull: 763 case TypeKind::Ref: 754 764 RELEASE_ASSERT_NOT_REACHED(); 755 765 } -
trunk/Source/JavaScriptCore/wasm/WasmParser.h
r273813 r279265 85 85 86 86 PartialResult WARN_UNUSED_RETURN parseBlockSignature(const ModuleInformation&, BlockSignature&); 87 bool WARN_UNUSED_RETURN parseValueType( Type&);88 bool WARN_UNUSED_RETURN parseRefType( Type&);87 bool WARN_UNUSED_RETURN parseValueType(const ModuleInformation&, Type&); 88 bool WARN_UNUSED_RETURN parseRefType(const ModuleInformation&, Type&); 89 89 bool WARN_UNUSED_RETURN parseExternalKind(ExternalKind&); 90 90 … … 278 278 int8_t typeKind; 279 279 if (peekInt7(typeKind) && isValidTypeKind(typeKind)) { 280 Type type = {static_cast<TypeKind>(typeKind), 0};280 Type type = {static_cast<TypeKind>(typeKind), Nullable::Yes, 0}; 281 281 WASM_PARSER_FAIL_IF(!(isValueType(type) || type.isVoid()), "result type of block: ", makeString(type.kind), " is not a value type or Void"); 282 282 result = m_signatureInformation.thunkFor(type); … … 297 297 298 298 template<typename SuccessType> 299 ALWAYS_INLINE bool Parser<SuccessType>::parseValueType( Type& result)299 ALWAYS_INLINE bool Parser<SuccessType>::parseValueType(const ModuleInformation& info, Type& result) 300 300 { 301 301 int8_t kind; 302 302 if (!parseInt7(kind)) 303 303 return false; 304 Type type = {static_cast<TypeKind>(kind), 0}; 305 if (!isValidTypeKind(kind) || !isValueType(type)) 304 if (!isValidTypeKind(kind)) 305 return false; 306 307 TypeKind typeKind = static_cast<TypeKind>(kind); 308 bool isNullable = true; 309 SignatureIndex sigIndex = 0; 310 if (typeKind == TypeKind::Ref || typeKind == TypeKind::RefNull) { 311 if (!Options::useWebAssemblyTypedFunctionReferences()) 312 return false; 313 314 int32_t heapType; 315 isNullable = typeKind == TypeKind::RefNull; 316 317 if (!parseVarInt32(heapType)) 318 return false; 319 if (heapType < 0) { 320 TypeKind heapKind = static_cast<TypeKind>(heapType); 321 if (!isValidHeapTypeKind(heapKind)) 322 return false; 323 typeKind = heapKind; 324 } else { 325 typeKind = TypeKind::TypeIdx; 326 if (static_cast<size_t>(heapType) >= info.usedSignatures.size()) 327 return false; 328 sigIndex = SignatureInformation::get(info.usedSignatures[heapType].get()); 329 } 330 } 331 332 Type type = { typeKind, static_cast<Nullable>(isNullable), sigIndex }; 333 if (!isValueType(type)) 306 334 return false; 307 335 result = type; … … 310 338 311 339 template<typename SuccessType> 312 ALWAYS_INLINE bool Parser<SuccessType>::parseRefType( Type& result)313 { 314 const bool parsed = parseValueType( result);340 ALWAYS_INLINE bool Parser<SuccessType>::parseRefType(const ModuleInformation& info, Type& result) 341 { 342 const bool parsed = parseValueType(info, result); 315 343 return parsed && isRefType(result); 316 344 } -
trunk/Source/JavaScriptCore/wasm/WasmSectionParser.cpp
r278340 r279265 61 61 for (unsigned i = 0; i < argumentCount; ++i) { 62 62 Type argumentType; 63 WASM_PARSER_FAIL_IF(!parseValueType( argumentType), "can't get ", i, "th argument Type");63 WASM_PARSER_FAIL_IF(!parseValueType(m_info, argumentType), "can't get ", i, "th argument Type"); 64 64 arguments.append(argumentType); 65 65 } … … 73 73 for (unsigned i = 0; i < returnCount; ++i) { 74 74 Type value; 75 WASM_PARSER_FAIL_IF(!parseValueType( value), "can't get ", i, "th Type's return value");75 WASM_PARSER_FAIL_IF(!parseValueType(m_info, value), "can't get ", i, "th Type's return value"); 76 76 returnTypes.append(value); 77 77 } … … 484 484 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyReferences(), "references are not enabled"); 485 485 Type refType; 486 WASM_PARSER_FAIL_IF(!parseRefType( refType), "can't parse reftype in elem section");486 WASM_PARSER_FAIL_IF(!parseRefType(m_info, refType), "can't parse reftype in elem section"); 487 487 WASM_PARSER_FAIL_IF(!refType.isFuncref(), "reftype in element section should be funcref"); 488 488 … … 508 508 509 509 Type refType; 510 WASM_PARSER_FAIL_IF(!parseRefType( refType), "can't parse reftype in elem section");510 WASM_PARSER_FAIL_IF(!parseRefType(m_info, refType), "can't parse reftype in elem section"); 511 511 WASM_PARSER_FAIL_IF(!refType.isFuncref(), "reftype in element section should be funcref"); 512 512 … … 526 526 527 527 Type refType; 528 WASM_PARSER_FAIL_IF(!parseRefType( refType), "can't parse reftype in elem section");528 WASM_PARSER_FAIL_IF(!parseRefType(m_info, refType), "can't parse reftype in elem section"); 529 529 WASM_PARSER_FAIL_IF(!refType.isFuncref(), "reftype in element section should be funcref"); 530 530 … … 606 606 case RefNull: { 607 607 Type typeOfNull; 608 WASM_PARSER_FAIL_IF(!parseRefType( typeOfNull), "ref.null type must be a reference type");608 WASM_PARSER_FAIL_IF(!parseRefType(m_info, typeOfNull), "ref.null type must be a reference type"); 609 609 resultType = typeOfNull; 610 610 bitsOrImportNumber = JSValue::encode(jsNull()); … … 617 617 WASM_PARSER_FAIL_IF(index >= m_info->functions.size(), "ref.func index", index, " exceeds the number of functions ", m_info->functions.size()); 618 618 619 resultType = Types::Funcref; 619 if (Options::useWebAssemblyTypedFunctionReferences()) { 620 SignatureIndex signatureIndex = m_info->signatureIndexFromFunctionIndexSpace(index); 621 resultType = { TypeKind::TypeIdx, Nullable::No, signatureIndex }; 622 } else 623 resultType = Types::Funcref; 624 620 625 bitsOrImportNumber = index; 621 626 break; … … 692 697 } else { 693 698 Type typeOfNull; 694 WASM_PARSER_FAIL_IF(!parseRefType( typeOfNull), "ref.null type must be a func type in elem section");699 WASM_PARSER_FAIL_IF(!parseRefType(m_info, typeOfNull), "ref.null type must be a func type in elem section"); 695 700 WASM_PARSER_FAIL_IF(!typeOfNull.isFuncref(), "ref.null extern is forbidden in element section's, ", elementNum, "th element's ", index, "th index"); 696 701 functionIndex = Element::nullFuncIndex; … … 728 733 { 729 734 uint8_t mutability; 730 WASM_PARSER_FAIL_IF(!parseValueType( global.type), "can't get Global's value type");735 WASM_PARSER_FAIL_IF(!parseValueType(m_info, global.type), "can't get Global's value type"); 731 736 WASM_PARSER_FAIL_IF(!parseUInt8(mutability), "can't get Global type's mutability"); 732 737 WASM_PARSER_FAIL_IF(mutability != 0x0 && mutability != 0x1, "invalid Global's mutability: 0x", hex(mutability, 2, Lowercase)); -
trunk/Source/JavaScriptCore/wasm/WasmSignature.cpp
r277920 r279265 71 71 for (uint32_t i = 0; i < argumentCount; ++i) { 72 72 accumulator = WTF::pairIntHash(accumulator, WTF::IntHash<uint8_t>::hash(static_cast<uint8_t>(argumentTypes[i].kind))); 73 accumulator = WTF::pairIntHash(accumulator, WTF::IntHash<uint8_t>::hash(static_cast<uint8_t>(argumentTypes[i].nullable))); 73 74 accumulator = WTF::pairIntHash(accumulator, WTF::IntHash<unsigned>::hash(argumentTypes[i].index)); 74 75 } 75 76 for (uint32_t i = 0; i < returnCount; ++i) { 76 77 accumulator = WTF::pairIntHash(accumulator, WTF::IntHash<uint8_t>::hash(static_cast<uint8_t>(returnTypes[i].kind))); 78 accumulator = WTF::pairIntHash(accumulator, WTF::IntHash<uint8_t>::hash(static_cast<uint8_t>(returnTypes[i].nullable))); 77 79 accumulator = WTF::pairIntHash(accumulator, WTF::IntHash<unsigned>::hash(returnTypes[i].index)); 78 80 } -
trunk/Source/JavaScriptCore/wasm/generateWasmOpsHeader.py
r273962 r279265 213 213 #undef CREATE_ENUM_VALUE 214 214 215 enum class Nullable : bool { 216 No = false, 217 Yes = true, 218 }; 219 215 220 using SignatureIndex = uintptr_t; 216 221 217 222 struct Type { 218 223 TypeKind kind; 224 Nullable nullable; 219 225 SignatureIndex index; 220 226 221 227 bool operator==(const Type& other) const 222 228 { 223 return other.kind == kind && other. index == index;229 return other.kind == kind && other.nullable == nullable && other.index == index; 224 230 } 225 231 … … 229 235 } 230 236 237 bool isNullable() const 238 { 239 return static_cast<bool>(nullable); 240 } 241 231 242 #define CREATE_PREDICATE(name, ...) bool is ## name() const { return kind == TypeKind::name; } 232 243 FOR_EACH_WASM_TYPE(CREATE_PREDICATE) … … 236 247 namespace Types 237 248 { 238 #define CREATE_CONSTANT(name, id, ...) constexpr Type name = Type{TypeKind::name, 0u};249 #define CREATE_CONSTANT(name, id, ...) constexpr Type name = Type{TypeKind::name, Nullable::Yes, 0u}; 239 250 FOR_EACH_WASM_TYPE(CREATE_CONSTANT) 240 251 #undef CREATE_CONSTANT -
trunk/Source/JavaScriptCore/wasm/js/WasmToJS.cpp
r277928 r279265 105 105 case TypeKind::Void: 106 106 case TypeKind::Func: 107 case TypeKind::RefNull: 108 case TypeKind::Ref: 107 109 RELEASE_ASSERT_NOT_REACHED(); // Handled above. 108 110 case TypeKind::TypeIdx: … … 178 180 case TypeKind::Void: 179 181 case TypeKind::Func: 182 case TypeKind::RefNull: 183 case TypeKind::Ref: 180 184 RELEASE_ASSERT_NOT_REACHED(); // Handled above. 181 185 case TypeKind::TypeIdx: … … 279 283 case TypeKind::Void: 280 284 case TypeKind::Func: 285 case TypeKind::RefNull: 286 case TypeKind::Ref: 281 287 // For the JavaScript embedding, imports with these types in their signature return are a WebAssembly.Module validation error. 282 288 RELEASE_ASSERT_NOT_REACHED(); -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp
r278253 r279265 86 86 case Wasm::TypeKind::TypeIdx: 87 87 case Wasm::TypeKind::Funcref: { 88 if (!isWebAssemblyHostFunction(vm, arg) && !arg.isNull()) 88 bool isNullable = signature.argument(argIndex).isNullable(); 89 WebAssemblyFunction* wasmFunction = nullptr; 90 WebAssemblyWrapperFunction* wasmWrapperFunction = nullptr; 91 if (!isWebAssemblyHostFunction(vm, arg, wasmFunction, wasmWrapperFunction) && (!isNullable || !arg.isNull())) 89 92 return JSValue::encode(throwException(globalObject, scope, createJSWebAssemblyRuntimeError(globalObject, vm, "Funcref must be an exported wasm function"))); 93 if (signature.argument(argIndex).kind == Wasm::TypeKind::TypeIdx && (wasmFunction || wasmWrapperFunction)) { 94 Wasm::SignatureIndex paramIndex = signature.argument(argIndex).index; 95 Wasm::SignatureIndex argIndex; 96 if (wasmFunction) 97 argIndex = wasmFunction->signatureIndex(); 98 else 99 argIndex = wasmWrapperFunction->signatureIndex(); 100 if (paramIndex != argIndex) 101 return JSValue::encode(throwException(globalObject, scope, createJSWebAssemblyRuntimeError(globalObject, vm, "Argument function did not match the reference type"))); 102 } 90 103 break; 91 104 } 92 105 case Wasm::TypeKind::Externref: 106 if (!signature.argument(argIndex).isNullable() && arg.isNull()) 107 return JSValue::encode(throwException(globalObject, scope, createJSWebAssemblyRuntimeError(globalObject, vm, "Non-null Externref cannot be null"))); 93 108 break; 94 109 case Wasm::TypeKind::I64: … … 103 118 case Wasm::TypeKind::Void: 104 119 case Wasm::TypeKind::Func: 120 case Wasm::TypeKind::RefNull: 121 case Wasm::TypeKind::Ref: 105 122 RELEASE_ASSERT_NOT_REACHED(); 106 123 } … … 278 295 break; 279 296 } 297 case Wasm::TypeKind::TypeIdx: 280 298 case Wasm::TypeKind::Funcref: { 281 299 // Ensure we have a WASM exported function. 282 300 jit.load64(jsParam, scratchGPR); 283 301 auto isNull = jit.branchIfNull(scratchGPR); 302 if (!type.isNullable()) 303 slowPath.append(isNull); 284 304 slowPath.append(jit.branchIfNotCell(scratchGPR)); 285 305 … … 295 315 296 316 isWasmFunction.link(&jit); 297 isNull.link(&jit); 317 if (type.kind == Wasm::TypeKind::TypeIdx) { 318 jit.load64(jsParam, scratchGPR); 319 jit.loadPtr(CCallHelpers::Address(scratchGPR, WebAssemblyFunctionBase::offsetOfSignatureIndex()), scratchGPR); 320 slowPath.append(jit.branchPtr(CCallHelpers::NotEqual, scratchGPR, CCallHelpers::TrustedImmPtr(type.index))); 321 } 322 323 if (type.isNullable()) 324 isNull.link(&jit); 298 325 FALLTHROUGH; 299 326 } … … 301 328 if (isStack) { 302 329 jit.load64(jsParam, scratchGPR); 330 if (!type.isNullable()) 331 slowPath.append(jit.branchIfNull(scratchGPR)); 303 332 jit.store64(scratchGPR, calleeFrame.withOffset(wasmCallInfo.params[i].offsetFromSP())); 304 } else 305 jit.load64(jsParam, wasmCallInfo.params[i].gpr()); 333 } else { 334 auto externGPR = wasmCallInfo.params[i].gpr(); 335 jit.load64(jsParam, externGPR); 336 if (!type.isNullable()) 337 slowPath.append(jit.branchIfNull(externGPR)); 338 } 306 339 break; 307 340 } -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunctionBase.h
r277648 r279265 53 53 static ptrdiff_t offsetOfInstance() { return OBJECT_OFFSETOF(WebAssemblyFunctionBase, m_instance); } 54 54 55 static ptrdiff_t offsetOfSignatureIndex() { return OBJECT_OFFSETOF(WebAssemblyFunctionBase, m_importableFunction) + WasmToWasmImportableFunction::offsetOfSignatureIndex(); } 56 55 57 static ptrdiff_t offsetOfEntrypointLoadLocation() { return OBJECT_OFFSETOF(WebAssemblyFunctionBase, m_importableFunction) + WasmToWasmImportableFunction::offsetOfEntrypointLoadLocation(); } 56 58 -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp
r278253 r279265 248 248 return exception(createJSWebAssemblyLinkError(globalObject, vm, importFailMessage(import, "imported global", "must be a same mutability"))); 249 249 switch (moduleInformation.globals[import.kindIndex].type.kind) { 250 case Wasm::TypeKind::Funcref: 250 case Wasm::TypeKind::TypeIdx: 251 case Wasm::TypeKind::Funcref: { 252 bool isNullable = global.type.isNullable(); 253 WebAssemblyFunction* wasmFunction = nullptr; 254 WebAssemblyWrapperFunction* wasmWrapperFunction = nullptr; 251 255 value = globalValue->global()->get(globalObject); 252 256 RETURN_IF_EXCEPTION(scope, void()); 253 if (!isWebAssemblyHostFunction(vm, value) && !value.isNull()) 254 return exception(createJSWebAssemblyLinkError(globalObject, vm, importFailMessage(import, "imported global", "must be a wasm exported function or null"))); 257 if (!isWebAssemblyHostFunction(vm, value, wasmFunction, wasmWrapperFunction) && (!isNullable || !value.isNull())) { 258 const char* msg = isNullable ? "must be a wasm exported function or null" : "must be a wasm exported function"; 259 return exception(createJSWebAssemblyLinkError(globalObject, vm, importFailMessage(import, "imported global", msg))); 260 } 261 if (global.type.kind == Wasm::TypeKind::TypeIdx && (wasmFunction || wasmWrapperFunction)) { 262 Wasm::SignatureIndex paramIndex = global.type.index; 263 Wasm::SignatureIndex argIndex; 264 if (wasmFunction) 265 argIndex = wasmFunction->signatureIndex(); 266 else 267 argIndex = wasmWrapperFunction->signatureIndex(); 268 if (paramIndex != argIndex) 269 return exception(createJSWebAssemblyLinkError(globalObject, vm, importFailMessage(import, "imported global", "Argument function did not match the reference type"))); 270 } 255 271 m_instance->instance().setGlobal(import.kindIndex, value); 256 272 break; 273 } 257 274 case Wasm::TypeKind::Externref: 258 275 value = globalValue->global()->get(globalObject); 259 276 RETURN_IF_EXCEPTION(scope, void()); 277 if (!global.type.isNullable() && value.isNull()) 278 return exception(createJSWebAssemblyLinkError(globalObject, vm, importFailMessage(import, "imported global", "non-null externref cannot be null"))); 260 279 m_instance->instance().setGlobal(import.kindIndex, value); 261 280 break; … … 284 303 // iii. Append ToWebAssemblyValue(v) to imports. 285 304 switch (globalType.kind) { 286 case Wasm::TypeKind::Funcref: 287 if (!isWebAssemblyHostFunction(vm, value) && !value.isNull()) 288 return exception(createJSWebAssemblyLinkError(globalObject, vm, importFailMessage(import, "imported global", "must be a wasm exported function or null"))); 305 case Wasm::TypeKind::TypeIdx: 306 case Wasm::TypeKind::Funcref: { 307 bool isNullable = globalType.isNullable(); 308 WebAssemblyFunction* wasmFunction = nullptr; 309 WebAssemblyWrapperFunction* wasmWrapperFunction = nullptr; 310 if (!isWebAssemblyHostFunction(vm, value, wasmFunction, wasmWrapperFunction) && (!isNullable || !value.isNull())) { 311 const char* msg = isNullable ? "must be a wasm exported function or null" : "must be a wasm exported function"; 312 return exception(createJSWebAssemblyLinkError(globalObject, vm, importFailMessage(import, "imported global", msg))); 313 } 314 if (globalType.kind == Wasm::TypeKind::TypeIdx && (wasmFunction || wasmWrapperFunction)) { 315 Wasm::SignatureIndex paramIndex = global.type.index; 316 Wasm::SignatureIndex argIndex; 317 if (wasmFunction) 318 argIndex = wasmFunction->signatureIndex(); 319 else 320 argIndex = wasmWrapperFunction->signatureIndex(); 321 if (paramIndex != argIndex) 322 return exception(createJSWebAssemblyLinkError(globalObject, vm, importFailMessage(import, "imported global", "Argument function did not match the reference type"))); 323 } 289 324 m_instance->instance().setGlobal(import.kindIndex, value); 290 325 break; 326 } 291 327 case Wasm::TypeKind::Externref: 328 if (!globalType.isNullable() && value.isNull()) 329 return exception(createJSWebAssemblyLinkError(globalObject, vm, importFailMessage(import, "imported global", "must be a non-null value"))); 292 330 m_instance->instance().setGlobal(import.kindIndex, value); 293 331 break; … … 491 529 case Wasm::TypeKind::Externref: 492 530 case Wasm::TypeKind::Funcref: 531 case Wasm::TypeKind::TypeIdx: 493 532 case Wasm::TypeKind::I32: 494 533 case Wasm::TypeKind::I64: -
trunk/Source/JavaScriptCore/wasm/wasm.json
r276896 r279265 14 14 "funcref": { "type": "varint7", "value": -16, "b3type": "B3::Int64" }, 15 15 "externref": { "type": "varint7", "value": -17, "b3type": "B3::Int64" }, 16 "ref_null": { "type": "varint7", "value": -20, "b3type": "B3::Int64" }, 17 "ref": { "type": "varint7", "value": -21, "b3type": "B3::Int64" }, 16 18 "func": { "type": "varint7", "value": -32, "b3type": "B3::Void" }, 17 19 "void": { "type": "varint7", "value": -64, "b3type": "B3::Void" },
Note: See TracChangeset
for help on using the changeset viewer.