mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 15:12:12 +00:00
Fix partial function prototypes not sharing their instances
This also made it necessary to extend the internal per-function instances map by one level for the respective class instance key so functions on differnt class instances with the same own type arguments don't collide.
This commit is contained in:
parent
0e33806cf6
commit
4c35dd6f7c
@ -551,13 +551,15 @@ export class Compiler extends DiagnosticEmitter {
|
||||
|
||||
// skip prototype and export instances
|
||||
case ElementKind.FUNCTION_PROTOTYPE: {
|
||||
for (let instance of (<FunctionPrototype>element).instances.values()) {
|
||||
let instanceName = name;
|
||||
if (instance.is(CommonFlags.GENERIC)) {
|
||||
let fullName = instance.internalName;
|
||||
instanceName += fullName.substring(fullName.lastIndexOf("<"));
|
||||
for (let instances of (<FunctionPrototype>element).instances.values()) {
|
||||
for (let instance of instances.values()) {
|
||||
let instanceName = name;
|
||||
if (instance.is(CommonFlags.GENERIC)) {
|
||||
let fullName = instance.internalName;
|
||||
instanceName += fullName.substring(fullName.lastIndexOf("<"));
|
||||
}
|
||||
this.makeModuleExport(instanceName, instance, prefix);
|
||||
}
|
||||
this.makeModuleExport(instanceName, instance, prefix);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -105,8 +105,10 @@ abstract class ExportsWalker {
|
||||
}
|
||||
|
||||
private visitFunctionInstances(element: FunctionPrototype): void {
|
||||
for (let instance of element.instances.values()) {
|
||||
if (instance.is(CommonFlags.COMPILED)) this.visitFunction(<Function>instance);
|
||||
for (let instances of element.instances.values()) {
|
||||
for (let instance of instances.values()) {
|
||||
if (instance.is(CommonFlags.COMPILED)) this.visitFunction(<Function>instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -516,8 +518,10 @@ function hasCompiledMember(element: Element): bool {
|
||||
for (let member of members.values()) {
|
||||
switch (member.kind) {
|
||||
case ElementKind.FUNCTION_PROTOTYPE: {
|
||||
for (let instance of (<FunctionPrototype>member).instances.values()) {
|
||||
if (instance.is(CommonFlags.COMPILED)) return true;
|
||||
for (let instances of (<FunctionPrototype>member).instances.values()) {
|
||||
for (let instance of instances.values()) {
|
||||
if (instance.is(CommonFlags.COMPILED)) return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2391,8 +2391,8 @@ export class FunctionPrototype extends Element {
|
||||
declaration: FunctionDeclaration;
|
||||
/** If an instance method, the class prototype reference. */
|
||||
classPrototype: ClassPrototype | null;
|
||||
/** Resolved instances. */
|
||||
instances: Map<string,Function> = new Map();
|
||||
/** Resolved instances by class type arguments and function type arguments. */
|
||||
instances: Map<string,Map<string,Function>> = new Map();
|
||||
/** Class type arguments, if a partially resolved method of a generic class. Not set otherwise. */
|
||||
classTypeArguments: Type[] | null = null;
|
||||
/** Operator kind, if an overload. */
|
||||
|
@ -713,9 +713,14 @@ export class Resolver extends DiagnosticEmitter {
|
||||
contextualTypeArguments: Map<string,Type> | null = null,
|
||||
reportMode: ReportMode = ReportMode.REPORT
|
||||
): Function | null {
|
||||
var classTypeArguments = prototype.classTypeArguments;
|
||||
var classInstanceKey = classTypeArguments ? typesToString(classTypeArguments) : "";
|
||||
var instanceKey = typeArguments ? typesToString(typeArguments) : "";
|
||||
var instance = prototype.instances.get(instanceKey);
|
||||
if (instance) return instance;
|
||||
var classInstances = prototype.instances.get(classInstanceKey);
|
||||
if (classInstances) {
|
||||
let instance = classInstances.get(instanceKey);
|
||||
if (instance) return instance;
|
||||
}
|
||||
|
||||
var declaration = prototype.declaration;
|
||||
var isInstance = prototype.is(CommonFlags.INSTANCE);
|
||||
@ -734,7 +739,6 @@ export class Resolver extends DiagnosticEmitter {
|
||||
}
|
||||
|
||||
// override with class type arguments if a partially resolved instance method
|
||||
var classTypeArguments = prototype.classTypeArguments;
|
||||
if (classTypeArguments) { // set only if partially resolved
|
||||
assert(prototype.is(CommonFlags.INSTANCE));
|
||||
let classDeclaration = assert(classPrototype).declaration;
|
||||
@ -818,7 +822,7 @@ export class Resolver extends DiagnosticEmitter {
|
||||
|
||||
var internalName = prototype.internalName;
|
||||
if (instanceKey.length) internalName += "<" + instanceKey + ">";
|
||||
instance = new Function(
|
||||
var instance = new Function(
|
||||
prototype,
|
||||
internalName,
|
||||
signature,
|
||||
@ -827,7 +831,8 @@ export class Resolver extends DiagnosticEmitter {
|
||||
: classPrototype,
|
||||
contextualTypeArguments
|
||||
);
|
||||
prototype.instances.set(instanceKey, instance);
|
||||
if (!classInstances) prototype.instances.set(classInstanceKey, classInstances = new Map());
|
||||
classInstances.set(instanceKey, instance);
|
||||
this.program.instancesLookup.set(internalName, instance);
|
||||
return instance;
|
||||
}
|
||||
@ -856,6 +861,7 @@ export class Resolver extends DiagnosticEmitter {
|
||||
partialPrototype.flags = prototype.flags;
|
||||
partialPrototype.operatorKind = prototype.operatorKind;
|
||||
partialPrototype.classTypeArguments = typeArguments;
|
||||
partialPrototype.instances = prototype.instances;
|
||||
return partialPrototype;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user