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
12 changes: 12 additions & 0 deletions tslang/lib/TypeScript/MLIRGenImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1611,12 +1611,18 @@ class MLIRGenImpl
// And a tuple literal folded to a constant with an array in it (`const st = [1, [6, 7]]`,
// `const o = { items: [1, 2] }`): its arrays are static headers over constant data, so
// it is widened to a tuple of heap copies once, here, like a const array literal (#479).
//
// And a tuple literal built at run time (`const nt = [x, [2, [3, 4]]]`), whose arrays
// are born with no count: folded, nothing counted them, and `nt[1][1].push(5)` had no
// reference to change the array through (#486).
MLIRTypeHelper mth(builder.getContext(), compileOptions);
needsIdentityStorage = mth.hasBoundMethodField(type) || isa<mlir_ts::ConstArrayType>(type)
|| MLIRTypeHelper::isConstTupleHoldingArray(type)
|| ((isa<mlir_ts::ArrayType>(type) || MLIRTypeHelper::isSharedHandleType(type)
|| (readsLocalSlot(initial) && mth.ownsHeapMemory(location, type))
|| (readsLiteralSlot(mth, location, initial) && isa<mlir_ts::TupleType>(type)
&& mth.ownsHeapMemory(location, type))
|| (initial && initial.getDefiningOp<mlir_ts::CreateTupleOp>() && isa<mlir_ts::TupleType>(type)
&& mth.ownsHeapMemory(location, type)))
&& !(varClass == VariableType::ConstRef)
&& !(initial && initial.getDefiningOp<mlir_ts::SafeCastOp>()));
Expand Down Expand Up @@ -9698,6 +9704,12 @@ class MLIRGenImpl
{
CAST(value, location, mth.convertConstTupleTypeToTupleType(value.getType()), value, genContext);
}
// and a constant array (`[x, [1]]`) is an array of its own, which push and pop change:
// kept as the literal's constant data, `t[1].push(2)` did not resolve (#486)
else if (isa<mlir_ts::ConstArrayType>(value.getType()))
{
CAST(value, location, mth.convertConstArrayTypeToArrayType(value.getType()), value, genContext);
}

fieldInfos.push_back({mlir::Attribute(), value.getType(), false, mlir_ts::AccessLevel::Public});
arrayValues.push_back(value);
Expand Down
3 changes: 3 additions & 0 deletions tslang/test/tester/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ tslang_add_test(NAME test-compile-00-array-rest-copy COMMAND test-runner "${PROJ
tslang_add_test(NAME test-compile-00-arrays6 COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00array6.ts")
tslang_add_test(NAME test-compile-00-array-static-nested COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00array_static_nested.ts")
tslang_add_test(NAME test-compile-00-array-literal-copy COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00array_literal_copy.ts")
tslang_add_test(NAME test-compile-00-tuple-runtime-arrays COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00tuple_runtime_arrays.ts")
tslang_add_test(NAME test-compile-00-const-record-owned-fields COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00const_record_owned_fields.ts")
tslang_add_test(NAME test-compile-00-array-length-valid COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00array_length_valid.ts")
tslang_add_test(NAME test-compile-00-string-view-copy COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00string_view_copy.ts")
Expand Down Expand Up @@ -853,6 +854,7 @@ tslang_add_test(NAME test-jit-00-array-rest-copy COMMAND test-runner -jit "${PRO
tslang_add_test(NAME test-jit-00-arrays6 COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00array6.ts")
tslang_add_test(NAME test-jit-00-array-static-nested COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00array_static_nested.ts")
tslang_add_test(NAME test-jit-00-array-literal-copy COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00array_literal_copy.ts")
tslang_add_test(NAME test-jit-00-tuple-runtime-arrays COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00tuple_runtime_arrays.ts")
tslang_add_test(NAME test-jit-00-const-record-owned-fields COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00const_record_owned_fields.ts")
tslang_add_test(NAME test-jit-00-array-length-valid COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00array_length_valid.ts")
tslang_add_test(NAME test-jit-00-string-view-copy COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00string_view_copy.ts")
Expand Down Expand Up @@ -1687,6 +1689,7 @@ set(TSLANG_CORPUS
00array6.ts
00array_static_nested.ts
00array_literal_copy.ts
00tuple_runtime_arrays.ts
00const_record_owned_fields.ts
00array_length_valid.ts
00string_view_copy.ts
Expand Down
27 changes: 27 additions & 0 deletions tslang/test/tester/tests/00tuple_runtime_arrays.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// The arrays of a tuple literal built at run time can be changed (#486): a constant array in it
// (`[x, [1]]`) is a heap array of its own, not the literal's constant data that push did not
// resolve on, and a `const` of such a tuple has storage, as a `let` has, so `nt[1][1].push(5)`
// has a reference to change the array through and the arrays are counted.
function g(t: [number, number[]]) { t[1].push(9); return t[1].length; }
function main() {
let x = 3;
let t = [x, [1]];
t[1].push(2);
assert(t[1].length == 2 && t[1][1] == 2, "let, constant array in a run-time tuple");
const c = [x, [1]];
c[1].pop();
assert(c[1].length == 0, "const, constant array in a run-time tuple");
const nt = [x, [2, [3, 4]]];
nt[1][1].push(5);
assert(nt[1][1].length == 3, "const, nested");
const s = ["a" + x, [x, x]];
s[1].push(1);
assert(s[0] == "a3" && s[1].length == 3, "a string and an array");
assert(g([x, [1, 2]]) == 3, "to a tuple parameter");
for (let i = 0; i < 3; i++) {
const e = [i, [i]];
e[1].push(i);
assert(e[1].length == 2, "a new array each pass");
}
print("done.");
}
Loading