diff --git a/includes/type/leb128.pat b/includes/type/leb128.pat index 4a50f17..7231c19 100644 --- a/includes/type/leb128.pat +++ b/includes/type/leb128.pat @@ -5,29 +5,51 @@ namespace type { - struct LEB128 { + struct _LEB128 { u8 array[while($ == addressof(this) || std::mem::read_unsigned($-1, 1) & 0x80 != 0)] [[hidden]]; - } [[sealed, format("type::impl::format_leb128"), transform("type::impl::transform_leb128")]]; + } [[sealed]]; + + using uLEB128 = _LEB128 [[format("type::impl::format_uleb128"), transform("type::impl::transform_uleb128")]]; + using sLEB128 = _LEB128 [[format("type::impl::format_sleb128"), transform("type::impl::transform_sleb128")]]; + + using LEB128 = uLEB128; namespace impl { - fn transform_leb128_array(auto array) { + fn transform_uleb128_array(auto array) { u128 res = array[0] & 0x7f; for(u8 i = 1, array[i-1] & 0x80 != 0, i+=1) { - res |= u64(array[i] & 0x7f) << 7 * i; + res |= u128(array[i] & 0x7f) << 7 * i; + } + return res; + }; + + fn transform_sleb128_array(auto array) { + s128 res = type::impl::transform_uleb128_array(array); + if (res & 0x40 != 0) { + res |= ~0 << (sizeof(array) / sizeof(u8)) * 7; } return res; }; - fn format_leb128(auto leb128) { - u128 res = type::impl::transform_leb128_array(leb128.array); + fn format_uleb128(auto leb128) { + u128 res = type::impl::transform_uleb128_array(leb128.array); return std::format("{} ({:#x})", res, res); }; - fn transform_leb128(auto leb128) { - return type::impl::transform_leb128_array(leb128.array); + fn transform_uleb128(auto leb128) { + return type::impl::transform_uleb128_array(leb128.array); }; + + fn format_sleb128(auto leb128) { + s128 res = type::impl::transform_sleb128_array(leb128.array); + return std::format("{} ({:#x})", res, res); + }; + + fn transform_sleb128(auto leb128) { + return type::impl::transform_sleb128_array(leb128.array); + }; + } } -