MCPcopy Create free account
hub / github.com/WasmEdge/WasmEdge / TEST

Function TEST

test/executor/ExecutorRegressionTest.cpp:530–788  ·  view source on GitHub ↗

Regression test for ref.test on externalized nullable references. The bug: runRefTestOp always created non-nullable types for externalized references (TypeCode::Ref), discarding the original nullability info. The fix preserves nullability by checking isNullableRefType(). This test exercises the externalized reference code path in ref.test via the extern.convert_any + ref.test pattern, verifying

Source from the content-addressed store, hash-verified

528/// both nullable and non-nullable ref.test targets, as well as null and
529/// non-null input values.
530TEST(ExecutorRegression, RefTestNullAbility) {
531 WasmEdge::Configure Conf;
532 WasmEdge::VM::VM VM(Conf);
533
534 ASSERT_TRUE(VM.loadWasm(RefTestNullabilityWasm));
535 ASSERT_TRUE(VM.validate());
536 ASSERT_TRUE(VM.instantiate());
537
538 // --- Part 1: Non-null anyref input ---
539 //
540 // When a non-null anyref is externalized via extern.convert_any, the
541 // externalized flag is set on the value. The ref.test instruction must
542 // correctly handle this externalized type when matching against both
543 // nullable and non-nullable extern targets.
544 //
545 // Note: The runtime parameter-pushing code converts non-null nullable refs
546 // to non-nullable before execution. So the externalized type at ref.test
547 // time will be non-nullable. Both ref.test targets should succeed.
548 {
549 int DummyObj = 42;
550 RefVariant AnyRefVal(ValType(TypeCode::RefNull, TypeCode::AnyRef),
551 reinterpret_cast<void *>(&DummyObj));
552
553 std::vector<ValVariant> Params = {ValVariant(AnyRefVal)};
554 std::vector<ValType> ParamTypes = {ValType(TypeCode::AnyRef)};
555
556 // Test 1: extern.convert_any + ref.test (ref null extern)
557 // Non-null externalized ref with non-nullable type should match
558 // nullable extern target.
559 {
560 auto Result = VM.execute("test_nullable", Params, ParamTypes);
561 ASSERT_TRUE(Result);
562 ASSERT_EQ((*Result).size(), 1U);
563 EXPECT_EQ((*Result)[0].first.get<uint32_t>(), 1U)
564 << "Non-null externalized anyref should match (ref null extern)";
565 }
566
567 // Test 2: extern.convert_any + ref.test (ref extern)
568 // Non-null externalized ref with non-nullable type should also match
569 // non-nullable extern target (the externalized type is (ref extern)
570 // because the runtime made it non-nullable before execution).
571 {
572 auto Result = VM.execute("test_nonnull", Params, ParamTypes);
573 ASSERT_TRUE(Result);
574 ASSERT_EQ((*Result).size(), 1U);
575 EXPECT_EQ((*Result)[0].first.get<uint32_t>(), 1U)
576 << "Non-null externalized anyref should match (ref extern)";
577 }
578 }
579
580 // --- Part 2: Null anyref input ---
581 //
582 // When a null anyref is externalized, extern.convert_any creates a new
583 // RefVariant with type (ref null noextern) without setting the externalized
584 // flag. ref.test follows the normal (non-externalized) code path.
585 // A null value should match nullable target but not non-nullable.
586 {
587 RefVariant NullAnyRef(ValType(TypeCode::RefNull, TypeCode::NullRef));

Callers

nothing calls this directly

Calls 12

ValTypeClass · 0.85
checkNullTableEntryFunction · 0.85
loadWasmMethod · 0.80
setExternalizedMethod · 0.80
isExternalizedMethod · 0.80
isNullableRefTypeMethod · 0.80
validateMethod · 0.45
instantiateMethod · 0.45
executeMethod · 0.45
sizeMethod · 0.45
registerModuleMethod · 0.45
getValuesMethod · 0.45

Tested by

no test coverage detected