Skip to content

Commit 743ef7e

Browse files
committed
Polishing
- Fix self compilation - Add strict property initialization flags for TS - Handle constructor inlining
1 parent e16b6e5 commit 743ef7e

40 files changed

+1120
-1960
lines changed

src/ast.ts

Lines changed: 123 additions & 123 deletions
Large diffs are not rendered by default.

src/builtins.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -597,19 +597,19 @@ export namespace BuiltinNames {
597597
/** Builtin compilation context. */
598598
export class BuiltinContext {
599599
/** Compiler reference. */
600-
compiler: Compiler;
600+
compiler!: Compiler;
601601
/** Prototype being called. */
602-
prototype: FunctionPrototype;
602+
prototype!: FunctionPrototype;
603603
/** Provided type arguments. */
604-
typeArguments: Type[] | null;
604+
typeArguments: Type[] | null = null;
605605
/** Provided operands. */
606-
operands: Expression[];
606+
operands!: Expression[];
607607
/** Contextual type. */
608-
contextualType: Type;
608+
contextualType!: Type;
609609
/** Respective call expression. */
610-
reportNode: CallExpression;
610+
reportNode!: CallExpression;
611611
/** Whether originating from inline assembly. */
612-
contextIsExact: bool;
612+
contextIsExact!: bool;
613613
}
614614

615615
/** Global builtins map. */

src/compiler.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -318,13 +318,13 @@ export class Compiler extends DiagnosticEmitter {
318318
module: Module;
319319

320320
/** Current control flow. */
321-
currentFlow: Flow;
321+
currentFlow!: Flow;
322322
/** Current parent element if not a function, i.e. an enum or namespace. */
323323
currentParent: Element | null = null;
324324
/** Current type in compilation. */
325325
currentType: Type = Type.void;
326326
/** Start function statements. */
327-
currentBody: ExpressionRef[];
327+
currentBody!: ExpressionRef[];
328328
/** Counting memory offset. */
329329
memoryOffset: i64;
330330
/** Memory segments being compiled. */
@@ -2814,7 +2814,7 @@ export class Compiler extends DiagnosticEmitter {
28142814
outerFlow.popBreakLabel();
28152815

28162816
// If the switch has a default (guaranteed to handle any value), propagate common flags
2817-
if (defaultIndex >= 0){
2817+
if (defaultIndex >= 0) {
28182818
outerFlow.flags |= commonCategorical & ~FlowFlags.BREAKS;
28192819

28202820
// If the switch:
@@ -2826,7 +2826,7 @@ export class Compiler extends DiagnosticEmitter {
28262826
if (flows.length == 1) {
28272827
this.currentFlow.inheritFieldFlags(flows[0]);
28282828
} else {
2829-
for(let i = 0; i < flows.length; ++i) {
2829+
for (let i = 0; i < flows.length; ++i) {
28302830
if (i < (flows.length - 1)) {
28312831
const left = flows[i];
28322832
const right = flows[i + 1];
@@ -8900,7 +8900,6 @@ export class Compiler extends DiagnosticEmitter {
89008900
): ExpressionRef {
89018901
var ctor = this.ensureConstructor(classInstance, reportNode);
89028902
if (classInstance.type.isUnmanaged || ctor.hasDecorator(DecoratorFlags.UNSAFE)) this.checkUnsafe(reportNode);
8903-
this.checkFieldInitialization(classInstance);
89048903
var expr = this.compileCallDirect( // no need for another autoreleased local
89058904
ctor,
89068905
argumentExpressions,
@@ -8911,6 +8910,8 @@ export class Compiler extends DiagnosticEmitter {
89118910
if (getExpressionType(expr) != NativeType.None) { // possibly IMM_DROPPED
89128911
this.currentType = classInstance.type; // important because a super ctor could be called
89138912
}
8913+
8914+
this.checkFieldInitialization(classInstance);
89148915
return expr;
89158916
}
89168917

@@ -10119,7 +10120,7 @@ export class Compiler extends DiagnosticEmitter {
1011910120
field.memoryOffset
1012010121
)
1012110122
);
10122-
flow.setFieldFlag(field.internalName, FieldFlags.INITIALIZED)
10123+
flow.setFieldFlag(field.internalName, FieldFlags.INITIALIZED);
1012310124
} else {
1012410125
flow.setFieldFlag(field.internalName, FieldFlags.NONE);
1012510126
}

src/definitions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export abstract class ExportsWalker {
5757
/** Constructs a new Element walker. */
5858
constructor(program: Program, includePrivate: bool = false) {
5959
this.program = program;
60-
this.includePrivate;
60+
this.includePrivate = includePrivate;
6161
}
6262

6363
/** Walks all elements and calls the respective handlers. */

src/flow.ts

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -189,43 +189,36 @@ export const enum ConditionKind {
189189
export class Flow {
190190

191191
/** Parent flow. */
192-
parent: Flow | null;
192+
parent: Flow | null = null;
193193
/** Flow flags indicating specific conditions. */
194-
flags: FlowFlags;
194+
flags: FlowFlags = FlowFlags.NONE;
195195
/** Function this flow belongs to. */
196-
parentFunction: Function;
196+
parentFunction!: Function;
197197
/** The label we break to when encountering a continue statement. */
198-
continueLabel: string | null;
198+
continueLabel: string | null = null;
199199
/** The label we break to when encountering a break statement. */
200-
breakLabel: string | null;
200+
breakLabel: string | null = null;
201201
/** The current return type. */
202-
returnType: Type;
202+
returnType!: Type;
203203
/** The current contextual type arguments. */
204-
contextualTypeArguments: Map<string,Type> | null;
204+
contextualTypeArguments: Map<string,Type> | null = null;
205205
/** Scoped local variables. */
206206
scopedLocals: Map<string,Local> | null = null;
207207
/** Local flags. */
208-
localFlags: LocalFlags[];
208+
localFlags: LocalFlags[] = [];
209209
/** Field flags. */
210210
fieldFlags: Map<string, FieldFlags> | null = null;
211211
/** Function being inlined, when inlining. */
212-
inlineFunction: Function | null;
212+
inlineFunction: Function | null = null;
213213
/** The label we break to when encountering a return statement, when inlining. */
214-
inlineReturnLabel: string | null;
214+
inlineReturnLabel: string | null = null;
215215

216216
/** Creates the parent flow of the specified function. */
217217
static create(parentFunction: Function): Flow {
218218
var flow = new Flow();
219-
flow.parent = null;
220-
flow.flags = FlowFlags.NONE;
221219
flow.parentFunction = parentFunction;
222-
flow.continueLabel = null;
223-
flow.breakLabel = null;
224220
flow.returnType = parentFunction.signature.returnType;
225221
flow.contextualTypeArguments = parentFunction.contextualTypeArguments;
226-
flow.localFlags = [];
227-
flow.inlineFunction = null;
228-
flow.inlineReturnLabel = null;
229222

230223
if (flow.actualFunction.is(CommonFlags.CONSTRUCTOR)) {
231224
flow.fieldFlags = new Map();
@@ -240,6 +233,7 @@ export class Flow {
240233
flow.inlineReturnLabel = inlineFunction.internalName + "|inlined." + (inlineFunction.nextInlineId++).toString();
241234
flow.returnType = inlineFunction.signature.returnType;
242235
flow.contextualTypeArguments = inlineFunction.contextualTypeArguments;
236+
flow.fieldFlags = inlineFunction.flow.fieldFlags;
243237
return flow;
244238
}
245239

@@ -536,14 +530,16 @@ export class Flow {
536530
localFlags[index] = flags & ~flag;
537531
}
538532

533+
/** Associates the given flag with the given field name */
539534
setFieldFlag(name: string, flag: FieldFlags): void {
540-
let fieldFlags = this.fieldFlags;
535+
var fieldFlags = this.fieldFlags;
541536
if (fieldFlags) {
542537
const flags = fieldFlags.has(name) ? assert(fieldFlags.get(name)) : FieldFlags.NONE;
543538
fieldFlags.set(name, flags | flag);
544539
}
545540
}
546541

542+
/** Tests if the given field name and flag exist */
547543
isFieldFlag(name: string, flag: FieldFlags): bool {
548544
const fieldFlags = this.fieldFlags;
549545

@@ -845,6 +841,11 @@ export class Flow {
845841
this.mergeFieldFlags(left, right);
846842
}
847843

844+
/**
845+
* Merges the fields flags of the given flows
846+
* into the current flow. Flags will only be merged
847+
* if both flows definitely define the flags.
848+
*/
848849
mergeFieldFlags(left: Flow, right: Flow): void {
849850
if (left.fieldFlags !== null &&
850851
right.fieldFlags !== null &&
@@ -870,6 +871,7 @@ export class Flow {
870871
}
871872
}
872873

874+
/** Inherits the fields flags of the given flow into the current flow */
873875
inheritFieldFlags(other: Flow): void {
874876
if (
875877
this.fieldFlags !== null &&
@@ -884,7 +886,7 @@ export class Flow {
884886
const key = otherKeys[i];
885887
const otherValue = otherValues[i];
886888
if (otherValue & FieldFlags.INITIALIZED) {
887-
currentFieldFlags.set(key, FieldFlags.INITIALIZED)
889+
currentFieldFlags.set(key, FieldFlags.INITIALIZED);
888890
}
889891
}
890892
}

src/module.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -468,8 +468,8 @@ export enum SIMDLoadOp {
468468

469469
export class MemorySegment {
470470

471-
buffer: Uint8Array;
472-
offset: i64;
471+
buffer!: Uint8Array;
472+
offset!: i64;
473473

474474
static create(buffer: Uint8Array, offset: i64): MemorySegment {
475475
var segment = new MemorySegment();
@@ -481,9 +481,9 @@ export class MemorySegment {
481481

482482
export class Module {
483483

484-
ref: ModuleRef;
484+
ref!: ModuleRef;
485485

486-
private lit: usize;
486+
private lit!: usize;
487487

488488
static create(): Module {
489489
var module = new Module();
@@ -1896,8 +1896,8 @@ export function getEventResults(event: EventRef): NativeType {
18961896

18971897
export class Relooper {
18981898

1899-
module: Module;
1900-
ref: RelooperRef;
1899+
module!: Module;
1900+
ref!: RelooperRef;
19011901

19021902
static create(module: Module): Relooper {
19031903
var relooper = new Relooper();
@@ -2141,9 +2141,9 @@ export function readString(ptr: usize): string | null {
21412141
/** Result structure of {@link Module#toBinary}. */
21422142
export class BinaryModule {
21432143
/** WebAssembly binary. */
2144-
output: Uint8Array;
2144+
output!: Uint8Array;
21452145
/** Source map, if generated. */
2146-
sourceMap: string | null;
2146+
sourceMap: string | null = null;
21472147
}
21482148

21492149
/** Tests if an expression needs an explicit 'unreachable' when it is the terminating statement. */

src/parser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ export class Parser extends DiagnosticEmitter {
106106
/** Optional handler to intercept comments while tokenizing. */
107107
onComment: CommentHandler | null = null;
108108
/** Current file being parsed. */
109-
currentSource: Source;
109+
currentSource!: Source;
110110
/** Dependency map **/
111111
dependees: Map<string, Source> = new Map();
112112

src/program.ts

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -448,68 +448,68 @@ export class Program extends DiagnosticEmitter {
448448
// standard references
449449

450450
/** ArrayBufferView reference. */
451-
arrayBufferViewInstance: Class;
451+
arrayBufferViewInstance!: Class;
452452
/** ArrayBuffer instance reference. */
453-
arrayBufferInstance: Class;
453+
arrayBufferInstance!: Class;
454454
/** Array prototype reference. */
455-
arrayPrototype: ClassPrototype;
455+
arrayPrototype!: ClassPrototype;
456456
/** Static array prototype reference. */
457-
staticArrayPrototype: ClassPrototype;
457+
staticArrayPrototype!: ClassPrototype;
458458
/** Set prototype reference. */
459-
setPrototype: ClassPrototype;
459+
setPrototype!: ClassPrototype;
460460
/** Map prototype reference. */
461-
mapPrototype: ClassPrototype;
461+
mapPrototype!: ClassPrototype;
462462
/** Int8Array prototype. */
463-
i8ArrayPrototype: ClassPrototype;
463+
i8ArrayPrototype!: ClassPrototype;
464464
/** Int16Array prototype. */
465-
i16ArrayPrototype: ClassPrototype;
465+
i16ArrayPrototype!: ClassPrototype;
466466
/** Int32Array prototype. */
467-
i32ArrayPrototype: ClassPrototype;
467+
i32ArrayPrototype!: ClassPrototype;
468468
/** Int64Array prototype. */
469-
i64ArrayPrototype: ClassPrototype;
469+
i64ArrayPrototype!: ClassPrototype;
470470
/** Uint8Array prototype. */
471-
u8ArrayPrototype: ClassPrototype;
471+
u8ArrayPrototype!: ClassPrototype;
472472
/** Uint8ClampedArray prototype. */
473-
u8ClampedArrayPrototype: ClassPrototype;
473+
u8ClampedArrayPrototype!: ClassPrototype;
474474
/** Uint16Array prototype. */
475-
u16ArrayPrototype: ClassPrototype;
475+
u16ArrayPrototype!: ClassPrototype;
476476
/** Uint32Array prototype. */
477-
u32ArrayPrototype: ClassPrototype;
477+
u32ArrayPrototype!: ClassPrototype;
478478
/** Uint64Array prototype. */
479-
u64ArrayPrototype: ClassPrototype;
479+
u64ArrayPrototype!: ClassPrototype;
480480
/** Float32Array prototype. */
481-
f32ArrayPrototype: ClassPrototype;
481+
f32ArrayPrototype!: ClassPrototype;
482482
/** Float64Array prototype. */
483-
f64ArrayPrototype: ClassPrototype;
483+
f64ArrayPrototype!: ClassPrototype;
484484
/** String instance reference. */
485-
stringInstance: Class;
485+
stringInstance!: Class;
486486
/** Abort function reference, if not explicitly disabled. */
487-
abortInstance: Function | null;
487+
abortInstance: Function | null = null;
488488

489489
// runtime references
490490

491491
/** RT `__alloc(size: usize, id: u32): usize` */
492-
allocInstance: Function;
492+
allocInstance!: Function;
493493
/** RT `__realloc(ptr: usize, newSize: usize): usize` */
494-
reallocInstance: Function;
494+
reallocInstance!: Function;
495495
/** RT `__free(ptr: usize): void` */
496-
freeInstance: Function;
496+
freeInstance!: Function;
497497
/** RT `__retain(ptr: usize): usize` */
498-
retainInstance: Function;
498+
retainInstance!: Function;
499499
/** RT `__release(ptr: usize): void` */
500-
releaseInstance: Function;
500+
releaseInstance!: Function;
501501
/** RT `__collect(): void` */
502-
collectInstance: Function;
502+
collectInstance!: Function;
503503
/** RT `__visit(ptr: usize, cookie: u32): void` */
504-
visitInstance: Function;
504+
visitInstance!: Function;
505505
/** RT `__typeinfo(id: u32): RTTIFlags` */
506-
typeinfoInstance: Function;
506+
typeinfoInstance!: Function;
507507
/** RT `__instanceof(ptr: usize, superId: u32): bool` */
508-
instanceofInstance: Function;
508+
instanceofInstance!: Function;
509509
/** RT `__allocBuffer(size: usize, id: u32, data: usize = 0): usize` */
510-
allocBufferInstance: Function;
510+
allocBufferInstance!: Function;
511511
/** RT `__allocArray(length: i32, alignLog2: usize, id: u32, data: usize = 0): usize` */
512-
allocArrayInstance: Function;
512+
allocArrayInstance!: Function;
513513

514514
/** Next class id. */
515515
nextClassId: u32 = 0;
@@ -2695,9 +2695,9 @@ export abstract class VariableLikeElement extends TypedElement {
26952695
/** Constant value kind. */
26962696
constantValueKind: ConstantValueKind = ConstantValueKind.NONE;
26972697
/** Constant integer value, if applicable. */
2698-
constantIntegerValue: i64;
2698+
constantIntegerValue!: i64;
26992699
/** Constant float value, if applicable. */
2700-
constantFloatValue: f64;
2700+
constantFloatValue!: f64;
27012701

27022702
/** Constructs a new variable-like element. */
27032703
protected constructor(

src/tokenizer.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,11 +1567,11 @@ export class Tokenizer extends DiagnosticEmitter {
15671567
/** Tokenizer state as returned by {@link Tokenizer#mark} and consumed by {@link Tokenizer#reset}. */
15681568
export class State {
15691569
/** Current position. */
1570-
pos: i32;
1570+
pos!: i32;
15711571
/** Current token. */
1572-
token: Token;
1572+
token!: Token;
15731573
/** Current token's position. */
1574-
tokenPos: i32;
1574+
tokenPos!: i32;
15751575
}
15761576

15771577
// Reusable state object to reduce allocations

0 commit comments

Comments
 (0)