Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion tslang/include/TypeScript/LowerToLLVM/CastLogicHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ class CastLogicHelper

if (inType.isIndex() && isResString)
{
return castIntToString(in, tch.getIndexTypeBitwidth(), false);
// signed, as index compares and converts to number: `s.length - 3` is -1, not 18446744073709551615
return castIntToString(in, tch.getIndexTypeBitwidth(), true);
}

if (isa<mlir::IntegerType>(inType) && isResString)
Expand Down Expand Up @@ -150,6 +151,13 @@ class CastLogicHelper
}
}

// a signed integer keeps its sign as an index: `let n = s.length; n = -1` held 4294967295 under the
// zext in castLLVMTypesLogic
if (inType.isSignedInteger() && resType.isIndex() && resLLVMType.getIntOrFloatBitWidth() > inType.getIntOrFloatBitWidth())
{
return rewriter.create<LLVM::SExtOp>(loc, resLLVMType, in);
}

// TODO: should be in LLVM cast?
if (inType.isSignedInteger() && resType.isSignedInteger() && resType.getIntOrFloatBitWidth() > inType.getIntOrFloatBitWidth())
{
Expand Down
2 changes: 2 additions & 0 deletions tslang/test/tester/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ tslang_add_test(NAME test-compile-00-union-nullable-value COMMAND test-runner "$
tslang_add_test(NAME test-compile-00-union-value-equality COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00union_value_equality.ts")
tslang_add_test(NAME test-compile-00-strict-equals-mismatched-types COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00strict_equals_mismatched_types.ts")
tslang_add_test(NAME test-compile-00-length-with-negative-merge COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00length_with_negative_merge.ts")
tslang_add_test(NAME test-compile-00-length-signed-arithmetic COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00length_signed_arithmetic.ts")
tslang_add_test(NAME test-compile-00-intersection-type COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00intersection_type.ts")
tslang_add_test(NAME test-compile-00-intersection-type-generic COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00intersection_type_generic.ts")
tslang_add_test(NAME test-compile-00-length COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00length.ts")
Expand Down Expand Up @@ -867,6 +868,7 @@ tslang_add_test(NAME test-jit-00-union-nullable-value COMMAND test-runner -jit "
tslang_add_test(NAME test-jit-00-union-value-equality COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00union_value_equality.ts")
tslang_add_test(NAME test-jit-00-strict-equals-mismatched-types COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00strict_equals_mismatched_types.ts")
tslang_add_test(NAME test-jit-00-length-with-negative-merge COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00length_with_negative_merge.ts")
tslang_add_test(NAME test-jit-00-length-signed-arithmetic COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00length_signed_arithmetic.ts")
tslang_add_test(NAME test-jit-00-union-global-init COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00union_global_init.ts")
tslang_add_test(NAME test-jit-00-intersection-type COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00intersection_type.ts")
tslang_add_test(NAME test-jit-00-intersection-type-generic COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00intersection_type_generic.ts")
Expand Down
45 changes: 45 additions & 0 deletions tslang/test/tester/tests/00length_signed_arithmetic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// A length is an index; it holds, compares and prints as a signed value, as a JS number would:
// a variable initialised from one keeps -1 when assigned it, and a length minus more is negative
function assigned(s: string) {
let n = s.length;
n = -1;
assert(n == -1, "n == -1");
assert(n < 0, "n < 0");
const asNumber: number = n;
assert(asNumber == -1, "as number");
assert(`${n}` == "-1", "as text");
assert("" + n == "-1", "concatenated");
const boxed: any = n;
assert(`${boxed}` == "-1", "boxed");
}

function subtracted(s: string, a: number[]) {
assert(`${s.length - 3}` == "-1", "string length - 3");
assert(`${a.length - 5}` == "-3", "array length - 5");
assert(a.length - 5 < 0, "array length - 5 < 0");

let i = s.length;
i--; i--; i--; i--;
assert(`${i}` == "-2", "decremented");

let w = a.length;
w -= 5;
assert(`${w}` == "-3", "-=");
}

function countdown(s: string) {
let visited = 0;
for (let k = s.length - 1; k >= 0; k--) {
visited++;
if (visited > 10) break;
}

assert(visited == 2, "countdown");
}

function main() {
assigned("ab");
subtracted("ab", [1, 2]);
countdown("ab");
print("done.");
}
Loading