Skip to content

Commit 7edbea2

Browse files
authored
Merge branch 'AssemblyScript:main' into opt-zero-init
2 parents 69d3d89 + 7322bfc commit 7edbea2

File tree

5 files changed

+175
-158
lines changed

5 files changed

+175
-158
lines changed

src/builtins.ts

Lines changed: 158 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ import {
4343
NodeKind,
4444
LiteralExpression,
4545
ArrayLiteralExpression,
46-
IdentifierExpression
46+
IdentifierExpression,
47+
NamedTypeNode
4748
} from "./ast";
4849

4950
import {
@@ -85,7 +86,9 @@ import {
8586
DecoratorFlags,
8687
Class,
8788
PropertyPrototype,
88-
VariableLikeElement
89+
VariableLikeElement,
90+
Element,
91+
OperatorKind
8992
} from "./program";
9093

9194
import {
@@ -94,11 +97,13 @@ import {
9497
} from "./flow";
9598

9699
import {
97-
ReportMode
100+
ReportMode,
101+
Resolver
98102
} from "./resolver";
99103

100104
import {
101105
CommonFlags,
106+
CommonNames,
102107
Feature,
103108
featureToString,
104109
TypeinfoFlags
@@ -768,6 +773,17 @@ export namespace BuiltinNames {
768773
export const Object = "~lib/object/Object";
769774
}
770775

776+
/** Builtin types context. */
777+
export class BuiltinTypesContext {
778+
constructor(
779+
public resolver: Resolver,
780+
public node: NamedTypeNode,
781+
public ctxElement: Element,
782+
public ctxTypes: Map<string, Type> | null,
783+
public reportMode: ReportMode
784+
) {}
785+
}
786+
771787
/** Builtin variable compilation context. */
772788
export class BuiltinVariableContext {
773789
constructor(
@@ -804,13 +820,152 @@ export class BuiltinFunctionContext {
804820
) {}
805821
}
806822

823+
/** Builtin types map. */
824+
export const builtinTypes = new Map<string, (ctx: BuiltinTypesContext) => Type | null>();
825+
807826
/** Builtin functions map. */
808827
export const builtinFunctions = new Map<string, (ctx: BuiltinFunctionContext) => ExpressionRef>();
809828

810829
/** Builtin variables map. */
811830
export const builtinVariables_onCompile = new Map<string, (ctx: BuiltinVariableContext) => void>();
812831
export const builtinVariables_onAccess = new Map<string, (ctx: BuiltinVariableContext) => ExpressionRef>();
813832

833+
// === Builtin Types ==========================================================================
834+
function builtin_resolveNativeType(ctx: BuiltinTypesContext): Type | null {
835+
let resolver = ctx.resolver;
836+
let node = ctx.node;
837+
let ctxElement = ctx.ctxElement;
838+
let ctxTypes = ctx.ctxTypes;
839+
let reportMode = ctx.reportMode;
840+
const typeArgumentNode = resolver.ensureOneTypeArgument(node, reportMode);
841+
if (!typeArgumentNode) return null;
842+
let typeArgument = resolver.resolveType(typeArgumentNode, null, ctxElement, ctxTypes, reportMode);
843+
if (!typeArgument) return null;
844+
switch (typeArgument.kind) {
845+
case TypeKind.I8:
846+
case TypeKind.I16:
847+
case TypeKind.I32: return Type.i32;
848+
case TypeKind.Isize: if (!resolver.program.options.isWasm64) return Type.i32;
849+
case TypeKind.I64: return Type.i64;
850+
case TypeKind.U8:
851+
case TypeKind.U16:
852+
case TypeKind.U32:
853+
case TypeKind.Bool: return Type.u32;
854+
case TypeKind.Usize: if (!resolver.program.options.isWasm64) return Type.u32;
855+
case TypeKind.U64: return Type.u64;
856+
case TypeKind.F32: return Type.f32;
857+
case TypeKind.F64: return Type.f64;
858+
case TypeKind.V128: return Type.v128;
859+
case TypeKind.Void: return Type.void;
860+
default: assert(false);
861+
}
862+
return null;
863+
}
864+
builtinTypes.set(CommonNames.native, builtin_resolveNativeType);
865+
866+
function builtin_resolveIndexOfType(ctx: BuiltinTypesContext): Type | null {
867+
let resolver = ctx.resolver;
868+
let node = ctx.node;
869+
let ctxElement = ctx.ctxElement;
870+
let ctxTypes = ctx.ctxTypes;
871+
let reportMode = ctx.reportMode;
872+
const typeArgumentNode = resolver.ensureOneTypeArgument(node, reportMode);
873+
if (!typeArgumentNode) return null;
874+
let typeArgument = resolver.resolveType(typeArgumentNode, null, ctxElement, ctxTypes, reportMode);
875+
if (!typeArgument) return null;
876+
let classReference = typeArgument.classReference;
877+
if (!classReference) {
878+
if (reportMode == ReportMode.Report) {
879+
resolver.error(
880+
DiagnosticCode.Index_signature_is_missing_in_type_0,
881+
typeArgumentNode.range, typeArgument.toString()
882+
);
883+
}
884+
return null;
885+
}
886+
let overload = classReference.lookupOverload(OperatorKind.IndexedGet);
887+
if (overload) {
888+
let parameterTypes = overload.signature.parameterTypes;
889+
if (overload.is(CommonFlags.Static)) {
890+
assert(parameterTypes.length == 2);
891+
return parameterTypes[1];
892+
} else {
893+
assert(parameterTypes.length == 1);
894+
return parameterTypes[0];
895+
}
896+
}
897+
if (reportMode == ReportMode.Report) {
898+
resolver.error(
899+
DiagnosticCode.Index_signature_is_missing_in_type_0,
900+
typeArgumentNode.range, typeArgument.toString()
901+
);
902+
}
903+
return null;
904+
}
905+
builtinTypes.set(CommonNames.indexof, builtin_resolveIndexOfType);
906+
907+
function builtin_resolveValueOfType(ctx: BuiltinTypesContext): Type | null {
908+
let resolver = ctx.resolver;
909+
let node = ctx.node;
910+
let ctxElement = ctx.ctxElement;
911+
let ctxTypes = ctx.ctxTypes;
912+
let reportMode = ctx.reportMode;
913+
const typeArgumentNode = resolver.ensureOneTypeArgument(node, reportMode);
914+
if (!typeArgumentNode) return null;
915+
let typeArgument = resolver.resolveType(typeArgumentNode, null, ctxElement, ctxTypes, reportMode);
916+
if (!typeArgument) return null;
917+
let classReference = typeArgument.getClassOrWrapper(resolver.program);
918+
if (classReference) {
919+
let overload = classReference.lookupOverload(OperatorKind.IndexedGet);
920+
if (overload) return overload.signature.returnType;
921+
}
922+
if (reportMode == ReportMode.Report) {
923+
resolver.error(
924+
DiagnosticCode.Index_signature_is_missing_in_type_0,
925+
typeArgumentNode.range, typeArgument.toString()
926+
);
927+
}
928+
return null;
929+
}
930+
builtinTypes.set(CommonNames.valueof, builtin_resolveValueOfType);
931+
932+
function builtin_resolveReturnOfType(ctx: BuiltinTypesContext): Type | null {
933+
let resolver = ctx.resolver;
934+
let node = ctx.node;
935+
let ctxElement = ctx.ctxElement;
936+
let ctxTypes = ctx.ctxTypes;
937+
let reportMode = ctx.reportMode;
938+
const typeArgumentNode = resolver.ensureOneTypeArgument(node, reportMode);
939+
if (!typeArgumentNode) return null;
940+
let typeArgument = resolver.resolveType(typeArgumentNode, null, ctxElement, ctxTypes, reportMode);
941+
if (!typeArgument) return null;
942+
let signatureReference = typeArgument.getSignature();
943+
if (signatureReference) return signatureReference.returnType;
944+
if (reportMode == ReportMode.Report) {
945+
resolver.error(
946+
DiagnosticCode.Type_0_has_no_call_signatures,
947+
typeArgumentNode.range, typeArgument.toString()
948+
);
949+
}
950+
return null;
951+
}
952+
builtinTypes.set(CommonNames.returnof, builtin_resolveReturnOfType);
953+
954+
function builtin_resolveNonnullableType(ctx: BuiltinTypesContext): Type | null {
955+
let resolver = ctx.resolver;
956+
let node = ctx.node;
957+
let ctxElement = ctx.ctxElement;
958+
let ctxTypes = ctx.ctxTypes;
959+
let reportMode = ctx.reportMode;
960+
const typeArgumentNode = resolver.ensureOneTypeArgument(node, reportMode);
961+
if (!typeArgumentNode) return null;
962+
let typeArgument = resolver.resolveType(typeArgumentNode, null, ctxElement, ctxTypes, reportMode);
963+
if (!typeArgument) return null;
964+
if (!typeArgument.isNullableReference) return typeArgument;
965+
return typeArgument.nonNullableType;
966+
}
967+
builtinTypes.set(CommonNames.nonnull, builtin_resolveNonnullableType);
968+
814969
// === Static type evaluation =================================================================
815970

816971
// helper global used by checkConstantType

src/compiler.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ import {
4848
getBlockChildCount,
4949
getBlockChildAt,
5050
getBlockName,
51-
getLocalSetValue,
5251
getGlobalGetName,
5352
isGlobalMutable,
5453
getSideEffects,
@@ -9232,11 +9231,12 @@ export class Compiler extends DiagnosticEmitter {
92329231
let flow = this.currentFlow;
92339232

92349233
// make a getter for the expression (also obtains the type)
9235-
let getValue = this.compileExpression( // reports
9234+
const getValueOriginal = this.compileExpression( // reports
92369235
expression.operand,
92379236
contextualType.exceptVoid,
92389237
Constraints.None
92399238
);
9239+
let getValue: ExpressionRef;
92409240

92419241
// if the value isn't dropped, a temp. local is required to remember the original value,
92429242
// except if a static overload is found, which reverses the use of a temp. (see below)
@@ -9245,24 +9245,25 @@ export class Compiler extends DiagnosticEmitter {
92459245
tempLocal = flow.getTempLocal(this.currentType);
92469246
getValue = module.local_tee(
92479247
tempLocal.index,
9248-
getValue,
9248+
getValueOriginal,
92499249
this.currentType.isManaged
92509250
);
9251+
} else {
9252+
getValue = getValueOriginal;
92519253
}
92529254

92539255
let expr: ExpressionRef;
92549256

92559257
switch (expression.operator) {
92569258
case Token.Plus_Plus: {
9257-
92589259
// check operator overload
92599260
let classReference = this.currentType.getClassOrWrapper(this.program);
92609261
if (classReference) {
92619262
let overload = classReference.lookupOverload(OperatorKind.PostfixInc);
92629263
if (overload) {
92639264
let isInstance = overload.is(CommonFlags.Instance);
92649265
if (tempLocal && !isInstance) { // revert: static overload simply returns
9265-
getValue = getLocalSetValue(getValue);
9266+
getValue = getValueOriginal;
92669267
tempLocal = null;
92679268
}
92689269
expr = this.compileUnaryOverload(overload, expression.operand, getValue, expression);
@@ -9338,19 +9339,18 @@ export class Compiler extends DiagnosticEmitter {
93389339
break;
93399340
}
93409341
case Token.Minus_Minus: {
9341-
93429342
// check operator overload
93439343
let classReference = this.currentType.getClassOrWrapper(this.program);
93449344
if (classReference) {
93459345
let overload = classReference.lookupOverload(OperatorKind.PostfixDec);
93469346
if (overload) {
93479347
let isInstance = overload.is(CommonFlags.Instance);
93489348
if (tempLocal && !isInstance) { // revert: static overload simply returns
9349-
getValue = getLocalSetValue(getValue);
9349+
getValue = getValueOriginal;
93509350
tempLocal = null;
93519351
}
93529352
expr = this.compileUnaryOverload(overload, expression.operand, getValue, expression);
9353-
if (overload.is(CommonFlags.Instance)) break;
9353+
if (isInstance) break;
93549354
return expr; // here
93559355
}
93569356
}

0 commit comments

Comments
 (0)