more loader updates

This commit is contained in:
dcode
2019-05-24 20:31:52 +02:00
parent 7cd04b65ef
commit a6896d7bc2
12 changed files with 225 additions and 141 deletions

View File

@ -4160,7 +4160,8 @@ export function compileRTTI(compiler: Compiler): void {
var data = new Uint8Array(size);
writeI32(count, data, 0);
var off = 4;
var arrayPrototype = program.arrayPrototype;
var abvInstance = program.arrayBufferViewInstance;
var abvPrototype = abvInstance.prototype;
var setPrototype = program.setPrototype;
var mapPrototype = program.mapPrototype;
var lastId = 0;
@ -4168,17 +4169,16 @@ export function compileRTTI(compiler: Compiler): void {
assert(id == lastId++);
let flags: TypeinfoFlags = 0;
if (instance.isAcyclic) flags |= TypeinfoFlags.ACYCLIC;
if (instance.prototype.extends(arrayPrototype)) {
let typeArguments = assert(instance.getTypeArgumentsTo(arrayPrototype));
assert(typeArguments.length == 1);
if (instance !== abvInstance && instance.extends(abvPrototype)) {
let valueType = instance.getArrayValueType();
flags |= TypeinfoFlags.ARRAY;
flags |= TypeinfoFlags.VALUE_ALIGN_0 * typeToRuntimeFlags(typeArguments[0]);
} else if (instance.prototype.extends(setPrototype)) {
flags |= TypeinfoFlags.VALUE_ALIGN_0 * typeToRuntimeFlags(valueType);
} else if (instance.extends(setPrototype)) {
let typeArguments = assert(instance.getTypeArgumentsTo(setPrototype));
assert(typeArguments.length == 1);
flags |= TypeinfoFlags.SET;
flags |= TypeinfoFlags.VALUE_ALIGN_0 * typeToRuntimeFlags(typeArguments[0]);
} else if (instance.prototype.extends(mapPrototype)) {
} else if (instance.extends(mapPrototype)) {
let typeArguments = assert(instance.getTypeArgumentsTo(mapPrototype));
assert(typeArguments.length == 2);
flags |= TypeinfoFlags.MAP;

View File

@ -178,6 +178,17 @@ export namespace CommonSymbols {
export const ArrayBuffer = "ArrayBuffer";
export const Math = "Math";
export const Mathf = "Mathf";
export const Int8Array = "Int8Array";
export const Int16Array = "Int16Array";
export const Int32Array = "Int32Array";
export const Int64Array = "Int64Array";
export const Uint8Array = "Uint8Array";
export const Uint8ClampedArray = "Uint8ClampedArray";
export const Uint16Array = "Uint16Array";
export const Uint32Array = "Uint32Array";
export const Uint64Array = "Uint64Array";
export const Float32Array = "Float32Array";
export const Float64Array = "Float64Array";
// runtime
export const abort = "abort";
export const pow = "pow";

View File

@ -356,6 +356,28 @@ export class Program extends DiagnosticEmitter {
mapPrototype: ClassPrototype;
/** Fixed array prototype reference. */
fixedArrayPrototype: ClassPrototype;
/** Int8Array prototype. */
i8ArrayPrototype: ClassPrototype;
/** Int16Array prototype. */
i16ArrayPrototype: ClassPrototype;
/** Int32Array prototype. */
i32ArrayPrototype: ClassPrototype;
/** Int64Array prototype. */
i64ArrayPrototype: ClassPrototype;
/** Uint8Array prototype. */
u8ArrayPrototype: ClassPrototype;
/** Uint8ClampedArray prototype. */
u8ClampedArrayPrototype: ClassPrototype;
/** Uint16Array prototype. */
u16ArrayPrototype: ClassPrototype;
/** Uint32Array prototype. */
u32ArrayPrototype: ClassPrototype;
/** Uint64Array prototype. */
u64ArrayPrototype: ClassPrototype;
/** Float32Array prototype. */
f32ArrayPrototype: ClassPrototype;
/** Float64Array prototype. */
f64ArrayPrototype: ClassPrototype;
/** String instance reference. */
stringInstance: Class;
/** Abort function reference, if present. */
@ -734,12 +756,14 @@ export class Program extends DiagnosticEmitter {
}
}
// register ArrayBuffer (id=0) and String (id=1)
// register ArrayBuffer (id=0), String (id=1), ArrayBufferView (id=2)
assert(this.nextClassId == 0);
this.arrayBufferInstance = this.requireClass(CommonSymbols.ArrayBuffer);
assert(this.arrayBufferInstance.id == 0);
this.stringInstance = this.requireClass(CommonSymbols.String);
assert(this.stringInstance.id == 1);
this.arrayBufferViewInstance = this.requireClass(CommonSymbols.ArrayBufferView);
assert(this.arrayBufferViewInstance.id == 2);
// register classes backing basic types
this.registerNativeTypeClass(TypeKind.I8, CommonSymbols.I8);
@ -757,6 +781,19 @@ export class Program extends DiagnosticEmitter {
this.registerNativeTypeClass(TypeKind.F64, CommonSymbols.F64);
if (options.hasFeature(Feature.SIMD)) this.registerNativeTypeClass(TypeKind.V128, CommonSymbols.V128);
// register views but don't instantiate them yet
this.i8ArrayPrototype = <ClassPrototype>this.require(CommonSymbols.Int8Array, ElementKind.CLASS_PROTOTYPE);
this.i16ArrayPrototype = <ClassPrototype>this.require(CommonSymbols.Int16Array, ElementKind.CLASS_PROTOTYPE);
this.i32ArrayPrototype = <ClassPrototype>this.require(CommonSymbols.Int32Array, ElementKind.CLASS_PROTOTYPE);
this.i64ArrayPrototype = <ClassPrototype>this.require(CommonSymbols.Int64Array, ElementKind.CLASS_PROTOTYPE);
this.u8ArrayPrototype = <ClassPrototype>this.require(CommonSymbols.Uint8Array, ElementKind.CLASS_PROTOTYPE);
this.u8ClampedArrayPrototype = <ClassPrototype>this.require(CommonSymbols.Uint8ClampedArray, ElementKind.CLASS_PROTOTYPE);
this.u16ArrayPrototype = <ClassPrototype>this.require(CommonSymbols.Uint16Array, ElementKind.CLASS_PROTOTYPE);
this.u32ArrayPrototype = <ClassPrototype>this.require(CommonSymbols.Uint32Array, ElementKind.CLASS_PROTOTYPE);
this.u64ArrayPrototype = <ClassPrototype>this.require(CommonSymbols.Uint64Array, ElementKind.CLASS_PROTOTYPE);
this.f32ArrayPrototype = <ClassPrototype>this.require(CommonSymbols.Float32Array, ElementKind.CLASS_PROTOTYPE);
this.f64ArrayPrototype = <ClassPrototype>this.require(CommonSymbols.Float64Array, ElementKind.CLASS_PROTOTYPE);
// resolve base prototypes of derived classes
var resolver = this.resolver;
for (let i = 0, k = queuedExtends.length; i < k; ++i) {
@ -813,7 +850,6 @@ export class Program extends DiagnosticEmitter {
}
// register stdlib components
this.arrayBufferViewInstance = this.requireClass(CommonSymbols.ArrayBufferView);
this.arrayPrototype = <ClassPrototype>this.require(CommonSymbols.Array, ElementKind.CLASS_PROTOTYPE);
this.fixedArrayPrototype = <ClassPrototype>this.require(CommonSymbols.FixedArray, ElementKind.CLASS_PROTOTYPE);
this.setPrototype = <ClassPrototype>this.require(CommonSymbols.Set, ElementKind.CLASS_PROTOTYPE);
@ -3200,6 +3236,32 @@ export class Class extends TypedElement {
return null;
}
/** Gets the value type of an array. Must be an array. */
getArrayValueType(): Type {
var current: Class = this;
var program = this.program;
var abvInstance = program.arrayBufferViewInstance;
while (current.base !== abvInstance) {
current = assert(current.base);
}
switch (current.prototype) {
case program.i8ArrayPrototype: return Type.i8;
case program.i16ArrayPrototype: return Type.i16;
case program.i32ArrayPrototype: return Type.i32;
case program.i64ArrayPrototype: return Type.i64;
case program.u8ArrayPrototype:
case program.u8ClampedArrayPrototype: return Type.u8;
case program.u16ArrayPrototype: return Type.u16;
case program.u32ArrayPrototype: return Type.u32;
case program.u64ArrayPrototype: return Type.u64;
case program.f32ArrayPrototype: return Type.f32;
case program.f64ArrayPrototype: return Type.f64;
case program.arrayPrototype: return assert(this.getTypeArgumentsTo(program.arrayPrototype))[0];
default: assert(false);
}
return Type.void;
}
/** Tests if this class is inherently acyclic. */
get isAcyclic(): bool {
var acyclic = this._acyclic;