mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 00:42:44 +00:00 
			
		
		
		
	Meta: Generate bigint values for v128 constants in Wasm tests
This commit is contained in:
		
							parent
							
								
									2462064fcd
								
							
						
					
					
						commit
						5f013e5374
					
				
					 2 changed files with 93 additions and 3 deletions
				
			
		|  | @ -8,6 +8,7 @@ import math | |||
| from tempfile import NamedTemporaryFile | ||||
| from subprocess import call | ||||
| import json | ||||
| import array | ||||
| 
 | ||||
| atom_end = set('()"' + whitespace) | ||||
| 
 | ||||
|  | @ -61,8 +62,89 @@ def parse_typed_value(ast): | |||
|         'i64.const': 'i64', | ||||
|         'f32.const': 'float', | ||||
|         'f64.const': 'double', | ||||
|         'v128.const': 'bigint', | ||||
|     } | ||||
|     if len(ast) == 2 and ast[0][0] in types: | ||||
| 
 | ||||
|     v128_sizes = { | ||||
|         'i8x16': 1, | ||||
|         'i16x8': 2, | ||||
|         'i32x4': 4, | ||||
|         'i64x2': 8, | ||||
|         'f32x4': 4, | ||||
|         'f64x2': 8, | ||||
|     } | ||||
|     v128_format_names = { | ||||
|         'i8x16': 'b', | ||||
|         'i16x8': 'h', | ||||
|         'i32x4': 'i', | ||||
|         'i64x2': 'q', | ||||
|         'f32x4': 'f', | ||||
|         'f64x2': 'd', | ||||
|     } | ||||
|     v128_format_names_unsigned = { | ||||
|         'i8x16': 'B', | ||||
|         'i16x8': 'H', | ||||
|         'i32x4': 'I', | ||||
|         'i64x2': 'Q', | ||||
|     } | ||||
| 
 | ||||
|     def parse_v128_chunk(num, type) -> array: | ||||
|         negative = 1 | ||||
|         if num.startswith('-'): | ||||
|             negative = -1 | ||||
|             num = num[1:] | ||||
|         elif num.startswith('+'): | ||||
|             num = num[1:] | ||||
| 
 | ||||
|         # wtf spec test, split your wast tests already | ||||
|         while num.startswith('0') and not num.startswith('0x'): | ||||
|             num = num[1:] | ||||
| 
 | ||||
|         if num == '': | ||||
|             num = '0' | ||||
| 
 | ||||
|         if type.startswith('f'): | ||||
|             def generate(): | ||||
|                 if num == 'nan:canonical': | ||||
|                     return float.fromhex('0x7fc00000') | ||||
|                 if num == 'nan:arithmetic': | ||||
|                     return float.fromhex('0x7ff00000') | ||||
|                 if num == 'nan:signaling': | ||||
|                     return float.fromhex('0x7ff80000') | ||||
|                 if num.startswith('nan:'): | ||||
|                     # FIXME: I have no idea if this is actually correct :P | ||||
|                     rest = num[4:] | ||||
|                     return float.fromhex('0x7ff80000') + int(rest, base=16) | ||||
|                 if num.lower() == 'infinity': | ||||
|                     return float.fromhex('0x7ff00000') * negative | ||||
|                 try: | ||||
|                     return float(num) * negative | ||||
|                 except ValueError: | ||||
|                     return float.fromhex(num) * negative | ||||
| 
 | ||||
|             value = generate() | ||||
|             return struct.pack(f'={v128_format_names[type]}', value) | ||||
|         value = negative * int(num.replace('_', ''), base=0) | ||||
|         try: | ||||
|             return struct.pack(f'={v128_format_names[type]}', value) | ||||
|         except struct.error: | ||||
|             # The test format uses signed and unsigned values interchangeably, this is probably an unsigned value. | ||||
|             return struct.pack(f'={v128_format_names_unsigned[type]}', value) | ||||
| 
 | ||||
|     if len(ast) >= 2 and ast[0][0] in types: | ||||
|         if ast[0][0] == 'v128.const': | ||||
|             value = array.array('b') | ||||
|             for i, num in enumerate(ast[2:]): | ||||
|                 size = v128_sizes[ast[1][0]] | ||||
|                 s = len(value) | ||||
|                 value.frombytes(parse_v128_chunk(num[0], ast[1][0])) | ||||
|                 assert len(value) - s == size, f'Expected {size} bytes, got {len(value) - s} bytes' | ||||
| 
 | ||||
|             return { | ||||
|                 'type': types[ast[0][0]], | ||||
|                 'value': value.tobytes().hex() | ||||
|             } | ||||
| 
 | ||||
|         return {"type": types[ast[0][0]], "value": ast[1][0]} | ||||
| 
 | ||||
|     return {"type": "error"} | ||||
|  | @ -285,6 +367,9 @@ def genarg(spec): | |||
| 
 | ||||
|     def gen(): | ||||
|         x = spec['value'] | ||||
|         if spec['type'] == 'bigint': | ||||
|             return f"0x{x}n" | ||||
| 
 | ||||
|         if spec['type'] in ('i32', 'i64'): | ||||
|             if x.startswith('0x'): | ||||
|                 if spec['type'] == 'i32': | ||||
|  |  | |||
|  | @ -235,7 +235,9 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::wasm_invoke) | |||
|             } | ||||
| 
 | ||||
|             u128 bits; | ||||
|             (void)argument.as_bigint().big_integer().export_data({ bit_cast<u8*>(&bits), sizeof(bits) }); | ||||
|             (void)argument.as_bigint().big_integer().unsigned_value().export_data({ bit_cast<u8*>(&bits), sizeof(bits) }); | ||||
|             VERIFY(!argument.as_bigint().big_integer().is_negative()); | ||||
| 
 | ||||
|             arguments.append(Wasm::Value(bits)); | ||||
|             break; | ||||
|         } | ||||
|  | @ -269,7 +271,10 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::wasm_invoke) | |||
|             [](auto const& value) { return JS::Value(static_cast<double>(value)); }, | ||||
|             [](i32 value) { return JS::Value(static_cast<double>(value)); }, | ||||
|             [&](i64 value) { return JS::Value(JS::BigInt::create(vm, Crypto::SignedBigInteger { value })); }, | ||||
|             [&](u128 value) { return JS::Value(JS::BigInt::create(vm, Crypto::SignedBigInteger::import_data(bit_cast<u8 const*>(&value), sizeof(value)))); }, | ||||
|             [&](u128 value) { | ||||
|                 auto unsigned_bigint_value = Crypto::UnsignedBigInteger::import_data(bit_cast<u8 const*>(&value), sizeof(value)); | ||||
|                 return JS::Value(JS::BigInt::create(vm, Crypto::SignedBigInteger(move(unsigned_bigint_value), false))); | ||||
|             }, | ||||
|             [](Wasm::Reference const& reference) { | ||||
|                 return reference.ref().visit( | ||||
|                     [](const Wasm::Reference::Null&) { return JS::js_null(); }, | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Ali Mohammad Pur
						Ali Mohammad Pur