UNPKG

as-soroban-sdk

Version:

AssemblyScript SDK for writing contracts for Soroban.

811 lines (722 loc) 21.5 kB
import {BoolVal, errorCodeArithDomain, errorTypeObject, fromFalse, fromTrue, fromI128Pieces, getErrorCode, getErrorType, isError, isI128Small, fromI128Small, toI128Small, isI128Object, toI128Low64,toI128High64, fromU32} from "../../lib/value"; import { i128Add, i128Compare, i128Div, i128IsEqual, i128IsGreaterThan, i128IsLowerThan, i128Mul, i128MulDiv, i128Pow, i128RemEuclid, i128Shl, i128Shr, i128Sub, isI128Negative } from "../../lib/arithm128"; import * as u128 from "../../lib/u128_math"; export function testI128Add():BoolVal { let falseVal = fromFalse(); // small + small let lhs = fromI128Small(2); let rhs = fromI128Small(2); let res = i128Add(lhs, rhs); if (!isI128Small(res) || toI128Small(res) != 4) { return falseVal; } // small + ( - small) rhs = fromI128Small(-4); res = i128Add(lhs, rhs); if (!isI128Small(res) || toI128Small(res) != -2) { return falseVal; } // (- small) + ( - small) lhs = fromI128Small(-2); rhs = fromI128Small(-4); res = i128Add(lhs, rhs); if (!isI128Small(res) || toI128Small(res) != -6) { return falseVal; } // @ts-ignore const i64Max = i64.MAX_VALUE; // @ts-ignore const u64Max = u64.MAX_VALUE; // small + obj rhs = fromI128Small(2); lhs = fromI128Pieces(i64Max, 10) res = i128Add(lhs, rhs); if (isI128Object(res)) { let lo = toI128Low64(res); let hi = toI128High64(res); if (lo != 12 || hi != i64Max) { return falseVal; } } else { return falseVal; } // - small + obj rhs = fromI128Small(-2); lhs = fromI128Pieces(i64Max, 10) res = i128Add(lhs, rhs); if (isI128Object(res)) { let lo = toI128Low64(res); let hi = toI128High64(res); if (lo != 8 || hi != i64Max) { return falseVal; } } else { return falseVal; } // @ts-ignore const i64Min = i64.MIN_VALUE; // small + -obj rhs = fromI128Small(2); lhs = fromI128Pieces(i64Min, 10) res = i128Add(lhs, rhs); if (isI128Object(res)) { let lo = toI128Low64(res); let hi = toI128High64(res); if (lo != 12 || hi != i64Min) { return falseVal; } } else { return falseVal; } // -small + -obj rhs = fromI128Small(-2); lhs = fromI128Pieces(i64Min, 10) res = i128Add(lhs, rhs); if (isI128Object(res)) { let lo = toI128Low64(res); let hi = toI128High64(res); if (lo != 8 || hi != i64Min) { return falseVal; } } else { return falseVal; } // obj + obj lhs = fromI128Pieces(1, u64Max); rhs = fromI128Pieces(10, 1); res = i128Add(lhs, rhs); if (isI128Object(res)) { let lo = toI128Low64(res); let hi = toI128High64(res); if (lo != 0 || hi != 12) { return falseVal; } } else { return falseVal; } // obj + -obj lhs = fromI128Pieces(1, u64Max); rhs = fromI128Pieces(-10, 1); res = i128Add(lhs, rhs); if (isI128Object(res)) { let lo = toI128Low64(res); let hi = toI128High64(res); if (lo != 0 || hi != -8) { return falseVal; } } else { return falseVal; } // obj + -obj lhs = fromI128Pieces(1, u64Max - 2); rhs = fromI128Pieces(-1, u64Max - 2); res = i128Add(lhs, rhs); if (isI128Object(res)) { let lo = toI128Low64(res); let hi = toI128High64(res); if (lo != u64Max - 5 || hi != 1) { return falseVal; } } else { return falseVal; } // overflow lhs = fromI128Pieces(i64Max, u64Max); res = i128Add(lhs, fromI128Small(1)); if(!isError(res) || getErrorType(res) != errorTypeObject || getErrorCode(res) != errorCodeArithDomain) { return falseVal; } return fromTrue(); } export function testI128Sub():BoolVal { let falseVal = fromFalse(); // small - small let lhs = fromI128Small(4); let rhs = fromI128Small(2); let res = i128Sub(lhs, rhs); if (!isI128Small(res) || toI128Small(res) != 2) { return falseVal; } // small - ( - small) rhs = fromI128Small(-4); res = i128Sub(lhs, rhs); if (!isI128Small(res) || toI128Small(res) != 8) { return falseVal; } // (- small) - ( - small) lhs = fromI128Small(-2); rhs = fromI128Small(-4); res = i128Sub(lhs, rhs); if (!isI128Small(res) || toI128Small(res) != 2) { return falseVal; } // small - small neg res lhs = fromI128Small(4); rhs = fromI128Small(8); res = i128Sub(lhs, rhs); if (!isI128Small(res) || toI128Small(res) != -4) { return falseVal; } // @ts-ignore const i64Max = i64.MAX_VALUE; // obj - small lhs = fromI128Pieces(i64Max, 10) rhs = fromI128Small(2); res = i128Sub(lhs, rhs); if (isI128Object(res)) { let lo = toI128Low64(res); let hi = toI128High64(res); if (lo != 8 || hi != i64Max) { return falseVal; } } else { return falseVal; } // obj - (-small) lhs = fromI128Pieces(i64Max, 10) rhs = fromI128Small(-2); res = i128Sub(lhs, rhs); if (isI128Object(res)) { let lo = toI128Low64(res); let hi = toI128High64(res); if (lo != 12 || hi != i64Max) { return falseVal; } } else { return falseVal; } // obj - obj lhs = fromI128Pieces(10, i64Max); rhs = fromI128Pieces(9, 10); res = i128Sub(lhs, rhs); if (isI128Object(res)) { let lo = toI128Low64(res); let hi = toI128High64(res); if (lo != i64Max - 10 || hi != 1) { return falseVal; } } else { return falseVal; } // @ts-ignore const u64Max = u64.MAX_VALUE; // obj - obj neg result lhs = fromI128Pieces(1, u64Max - 2); rhs = fromI128Pieces(1, u64Max); res = i128Sub(lhs, rhs); if (!isI128Small(res) || toI128Small(res) != -2) { return falseVal; } return fromTrue(); } export function testI128Mul():BoolVal { let falseVal = fromFalse(); // small * small let lhs = fromI128Small(2); let rhs = fromI128Small(2); let res = i128Mul(lhs, rhs); if (!isI128Small(res) || toI128Small(res) != 4) { return falseVal; } // small * -small rhs = fromI128Small(-2); res = i128Mul(lhs, rhs); if (!isI128Small(res) || toI128Small(res) != -4) { return falseVal; } // small * obj lhs = fromI128Pieces(10, 10) rhs = fromI128Small(2); res = i128Mul(lhs, rhs); if (isI128Object(res)) { let lo = toI128Low64(res); let hi = toI128High64(res); if (lo != 20 || hi != 20) { return falseVal; } } else { return falseVal; } // obj * (-small) lhs = fromI128Pieces(10, 10) rhs = fromI128Small(-2); res = i128Mul(lhs, rhs); res = i128Div(res, rhs); if (isI128Object(res)) { let resLo = toI128Low64(res); let resHi = toI128High64(res); let lo = toI128Low64(lhs); let hi = toI128High64(lhs); if (lo != resLo || hi != resHi) { return falseVal; } } else { return falseVal; } // obj * obj lhs = fromI128Pieces(0, 75057594000000000); rhs = fromI128Pieces(0, 75057594000000000); res = i128Mul(lhs, rhs); if (isI128Object(res)) { let lo = toI128Low64(res); let hi = toI128High64(res); if (lo != 219342094686224384 || hi != 305400367379626) { return falseVal; } } else { return falseVal; } rhs = fromI128Pieces(-1, 75057594000000000); res = i128Mul(lhs, rhs); res = i128Div(res, rhs); if (isI128Object(res)) { let resLo = toI128Low64(res); let resHi = toI128High64(res); let lo = toI128Low64(lhs); let hi = toI128High64(lhs); if (lo != resLo || hi != resHi) { return falseVal; } } else { return falseVal; } // obj * obj / obj (muldiv) let number = fromI128Pieces(0, 75057594000000000); let nominator = fromI128Pieces(1000, 75057594000000000); let denominator = fromI128Pieces(0, 300); res = i128MulDiv(number, nominator, denominator); if (isI128Object(res)) { let lo = toI128Low64(res); let hi = toI128High64(res); if (lo != 13897278342510149632 || hi != 250192998001224598) { return falseVal; } let b_lo = u128.muldiv(75057594000000000, 0, 75057594000000000, 1000, 300, 0); let b_hi = u128.__hi; if (!i128IsEqual(res, fromI128Pieces(b_hi, b_lo))) { return falseVal; } } else { return falseVal; } // @ts-ignore const i64Max = i64.MAX_VALUE; // @ts-ignore const u64Max = u64.MAX_VALUE; // overflow lhs = fromI128Pieces(i64Max, u64Max); rhs = fromI128Pieces(i64Max, u64Max); res = i128Mul(lhs, rhs); if(!isError(res) || getErrorType(res) != errorTypeObject || getErrorCode(res) != errorCodeArithDomain) { return falseVal; } return fromTrue(); } export function testI128Div():BoolVal { let falseVal = fromFalse(); // small / small let lhs = fromI128Small(4); let rhs = fromI128Small(2); let res = i128Div(lhs, rhs); if (!isI128Small(res) || toI128Small(res) != 2) { return falseVal; } // small / -small rhs = fromI128Small(-2); res = i128Div(lhs, rhs); if (!isI128Small(res) || toI128Small(res) != -2) { return falseVal; } // obj / small lhs = fromI128Pieces(10, 10) rhs = fromI128Small(2); res = i128Div(lhs, rhs); if (isI128Object(res)) { let lo = toI128Low64(res); let hi = toI128High64(res); if (lo != 5 || hi != 5) { return falseVal; } } else { return falseVal; } // obj / (-small) lhs = fromI128Pieces(10, 10) rhs = fromI128Small(-2); res = i128Div(lhs, rhs); res = i128Mul(res, rhs); if (isI128Object(res)) { let resLo = toI128Low64(res); let resHi = toI128High64(res); let lo = toI128Low64(lhs); let hi = toI128High64(lhs); if (lo != resLo || hi != resHi) { return falseVal; } } else { return falseVal; } // @ts-ignore const u64Max = u64.MAX_VALUE; // @ts-ignore const i64Max = i64.MAX_VALUE; // obj / obj lhs = fromI128Pieces(i64Max, u64Max); rhs = fromI128Pieces(0, 75057594000000000); res = i128Div(lhs, rhs); if (isI128Object(res)) { let lo = toI128Low64(res); let hi = toI128High64(res); if (lo != 16305608318443096371 || hi != 122) { return falseVal; } } else { return falseVal; } // obj / -obj lhs = fromI128Pieces(i64Max, u64Max); rhs = fromI128Pieces(-1, 200); res = i128Div(lhs, rhs); if (isI128Object(res)) { let lo = toI128Low64(res); let hi = toI128High64(res); if (lo != 9223372036854775708 || hi != -1) { return falseVal; } } else { return falseVal; } // overflow lhs = fromI128Pieces(i64Max, u64Max); rhs = fromI128Small(0); res = i128Div(lhs, rhs); if(!isError(res) || getErrorType(res) != errorTypeObject || getErrorCode(res) != errorCodeArithDomain) { return falseVal; } return fromTrue(); } export function testI128RemEuclid():BoolVal { let falseVal = fromFalse(); // small % small let lhs = fromI128Small(4); let rhs = fromI128Small(3); let res = i128RemEuclid(lhs, rhs); if (!isI128Small(res) || toI128Small(res) != 1) { return falseVal; } // small % -small rhs = fromI128Small(-3); res = i128RemEuclid(lhs, rhs); if (!isI128Small(res) || toI128Small(res) != 1) { return falseVal; } // obj % -small lhs = fromI128Pieces(0, 7505759400002) res = i128RemEuclid(lhs, rhs); if (!isI128Small(res) || toI128Small(res) != 2) { return falseVal; } // obj % small lhs = fromI128Pieces(0, 7505759400002) rhs = fromI128Small(3); res = i128RemEuclid(lhs, rhs); if (!isI128Small(res) || toI128Small(res) != 2) { return falseVal; } // obj % obj lhs = fromI128Pieces(0, 75057594000000015); rhs = fromI128Pieces(0, 75057594000000000); res = i128RemEuclid(lhs, rhs); if (!isI128Small(res) || toI128Small(res) != 15) { return falseVal; } // @ts-ignore const u64Max = u64.MAX_VALUE; // @ts-ignore const i64Max = i64.MAX_VALUE; // overflow lhs = fromI128Pieces(i64Max, u64Max); rhs = fromI128Small(0); res = i128RemEuclid(lhs, rhs); if(!isError(res) || getErrorType(res) != errorTypeObject || getErrorCode(res) != errorCodeArithDomain) { return falseVal; } return fromTrue(); } export function testI128Pow():BoolVal { let falseVal = fromFalse(); // small ^ u32 let lhs = fromI128Small(2); let rhs = fromU32(2); let res = i128Pow(lhs, rhs); if (!isI128Small(res) || toI128Small(res) != 4) { return falseVal; } // obj ^ u32 lhs = fromI128Pieces(0, 75057594000000000); res = i128Pow(lhs, rhs); if (isI128Object(res)) { let lo = toI128Low64(res); let hi = toI128High64(res); if (lo != 219342094686224384 || hi != 305400367379626) { return falseVal; } let b_lo = u128.pow(75057594000000000, 0, 2); let b_hi = u128.__hi; if (!u128.eq(b_lo, b_hi, lo, hi)) { return falseVal; } } else { return falseVal; } // @ts-ignore const u64Max = u64.MAX_VALUE; // @ts-ignore const i64Max = i64.MAX_VALUE; // overflow lhs = fromI128Pieces(i64Max, u64Max); res = i128Pow(lhs, rhs); if(!isError(res) || getErrorType(res) != errorTypeObject || getErrorCode(res) != errorCodeArithDomain) { return falseVal; } return fromTrue(); } export function testI128Shl():BoolVal { let falseVal = fromFalse(); // small << u32 let lhs = fromI128Small(2); let rhs = fromU32(2); let res = i128Shl(lhs, rhs); if (!isI128Small(res) || toI128Small(res) != 8) { return falseVal; } // obj << small lhs = fromI128Pieces(0, 75057594000000000); rhs = fromU32(10); res = i128Shl(lhs, rhs); if (isI128Object(res)) { let lo = toI128Low64(res); let hi = toI128High64(res); if (lo != 3071999961161793536 || hi != 4) { return falseVal; } } else { return falseVal; } // @ts-ignore const u64Max = u64.MAX_VALUE; // @ts-ignore const i64Max = i64.MAX_VALUE; // overflow lhs = fromI128Pieces(i64Max, u64Max); res = i128Shl(lhs, rhs); if(!isError(res) || getErrorType(res) != errorTypeObject || getErrorCode(res) != errorCodeArithDomain) { return falseVal; } return fromTrue(); } export function testI128Shr():BoolVal { let falseVal = fromFalse(); // small << u32 let lhs = fromI128Small(8); let rhs = fromU32(2); let res = i128Shr(lhs, rhs); if (!isI128Small(res) || toI128Small(res) != 2) { return falseVal; } // obj << small lhs = fromI128Pieces(4, 3071999961161793536); rhs = fromU32(10); res = i128Shr(lhs, rhs); if (isI128Object(res)) { let lo = toI128Low64(res); let hi = toI128High64(res); if (lo != 75057594000000000 || hi != 0) { return falseVal; } } else { return falseVal; } // this will trap: /*lhs = fromI128Small(0); rhs = fromU32(4294967290); res = i128Shr(lhs, rhs); if(!isError(res) || getErrorType(res) != errorTypeObject || getErrorCode(res) != errorCodeArithDomain) { return falseVal; }*/ return fromTrue(); } export function testI128Util():BoolVal { let falseVal = fromFalse(); if (!isI128Negative(fromI128Small(-8))) { return falseVal; } if (!isI128Negative(fromI128Pieces(-1,1))) { return falseVal; } if (isI128Negative(fromI128Pieces(1,1))) { return falseVal; } if (isI128Negative(fromI128Small(8))) { return falseVal; } if (i128Compare(fromI128Small(8), fromI128Small(8)) != 0) { return falseVal; } if (!i128IsEqual(fromI128Small(8), fromI128Small(8))) { return falseVal; } if (i128Compare(fromI128Small(7), fromI128Small(8)) != -1) { return falseVal; } if (i128IsEqual(fromI128Small(7), fromI128Small(8))) { return falseVal; } if (i128IsGreaterThan(fromI128Small(7), fromI128Small(8))) { return falseVal; } if (!i128IsLowerThan(fromI128Small(7), fromI128Small(8))) { return falseVal; } if (i128Compare(fromI128Small(9), fromI128Small(8)) != 1) { return falseVal; } if (i128Compare(fromI128Small(-8), fromI128Small(-8)) != 0) { return falseVal; } if (!i128IsEqual(fromI128Small(-8), fromI128Small(-8))) { return falseVal; } if (i128Compare(fromI128Small(-7), fromI128Small(-8)) != 1) { return falseVal; } if (!i128IsGreaterThan(fromI128Small(-7), fromI128Small(-8))) { return falseVal; } if (i128Compare(fromI128Small(-9), fromI128Small(-8)) != -1) { return falseVal; } if (!i128IsLowerThan(fromI128Small(-9), fromI128Small(-8))) { return falseVal; } if (i128Compare(fromI128Small(-9), fromI128Small(8)) != -1) { return falseVal; } if (!i128IsLowerThan(fromI128Small(-9), fromI128Small(8))) { return falseVal; } if (i128Compare(fromI128Pieces(1,5), fromI128Pieces(1,5)) != 0) { return falseVal; } if (!i128IsEqual(fromI128Pieces(1,5), fromI128Pieces(1,5))) { return falseVal; } if (i128Compare(fromI128Pieces(1,4), fromI128Pieces(1,5)) != -1) { return falseVal; } if (!i128IsLowerThan(fromI128Pieces(1,4), fromI128Pieces(1,5))) { return falseVal; } if (i128IsGreaterThan(fromI128Pieces(1,4), fromI128Pieces(1,5))) { return falseVal; } if (i128Compare(fromI128Pieces(1,6), fromI128Pieces(1,5)) != 1) { return falseVal; } if (!i128IsGreaterThan(fromI128Pieces(1,6), fromI128Pieces(1,5))) { return falseVal; } if (i128IsLowerThan(fromI128Pieces(1,6), fromI128Pieces(1,5))) { return falseVal; } if (i128Compare(fromI128Pieces(-1,5), fromI128Pieces(-1,5)) != 0) { return falseVal; } if (!i128IsEqual(fromI128Pieces(-1,5), fromI128Pieces(-1,5))) { return falseVal; } if (i128Compare(fromI128Pieces(-1,5), fromI128Pieces(-1,4)) != 1) { return falseVal; } if (i128IsLowerThan(fromI128Pieces(-1,5), fromI128Pieces(-1,4))) { return falseVal; } if (!i128IsGreaterThan(fromI128Pieces(-1,5), fromI128Pieces(-1,4))) { return falseVal; } if (i128Compare(fromI128Pieces(-1,5), fromI128Pieces(-1,6)) != -1) { return falseVal; } if (!i128IsLowerThan(fromI128Pieces(-1,5), fromI128Pieces(-1,6))) { return falseVal; } if (i128IsGreaterThan(fromI128Pieces(-1,5), fromI128Pieces(-1,6))) { return falseVal; } if (i128Compare(fromI128Pieces(1,5), fromI128Small(8)) != 1) { return falseVal; } if (i128IsEqual(fromI128Pieces(1,5), fromI128Small(8))) { return falseVal; } if (!i128IsLowerThan(fromI128Pieces(-1,5), fromI128Small(8))) { return falseVal; } if (i128IsGreaterThan(fromI128Pieces(-1,5), fromI128Small(8))) { return falseVal; } if (i128Compare(fromI128Pieces(1,5), fromI128Small(-8)) != 1) { return falseVal; } if (i128IsEqual(fromI128Pieces(1,5), fromI128Small(-8))) { return falseVal; } if (!i128IsLowerThan(fromI128Pieces(-1,5), fromI128Small(-8))) { return falseVal; } if (i128IsGreaterThan(fromI128Pieces(-1,5), fromI128Small(-8))) { return falseVal; } if (i128Compare(fromI128Pieces(-1,5), fromI128Small(8)) != -1) { return falseVal; } if (i128IsEqual(fromI128Pieces(-1,5), fromI128Small(8))) { return falseVal; } if (!i128IsLowerThan(fromI128Pieces(-1,5), fromI128Small(8))) { return falseVal; } if (i128IsGreaterThan(fromI128Pieces(-1,5), fromI128Small(8))) { return falseVal; } if (i128Compare(fromI128Pieces(-1,5), fromI128Small(-8)) != -1) { return falseVal; } if (i128IsEqual(fromI128Pieces(-1,5), fromI128Small(-8))) { return falseVal; } if (!i128IsLowerThan(fromI128Pieces(-1,5), fromI128Small(-8))) { return falseVal; } if (i128IsGreaterThan(fromI128Pieces(-1,5), fromI128Small(-8))) { return falseVal; } return fromTrue(); }