|
Lines 378-418
auto SectionParser::parseElement() -> PartialResult
a/Source/JavaScriptCore/wasm/WasmSectionParser.cpp_sec1
|
| 378 |
WASM_PARSER_FAIL_IF(elementCount > maxTableEntries, "Element section's count is too big ", elementCount, " maximum ", maxTableEntries); |
378 |
WASM_PARSER_FAIL_IF(elementCount > maxTableEntries, "Element section's count is too big ", elementCount, " maximum ", maxTableEntries); |
| 379 |
WASM_PARSER_FAIL_IF(!m_info->elements.tryReserveCapacity(elementCount), "can't allocate memory for ", elementCount, " Elements"); |
379 |
WASM_PARSER_FAIL_IF(!m_info->elements.tryReserveCapacity(elementCount), "can't allocate memory for ", elementCount, " Elements"); |
| 380 |
for (unsigned elementNum = 0; elementNum < elementCount; ++elementNum) { |
380 |
for (unsigned elementNum = 0; elementNum < elementCount; ++elementNum) { |
| 381 |
uint32_t tableIndex; |
381 |
uint8_t elementFlags; |
| 382 |
uint64_t initExprBits; |
382 |
WASM_PARSER_FAIL_IF(!parseUInt8(elementFlags), "can't get ", elementNum, "th Element reserved byte, which should be element flags"); |
| 383 |
uint8_t initOpcode; |
383 |
|
| 384 |
uint32_t indexCount; |
384 |
switch (elementFlags) { |
|
|
385 |
case 0x00: { |
| 386 |
const uint32_t tableIndex = 0; |
| 387 |
WASM_FAIL_IF_HELPER_FAILS(validateElementTableIdx(tableIndex)); |
| 388 |
|
| 389 |
Optional<I32InitExpr> initExpr; |
| 390 |
WASM_FAIL_IF_HELPER_FAILS(parseI32InitExpr(initExpr)); |
| 391 |
|
| 392 |
uint32_t indexCount; |
| 393 |
WASM_FAIL_IF_HELPER_FAILS(parseIndexCountForElemSection(indexCount, elementNum)); |
| 394 |
ASSERT(!!m_info->tables[tableIndex]); |
| 395 |
|
| 396 |
Element element(Element::Kind::Active, TableElementType::Funcref, tableIndex, WTFMove(initExpr)); |
| 397 |
WASM_PARSER_FAIL_IF(!element.functionIndices.tryReserveCapacity(indexCount), "can't allocate memory for ", indexCount, " Element indices"); |
| 398 |
|
| 399 |
for (uint32_t index = 0; index < indexCount; ++index) { |
| 400 |
Optional<uint32_t> funcIdx; |
| 401 |
WASM_FAIL_IF_HELPER_FAILS(parseFuncIdxForElemSection(funcIdx, elementNum, index)); |
| 402 |
element.functionIndices.uncheckedAppend(WTFMove(funcIdx)); |
| 403 |
} |
| 404 |
|
| 405 |
m_info->elements.uncheckedAppend(WTFMove(element)); |
| 406 |
break; |
| 407 |
} |
| 408 |
case 0x01: { |
| 409 |
WASM_PARSER_FAIL_IF(!Options::useWebAssemblyReferences(), "references are not enabled"); |
| 410 |
uint8_t elemKind; |
| 411 |
WASM_FAIL_IF_HELPER_FAILS(parseElemKind(elemKind)); |
| 412 |
|
| 413 |
uint32_t indexCount; |
| 414 |
WASM_FAIL_IF_HELPER_FAILS(parseIndexCountForElemSection(indexCount, elementNum)); |
| 385 |
|
415 |
|
| 386 |
uint8_t magic; |
416 |
Element element(Element::Kind::Passive, TableElementType::Funcref); |
| 387 |
WASM_PARSER_FAIL_IF(!parseUInt8(magic) || (magic && magic != 2), "can't get ", elementNum, "th Element reserved byte, which should be either 0x00 or 0x02 followed by a table index"); |
417 |
WASM_PARSER_FAIL_IF(!element.functionIndices.tryReserveCapacity(indexCount), "can't allocate memory for ", indexCount, " Element indices"); |
| 388 |
|
418 |
|
| 389 |
if (magic == 2) |
419 |
for (uint32_t index = 0; index < indexCount; ++index) { |
|
|
420 |
Optional<uint32_t> funcIdx; |
| 421 |
WASM_FAIL_IF_HELPER_FAILS(parseFuncIdxForElemSection(funcIdx, elementNum, index)); |
| 422 |
element.functionIndices.uncheckedAppend(WTFMove(funcIdx)); |
| 423 |
} |
| 424 |
|
| 425 |
m_info->elements.uncheckedAppend(WTFMove(element)); |
| 426 |
break; |
| 427 |
} |
| 428 |
case 0x02: { |
| 429 |
uint32_t tableIndex; |
| 390 |
WASM_PARSER_FAIL_IF(!parseVarUInt32(tableIndex), "can't get ", elementNum, "th Element table index"); |
430 |
WASM_PARSER_FAIL_IF(!parseVarUInt32(tableIndex), "can't get ", elementNum, "th Element table index"); |
| 391 |
else |
431 |
WASM_FAIL_IF_HELPER_FAILS(validateElementTableIdx(tableIndex)); |
| 392 |
tableIndex = 0; |
432 |
|
| 393 |
|
433 |
Optional<I32InitExpr> initExpr; |
| 394 |
WASM_PARSER_FAIL_IF(tableIndex >= m_info->tableCount(), "Element section for Table ", tableIndex, " exceeds available Table ", m_info->tableCount()); |
434 |
WASM_FAIL_IF_HELPER_FAILS(parseI32InitExpr(initExpr)); |
| 395 |
WASM_PARSER_FAIL_IF(m_info->tables[tableIndex].type() != TableElementType::Funcref, "Table ", tableIndex, " must have type 'funcref' to have an element section"); |
435 |
|
| 396 |
Type initExprType; |
436 |
uint8_t elemKind; |
| 397 |
WASM_FAIL_IF_HELPER_FAILS(parseInitExpr(initOpcode, initExprBits, initExprType)); |
437 |
WASM_FAIL_IF_HELPER_FAILS(parseElemKind(elemKind)); |
| 398 |
WASM_PARSER_FAIL_IF(initExprType != I32, "Element init_expr must produce an i32"); |
|
|
| 399 |
WASM_PARSER_FAIL_IF(!parseVarUInt32(indexCount), "can't get ", elementNum, "th index count for Element section"); |
| 400 |
WASM_PARSER_FAIL_IF(indexCount == std::numeric_limits<uint32_t>::max(), "Element section's ", elementNum, "th index count is too big ", indexCount); |
| 401 |
|
438 |
|
| 402 |
ASSERT(!!m_info->tables[tableIndex]); |
439 |
uint32_t indexCount; |
|
|
440 |
WASM_FAIL_IF_HELPER_FAILS(parseIndexCountForElemSection(indexCount, elementNum)); |
| 441 |
ASSERT(!!m_info->tables[tableIndex]); |
| 403 |
|
442 |
|
| 404 |
Element element(tableIndex, makeI32InitExpr(initOpcode, initExprBits)); |
443 |
Element element(Element::Kind::Active, TableElementType::Funcref, tableIndex, WTFMove(initExpr)); |
| 405 |
WASM_PARSER_FAIL_IF(!element.functionIndices.tryReserveCapacity(indexCount), "can't allocate memory for ", indexCount, " Element indices"); |
444 |
WASM_PARSER_FAIL_IF(!element.functionIndices.tryReserveCapacity(indexCount), "can't allocate memory for ", indexCount, " Element indices"); |
| 406 |
|
445 |
|
| 407 |
for (unsigned index = 0; index < indexCount; ++index) { |
446 |
for (unsigned index = 0; index < indexCount; ++index) { |
| 408 |
uint32_t functionIndex; |
447 |
Optional<uint32_t> funcIdx; |
| 409 |
WASM_PARSER_FAIL_IF(!parseVarUInt32(functionIndex), "can't get Element section's ", elementNum, "th element's ", index, "th index"); |
448 |
WASM_FAIL_IF_HELPER_FAILS(parseFuncIdxForElemSection(funcIdx, elementNum, index)); |
| 410 |
WASM_PARSER_FAIL_IF(functionIndex >= m_info->functionIndexSpaceSize(), "Element section's ", elementNum, "th element's ", index, "th index is ", functionIndex, " which exceeds the function index space size of ", m_info->functionIndexSpaceSize()); |
449 |
element.functionIndices.uncheckedAppend(WTFMove(funcIdx)); |
|
|
450 |
} |
| 411 |
|
451 |
|
| 412 |
element.functionIndices.uncheckedAppend(functionIndex); |
452 |
m_info->elements.uncheckedAppend(WTFMove(element)); |
|
|
453 |
break; |
| 413 |
} |
454 |
} |
|
|
455 |
case 0x03: { |
| 456 |
WASM_PARSER_FAIL_IF(!Options::useWebAssemblyReferences(), "references are not enabled"); |
| 457 |
WASM_PARSER_FAIL_IF(true, "unsupported ", elementNum, "th Element reserved byte"); |
| 458 |
break; |
| 459 |
} |
| 460 |
case 0x04: { |
| 461 |
WASM_PARSER_FAIL_IF(!Options::useWebAssemblyReferences(), "references are not enabled"); |
| 462 |
|
| 463 |
const uint32_t tableIndex = 0; |
| 464 |
WASM_FAIL_IF_HELPER_FAILS(validateElementTableIdx(tableIndex)); |
| 465 |
|
| 466 |
Optional<I32InitExpr> initExpr; |
| 467 |
WASM_FAIL_IF_HELPER_FAILS(parseI32InitExpr(initExpr)); |
| 468 |
|
| 469 |
uint32_t indexCount; |
| 470 |
WASM_FAIL_IF_HELPER_FAILS(parseIndexCountForElemSection(indexCount, elementNum)); |
| 471 |
ASSERT(!!m_info->tables[tableIndex]); |
| 472 |
|
| 473 |
Element element(Element::Kind::Active, TableElementType::Funcref, tableIndex, WTFMove(initExpr)); |
| 474 |
WASM_PARSER_FAIL_IF(!element.functionIndices.tryReserveCapacity(indexCount), "can't allocate memory for ", indexCount, " Element indices"); |
| 475 |
|
| 476 |
for (unsigned index = 0; index < indexCount; ++index) { |
| 477 |
Optional<uint32_t> funcIdx; |
| 478 |
WASM_FAIL_IF_HELPER_FAILS(parseFuncIdxFromRefExpForElemSection(funcIdx, elementNum, index)); |
| 479 |
element.functionIndices.uncheckedAppend(WTFMove(funcIdx)); |
| 480 |
} |
| 481 |
|
| 482 |
m_info->elements.uncheckedAppend(WTFMove(element)); |
| 483 |
break; |
| 484 |
} |
| 485 |
case 0x05: { |
| 486 |
WASM_PARSER_FAIL_IF(!Options::useWebAssemblyReferences(), "references are not enabled"); |
| 487 |
Type refType; |
| 488 |
WASM_PARSER_FAIL_IF(!parseRefType(refType), "can't parse reftype in elem section"); |
| 489 |
WASM_PARSER_FAIL_IF(refType == Externref, "reftype in element section should be funcref"); |
| 490 |
|
| 491 |
uint32_t indexCount; |
| 492 |
WASM_FAIL_IF_HELPER_FAILS(parseIndexCountForElemSection(indexCount, elementNum)); |
| 493 |
|
| 494 |
Element element(Element::Kind::Passive, TableElementType::Funcref); |
| 495 |
WASM_PARSER_FAIL_IF(!element.functionIndices.tryReserveCapacity(indexCount), "can't allocate memory for ", indexCount, " Element indices"); |
| 496 |
|
| 497 |
for (unsigned index = 0; index < indexCount; ++index) { |
| 498 |
Optional<uint32_t> funcIdx; |
| 499 |
WASM_FAIL_IF_HELPER_FAILS(parseFuncIdxFromRefExpForElemSection(funcIdx, elementNum, index)); |
| 500 |
element.functionIndices.uncheckedAppend(WTFMove(funcIdx)); |
| 501 |
} |
| 502 |
|
| 503 |
m_info->elements.uncheckedAppend(WTFMove(element)); |
| 504 |
break; |
| 505 |
} |
| 506 |
case 0x06: { |
| 507 |
WASM_PARSER_FAIL_IF(!Options::useWebAssemblyReferences(), "references are not enabled"); |
| 508 |
|
| 509 |
uint32_t tableIndex; |
| 510 |
WASM_PARSER_FAIL_IF(!parseVarUInt32(tableIndex), "can't get ", elementNum, "th Element table index"); |
| 511 |
WASM_FAIL_IF_HELPER_FAILS(validateElementTableIdx(tableIndex)); |
| 512 |
|
| 513 |
Optional<I32InitExpr> initExpr; |
| 514 |
WASM_FAIL_IF_HELPER_FAILS(parseI32InitExpr(initExpr)); |
| 515 |
|
| 516 |
Type refType; |
| 517 |
WASM_PARSER_FAIL_IF(!parseRefType(refType), "can't parse reftype in elem section"); |
| 518 |
WASM_PARSER_FAIL_IF(refType == Externref, "reftype in element section should be funcref"); |
| 519 |
|
| 520 |
uint32_t indexCount; |
| 521 |
WASM_FAIL_IF_HELPER_FAILS(parseIndexCountForElemSection(indexCount, elementNum)); |
| 522 |
ASSERT(!!m_info->tables[tableIndex]); |
| 414 |
|
523 |
|
| 415 |
m_info->elements.uncheckedAppend(WTFMove(element)); |
524 |
Element element(Element::Kind::Active, TableElementType::Funcref, tableIndex, WTFMove(initExpr)); |
|
|
525 |
WASM_PARSER_FAIL_IF(!element.functionIndices.tryReserveCapacity(indexCount), "can't allocate memory for ", indexCount, " Element indices"); |
| 526 |
|
| 527 |
for (unsigned index = 0; index < indexCount; ++index) { |
| 528 |
Optional<uint32_t> funcIdx; |
| 529 |
WASM_FAIL_IF_HELPER_FAILS(parseFuncIdxFromRefExpForElemSection(funcIdx, elementNum, index)); |
| 530 |
element.functionIndices.uncheckedAppend(WTFMove(funcIdx)); |
| 531 |
} |
| 532 |
|
| 533 |
m_info->elements.uncheckedAppend(WTFMove(element)); |
| 534 |
break; |
| 535 |
} |
| 536 |
case 0x07: { |
| 537 |
WASM_PARSER_FAIL_IF(!Options::useWebAssemblyReferences(), "references are not enabled"); |
| 538 |
WASM_PARSER_FAIL_IF(true, "unsupported ", elementNum, "th Element reserved byte"); |
| 539 |
break; |
| 540 |
} |
| 541 |
default: |
| 542 |
WASM_PARSER_FAIL_IF(true, "can't get ", elementNum, "th Element reserved byte"); |
| 543 |
} |
| 416 |
} |
544 |
} |
| 417 |
|
545 |
|
| 418 |
return { }; |
546 |
return { }; |
|
Lines 504-509
auto SectionParser::parseInitExpr(uint8_t& opcode, uint64_t& bitsOrImportNumber,
a/Source/JavaScriptCore/wasm/WasmSectionParser.cpp_sec2
|
| 504 |
return { }; |
632 |
return { }; |
| 505 |
} |
633 |
} |
| 506 |
|
634 |
|
|
|
635 |
auto SectionParser::validateElementTableIdx(uint32_t tableIndex) -> PartialResult |
| 636 |
{ |
| 637 |
WASM_PARSER_FAIL_IF(tableIndex >= m_info->tableCount(), "Element section for Table ", tableIndex, " exceeds available Table ", m_info->tableCount()); |
| 638 |
WASM_PARSER_FAIL_IF(m_info->tables[tableIndex].type() != TableElementType::Funcref, "Table ", tableIndex, " must have type 'funcref' to have an element section"); |
| 639 |
|
| 640 |
return { }; |
| 641 |
} |
| 642 |
|
| 643 |
auto SectionParser::parseI32InitExpr(Optional<I32InitExpr>& initExpr) -> PartialResult |
| 644 |
{ |
| 645 |
uint8_t initOpcode; |
| 646 |
uint64_t initExprBits; |
| 647 |
Type initExprType; |
| 648 |
WASM_FAIL_IF_HELPER_FAILS(parseInitExpr(initOpcode, initExprBits, initExprType)); |
| 649 |
WASM_PARSER_FAIL_IF(initExprType != I32, "Element init_expr must produce an i32"); |
| 650 |
initExpr = makeI32InitExpr(initOpcode, initExprBits); |
| 651 |
|
| 652 |
return { }; |
| 653 |
} |
| 654 |
|
| 655 |
auto SectionParser::parseElemKind(uint8_t& resultElemKind) -> PartialResult |
| 656 |
{ |
| 657 |
uint8_t elemKind; |
| 658 |
WASM_PARSER_FAIL_IF(!parseUInt8(elemKind), "can't get elemkind"); |
| 659 |
WASM_PARSER_FAIL_IF(!!elemKind, "elemkind must be zero"); |
| 660 |
resultElemKind = elemKind; |
| 661 |
|
| 662 |
return { }; |
| 663 |
} |
| 664 |
|
| 665 |
auto SectionParser::parseIndexCountForElemSection(uint32_t& resultIndexCount, const unsigned elementNum) -> PartialResult |
| 666 |
{ |
| 667 |
uint32_t indexCount; |
| 668 |
WASM_PARSER_FAIL_IF(!parseVarUInt32(indexCount), "can't get ", elementNum, "th index count for Element section"); |
| 669 |
WASM_PARSER_FAIL_IF(indexCount == std::numeric_limits<uint32_t>::max(), "Element section's ", elementNum, "th index count is too big ", indexCount); |
| 670 |
resultIndexCount = indexCount; |
| 671 |
|
| 672 |
return { }; |
| 673 |
} |
| 674 |
|
| 675 |
auto SectionParser::parseFuncIdxFromRefExpForElemSection(Optional<uint32_t>& funcIdx, const unsigned elementNum, const unsigned index) -> PartialResult |
| 676 |
{ |
| 677 |
uint8_t opcode; |
| 678 |
WASM_PARSER_FAIL_IF(!parseUInt8(opcode), "can't get opcode for exp in element section's ", elementNum, "th element's ", index, "th index"); |
| 679 |
WASM_PARSER_FAIL_IF((opcode != RefFunc) && (opcode != RefNull), "opcode for exp in element section's should be either ref.func or ref.null ", elementNum, "th element's ", index, "th index"); |
| 680 |
|
| 681 |
if (opcode == RefFunc) { |
| 682 |
uint32_t functionIndex; |
| 683 |
WASM_PARSER_FAIL_IF(!parseVarUInt32(functionIndex), "can't get Element section's ", elementNum, "th element's ", index, "th index"); |
| 684 |
WASM_PARSER_FAIL_IF(functionIndex >= m_info->functionIndexSpaceSize(), "Element section's ", elementNum, "th element's ", index, "th index is ", functionIndex, " which exceeds the function index space size of ", m_info->functionIndexSpaceSize()); |
| 685 |
funcIdx = functionIndex; |
| 686 |
} else { |
| 687 |
Type typeOfNull; |
| 688 |
WASM_PARSER_FAIL_IF(!parseRefType(typeOfNull), "ref.null type must be a func type in elem section"); |
| 689 |
WASM_PARSER_FAIL_IF(typeOfNull != Funcref, "ref.null extern is forbidden in element section's, ", elementNum, "th element's ", index, "th index"); |
| 690 |
} |
| 691 |
|
| 692 |
WASM_PARSER_FAIL_IF(!parseUInt8(opcode), "can't get opcode for exp end in element section's ", elementNum, "th element's ", index, "th index"); |
| 693 |
WASM_PARSER_FAIL_IF(opcode != End, "malformed expr in element section's", elementNum, "th element's ", index, "th index"); |
| 694 |
|
| 695 |
return { }; |
| 696 |
} |
| 697 |
|
| 698 |
auto SectionParser::parseFuncIdxForElemSection(Optional<uint32_t>& funcIdx, const unsigned elementNum, const unsigned index) -> PartialResult |
| 699 |
{ |
| 700 |
uint32_t functionIndex; |
| 701 |
WASM_PARSER_FAIL_IF(!parseVarUInt32(functionIndex), "can't get Element section's ", elementNum, "th element's ", index, "th index"); |
| 702 |
WASM_PARSER_FAIL_IF(functionIndex >= m_info->functionIndexSpaceSize(), "Element section's ", elementNum, "th element's ", index, "th index is ", functionIndex, " which exceeds the function index space size of ", m_info->functionIndexSpaceSize()); |
| 703 |
funcIdx = functionIndex; |
| 704 |
|
| 705 |
return { }; |
| 706 |
} |
| 707 |
|
| 507 |
auto SectionParser::parseGlobalType(GlobalInformation& global) -> PartialResult |
708 |
auto SectionParser::parseGlobalType(GlobalInformation& global) -> PartialResult |
| 508 |
{ |
709 |
{ |
| 509 |
uint8_t mutability; |
710 |
uint8_t mutability; |