Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 34c34f3

Browse files
authoredJan 26, 2020
Split compilation of fields and properties (#1076)
1 parent 1bf4140 commit 34c34f3

File tree

2 files changed

+57
-16
lines changed

2 files changed

+57
-16
lines changed
 

‎src/compiler.ts

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,22 +1400,36 @@ export class Compiler extends DiagnosticEmitter {
14001400

14011401
/** Compiles an instance field to a getter and a setter. */
14021402
compileField(instance: Field): bool {
1403-
if (instance.is(CommonFlags.COMPILED)) return true;
1404-
instance.set(CommonFlags.COMPILED);
1403+
this.compileFieldGetter(instance);
1404+
this.compileFieldSetter(instance);
1405+
return instance.is(CommonFlags.COMPILED);
1406+
}
1407+
1408+
/** Compiles the getter of the specified instance field. */
1409+
compileFieldGetter(instance: Field): bool {
1410+
// A getter retains, while a load, as of a field access, does not.
1411+
if (instance.getterRef) return true;
14051412
var type = instance.type;
14061413
var nativeThisType = this.options.nativeSizeType;
14071414
var nativeValueType = type.toNativeType();
14081415
var module = this.module;
1409-
1410-
// Make a getter
1411-
var returnExpr = module.load(type.byteSize, type.is(TypeFlags.SIGNED),
1416+
var valueExpr = module.load(type.byteSize, type.is(TypeFlags.SIGNED),
14121417
module.local_get(0, nativeThisType),
14131418
nativeValueType, instance.memoryOffset
14141419
);
1415-
if (type.isManaged) returnExpr = this.makeRetain(returnExpr);
1416-
module.addFunction(instance.internalGetterName, nativeThisType, nativeValueType, null, returnExpr);
1420+
if (type.isManaged) valueExpr = this.makeRetain(valueExpr);
1421+
instance.getterRef = module.addFunction(instance.internalGetterName, nativeThisType, nativeValueType, null, valueExpr);
1422+
if (instance.setterRef) instance.set(CommonFlags.COMPILED);
1423+
return true;
1424+
}
14171425

1418-
// Make a setter
1426+
/** Compiles the setter of the specified instance field. */
1427+
compileFieldSetter(instance: Field): bool {
1428+
if (instance.setterRef) return true;
1429+
var type = instance.type;
1430+
var nativeThisType = this.options.nativeSizeType;
1431+
var nativeValueType = type.toNativeType();
1432+
var module = this.module;
14191433
var valueExpr = module.local_get(1, nativeValueType);
14201434
if (type.isManaged) {
14211435
valueExpr = this.makeReplace(
@@ -1426,26 +1440,50 @@ export class Compiler extends DiagnosticEmitter {
14261440
valueExpr
14271441
);
14281442
}
1429-
module.addFunction(instance.internalSetterName, createType([ nativeThisType, nativeValueType ]), NativeType.None, null,
1443+
instance.setterRef = module.addFunction(instance.internalSetterName, createType([ nativeThisType, nativeValueType ]), NativeType.None, null,
14301444
module.store(type.byteSize,
14311445
module.local_get(0, nativeThisType),
14321446
valueExpr,
14331447
nativeValueType, instance.memoryOffset
14341448
)
14351449
);
1436-
1450+
if (instance.getterRef) instance.set(CommonFlags.COMPILED);
14371451
return true;
14381452
}
14391453

14401454
/** Compiles a property to a getter and potentially a setter. */
14411455
compileProperty(instance: Property): bool {
1442-
if (instance.is(CommonFlags.COMPILED)) return true;
1443-
instance.set(CommonFlags.COMPILED);
1456+
this.compilePropertyGetter(instance);
1457+
this.compilePropertySetter(instance);
1458+
return instance.is(CommonFlags.COMPILED);
1459+
}
1460+
1461+
/* Compiles the getter of the specified property. */
1462+
compilePropertyGetter(instance: Property): bool {
14441463
var getterInstance = instance.getterInstance;
1445-
if (getterInstance) this.compileFunction(getterInstance);
1464+
if (getterInstance) {
1465+
let ret = this.compileFunction(getterInstance);
1466+
let setterInstance = instance.setterInstance;
1467+
if (getterInstance.is(CommonFlags.COMPILED) && (!setterInstance || setterInstance.is(CommonFlags.COMPILED))) {
1468+
instance.set(CommonFlags.COMPILED);
1469+
}
1470+
return ret;
1471+
}
1472+
return false;
1473+
}
1474+
1475+
/** Compiles the setter of the specified property. */
1476+
compilePropertySetter(instance: Property): bool {
14461477
var setterInstance = instance.setterInstance;
1447-
if (setterInstance) this.compileFunction(setterInstance);
1448-
return true;
1478+
if (setterInstance) {
1479+
let ret = this.compileFunction(setterInstance);
1480+
let getterInstance = instance.getterInstance;
1481+
if (getterInstance !== null && getterInstance.is(CommonFlags.COMPILED) && setterInstance.is(CommonFlags.COMPILED)) {
1482+
instance.set(CommonFlags.COMPILED);
1483+
}
1484+
return ret;
1485+
}
1486+
return false;
14491487
}
14501488

14511489
// === Memory ===================================================================================
@@ -8298,7 +8336,6 @@ export class Compiler extends DiagnosticEmitter {
82988336
assert((<Field>target).memoryOffset >= 0);
82998337
let thisExpression = assert(this.resolver.currentThisExpression);
83008338
let thisExpr = this.compileExpression(thisExpression, this.options.usizeType);
8301-
// FIXME
83028339
let thisType = this.currentType;
83038340
if (thisType.is(TypeFlags.NULLABLE)) {
83048341
if (!flow.isNonnull(thisExpr, thisType)) {

‎src/program.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3048,6 +3048,10 @@ export class Field extends VariableLikeElement {
30483048
prototype: FieldPrototype;
30493049
/** Field memory offset, if an instance field. */
30503050
memoryOffset: i32 = -1;
3051+
/** Getter function reference, if compiled. */
3052+
getterRef: FunctionRef = 0;
3053+
/** Setter function reference, if compiled. */
3054+
setterRef: FunctionRef = 0;
30513055

30523056
/** Constructs a new field. */
30533057
constructor(

0 commit comments

Comments
 (0)
Please sign in to comment.