diff --git a/stdlib/array.gr b/stdlib/array.gr index 557a5767c..609ea0065 100644 --- a/stdlib/array.gr +++ b/stdlib/array.gr @@ -91,6 +91,7 @@ provide let make = (length: Number, item: a) => { _ARRAY_START_OFFSET ) } + ignore(item) WasmI32.toGrain(array): Array } @@ -988,6 +989,7 @@ provide let join = (separator: String, items: Array) => { if (i != arrLen) Memory.copy(offset, sepPtr, sepSize) offset += sepSize } + ignore(separator) WasmI32.toGrain(newString): String } diff --git a/stdlib/bytes.gr b/stdlib/bytes.gr index 7c52c5e76..f63e7f246 100644 --- a/stdlib/bytes.gr +++ b/stdlib/bytes.gr @@ -113,6 +113,7 @@ provide let fromString = (string: String) => { let size = getSize(src) let dst = allocateBytes(size) Memory.copy(dst + _VALUE_OFFSET, src + _VALUE_OFFSET, size) + ignore(string) WasmI32.toGrain(dst): Bytes } @@ -134,6 +135,7 @@ provide let toString = (bytes: Bytes) => { let size = getSize(src) let dst = allocateString(size) Memory.copy(dst + _VALUE_OFFSET, src + _VALUE_OFFSET, size) + ignore(bytes) WasmI32.toGrain(dst): String } @@ -151,7 +153,9 @@ provide let toString = (bytes: Bytes) => { @unsafe provide let length = (bytes: Bytes) => { let b = WasmI32.fromGrain(bytes) - Conv.wasmI32ToNumber(getSize(b)) + let result = Conv.wasmI32ToNumber(getSize(b)) + ignore(bytes) + result } /** @@ -171,6 +175,7 @@ provide let copy = (bytes: Bytes) => { let size = getSize(src) let dst = allocateBytes(size) Memory.copy(dst + _VALUE_OFFSET, src + _VALUE_OFFSET, size) + ignore(bytes) WasmI32.toGrain(dst): Bytes } @@ -208,6 +213,7 @@ provide let slice = (start: Number, length: Number, bytes: Bytes) => { let dst = allocateBytes(length) let offset = start Memory.copy(dst + _VALUE_OFFSET, src + _VALUE_OFFSET + start, length) + ignore(bytes) WasmI32.toGrain(dst): Bytes } @@ -263,6 +269,7 @@ provide let resize = (left: Number, right: Number, bytes: Bytes) => { len ) } + ignore(bytes) WasmI32.toGrain(dst): Bytes } @@ -298,11 +305,11 @@ provide let move = ( let srcIndexOrig = srcIndex let dstIndexOrig = dstIndex let lenthOrig = length - let src = WasmI32.fromGrain(src) - let srcSize = getSize(src) + let srcPtr = WasmI32.fromGrain(src) + let srcSize = getSize(srcPtr) let srcIndex = coerceNumberToWasmI32(srcIndex) - let dst = WasmI32.fromGrain(dst) - let dstSize = getSize(dst) + let dstPtr = WasmI32.fromGrain(dst) + let dstSize = getSize(dstPtr) let dstIndex = coerceNumberToWasmI32(dstIndex) let length = coerceNumberToWasmI32(length) if (srcIndex + length > srcSize) { @@ -313,10 +320,12 @@ provide let move = ( } let end = srcIndex + length Memory.copy( - dst + _VALUE_OFFSET + dstIndex, - src + _VALUE_OFFSET + srcIndex, + dstPtr + _VALUE_OFFSET + dstIndex, + srcPtr + _VALUE_OFFSET + srcIndex, length ) + ignore(src) + ignore(dst) } /** @@ -362,6 +371,7 @@ provide let fill = (value: Uint8, bytes: Bytes) => { let size = getSize(src) let v = untagUint8(value) Memory.fill(src + _VALUE_OFFSET, v, size) + ignore(bytes) } /** @@ -383,6 +393,7 @@ provide let clear = (bytes: Bytes) => { let src = WasmI32.fromGrain(bytes) let size = getSize(src) Memory.fill(src + _VALUE_OFFSET, 0n, size) + ignore(bytes) } /** @@ -411,6 +422,7 @@ provide let getInt8 = (index: Number, bytes: Bytes) => { let offset = coerceNumberToWasmI32(index) checkIndexIsInBounds(offset, _INT8_BYTE_SIZE, size) let n = WasmI32.load8S(ptr + offset, _VALUE_OFFSET) + ignore(bytes) tagInt8(n) } @@ -440,6 +452,7 @@ provide let setInt8 = (index: Number, value: Int8, bytes: Bytes) => { let offset = coerceNumberToWasmI32(index) checkIndexIsInBounds(offset, _INT8_BYTE_SIZE, size) let v = untagInt8(value) + ignore(bytes) WasmI32.store8(ptr + offset, v, _VALUE_OFFSET) } @@ -469,6 +482,7 @@ provide let getUint8 = (index: Number, bytes: Bytes) => { let offset = coerceNumberToWasmI32(index) checkIndexIsInBounds(offset, _INT8_BYTE_SIZE, size) let n = WasmI32.load8U(ptr + offset, _VALUE_OFFSET) + ignore(bytes) tagUint8(n) } @@ -498,6 +512,7 @@ provide let setUint8 = (index: Number, value: Uint8, bytes: Bytes) => { checkIndexIsInBounds(offset, _INT8_BYTE_SIZE, size) let v = untagUint8(value) WasmI32.store8(ptr + offset, v, _VALUE_OFFSET) + ignore(bytes) } /** @@ -526,6 +541,7 @@ provide let getInt16 = (index: Number, bytes: Bytes) => { let offset = coerceNumberToWasmI32(index) checkIndexIsInBounds(offset, _INT16_BYTE_SIZE, size) let n = WasmI32.load16S(ptr + offset, _VALUE_OFFSET) + ignore(bytes) tagInt16(n) } @@ -556,6 +572,7 @@ provide let setInt16 = (index: Number, value: Int16, bytes: Bytes) => { checkIndexIsInBounds(offset, _INT16_BYTE_SIZE, size) let v = untagInt16(value) WasmI32.store16(ptr + offset, v, _VALUE_OFFSET) + ignore(bytes) } /** @@ -584,6 +601,7 @@ provide let getUint16 = (index: Number, bytes: Bytes) => { let offset = coerceNumberToWasmI32(index) checkIndexIsInBounds(offset, _INT16_BYTE_SIZE, size) let n = WasmI32.load16U(ptr + offset, _VALUE_OFFSET) + ignore(bytes) tagUint16(n) } @@ -613,6 +631,7 @@ provide let setUint16 = (index: Number, value: Uint16, bytes: Bytes) => { checkIndexIsInBounds(offset, _INT16_BYTE_SIZE, size) let v = untagUint16(value) WasmI32.store16(ptr + offset, v, _VALUE_OFFSET) + ignore(bytes) } /** @@ -640,6 +659,7 @@ provide let getInt32 = (index: Number, bytes: Bytes) => { let offset = coerceNumberToWasmI32(index) checkIndexIsInBounds(offset, _INT32_BYTE_SIZE, size) let n = WasmI32.load(ptr + offset, _VALUE_OFFSET) + ignore(bytes) Conv.toInt32(n) } @@ -669,6 +689,7 @@ provide let setInt32 = (index: Number, value: Int32, bytes: Bytes) => { checkIndexIsInBounds(offset, _INT32_BYTE_SIZE, size) let v = Conv.fromInt32(value) WasmI32.store(ptr + offset, v, _VALUE_OFFSET) + ignore(bytes) } /** @@ -696,6 +717,7 @@ provide let getUint32 = (index: Number, bytes: Bytes) => { let offset = coerceNumberToWasmI32(index) checkIndexIsInBounds(offset, _INT32_BYTE_SIZE, size) let n = WasmI32.load(ptr + offset, _VALUE_OFFSET) + ignore(bytes) Conv.toUint32(n) } @@ -725,6 +747,7 @@ provide let setUint32 = (index: Number, value: Uint32, bytes: Bytes) => { checkIndexIsInBounds(offset, _INT32_BYTE_SIZE, size) let v = Conv.fromUint32(value) WasmI32.store(ptr + offset, v, _VALUE_OFFSET) + ignore(bytes) } /** @@ -752,6 +775,7 @@ provide let getFloat32 = (index: Number, bytes: Bytes) => { let offset = coerceNumberToWasmI32(index) checkIndexIsInBounds(offset, _INT32_BYTE_SIZE, size) let n = WasmF32.load(ptr + offset, _VALUE_OFFSET) + ignore(bytes) Conv.toFloat32(n) } @@ -781,6 +805,7 @@ provide let setFloat32 = (index: Number, value: Float32, bytes: Bytes) => { checkIndexIsInBounds(offset, _INT32_BYTE_SIZE, size) let v = Conv.fromFloat32(value) WasmF32.store(ptr + offset, v, _VALUE_OFFSET) + ignore(bytes) } /** @@ -808,6 +833,7 @@ provide let getInt64 = (index: Number, bytes: Bytes) => { let offset = coerceNumberToWasmI32(index) checkIndexIsInBounds(offset, _INT64_BYTE_SIZE, size) let n = WasmI64.load(ptr + offset, _VALUE_OFFSET) + ignore(bytes) Conv.toInt64(n) } @@ -837,6 +863,7 @@ provide let setInt64 = (index: Number, value: Int64, bytes: Bytes) => { checkIndexIsInBounds(offset, _INT64_BYTE_SIZE, size) let v = Conv.fromInt64(value) WasmI64.store(ptr + offset, v, _VALUE_OFFSET) + ignore(bytes) } /** @@ -864,6 +891,7 @@ provide let getUint64 = (index: Number, bytes: Bytes) => { let offset = coerceNumberToWasmI32(index) checkIndexIsInBounds(offset, _INT64_BYTE_SIZE, size) let n = WasmI64.load(ptr + offset, _VALUE_OFFSET) + ignore(bytes) Conv.toUint64(n) } @@ -893,6 +921,7 @@ provide let setUint64 = (index: Number, value: Uint64, bytes: Bytes) => { checkIndexIsInBounds(offset, _INT64_BYTE_SIZE, size) let v = Conv.fromUint64(value) WasmI64.store(ptr + offset, v, _VALUE_OFFSET) + ignore(bytes) } /** @@ -920,6 +949,7 @@ provide let getFloat64 = (index: Number, bytes: Bytes) => { let offset = coerceNumberToWasmI32(index) checkIndexIsInBounds(offset, _FLOAT64_BYTE_SIZE, size) let n = WasmF64.load(ptr + offset, _VALUE_OFFSET) + ignore(bytes) Conv.toFloat64(n) } @@ -949,4 +979,5 @@ provide let setFloat64 = (index: Number, value: Float64, bytes: Bytes) => { checkIndexIsInBounds(offset, _FLOAT64_BYTE_SIZE, size) let v = Conv.fromFloat64(value) WasmF64.store(ptr + offset, v, _VALUE_OFFSET) + ignore(bytes) } diff --git a/stdlib/hash.gr b/stdlib/hash.gr index 3997137ca..0ff4e8edd 100644 --- a/stdlib/hash.gr +++ b/stdlib/hash.gr @@ -262,6 +262,8 @@ provide let hash = anything => { } hashOne(WasmI32.fromGrain(anything), 0n) + ignore(anything) + finalize(0n) // Tag the number on the way out. diff --git a/stdlib/map.gr b/stdlib/map.gr index 452329206..4ec222da9 100644 --- a/stdlib/map.gr +++ b/stdlib/map.gr @@ -436,13 +436,14 @@ provide let toArray = (map: Map) => { use WasmI32.{ (+) as addWasmI32 } // Assign the values into the array. // We store them directly to prevent GC on uninitialized array data. - let array = WasmI32.fromGrain(array) + let arrayPtr = WasmI32.fromGrain(array) let item = (key, value) WasmI32.store( - addWasmI32(array, untagSimpleNumber(i) * 4n), + addWasmI32(arrayPtr, untagSimpleNumber(i) * 4n), Memory.incRef(WasmI32.fromGrain(item)), 8n ) + ignore(array) i + 1 } reduce(reducer, 0, map) diff --git a/stdlib/runtime/numbers.gr b/stdlib/runtime/numbers.gr index 80a790a3b..fde3e2336 100644 --- a/stdlib/runtime/numbers.gr +++ b/stdlib/runtime/numbers.gr @@ -402,31 +402,31 @@ provide let boxedRationalDenominator = xptr => { @unsafe provide let coerceNumberToWasmF32 = (x: Number) => { - let x = WasmI32.fromGrain(x) - if (isSimpleNumber(x)) { - WasmF32.convertI32S(untagSimple(x)) + let xVal = WasmI32.fromGrain(x) + let result = if (isSimpleNumber(xVal)) { + WasmF32.convertI32S(untagSimple(xVal)) } else { - let xtag = boxedNumberTag(x) + let xtag = boxedNumberTag(xVal) match (xtag) { t when t == Tags._GRAIN_INT64_BOXED_NUM_TAG => { - WasmF32.convertI64S(boxedInt64Number(x)) + WasmF32.convertI64S(boxedInt64Number(xVal)) }, t when t == Tags._GRAIN_BIGINT_BOXED_NUM_TAG => { - BI.toFloat32(x) + BI.toFloat32(xVal) }, t when t == Tags._GRAIN_RATIONAL_BOXED_NUM_TAG => { use WasmF32.{ (/) } - BI.toFloat32(boxedRationalNumerator(x)) / - BI.toFloat32(boxedRationalDenominator(x)) + BI.toFloat32(boxedRationalNumerator(xVal)) / + BI.toFloat32(boxedRationalDenominator(xVal)) }, t when t == Tags._GRAIN_FLOAT64_BOXED_NUM_TAG => { use WasmF64.{ (<), (>) } - let xval = boxedFloat64Number(x) - if (xval > _F32_MAX || xval < _F32_MIN) { + let boxedVal = boxedFloat64Number(xVal) + if (boxedVal > _F32_MAX || boxedVal < _F32_MIN) { // Not an actual return value throw Exception.Overflow } else { - WasmF32.demoteF64(xval) + WasmF32.demoteF64(boxedVal) } }, _ => { @@ -434,50 +434,54 @@ provide let coerceNumberToWasmF32 = (x: Number) => { }, } } + ignore(x) + result } @unsafe provide let coerceNumberToWasmF64 = (x: Number) => { - let x = WasmI32.fromGrain(x) - if (isSimpleNumber(x)) { - WasmF64.convertI32S(untagSimple(x)) + let xVal = WasmI32.fromGrain(x) + let result = if (isSimpleNumber(xVal)) { + WasmF64.convertI32S(untagSimple(xVal)) } else { - let xtag = boxedNumberTag(x) + let xtag = boxedNumberTag(xVal) match (xtag) { t when t == Tags._GRAIN_INT64_BOXED_NUM_TAG => { - WasmF64.convertI64S(boxedInt64Number(x)) + WasmF64.convertI64S(boxedInt64Number(xVal)) }, t when t == Tags._GRAIN_BIGINT_BOXED_NUM_TAG => { - BI.toFloat64(x) + BI.toFloat64(xVal) }, t when t == Tags._GRAIN_RATIONAL_BOXED_NUM_TAG => { use WasmF64.{ (/) } - BI.toFloat64(boxedRationalNumerator(x)) / - BI.toFloat64(boxedRationalDenominator(x)) + BI.toFloat64(boxedRationalNumerator(xVal)) / + BI.toFloat64(boxedRationalDenominator(xVal)) }, t when t == Tags._GRAIN_FLOAT64_BOXED_NUM_TAG => { - boxedFloat64Number(x) + boxedFloat64Number(xVal) }, _ => { throw UnknownNumberTag }, } } + ignore(x) + result } @unsafe provide let coerceNumberToWasmI64 = (x: Number) => { - let x = WasmI32.fromGrain(x) - if (isSimpleNumber(x)) { - WasmI64.extendI32S(untagSimple(x)) + let xVal = WasmI32.fromGrain(x) + let result = if (isSimpleNumber(xVal)) { + WasmI64.extendI32S(untagSimple(xVal)) } else { - let xtag = boxedNumberTag(x) + let xtag = boxedNumberTag(xVal) match (xtag) { t when t == Tags._GRAIN_INT64_BOXED_NUM_TAG => { - boxedInt64Number(x) + boxedInt64Number(xVal) }, t when t == Tags._GRAIN_BIGINT_BOXED_NUM_TAG => { - BI.toInt64(x) + BI.toInt64(xVal) }, _ => { // rationals are never integral, and we refuse to coerce floats to ints @@ -485,26 +489,28 @@ provide let coerceNumberToWasmI64 = (x: Number) => { }, } } + ignore(x) + result } @unsafe provide let coerceNumberToWasmI32 = (x: Number) => { use WasmI64.{ (<), (>) } - let x = WasmI32.fromGrain(x) - if (isSimpleNumber(x)) { - untagSimple(x) + let xVal = WasmI32.fromGrain(x) + let result = if (isSimpleNumber(xVal)) { + untagSimple(xVal) } else { - let xtag = boxedNumberTag(x) + let xtag = boxedNumberTag(xVal) match (xtag) { t when t == Tags._GRAIN_INT64_BOXED_NUM_TAG => { - let int64 = boxedInt64Number(x) + let int64 = boxedInt64Number(xVal) if (int64 > _I32_MAX || int64 < _I32_MIN) { throw Exception.Overflow } WasmI32.wrapI64(int64) }, t when t == Tags._GRAIN_BIGINT_BOXED_NUM_TAG => { - BI.toInt32(x) + BI.toInt32(xVal) }, _ => { // rationals are never integral, and we refuse to coerce floats to ints @@ -512,31 +518,33 @@ provide let coerceNumberToWasmI32 = (x: Number) => { }, } } + ignore(x) + result } @unsafe provide let coerceNumberToUnsignedWasmI64 = (x: Number) => { use WasmI32.{ (<) } - let x = WasmI32.fromGrain(x) - if (isSimpleNumber(x)) { - let num = untagSimple(x) + let xVal = WasmI32.fromGrain(x) + let result = if (isSimpleNumber(xVal)) { + let num = untagSimple(xVal) if (num < 0n) { throw Exception.Overflow } WasmI64.extendI32U(num) } else { - let xtag = boxedNumberTag(x) + let xtag = boxedNumberTag(xVal) match (xtag) { t when t == Tags._GRAIN_INT64_BOXED_NUM_TAG => { use WasmI64.{ (<) } - let int64 = boxedInt64Number(x) + let int64 = boxedInt64Number(xVal) if (int64 < 0N) { throw Exception.Overflow } int64 }, t when t == Tags._GRAIN_BIGINT_BOXED_NUM_TAG => { - BI.toUnsignedInt64(x) + BI.toUnsignedInt64(xVal) }, _ => { // rationals are never integral, and we refuse to coerce floats to ints @@ -544,31 +552,33 @@ provide let coerceNumberToUnsignedWasmI64 = (x: Number) => { }, } } + ignore(x) + result } @unsafe provide let coerceNumberToUnsignedWasmI32 = (x: Number) => { use WasmI32.{ (<) } - let x = WasmI32.fromGrain(x) - if (isSimpleNumber(x)) { - let num = untagSimple(x) + let xVal = WasmI32.fromGrain(x) + let result = if (isSimpleNumber(xVal)) { + let num = untagSimple(xVal) if (num < 0n) { throw Exception.Overflow } num } else { - let xtag = boxedNumberTag(x) + let xtag = boxedNumberTag(xVal) match (xtag) { t when t == Tags._GRAIN_INT64_BOXED_NUM_TAG => { use WasmI64.{ (<), (>) } - let int64 = boxedInt64Number(x) + let int64 = boxedInt64Number(xVal) if (int64 > _U32_MAX || int64 < _U32_MIN) { throw Exception.Overflow } WasmI32.wrapI64(int64) }, t when t == Tags._GRAIN_BIGINT_BOXED_NUM_TAG => { - BI.toInt32(x) + BI.toInt32(xVal) }, _ => { // rationals are never integral, and we refuse to coerce floats to ints @@ -576,22 +586,24 @@ provide let coerceNumberToUnsignedWasmI32 = (x: Number) => { }, } } + ignore(x) + result } @unsafe let coerceNumberToBigInt = (x: Number) => { - let x = WasmI32.fromGrain(x) - if (isSimpleNumber(x)) { - BI.makeWrappedInt32(untagSimple(x)) + let xVal = WasmI32.fromGrain(x) + let result = if (isSimpleNumber(xVal)) { + BI.makeWrappedInt32(untagSimple(xVal)) } else { - let xtag = boxedNumberTag(x) + let xtag = boxedNumberTag(xVal) match (xtag) { t when t == Tags._GRAIN_INT64_BOXED_NUM_TAG => { - BI.makeWrappedInt64(boxedInt64Number(x)) + BI.makeWrappedInt64(boxedInt64Number(xVal)) }, t when t == Tags._GRAIN_BIGINT_BOXED_NUM_TAG => { - Memory.incRef(x) - x + Memory.incRef(xVal) + xVal }, _ => { // rationals are never integral, and we refuse to coerce floats to ints @@ -599,6 +611,8 @@ let coerceNumberToBigInt = (x: Number) => { }, } } + ignore(x) + result } @unsafe @@ -1165,8 +1179,9 @@ provide let cmpRationals = (x, y) => { */ @unsafe provide let rationalNumerator = (x: Rational) => { - let x = WasmI32.fromGrain(x) - let num = boxedRationalNumerator(x) + let xVal = WasmI32.fromGrain(x) + let num = boxedRationalNumerator(xVal) + ignore(x) Memory.incRef(num) WasmI32.toGrain(reducedBigInteger(num)): Number } @@ -1181,8 +1196,9 @@ provide let rationalNumerator = (x: Rational) => { */ @unsafe provide let rationalDenominator = (x: Rational) => { - let x = WasmI32.fromGrain(x) - let num = boxedRationalDenominator(x) + let xVal = WasmI32.fromGrain(x) + let num = boxedRationalDenominator(xVal) + ignore(x) Memory.incRef(num) WasmI32.toGrain(reducedBigInteger(num)): Number } @@ -1912,7 +1928,10 @@ provide let (<) = (num1: Number, num2: Number) => { use WasmI32.{ (<) } let x = WasmI32.fromGrain(num1) let y = WasmI32.fromGrain(num2) - !isNaN(x) && !isNaN(y) && cmp(x, y) < 0n + let result = !isNaN(x) && !isNaN(y) && cmp(x, y) < 0n + ignore(num1) + ignore(num2) + result } /** @@ -1929,7 +1948,10 @@ provide let (>) = (num1: Number, num2: Number) => { use WasmI32.{ (>) } let x = WasmI32.fromGrain(num1) let y = WasmI32.fromGrain(num2) - !isNaN(x) && !isNaN(y) && cmp(x, y) > 0n + let result = !isNaN(x) && !isNaN(y) && cmp(x, y) > 0n + ignore(num1) + ignore(num2) + result } /** @@ -1946,7 +1968,10 @@ provide let (<=) = (num1: Number, num2: Number) => { use WasmI32.{ (<=) } let x = WasmI32.fromGrain(num1) let y = WasmI32.fromGrain(num2) - !isNaN(x) && !isNaN(y) && cmp(x, y) <= 0n + let result = !isNaN(x) && !isNaN(y) && cmp(x, y) <= 0n + ignore(num1) + ignore(num2) + result } /** @@ -1963,14 +1988,20 @@ provide let (>=) = (num1: Number, num2: Number) => { use WasmI32.{ (>=) } let x = WasmI32.fromGrain(num1) let y = WasmI32.fromGrain(num2) - !isNaN(x) && !isNaN(y) && cmp(x, y) >= 0n + let result = !isNaN(x) && !isNaN(y) && cmp(x, y) >= 0n + ignore(num1) + ignore(num2) + result } @unsafe provide let compare = (x: Number, y: Number) => { - let x = WasmI32.fromGrain(x) - let y = WasmI32.fromGrain(y) - WasmI32.toGrain(tagSimple(cmp(x, y))): Number + let xVal = WasmI32.fromGrain(x) + let yVal = WasmI32.fromGrain(y) + let result = WasmI32.toGrain(tagSimple(cmp(xVal, yVal))): Number + ignore(x) + ignore(y) + result } /* @@ -1979,9 +2010,12 @@ provide let compare = (x: Number, y: Number) => { @unsafe provide let numberEq = (x: Number, y: Number) => { - let x = WasmI32.fromGrain(x) - let y = WasmI32.fromGrain(y) - numberEqual(x, y) + let xVal = WasmI32.fromGrain(x) + let yVal = WasmI32.fromGrain(y) + let result = numberEqual(xVal, yVal) + ignore(x) + ignore(y) + result } /* @@ -2001,12 +2035,14 @@ provide let numberEq = (x: Number, y: Number) => { @unsafe provide let lnot = (value: Number) => { let xw32 = WasmI32.fromGrain(value) - if (isBigInt(xw32)) { + let result = if (isBigInt(xw32)) { WasmI32.toGrain(reducedBigInteger(BI.bitwiseNot(xw32))): Number } else { let xval = coerceNumberToWasmI64(value) WasmI32.toGrain(reducedInteger(i64not(xval))): Number } + ignore(value) + result } /** @@ -2024,7 +2060,7 @@ provide let lnot = (value: Number) => { provide let (<<) = (value: Number, amount: Number) => { use WasmI64.{ (-), (<<) } let xw32 = WasmI32.fromGrain(value) - if (isBigInt(xw32)) { + let result = if (isBigInt(xw32)) { let yval = coerceNumberToWasmI32(amount) WasmI32.toGrain(reducedBigInteger(BI.shl(xw32, yval))): Number } else { @@ -2040,6 +2076,8 @@ provide let (<<) = (value: Number, amount: Number) => { WasmI32.toGrain(reducedInteger(xval << yval)): Number } } + ignore(value) + result } /** @@ -2057,7 +2095,7 @@ provide let (<<) = (value: Number, amount: Number) => { provide let (>>>) = (value: Number, amount: Number) => { use WasmI64.{ (>>>) } let xw32 = WasmI32.fromGrain(value) - if (isBigInt(xw32)) { + let result = if (isBigInt(xw32)) { let yval = coerceNumberToWasmI32(amount) // [NOTE]: For BigInts, shrU is the same as shrS because there // are an *infinite* number of leading ones @@ -2067,6 +2105,8 @@ provide let (>>>) = (value: Number, amount: Number) => { let yval = coerceNumberToWasmI64(amount) WasmI32.toGrain(reducedInteger(xval >>> yval)): Number } + ignore(value) + result } /** @@ -2085,7 +2125,7 @@ provide let (&) = (value1: Number, value2: Number) => { use WasmI64.{ (&) } let xw32 = WasmI32.fromGrain(value1) let yw32 = WasmI32.fromGrain(value2) - if (isBigInt(xw32) || isBigInt(yw32)) { + let result = if (isBigInt(xw32) || isBigInt(yw32)) { let xval = coerceNumberToBigInt(value1) let yval = coerceNumberToBigInt(value2) let ret = WasmI32.toGrain(reducedBigInteger(BI.bitwiseAnd(xval, yval))): @@ -2104,6 +2144,9 @@ provide let (&) = (value1: Number, value2: Number) => { let yval = coerceNumberToWasmI64(value2) WasmI32.toGrain(reducedInteger(xval & yval)): Number } + ignore(value1) + ignore(value2) + result } /** @@ -2122,7 +2165,7 @@ provide let (|) = (value1: Number, value2: Number) => { use WasmI64.{ (|) } let xw32 = WasmI32.fromGrain(value1) let yw32 = WasmI32.fromGrain(value2) - if (isBigInt(xw32) || isBigInt(yw32)) { + let result = if (isBigInt(xw32) || isBigInt(yw32)) { let xval = coerceNumberToBigInt(value1) let yval = coerceNumberToBigInt(value2) let ret = WasmI32.toGrain(reducedBigInteger(BI.bitwiseOr(xval, yval))): @@ -2141,6 +2184,9 @@ provide let (|) = (value1: Number, value2: Number) => { let yval = coerceNumberToWasmI64(value2) WasmI32.toGrain(reducedInteger(xval | yval)): Number } + ignore(value1) + ignore(value2) + result } /** @@ -2160,7 +2206,7 @@ provide let (^) = (value1: Number, value2: Number) => { use WasmI64.{ (^) } let xw32 = WasmI32.fromGrain(value1) let yw32 = WasmI32.fromGrain(value2) - if (isBigInt(xw32) || isBigInt(yw32)) { + let result = if (isBigInt(xw32) || isBigInt(yw32)) { let xval = coerceNumberToBigInt(value1) let yval = coerceNumberToBigInt(value2) let ret = WasmI32.toGrain(reducedBigInteger(BI.bitwiseXor(xval, yval))): @@ -2179,6 +2225,9 @@ provide let (^) = (value1: Number, value2: Number) => { let yval = coerceNumberToWasmI64(value2) WasmI32.toGrain(reducedInteger(xval ^ yval)): Number } + ignore(value1) + ignore(value2) + result } /** @@ -2196,7 +2245,7 @@ provide let (^) = (value1: Number, value2: Number) => { provide let (>>) = (value: Number, amount: Number) => { use WasmI64.{ (>>) } let xw32 = WasmI32.fromGrain(value) - if (isBigInt(xw32)) { + let result = if (isBigInt(xw32)) { let yval = coerceNumberToWasmI32(amount) // [NOTE]: For BigInts, shrU is the same as shrS because there // are an *infinite* number of leading ones @@ -2206,6 +2255,8 @@ provide let (>>) = (value: Number, amount: Number) => { let yval = coerceNumberToWasmI64(amount) WasmI32.toGrain(reducedInteger(xval >> yval)): Number } + ignore(value) + result } /// USER-EXPOSED COERCION FUNCTIONS @@ -2216,22 +2267,22 @@ provide let (>>) = (value: Number, amount: Number) => { @unsafe let coerceNumberToShortUint = (x: Number, max32, max64, is8bit) => { use WasmI32.{ (&), (<), (>) } - let x = WasmI32.fromGrain(x) - let int32 = if (isSimpleNumber(x)) { - untagSimple(x) + let xVal = WasmI32.fromGrain(x) + let int32 = if (isSimpleNumber(xVal)) { + untagSimple(xVal) } else { - let xtag = boxedNumberTag(x) + let xtag = boxedNumberTag(xVal) match (xtag) { t when t == Tags._GRAIN_INT64_BOXED_NUM_TAG => { use WasmI64.{ (<), (>) } - let int64 = boxedInt64Number(x) + let int64 = boxedInt64Number(xVal) if (int64 > max64 || int64 < 0N) { throw Exception.Overflow } WasmI32.wrapI64(int64) }, t when t == Tags._GRAIN_BIGINT_BOXED_NUM_TAG => { - BI.toInt32(x) + BI.toInt32(xVal) }, _ => { // rationals are never integral, and we refuse to coerce floats to ints @@ -2239,6 +2290,7 @@ let coerceNumberToShortUint = (x: Number, max32, max64, is8bit) => { }, } } + ignore(x) if (int32 > max32 || int32 < 0n) { throw Exception.Overflow } @@ -2248,22 +2300,22 @@ let coerceNumberToShortUint = (x: Number, max32, max64, is8bit) => { @unsafe let coerceNumberToShortInt = (x: Number, min32, max32, min64, max64, is8bit) => { use WasmI32.{ (<), (>) } - let x = WasmI32.fromGrain(x) - let int32 = if (isSimpleNumber(x)) { - untagSimple(x) + let xVal = WasmI32.fromGrain(x) + let int32 = if (isSimpleNumber(xVal)) { + untagSimple(xVal) } else { - let xtag = boxedNumberTag(x) + let xtag = boxedNumberTag(xVal) match (xtag) { t when t == Tags._GRAIN_INT64_BOXED_NUM_TAG => { use WasmI64.{ (<), (>) } - let int64 = boxedInt64Number(x) + let int64 = boxedInt64Number(xVal) if (int64 > max64 || int64 < min64) { throw Exception.Overflow } WasmI32.wrapI64(int64) }, t when t == Tags._GRAIN_BIGINT_BOXED_NUM_TAG => { - BI.toInt32(x) + BI.toInt32(xVal) }, _ => { // rationals are never integral, and we refuse to coerce floats to ints @@ -2271,6 +2323,7 @@ let coerceNumberToShortInt = (x: Number, min32, max32, min64, max64, is8bit) => }, } } + ignore(x) if (int32 > max32 || int32 < min32) { throw Exception.Overflow } @@ -2384,6 +2437,7 @@ provide let coerceNumberToInt64 = (number: Number) => { Memory.incRef(x) newInt64(coerceNumberToWasmI64(WasmI32.toGrain(x): Number)) } + ignore(number) WasmI32.toGrain(result): Int64 } @@ -2430,6 +2484,7 @@ provide let coerceNumberToRational = (number: Number) => { throw Exception.NumberNotRational } } + ignore(number) WasmI32.toGrain(result): Rational } @@ -2470,6 +2525,7 @@ provide let coerceNumberToFloat64 = (number: Number) => { Memory.incRef(x) newFloat64(coerceNumberToWasmF64(WasmI32.toGrain(x): Number)) } + ignore(number) WasmI32.toGrain(result): Float64 } @@ -2541,6 +2597,7 @@ provide let coerceUint16ToNumber = (value: Uint16) => { provide let coerceInt32ToNumber = (value: Int32) => { let x = WasmI32.load(WasmI32.fromGrain(value), 4n) let result = reducedInteger(WasmI64.extendI32S(x)) + ignore(value) WasmI32.toGrain(result): Number } @@ -2554,8 +2611,10 @@ provide let coerceInt32ToNumber = (value: Int32) => { */ @unsafe provide let coerceInt64ToNumber = (value: Int64) => { - WasmI32.toGrain(reducedInteger(boxedInt64Number(WasmI32.fromGrain(value)))): - Number + let x = WasmI32.fromGrain(value) + let result = WasmI32.toGrain(reducedInteger(boxedInt64Number(x))): Number + ignore(value) + result } /** @@ -2572,7 +2631,9 @@ provide let coerceBigIntToNumber = (num: BigInt) => { // reducedBigInteger assumes that the bigint is dead, // but in our case, it is not Memory.incRef(x) - WasmI32.toGrain(reducedBigInteger(x)): Number + let result = WasmI32.toGrain(reducedBigInteger(x)): Number + ignore(num) + result } /** @@ -2594,7 +2655,9 @@ provide let coerceRationalToNumber = (rational: Rational) => { } // incRef x to reuse it via WasmI32.toGrain Memory.incRef(x) - WasmI32.toGrain(x): Number + let result = WasmI32.toGrain(x): Number + ignore(rational) + result } /** @@ -2609,7 +2672,9 @@ provide let coerceRationalToNumber = (rational: Rational) => { provide let coerceFloat32ToNumber = (float: Float32) => { let x = WasmF32.load(WasmI32.fromGrain(float), 4n) let x64 = WasmF64.promoteF32(x) - WasmI32.toGrain(newFloat64(x64)): Number + let result = WasmI32.toGrain(newFloat64(x64)): Number + ignore(float) + result } /** @@ -2625,7 +2690,9 @@ provide let coerceFloat64ToNumber = (float: Float64) => { let x = WasmI32.fromGrain(float) // incRef x to reuse it via WasmI32.toGrain Memory.incRef(x) - WasmI32.toGrain(x): Number + let result = WasmI32.toGrain(x): Number + ignore(float) + result } /// USER-EXPOSED CONVERSION FUNCTIONS @@ -2666,7 +2733,10 @@ let convertInexactToExactHelp = x => { @unsafe provide let convertInexactToExact = (x: Number) => { - WasmI32.toGrain(convertInexactToExactHelp(WasmI32.fromGrain(x))): Number + let xVal = WasmI32.fromGrain(x) + let result = WasmI32.toGrain(convertInexactToExactHelp(xVal)): Number + ignore(x) + result } /** @@ -2751,7 +2821,10 @@ provide let (/) = (num1: Number, num2: Number) => { provide let (%) = (num1: Number, num2: Number) => { let x = WasmI32.fromGrain(num1) let y = WasmI32.fromGrain(num2) - WasmI32.toGrain(numberMod(x, y)): Number + let result = WasmI32.toGrain(numberMod(x, y)): Number + ignore(num1) + ignore(num2) + result } // inc/dec @@ -2782,8 +2855,10 @@ provide let decr = value => { @unsafe provide let isBigInt = x => { - let x = WasmI32.fromGrain(x) - isBigInt(x) + let xVal = WasmI32.fromGrain(x) + let result = isBigInt(xVal) + ignore(x) + result } // Scalbn is based on https://git.musl-libc.org/cgit/musl/tree/src/math/scalbn.c @@ -2874,13 +2949,13 @@ provide let (**) = (base, power) => { let (!=) = (x, y) => !numberEq(x, y) let basePtr = WasmI32.fromGrain(base) let powerPtr = WasmI32.fromGrain(power) - if (base == 1 && power != 0) { - return 1 + let result = if (base == 1 && power != 0) { + 1 } else if (isInteger(basePtr) && isInteger(powerPtr)) { if (power < 0) - return expBySquaring(1, 1 / base, power * -1) + expBySquaring(1, 1 / base, power * -1) else - return expBySquaring(1, base, power) + expBySquaring(1, base, power) } else if (isRational(basePtr) && isInteger(powerPtr)) { // Apply expBySquaring to numerator and denominator let numerator = WasmI32.fromGrain(base) @@ -2899,7 +2974,7 @@ provide let (**) = (base, power) => { expBySquaring(1, 1 / denominator, power * -1) else expBySquaring(1, denominator, power) - return numerator / denominator + numerator / denominator } else { // Based on https://git.musl-libc.org/cgit/musl/tree/src/math/pow.c use WasmF64.{ (==), (!=), (<=), (/), (*), (+) } @@ -3248,6 +3323,12 @@ provide let (**) = (base, power) => { WasmI64.reinterpretF64(z) & 0xFFFFFFFFN | WasmI64.extendI32S(j) << 32N ) } - return WasmI32.toGrain(newFloat64(s * z)): Number + WasmI32.toGrain(newFloat64(s * z)): Number } + + ignore(base) + ignore(power) + + // This return is never hit but is here because we need to hold on to references + return result } diff --git a/stdlib/string.gr b/stdlib/string.gr index 77d1239de..b9f42031a 100644 --- a/stdlib/string.gr +++ b/stdlib/string.gr @@ -64,11 +64,11 @@ provide let concat = (++) @unsafe provide let length = (string: String) => { use WasmI32.{ (+), (&), (!=) } - let string = WasmI32.fromGrain(string) - let size = WasmI32.load(string, 4n) + let stringPtr = WasmI32.fromGrain(string) + let size = WasmI32.load(stringPtr, 4n) let mut len = 0n - let mut ptr = string + 8n + let mut ptr = stringPtr + 8n let end = ptr + size while (WasmI32.ltU(ptr, end)) { @@ -79,6 +79,8 @@ provide let length = (string: String) => { ptr += 1n } + ignore(string) + Conv.wasmI32ToNumber(len) } @@ -94,8 +96,10 @@ provide let length = (string: String) => { */ @unsafe provide let byteLength = (string: String) => { - let string = WasmI32.fromGrain(string) - Conv.wasmI32ToNumber(WasmI32.load(string, 4n)) + let stringPtr = WasmI32.fromGrain(string) + let result = Conv.wasmI32ToNumber(WasmI32.load(stringPtr, 4n)) + ignore(string) + result } /** @@ -110,7 +114,9 @@ provide let byteLength = (string: String) => { provide let isEmpty = (string: String) => { use WasmI32.{ (==) } let strPtr = WasmI32.fromGrain(string) - WasmI32.load(strPtr, 4n) == 0n + let result = WasmI32.load(strPtr, 4n) == 0n + ignore(string) + result } /** @@ -126,19 +132,19 @@ provide let isEmpty = (string: String) => { */ @unsafe provide let indexOf = (search: String, string: String) => { - let search = WasmI32.fromGrain(search) - let string = WasmI32.fromGrain(string) + let searchPtr = WasmI32.fromGrain(search) + let stringPtr = WasmI32.fromGrain(string) - let size = WasmI32.load(string, 4n) - let psize = WasmI32.load(search, 4n) + let size = WasmI32.load(stringPtr, 4n) + let psize = WasmI32.load(searchPtr, 4n) use WasmI32.{ (+), (-), (&), ltU as (<), gtU as (>), (==) } if (psize > size) { return None } let mut idx = 0n - let mut ptr = string + 8n - let pptr = search + 8n + let mut ptr = stringPtr + 8n + let pptr = searchPtr + 8n let end = ptr + size - psize + 1n while (ptr < end) { @@ -158,6 +164,9 @@ provide let indexOf = (search: String, string: String) => { } } + ignore(search) + ignore(string) + return None } @@ -179,16 +188,16 @@ provide let lastIndexOf = (search: String, string: String) => { use WasmI32.{ (+), (-), (&), gtU as (>), geU as (>=), (==), (!=) } - let search = WasmI32.fromGrain(search) - let string = WasmI32.fromGrain(string) - let searchSize = WasmI32.load(search, 4n) - let stringSize = WasmI32.load(string, 4n) + let searchPtr = WasmI32.fromGrain(search) + let stringPtr = WasmI32.fromGrain(string) + let searchSize = WasmI32.load(searchPtr, 4n) + let stringSize = WasmI32.load(stringPtr, 4n) if (searchSize > stringSize) { return None } let mut stringIndex = untagSimpleNumber(lastIndex) - let searchPtr = search + 8n - let stringStartPtr = string + 8n + let searchPtr = searchPtr + 8n + let stringStartPtr = stringPtr + 8n for ( let mut stringPtr = stringStartPtr + stringSize - searchSize; stringPtr >= stringStartPtr; @@ -205,6 +214,9 @@ provide let lastIndexOf = (search: String, string: String) => { stringIndex -= 1n } + ignore(search) + ignore(string) + return None } @@ -268,8 +280,8 @@ let charAtHelp = (position, string: String) => { use WasmI32.{ (+), (&), (>>>), ltU as (<), (==) } let size = WasmI32.fromGrain(byteLength(string)) >>> 1n let position = WasmI32.fromGrain(position) >>> 1n - let string = WasmI32.fromGrain(string) - let mut ptr = string + 8n + let stringPre = WasmI32.fromGrain(string) + let mut ptr = stringPre + 8n let end = ptr + size let mut counter = 0n while (ptr < end) { @@ -290,6 +302,8 @@ let charAtHelp = (position, string: String) => { ptr += n } + ignore(string) + fail "charAt: should be impossible (please report)" } @@ -338,9 +352,9 @@ let explodeHelp = (s: String, chars) => { let size = WasmI32.fromGrain(byteLength(s)) >>> 1n let len = WasmI32.fromGrain(length(s)) >>> 1n - let s = WasmI32.fromGrain(s) + let sPtr = WasmI32.fromGrain(s) - let mut ptr = s + 8n + let mut ptr = sPtr + 8n let end = ptr + size let arr = allocateArray(len) @@ -361,9 +375,9 @@ let explodeHelp = (s: String, chars) => { let c = if (chars) { WasmI32.fromGrain(tagChar(getCodePoint(ptr))) } else { - let s = allocateString(n) - Memory.copy(s + 8n, ptr, n) - s + let sPtr = allocateString(n) + Memory.copy(sPtr + 8n, ptr, n) + sPtr } WasmI32.store(arr + arrIdx, c, 8n) @@ -371,6 +385,8 @@ let explodeHelp = (s: String, chars) => { ptr += n } + ignore(s) + arr } @@ -523,11 +539,11 @@ provide let split = (separator: String, string: String) => { } else if (psize > size) { [> string] } else { - let string = WasmI32.fromGrain(string) - let separator = WasmI32.fromGrain(separator) + let stringPtr = WasmI32.fromGrain(string) + let separatorPtr = WasmI32.fromGrain(separator) - let mut ptr = string + 8n - let mut pptr = separator + 8n + let mut ptr = stringPtr + 8n + let mut pptr = separatorPtr + 8n let end = ptr + size - psize + 1n let mut numStrings = 1n @@ -548,7 +564,7 @@ provide let split = (separator: String, string: String) => { } } - ptr = string + 8n + ptr = stringPtr + 8n let mut last = ptr let arr = allocateArray(numStrings) let mut arrIdx = 0n @@ -577,11 +593,14 @@ provide let split = (separator: String, string: String) => { } // Grab last string - let strSize = string + 8n + size - last + let strSize = stringPtr + 8n + size - last let lastStr = allocateString(strSize) Memory.copy(lastStr + 8n, last, strSize) WasmI32.store(arr + arrIdx, lastStr, 8n) + ignore(separator) + ignore(string) + WasmI32.toGrain(arr): Array } } @@ -613,7 +632,7 @@ provide let slice = (start: Number, end=length(string), string: String) => { let len = WasmI32.fromGrain(length(string)) >> 1n let size = WasmI32.fromGrain(byteLength(string)) >> 1n - let string = WasmI32.fromGrain(string) + let stringPtr = WasmI32.fromGrain(string) let mut start = WasmI32.fromGrain(start) if ((start & 1n) != 1n) { @@ -642,7 +661,7 @@ provide let slice = (start: Number, end=length(string), string: String) => { throw InvalidArgument("Start index exceeds end index") } - let mut ptr = string + 8n + let mut ptr = stringPtr + 8n let mut begin = ptr let mut end = ptr let stop = ptr + size @@ -663,7 +682,7 @@ provide let slice = (start: Number, end=length(string), string: String) => { ptr += 1n } if (to == len) { - end = string + 8n + size + end = stringPtr + 8n + size } if (start == to) { begin = end @@ -674,6 +693,8 @@ provide let slice = (start: Number, end=length(string), string: String) => { Memory.copy(newString + 8n, begin, newSize) + ignore(string) + WasmI32.toGrain(newString): String } @@ -710,11 +731,11 @@ provide let contains = (search: String, string: String) => { let n = WasmI32.fromGrain(byteLength(string)) >> 1n let m = WasmI32.fromGrain(byteLength(search)) >> 1n - let mut string = WasmI32.fromGrain(string) - let mut search = WasmI32.fromGrain(search) + let mut stringPtr = WasmI32.fromGrain(string) + let mut searchPtr = WasmI32.fromGrain(search) - string += 8n - search += 8n + stringPtr += 8n + searchPtr += 8n let mut j = 0n and k = 0n @@ -731,9 +752,9 @@ provide let contains = (search: String, string: String) => { return true } - let pat = WasmI32.load8U(search, 0n) + let pat = WasmI32.load8U(searchPtr, 0n) while (j < n) { - if (pat == WasmI32.load8U(string + j, 0n)) { + if (pat == WasmI32.load8U(stringPtr + j, 0n)) { return true } else { j += 1n @@ -744,7 +765,7 @@ provide let contains = (search: String, string: String) => { } // NSM preprocessing - if (WasmI32.load8U(search, 0n) == WasmI32.load8U(search, 1n)) { + if (WasmI32.load8U(searchPtr, 0n) == WasmI32.load8U(searchPtr, 1n)) { k = 2n ell = 1n } else { @@ -754,12 +775,12 @@ provide let contains = (search: String, string: String) => { // NSM searching while (j <= n - m) { - if (WasmI32.load8U(search, 1n) != WasmI32.load8U(string + j, 1n)) { + if (WasmI32.load8U(searchPtr, 1n) != WasmI32.load8U(stringPtr + j, 1n)) { j += k } else { if ( - Memory.compare(search + 2n, string + j + 2n, m - 2n) == 0n && - WasmI32.load8U(search, 0n) == WasmI32.load8U(string + j, 0n) + Memory.compare(searchPtr + 2n, stringPtr + j + 2n, m - 2n) == 0n && + WasmI32.load8U(searchPtr, 0n) == WasmI32.load8U(stringPtr + j, 0n) ) { return true } @@ -767,6 +788,9 @@ provide let contains = (search: String, string: String) => { } } + ignore(search) + ignore(string) + return false } @@ -787,21 +811,26 @@ provide let startsWith = (search: String, string: String) => { let pOrig = search let sOrig = string - let mut search = WasmI32.fromGrain(search) - let mut string = WasmI32.fromGrain(string) + let mut searchPtr = WasmI32.fromGrain(search) + let mut stringPtr = WasmI32.fromGrain(string) - let n = WasmI32.load(string, 4n) - let m = WasmI32.load(search, 4n) + let n = WasmI32.load(stringPtr, 4n) + let m = WasmI32.load(searchPtr, 4n) - string += 8n - search += 8n + stringPtr += 8n + searchPtr += 8n // Bail if pattern length is longer than input length - if (m > n) { + let result = if (m > n) { false } else { - Memory.compare(search, string, m) == 0n + Memory.compare(searchPtr, stringPtr, m) == 0n } + + ignore(search) + ignore(string) + + result } /** @@ -821,21 +850,26 @@ provide let endsWith = (search: String, string: String) => { let pOrig = search let sOrig = string - let mut search = WasmI32.fromGrain(search) - let mut string = WasmI32.fromGrain(string) + let mut searchPtr = WasmI32.fromGrain(search) + let mut stringPtr = WasmI32.fromGrain(string) - let n = WasmI32.load(string, 4n) - let m = WasmI32.load(search, 4n) + let n = WasmI32.load(stringPtr, 4n) + let m = WasmI32.load(searchPtr, 4n) - string += 8n - search += 8n + stringPtr += 8n + searchPtr += 8n // Bail if pattern length is longer than input length - if (m > n) { + let result = if (m > n) { false } else { - Memory.compare(search, string + n - m, m) == 0n + Memory.compare(searchPtr, stringPtr + n - m, m) == 0n } + + ignore(search) + ignore(string) + + result } /** @@ -895,6 +929,10 @@ provide let replaceFirst = ( } } + ignore(searchPattern) + ignore(string) + ignore(replacement) + return string } @@ -957,6 +995,10 @@ provide let replaceLast = ( } } + ignore(searchPattern) + ignore(string) + ignore(replacement) + return string } @@ -989,7 +1031,7 @@ provide let replaceAll = ( let replacementLen = WasmI32.load(replacementPtr, 4n) // Bail if search str is longer than the string - if (stringLen < patternLen) { + let result = if (stringLen < patternLen) { string } else { patternPtr += 8n @@ -1043,6 +1085,12 @@ provide let replaceAll = ( string } } + + ignore(searchPattern) + ignore(string) + ignore(replacement) + + result } // String->Byte encoding and helper functions: @@ -1075,9 +1123,9 @@ let utf16Length = (s: String) => { let size = WasmI32.fromGrain(byteLength(s)) >>> 1n let len = WasmI32.fromGrain(length(s)) >>> 1n - let s = WasmI32.fromGrain(s) + let sPtr = WasmI32.fromGrain(s) - let mut ptr = s + 8n + let mut ptr = sPtr + 8n let end = ptr + size let mut size = 0n // <- number of UTF-16 code words @@ -1099,11 +1147,13 @@ let utf16Length = (s: String) => { } ptr += n } + + ignore(s) + // multiply by two to get number of bytes tagSimpleNumber(size << 1n) } -@unsafe let encodedLength = (s: String, encoding) => { match (encoding) { UTF32_BE => length(s) * 4, @@ -1131,9 +1181,9 @@ let encodeAtHelp = ( let byteSize = WasmI32.fromGrain(byteLength(string)) >>> 1n let len = WasmI32.fromGrain(length(string)) >>> 1n - let string = WasmI32.fromGrain(string) + let stringPtr = WasmI32.fromGrain(string) - let mut ptr = string + 8n + let mut ptr = stringPtr + 8n let end = ptr + byteSize let bytes = WasmI32.fromGrain(dest) @@ -1358,6 +1408,8 @@ let encodeAtHelp = ( }, } + ignore(string) + dest } @@ -1472,7 +1524,7 @@ let bytesHaveBom = (bytes: Bytes, encoding: Encoding, start: WasmI32) => { let ptr = WasmI32.fromGrain(bytes) let bytesSize = WasmI32.load(ptr, 4n) let ptr = ptr + start - match (encoding) { + let result = match (encoding) { UTF8 => { bytesSize >= 3n && WasmI32.load8U(ptr, _BYTES_OFFSET) == 0xEFn && @@ -1504,6 +1556,10 @@ let bytesHaveBom = (bytes: Bytes, encoding: Encoding, start: WasmI32) => { WasmI32.load8U(ptr + 3n, _BYTES_OFFSET) == 0x00n }, } + + ignore(bytes) + + result } @unsafe @@ -1537,7 +1593,7 @@ let decodedLength = ( } } let start = ptr + _BYTES_OFFSET + start - match (encoding) { + let result = match (encoding) { UTF8 => bytesSize, UTF16_BE => { let end = start + bytesSize @@ -1674,6 +1730,10 @@ let decodedLength = ( count }, } + + ignore(bytes) + + result } @unsafe @@ -1723,7 +1783,7 @@ let decodeRangeHelp = ( UTF32_BE => 4n, } } - if (stringSize == 0n) { + let result = if (stringSize == 0n) { WasmI32.toGrain(str): String } else { match (encoding) { @@ -1808,6 +1868,10 @@ let decodeRangeHelp = ( } WasmI32.toGrain(str): String } + + ignore(bytes) + + result } /** @@ -1842,7 +1906,15 @@ provide let decodeRange = ( let decodeHelp = (bytes: Bytes, encoding: Encoding, skipBom: Bool) => { let bytesPtr = WasmI32.fromGrain(bytes) let bytesSize = WasmI32.load(bytesPtr, 4n) - decodeRangeHelp(bytes, encoding, skipBom, 0, tagSimpleNumber(bytesSize)) + let result = decodeRangeHelp( + bytes, + encoding, + skipBom, + 0, + tagSimpleNumber(bytesSize) + ) + ignore(bytes) + result } /** @@ -1907,6 +1979,9 @@ provide let forEachCodePoint = (fn: Number => Void, str: String) => { ptr += codePointByteCount idx += 1n } + + ignore(str) + void } @@ -1959,6 +2034,9 @@ provide let forEachCodePointi = (fn: (Number, Number) => Void, str: String) => { ptr += codePointByteCount idx += 1n } + + ignore(str) + void } @@ -2031,6 +2109,7 @@ provide let trimStart = (string: String) => { let count = trimString(stringPtr, byteLength, false) let str = allocateString(byteLength - count) Memory.copy(str + 8n, stringPtr + count, byteLength - count) + ignore(string) WasmI32.toGrain(str): String } /** @@ -2052,6 +2131,7 @@ provide let trimEnd = (string: String) => { let count = trimString(stringPtr, byteLength, true) let str = allocateString(byteLength - count) Memory.copy(str + 8n, stringPtr, byteLength - count) + ignore(string) WasmI32.toGrain(str): String } /** @@ -2079,6 +2159,7 @@ provide let trim = (string: String) => { stringPtr + startCount, byteLength - startCount - endCount ) + ignore(string) return WasmI32.toGrain(str): String } diff --git a/stdlib/wasi/file.gr b/stdlib/wasi/file.gr index a181a9c55..1218232d1 100644 --- a/stdlib/wasi/file.gr +++ b/stdlib/wasi/file.gr @@ -760,6 +760,8 @@ provide let fdWrite = (fd: FileDescriptor, data: Bytes) => { return Err(Wasi.SystemError(tagSimpleNumber(err))) } + ignore(data) + nwritten = WasmI32.load(nwritten, 0n) Memory.free(iovs) return Ok(tagSimpleNumber(nwritten)) @@ -797,6 +799,9 @@ provide let fdPwrite = (fd: FileDescriptor, data: Bytes, offset: Int64) => { return Err(Wasi.SystemError(tagSimpleNumber(err))) } + ignore(data) + ignore(offset) + nwritten = WasmI32.load(nwritten, 0n) Memory.free(iovs) return Ok(tagSimpleNumber(nwritten))