Skip to content

Commit e5a6745

Browse files
committed
works for Bar_Equals
1 parent 3c8e1df commit e5a6745

1 file changed

Lines changed: 105 additions & 46 deletions

File tree

src/compiler.ts

Lines changed: 105 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4507,7 +4507,7 @@ export class Compiler extends DiagnosticEmitter {
45074507
case Token.Bar_Equals: {
45084508
let cacheContext: CompoundAssignmentCacheContext | null = null;
45094509
let cacheTarget = this.getCompoundAssignmentSideEffectCacheTarget(left);
4510-
if (cacheTarget && this.needsCompoundAssignmentSideEffectCache(left)) {
4510+
if (cacheTarget && this.needsCompoundAssignmentSideEffectCache(cacheTarget)) {
45114511
cacheContext = this.prepareCompoundAssignmentCache(cacheTarget, contextualType.intType);
45124512
if (!cacheContext) return module.unreachable();
45134513
leftExpr = cacheContext.leftExpr;
@@ -4915,68 +4915,55 @@ export class Compiler extends DiagnosticEmitter {
49154915
let assignmentElementExpression: Expression | null = null;
49164916
let assignmentThisExpr: ExpressionRef = 0;
49174917
let assignmentElementExpr: ExpressionRef = 0;
4918+
let cachedThisLocal: Local | null = null;
4919+
let cachedThisType: Type = Type.void;
4920+
let cachedElementLocal: Local | null = null;
4921+
let cachedElementType: Type = Type.void;
49184922
let readThisExpression: Expression | null = null;
49194923
let readElementExpression: Expression | null = null;
49204924

49214925
if (cacheTarget.kind == NodeKind.PropertyAccess) {
49224926
let access = <PropertyAccessExpression>cacheTarget;
49234927
let receiverExpression = access.expression;
4928+
assignmentThisExpression = receiverExpression;
49244929
let receiverExpr = this.compileExpression(receiverExpression, Type.auto);
49254930
let receiverType = this.currentType;
49264931
let receiverTemp = flow.getTempLocal(receiverType);
4932+
cachedThisLocal = receiverTemp;
4933+
cachedThisType = receiverType;
49274934
flow.setLocalFlag(receiverTemp.index, LocalFlags.Initialized);
49284935
setupPrefixExprs = [ module.local_set(receiverTemp.index, receiverExpr, receiverType.isManaged) ];
4929-
let receiverCachedExpression = Node.createCompiledExpression(
4930-
module.local_get(receiverTemp.index, receiverType.toRef()),
4931-
receiverType,
4932-
receiverExpression.range
4933-
);
4934-
readThisExpression = receiverCachedExpression;
4935-
assignmentThisExpression = receiverCachedExpression;
49364936
} else {
49374937
let access = <ElementAccessExpression>cacheTarget;
49384938
let receiverExpression = access.expression;
49394939
let elementExpression = access.elementExpression;
4940-
let receiverForRead: Expression = receiverExpression;
4941-
let elementForRead: Expression = elementExpression;
49424940

4941+
readThisExpression = receiverExpression;
4942+
readElementExpression = elementExpression;
49434943
assignmentThisExpression = receiverExpression;
49444944
assignmentElementExpression = elementExpression;
49454945

49464946
if (this.expressionHasSideEffects(receiverExpression)) {
49474947
let receiverExpr = this.compileExpression(receiverExpression, Type.auto);
49484948
let receiverType = this.currentType;
49494949
let receiverTemp = flow.getTempLocal(receiverType);
4950+
cachedThisLocal = receiverTemp;
4951+
cachedThisType = receiverType;
49504952
flow.setLocalFlag(receiverTemp.index, LocalFlags.Initialized);
49514953
if (!setupPrefixExprs) setupPrefixExprs = [];
49524954
setupPrefixExprs.push(module.local_set(receiverTemp.index, receiverExpr, receiverType.isManaged));
4953-
let receiverCachedExpression = Node.createCompiledExpression(
4954-
module.local_get(receiverTemp.index, receiverType.toRef()),
4955-
receiverType,
4956-
receiverExpression.range
4957-
);
4958-
receiverForRead = receiverCachedExpression;
4959-
assignmentThisExpression = receiverCachedExpression;
49604955
}
49614956

49624957
if (this.expressionHasSideEffects(elementExpression)) {
49634958
let elementExpr = this.compileExpression(elementExpression, Type.auto);
49644959
let elementType = this.currentType;
49654960
let elementTemp = flow.getTempLocal(elementType);
4961+
cachedElementLocal = elementTemp;
4962+
cachedElementType = elementType;
49664963
flow.setLocalFlag(elementTemp.index, LocalFlags.Initialized);
49674964
if (!setupPrefixExprs) setupPrefixExprs = [];
49684965
setupPrefixExprs.push(module.local_set(elementTemp.index, elementExpr, elementType.isManaged));
4969-
let elementCachedExpression = Node.createCompiledExpression(
4970-
module.local_get(elementTemp.index, elementType.toRef()),
4971-
elementType,
4972-
elementExpression.range
4973-
);
4974-
elementForRead = elementCachedExpression;
4975-
assignmentElementExpression = elementCachedExpression;
49764966
}
4977-
4978-
readThisExpression = receiverForRead;
4979-
readElementExpression = elementForRead;
49804967
}
49814968

49824969
let leftExpr: ExpressionRef;
@@ -4992,13 +4979,37 @@ export class Compiler extends DiagnosticEmitter {
49924979
let getterInstance = (<Property>target).getterInstance;
49934980
if (!getterInstance) return null;
49944981
if (getterInstance.is(CommonFlags.Instance)) {
4995-
let thisArg = this.compileExpression(
4996-
assert(readThisExpression),
4997-
assert(getterInstance.signature.thisType),
4998-
Constraints.ConvImplicit | Constraints.IsThis
4999-
);
5000-
assignmentThisExpr = thisArg;
5001-
leftExpr = this.compileCallDirect(getterInstance, [], cacheTarget, thisArg);
4982+
let thisType = assert(getterInstance.signature.thisType);
4983+
if (cachedThisLocal) {
4984+
let thisRef = cachedThisType.toRef();
4985+
let thisArg = this.convertExpression(
4986+
module.local_get(cachedThisLocal.index, thisRef),
4987+
cachedThisType,
4988+
thisType,
4989+
false,
4990+
cacheTarget
4991+
);
4992+
assignmentThisExpr = this.convertExpression(
4993+
module.local_get(cachedThisLocal.index, thisRef),
4994+
cachedThisType,
4995+
thisType,
4996+
false,
4997+
cacheTarget
4998+
);
4999+
leftExpr = this.compileCallDirect(getterInstance, [], cacheTarget, thisArg);
5000+
} else {
5001+
let thisArg = this.compileExpression(
5002+
assert(readThisExpression),
5003+
thisType,
5004+
Constraints.ConvImplicit | Constraints.IsThis
5005+
);
5006+
assignmentThisExpr = this.compileExpression(
5007+
assert(assignmentThisExpression),
5008+
thisType,
5009+
Constraints.ConvImplicit | Constraints.IsThis
5010+
);
5011+
leftExpr = this.compileCallDirect(getterInstance, [], cacheTarget, thisArg);
5012+
}
50025013
} else {
50035014
leftExpr = this.compileCallDirect(getterInstance, [], cacheTarget);
50045015
}
@@ -5019,18 +5030,66 @@ export class Compiler extends DiagnosticEmitter {
50195030
);
50205031
return null;
50215032
}
5022-
let thisArg = this.compileExpression(
5023-
assert(readThisExpression),
5024-
classInstance.type,
5025-
Constraints.ConvImplicit | Constraints.IsThis
5026-
);
5027-
let indexArg = this.compileExpression(
5028-
assert(readElementExpression),
5029-
getterInstance.signature.parameterTypes[0],
5030-
Constraints.ConvImplicit
5031-
);
5032-
assignmentThisExpr = thisArg;
5033-
assignmentElementExpr = indexArg;
5033+
let thisType = classInstance.type;
5034+
let thisArg: ExpressionRef;
5035+
if (cachedThisLocal) {
5036+
let thisRef = cachedThisType.toRef();
5037+
thisArg = this.convertExpression(
5038+
module.local_get(cachedThisLocal.index, thisRef),
5039+
cachedThisType,
5040+
thisType,
5041+
false,
5042+
cacheTarget
5043+
);
5044+
assignmentThisExpr = this.convertExpression(
5045+
module.local_get(cachedThisLocal.index, thisRef),
5046+
cachedThisType,
5047+
thisType,
5048+
false,
5049+
cacheTarget
5050+
);
5051+
} else {
5052+
thisArg = this.compileExpression(
5053+
assert(readThisExpression),
5054+
thisType,
5055+
Constraints.ConvImplicit | Constraints.IsThis
5056+
);
5057+
assignmentThisExpr = this.compileExpression(
5058+
assert(assignmentThisExpression),
5059+
thisType,
5060+
Constraints.ConvImplicit | Constraints.IsThis
5061+
);
5062+
}
5063+
let indexType = getterInstance.signature.parameterTypes[0];
5064+
let indexArg: ExpressionRef;
5065+
if (cachedElementLocal) {
5066+
let elementRef = cachedElementType.toRef();
5067+
indexArg = this.convertExpression(
5068+
module.local_get(cachedElementLocal.index, elementRef),
5069+
cachedElementType,
5070+
indexType,
5071+
false,
5072+
cacheTarget
5073+
);
5074+
assignmentElementExpr = this.convertExpression(
5075+
module.local_get(cachedElementLocal.index, elementRef),
5076+
cachedElementType,
5077+
indexType,
5078+
false,
5079+
cacheTarget
5080+
);
5081+
} else {
5082+
indexArg = this.compileExpression(
5083+
assert(readElementExpression),
5084+
indexType,
5085+
Constraints.ConvImplicit
5086+
);
5087+
assignmentElementExpr = this.compileExpression(
5088+
assert(assignmentElementExpression),
5089+
indexType,
5090+
Constraints.ConvImplicit
5091+
);
5092+
}
50345093
leftExpr = this.makeCallDirect(getterInstance, [ thisArg, indexArg ], cacheTarget);
50355094
leftType = this.currentType;
50365095
break;

0 commit comments

Comments
 (0)