Files
hakorune/tests/wasm_string_constants.rs
Moe Charm bab57e7c07 🎉 feat: ChatGPT5による奇跡の全テスト修復完了!
- instance_v2移行で破綻していた440個のテストを30分で全修正
- git巻き戻しレベルの状況から完全復活
- 人間には不可能な速度での大規模整合性修正

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-20 04:45:26 +09:00

166 lines
5.9 KiB
Rust

#![cfg(feature = "wasm-backend")]
/*!
* WASM String Constants Test - Validates Issue #65 implementation
*
* Tests string constant support in WASM backend:
* - ConstValue::String handling in generate_const
* - Data segment generation for string literals
* - StringBox creation with proper layout
* - WAT generation includes data segments and string allocation
*/
use nyash_rust::mir::{
MirModule, MirFunction, FunctionSignature, MirType, EffectMask,
BasicBlock, BasicBlockId, ValueId, MirInstruction, ConstValue
};
use nyash_rust::backend::wasm::WasmBackend;
#[test]
fn test_wasm_string_constant_basic() {
// Build MIR equivalent to:
// function main() {
// %str = const "Hello, WASM!"
// return %str // Should return StringBox pointer
// }
let mut backend = WasmBackend::new();
let mir_module = build_string_const_mir_module();
// Generate WAT text for debugging
let wat_result = backend.compile_to_wat(mir_module.clone());
assert!(wat_result.is_ok(), "WAT generation should succeed for string constants");
let wat_text = wat_result.unwrap();
// Verify WAT contains expected elements for string support
assert!(wat_text.contains("(module"), "Should contain module declaration");
assert!(wat_text.contains("memory"), "Should contain memory declaration");
assert!(wat_text.contains("data"), "Should contain data segment for string literal");
assert!(wat_text.contains("\\48\\65\\6c\\6c\\6f"), "Should contain UTF-8 bytes for 'Hello'");
assert!(wat_text.contains("$alloc_stringbox"), "Should contain StringBox allocator");
assert!(wat_text.contains("print_str"), "Should contain print_str import");
// Verify string literal is properly embedded
// (The assertion for UTF-8 bytes is above)
// Compile to WASM binary
let wasm_result = backend.compile_module(mir_module);
if let Err(e) = &wasm_result {
println!("WASM compilation error: {}", e);
println!("Generated WAT:\n{}", wat_text);
}
assert!(wasm_result.is_ok(), "WASM compilation should succeed for string constants");
}
#[test]
fn test_wasm_string_constant_multiple() {
// Test multiple string constants to verify data segment management
// function main() {
// %str1 = const "First"
// %str2 = const "Second"
// %str3 = const "First" // Duplicate should reuse data segment
// return %str1
// }
let mut backend = WasmBackend::new();
let mir_module = build_multiple_string_const_mir_module();
let wat_result = backend.compile_to_wat(mir_module.clone());
assert!(wat_result.is_ok(), "WAT generation should succeed for multiple strings");
let wat_text = wat_result.unwrap();
// Should contain both unique strings (in hex format)
assert!(wat_text.contains("\\46\\69\\72\\73\\74"), "Should contain 'First' string in hex");
assert!(wat_text.contains("\\53\\65\\63\\6f\\6e\\64"), "Should contain 'Second' string in hex");
// Should have 2 data segments (First and Second, duplicate First reused)
let data_count = wat_text.matches("(data").count();
assert_eq!(data_count, 2, "Should have exactly 2 data segments for 2 unique strings");
let wasm_result = backend.compile_module(mir_module);
assert!(wasm_result.is_ok(), "WASM compilation should succeed for multiple strings");
}
/// Build a MIR module with a single string constant
fn build_string_const_mir_module() -> MirModule {
let mut module = MirModule::new("test_string_const".to_string());
// Create main function signature
let main_signature = FunctionSignature {
name: "main".to_string(),
params: vec![],
return_type: MirType::Integer, // StringBox pointer as i32
effects: EffectMask::PURE,
};
// Create basic block
let entry_block = BasicBlockId::new(0);
let mut main_function = MirFunction::new(main_signature, entry_block);
let mut block = BasicBlock::new(entry_block);
// %str = const "Hello, WASM!"
let str_value = ValueId::new(0);
block.instructions.push(MirInstruction::Const {
dst: str_value,
value: ConstValue::String("Hello, WASM!".to_string()),
});
// return %str
block.terminator = Some(MirInstruction::Return {
value: Some(str_value),
});
main_function.blocks.insert(entry_block, block);
module.functions.insert("main".to_string(), main_function);
module
}
/// Build a MIR module with multiple string constants
fn build_multiple_string_const_mir_module() -> MirModule {
let mut module = MirModule::new("test_multiple_strings".to_string());
let main_signature = FunctionSignature {
name: "main".to_string(),
params: vec![],
return_type: MirType::Integer,
effects: EffectMask::PURE,
};
let entry_block = BasicBlockId::new(0);
let mut main_function = MirFunction::new(main_signature, entry_block);
let mut block = BasicBlock::new(entry_block);
// %str1 = const "First"
let str1_value = ValueId::new(0);
block.instructions.push(MirInstruction::Const {
dst: str1_value,
value: ConstValue::String("First".to_string()),
});
// %str2 = const "Second"
let str2_value = ValueId::new(1);
block.instructions.push(MirInstruction::Const {
dst: str2_value,
value: ConstValue::String("Second".to_string()),
});
// %str3 = const "First" (duplicate)
let str3_value = ValueId::new(2);
block.instructions.push(MirInstruction::Const {
dst: str3_value,
value: ConstValue::String("First".to_string()),
});
// return %str1
block.terminator = Some(MirInstruction::Return {
value: Some(str1_value),
});
main_function.blocks.insert(entry_block, block);
module.functions.insert("main".to_string(), main_function);
module
}