Skip to content

Commit 3c124bd

Browse files
committed
Merge remote-tracking branch 'origin/master' into release
2 parents 0e32ce8 + 0710219 commit 3c124bd

16 files changed

+3533
-163
lines changed

src/compiler.ts

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,17 +1440,37 @@ export class Compiler extends DiagnosticEmitter {
14401440
var nativeThisType = this.options.nativeSizeType;
14411441
var nativeValueType = type.toNativeType();
14421442
var module = this.module;
1443-
var valueExpr = module.local_get(1, nativeValueType);
1443+
var valueExpr: ExpressionRef;
1444+
var varTypes: NativeType[] | null = null;
14441445
if (type.isManaged) {
1445-
valueExpr = this.makeReplace(
1446-
module.load(type.byteSize, false,
1447-
module.local_get(0, nativeThisType),
1448-
nativeValueType, instance.memoryOffset
1446+
// Can't use makeReplace here since there's no corresponding flow, so
1447+
// 0: this, 1: value, 2: oldValue (temp)
1448+
valueExpr = module.block(null, [
1449+
module.if(
1450+
module.binary(nativeValueType == NativeType.I64 ? BinaryOp.NeI64 : BinaryOp.NeI32,
1451+
// value != (oldValue = this.field)
1452+
module.local_get(1, nativeValueType),
1453+
module.local_tee(2,
1454+
module.load(type.byteSize, false,
1455+
module.local_get(0, nativeThisType),
1456+
nativeValueType, instance.memoryOffset
1457+
)
1458+
)
1459+
),
1460+
module.block(null, [
1461+
module.drop(
1462+
this.makeRetain(module.local_get(1, nativeValueType))
1463+
),
1464+
this.makeRelease(module.local_get(2, nativeValueType))
1465+
])
14491466
),
1450-
valueExpr
1451-
);
1467+
module.local_get(1, nativeValueType)
1468+
], nativeValueType);
1469+
varTypes = [ nativeValueType ];
1470+
} else {
1471+
valueExpr = module.local_get(1, nativeValueType);
14521472
}
1453-
instance.setterRef = module.addFunction(instance.internalSetterName, createType([ nativeThisType, nativeValueType ]), NativeType.None, null,
1473+
instance.setterRef = module.addFunction(instance.internalSetterName, createType([ nativeThisType, nativeValueType ]), NativeType.None, varTypes,
14541474
module.store(type.byteSize,
14551475
module.local_get(0, nativeThisType),
14561476
valueExpr,
@@ -2652,7 +2672,7 @@ export class Compiler extends DiagnosticEmitter {
26522672
type = resolver.resolveType( // reports
26532673
declaration.type,
26542674
flow.actualFunction,
2655-
flow.contextualTypeArguments
2675+
makeMap(flow.contextualTypeArguments)
26562676
);
26572677
if (!type) continue;
26582678
if (declaration.initializer) {
@@ -3444,7 +3464,7 @@ export class Compiler extends DiagnosticEmitter {
34443464
let toType = this.resolver.resolveType( // reports
34453465
assert(expression.toType),
34463466
flow.actualFunction,
3447-
flow.contextualTypeArguments
3467+
makeMap(flow.contextualTypeArguments)
34483468
);
34493469
if (!toType) return this.module.unreachable();
34503470
return this.compileExpression(expression.expression, toType, inheritedConstraints | Constraints.CONV_EXPLICIT);
@@ -6702,7 +6722,14 @@ export class Compiler extends DiagnosticEmitter {
67026722
}
67036723

67046724
/** Makes a replace, retaining the new expression's value and releasing the old expression's value, in this order. */
6705-
makeReplace(oldExpr: ExpressionRef, newExpr: ExpressionRef, alreadyRetained: bool = false): ExpressionRef {
6725+
makeReplace(
6726+
/** Old value being replaced. */
6727+
oldExpr: ExpressionRef,
6728+
/** New value being assigned. */
6729+
newExpr: ExpressionRef,
6730+
/** Whether the new value is already retained. */
6731+
alreadyRetained: bool = false,
6732+
): ExpressionRef {
67066733
var module = this.module;
67076734
var flow = this.currentFlow;
67086735
var nativeSizeType = this.options.nativeSizeType;
@@ -7644,9 +7671,14 @@ export class Compiler extends DiagnosticEmitter {
76447671
// time of implementation, this seemed more useful because dynamic rhs expressions are not
76457672
// possible in AS anyway. also note that the code generated below must preserve side-effects of
76467673
// the LHS expression even when the result is a constant, i.e. return a block dropping `expr`.
7674+
var flow = this.currentFlow;
76477675
var expr = this.compileExpression(expression.expression, this.options.usizeType);
76487676
var actualType = this.currentType;
7649-
var expectedType = this.resolver.resolveType(expression.isType, this.currentFlow.actualFunction);
7677+
var expectedType = this.resolver.resolveType(
7678+
expression.isType,
7679+
flow.actualFunction,
7680+
makeMap(flow.contextualTypeArguments)
7681+
);
76507682
this.currentType = Type.bool;
76517683
if (!expectedType) return module.unreachable();
76527684

@@ -7687,7 +7719,6 @@ export class Compiler extends DiagnosticEmitter {
76877719
if (expectedType.isAssignableTo(actualType)) {
76887720
let program = this.program;
76897721
if (!(actualType.isUnmanaged || expectedType.isUnmanaged)) {
7690-
let flow = this.currentFlow;
76917722
let temp = flow.getTempLocal(actualType);
76927723
let instanceofInstance = assert(program.instanceofInstance);
76937724
this.compileFunction(instanceofInstance);
@@ -7737,7 +7768,6 @@ export class Compiler extends DiagnosticEmitter {
77377768
// FIXME: the temp local and the if can be removed here once flows
77387769
// perform null checking, which would error earlier when checking
77397770
// uninitialized (thus zero) `var a: A` to be an instance of something.
7740-
let flow = this.currentFlow;
77417771
let temp = flow.getTempLocal(actualType);
77427772
let instanceofInstance = assert(program.instanceofInstance);
77437773
this.compileFunction(instanceofInstance);

std/assembly/index.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1535,7 +1535,7 @@ interface RegExp {}
15351535
declare class Map<K,V> {
15361536
readonly size: i32;
15371537
has(key: K): bool;
1538-
set(key: K, value: V): void;
1538+
set(key: K, value: V): this;
15391539
get(key: K): V;
15401540
delete(key: K): bool;
15411541
clear(): void;
@@ -1547,7 +1547,7 @@ declare class Map<K,V> {
15471547
declare class Set<K> {
15481548
readonly size: i32;
15491549
has(value: K): bool;
1550-
add(value: K): void;
1550+
add(value: K): this;
15511551
delete(value: K): bool;
15521552
clear(): void;
15531553
values(): K[]; // preliminary

std/assembly/map.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export class Map<K,V> {
113113
}
114114

115115
@operator("[]=")
116-
set(key: K, value: V): void {
116+
set(key: K, value: V): this {
117117
var hashCode = HASH<K>(key);
118118
var entry = this.find(key, hashCode); // unmanaged!
119119
if (entry) {
@@ -151,6 +151,7 @@ export class Map<K,V> {
151151
entry.taggedNext = load<usize>(bucketPtrBase);
152152
store<usize>(bucketPtrBase, changetype<usize>(entry));
153153
}
154+
return this;
154155
}
155156

156157
delete(key: K): bool {

std/assembly/set.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export class Set<T> {
101101
return this.find(key, HASH<T>(key)) !== null;
102102
}
103103

104-
add(key: T): void {
104+
add(key: T): this {
105105
var hashCode = HASH<T>(key);
106106
var entry = this.find(key, hashCode); // unmanaged!
107107
if (!entry) {
@@ -124,6 +124,7 @@ export class Set<T> {
124124
entry.taggedNext = load<usize>(bucketPtrBase);
125125
store<usize>(bucketPtrBase, changetype<usize>(entry));
126126
}
127+
return this;
127128
}
128129

129130
@operator("[]=")

tests/compiler/extends-recursive.optimized.wat

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,11 @@
1212
i32.load
1313
)
1414
(func $extends-recursive/Parent#set:child (; 1 ;) (param $0 i32) (param $1 i32)
15-
(local $2 i32)
1615
local.get $0
17-
local.get $1
18-
local.tee $0
1916
i32.load
2017
drop
2118
local.get $0
19+
local.get $1
2220
i32.store
2321
)
2422
)

tests/compiler/extends-recursive.untouched.wat

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,21 @@
2121
nop
2222
)
2323
(func $extends-recursive/Parent#set:child (; 3 ;) (param $0 i32) (param $1 i32)
24+
(local $2 i32)
2425
local.get $0
2526
local.get $1
26-
local.tee $0
2727
local.get $0
2828
i32.load
29-
local.tee $1
29+
local.tee $2
3030
i32.ne
3131
if
32-
local.get $0
33-
call $~lib/rt/stub/__retain
34-
local.set $0
3532
local.get $1
33+
call $~lib/rt/stub/__retain
34+
drop
35+
local.get $2
3636
call $~lib/rt/stub/__release
3737
end
38-
local.get $0
38+
local.get $1
3939
i32.store
4040
)
4141
)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
exports.postInstantiate = function(instance) {
2+
const exports = instance.exports;
3+
4+
// using an integer value
5+
var basic = exports["Basic#constructor"](0, 123); // retain $0
6+
(() => {
7+
var val = exports["Basic#get:val"](basic);
8+
if (val != 123) throw Error("invalid value");
9+
exports["Basic#set:val"](basic, 42);
10+
val = exports["Basic#get:val"](basic);
11+
if (val != 42) throw Error("invalid value");
12+
})();
13+
14+
// using a managed value
15+
var managed = exports["Managed#constructor"](0, basic); // retain $1
16+
(() => {
17+
var foo = exports["Managed#get:foo"](managed); // retain $2
18+
if (foo != basic) throw Error("invalid value");
19+
exports.__release(foo); // release $2
20+
})();
21+
(() => {
22+
var foo = exports["Basic#constructor"](0, 321); // retain $3
23+
exports["Managed#set:foo"](managed, foo);
24+
exports.__release(foo); // release $3
25+
var expectedFoo = foo;
26+
foo = exports["Managed#get:foo"](managed); // retain $4
27+
if (foo != expectedFoo) throw Error("invalid value");
28+
exports.__release(foo); // releae $4
29+
})();
30+
31+
// combining both
32+
(() => {
33+
var foo = exports["Managed#get:foo"](managed); // retain $5
34+
var val = exports["Basic#get:val"](foo);
35+
if (val != 321) throw Error("invalid value");
36+
exports.__release(foo); // release $5
37+
})();
38+
39+
exports.__release(basic); // release $0
40+
exports.__release(managed); // release $1
41+
};
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"asc_flags": [
3+
"--runtime full",
4+
"--use ASC_RTRACE=1"
5+
]
6+
}

0 commit comments

Comments
 (0)