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
6 changes: 4 additions & 2 deletions tslang/lib/TypeScript/OwnershipFacts.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,9 @@ inline bool holdsAsIs(mlir::Type wide, mlir::Type narrow, bool onlyNullable = fa

// An op whose result is the very block its operand holds: a class widened to a union or an
// optional or narrowed back, a union made from its payload or read back from it, an object seen
// through an interface (`{vtable, this}`, released through `this`). rc's retain or release of
// through an interface (`{vtable, this}`, released through `this`), and an interface seen as
// another one or inside a union (`this` is the same; a vtable laid out for the other interface is
// interned, nobody's block). rc's retain or release of
// either is one of the block, so the pass looks through them. A cast that converts (a number
// printed into a string) or boxes (into `any`) makes a new block and is not one.
inline bool isView(mlir::Operation *op)
Expand All @@ -233,7 +235,7 @@ inline bool isView(mlir::Operation *op)
}

auto keeps = [](mlir::Type type) {
return mlir::isa<mlir_ts::ClassType, mlir_ts::UnionType, mlir_ts::OptionalType>(type);
return mlir::isa<mlir_ts::ClassType, mlir_ts::InterfaceType, mlir_ts::UnionType, mlir_ts::OptionalType>(type);
};
// a bound function and a hybrid one are the same `{func, this, tag}`: a closure passed on as
// a function value is still its box
Expand Down
8 changes: 8 additions & 0 deletions tslang/test/tester/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3774,6 +3774,14 @@ endforeach()
# a null class object given to an interface (also in TSLANG_CORPUS: rc, none)
tslang_add_test(NAME test-jit-own-00-class-to-interface-null COMMAND test-runner -jit -mm=own "${PROJECT_SOURCE_DIR}/test/tester/tests/00class_to_interface_null.ts")
tslang_add_test(NAME test-compile-own-00-class-to-interface-null COMMAND test-runner -mm=own "${PROJECT_SOURCE_DIR}/test/tester/tests/00class_to_interface_null.ts")
# an interface value seen as another interface, or as one inside a union, is the block it shows:
# own moves and borrows it as it does the object (also in TSLANG_CORPUS: rc, none)
foreach(iface_cast_test 00interface_cast_unrelated 00interface_union_cast_unrelated 00nullable_interface_to_interface
00null_interface_to_interface)
string(REPLACE "_" "-" iface_cast_name "${iface_cast_test}")
tslang_add_test(NAME test-jit-own-${iface_cast_name} COMMAND test-runner -jit -mm=own "${PROJECT_SOURCE_DIR}/test/tester/tests/${iface_cast_test}.ts")
tslang_add_test(NAME test-compile-own-${iface_cast_name} COMMAND test-runner -mm=own "${PROJECT_SOURCE_DIR}/test/tester/tests/${iface_cast_test}.ts")
endforeach()

# A `let` given a new value after its value moved owns the new one (#528); the same program under
# rc and gc (not none: nothing is freed there, and the loops would hold about 800 MB).
Expand Down
7 changes: 4 additions & 3 deletions tslang/test/tester/tests/00interface_cast_unrelated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ function main() {
assert(d2.dist == 3, "a field of a call's result");
assert(distOf(h) == 3, "a field of an argument");
assert((<HasDist>h).dist == 3, "a field through <T>");
const ds: HasDist[] = [h];
const ds: HasDist[] = [mkHit()];
assert(ds[0].dist == 3, "a field of an element");

// two members in another order
Expand Down Expand Up @@ -122,8 +122,9 @@ function main() {
// casts made again and again share one vtable per content and keep reading right
let sum: number = 0;
for (let i = 0; i < 1000; i++) {
const each: HasDist = i % 2 == 0 ? h : hc;
sum += each.dist;
const even: HasDist = h;
const odd: HasDist = hc;
sum += i % 2 == 0 ? even.dist : odd.dist;
}
assert(sum == 500 * 3 + 500 * 30, "casts in a loop");

Expand Down
3 changes: 1 addition & 2 deletions tslang/test/tester/tests/00null_interface_to_interface.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// @strict-null false
// A null interface cast to an interface it does not extend, whose members are elsewhere (#666 builds
// that interface's vtable out of the value's own one) is null still, and its methods throw: the null
// vtable's slots, stubs that throw, are what the new vtable is made of. Not under -mm=own, which
// does not take an interface value of one interface as another yet.
// vtable's slots, stubs that throw, are what the new vtable is made of.
interface Hit {
thing: number;
dist: number;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// An interface-or-null given to another interface-or-null whose interface it does not extend is the
// interface-to-interface cast (#666), which builds the target's vtable out of the value's own one. A
// plain copy kept the source's vtable, and a field read through the target read a method slot as the
// field's offset. A null value is null still, and its methods throw. Not under -mm=own, which does not
// take this program's interface values returned from calls yet.
// field's offset. A null value is null still, and its methods throw.
interface Shape {
id: number;
area(): number;
Expand Down
Loading