fix rc in Array#fill, add rtti logging for debugging

This commit is contained in:
dcode 2019-06-01 15:57:53 +02:00
parent 066ea1fbd2
commit 1468923025
15 changed files with 129 additions and 65 deletions

View File

@ -711,6 +711,9 @@ exports.main = function main(argv, options, callback) {
if (args.measure) { if (args.measure) {
printStats(stats, stderr); printStats(stats, stderr);
} }
if (args.printrtti) {
printRTTI(program, stderr);
}
return callback(null); return callback(null);
function readFileNode(filename, baseDir) { function readFileNode(filename, baseDir) {
@ -847,6 +850,15 @@ function printStats(stats, output) {
exports.printStats = printStats; exports.printStats = printStats;
/** Prints runtime type information. */
function printRTTI(program, output) {
if (!output) output = process.stderr;
output.write("# Runtime type information (RTTI)\n");
output.write(assemblyscript.buildRTTI(program));
}
exports.printRTTI = printRTTI;
var allocBuffer = typeof global !== "undefined" && global.Buffer var allocBuffer = typeof global !== "undefined" && global.Buffer
? global.Buffer.allocUnsafe || function(len) { return new global.Buffer(len); } ? global.Buffer.allocUnsafe || function(len) { return new global.Buffer(len); }
: function(len) { return new Uint8Array(len) }; : function(len) { return new Uint8Array(len) };

View File

@ -185,6 +185,11 @@
"type": "b", "type": "b",
"default": false "default": false
}, },
"printrtti": {
"description": "Prints the module's runtime type information to stderr.",
"type": "b",
"default": false
},
"noColors": { "noColors": {
"description": "Disables terminal colors.", "description": "Disables terminal colors.",
"type": "b", "type": "b",

2
dist/asc.js vendored

File diff suppressed because one or more lines are too long

2
dist/asc.js.map vendored

File diff suppressed because one or more lines are too long

View File

@ -218,7 +218,7 @@ declare module 'assemblyscript/src/diagnosticMessages.generated' {
Type_0_cannot_be_reinterpreted_as_type_1 = 203, Type_0_cannot_be_reinterpreted_as_type_1 = 203,
Basic_type_0_cannot_be_nullable = 204, Basic_type_0_cannot_be_nullable = 204,
Cannot_export_a_mutable_global = 205, Cannot_export_a_mutable_global = 205,
Compiling_constant_with_non_constant_initializer_as_mutable = 206, Mutable_value_cannot_be_inlined = 206,
Unmanaged_classes_cannot_extend_managed_classes_and_vice_versa = 207, Unmanaged_classes_cannot_extend_managed_classes_and_vice_versa = 207,
Unmanaged_classes_cannot_implement_interfaces = 208, Unmanaged_classes_cannot_implement_interfaces = 208,
Invalid_regular_expression_flags = 209, Invalid_regular_expression_flags = 209,
@ -2482,28 +2482,30 @@ declare module 'assemblyscript/src/flow' {
export enum LocalFlags { export enum LocalFlags {
/** No specific conditions. */ /** No specific conditions. */
NONE = 0, NONE = 0,
/** Local is constant. */
CONSTANT = 1,
/** Local is properly wrapped. Relevant for small integers. */ /** Local is properly wrapped. Relevant for small integers. */
WRAPPED = 1, WRAPPED = 2,
/** Local is non-null. */ /** Local is non-null. */
NONNULL = 2, NONNULL = 4,
/** Local is read from. */ /** Local is read from. */
READFROM = 4, READFROM = 8,
/** Local is written to. */ /** Local is written to. */
WRITTENTO = 8, WRITTENTO = 16,
/** Local is retained. */ /** Local is retained. */
RETAINED = 16, RETAINED = 32,
/** Local is conditionally read from. */ /** Local is conditionally read from. */
CONDITIONALLY_READFROM = 32, CONDITIONALLY_READFROM = 64,
/** Local is conditionally written to. */ /** Local is conditionally written to. */
CONDITIONALLY_WRITTENTO = 64, CONDITIONALLY_WRITTENTO = 128,
/** Local must be conditionally retained. */ /** Local must be conditionally retained. */
CONDITIONALLY_RETAINED = 128, CONDITIONALLY_RETAINED = 256,
/** Any categorical flag. */ /** Any categorical flag. */
ANY_CATEGORICAL = 31, ANY_CATEGORICAL = 63,
/** Any conditional flag. */ /** Any conditional flag. */
ANY_CONDITIONAL = 240, ANY_CONDITIONAL = 480,
/** Any retained flag. */ /** Any retained flag. */
ANY_RETAINED = 144 ANY_RETAINED = 288
} }
export namespace LocalFlags { export namespace LocalFlags {
function join(left: LocalFlags, right: LocalFlags): LocalFlags; function join(left: LocalFlags, right: LocalFlags): LocalFlags;
@ -2568,21 +2570,19 @@ declare module 'assemblyscript/src/flow' {
/** Forks this flow to a child flow. */ /** Forks this flow to a child flow. */
fork(): Flow; fork(): Flow;
/** Gets a free temporary local of the specified type. */ /** Gets a free temporary local of the specified type. */
getTempLocal(type: Type, except?: ExpressionRef): Local; getTempLocal(type: Type, except?: Set<i32> | null): Local;
/** Gets a local that sticks around until this flow is exited, and then released. */ /** Gets a local that sticks around until this flow is exited, and then released. */
getAutoreleaseLocal(type: Type, except?: ExpressionRef): Local; getAutoreleaseLocal(type: Type, except?: Set<i32> | null): Local;
/** Frees the temporary local for reuse. */ /** Frees the temporary local for reuse. */
freeTempLocal(local: Local): void; freeTempLocal(local: Local): void;
/** Gets and immediately frees a temporary local of the specified type. */ /** Gets and immediately frees a temporary local of the specified type. */
getAndFreeTempLocal(type: Type, except?: ExpressionRef): Local; getAndFreeTempLocal(type: Type, except?: Set<i32> | null): Local;
/** Gets the scoped local of the specified name. */
getScopedLocal(name: string): Local | null;
/** Adds a new scoped local of the specified name. */ /** Adds a new scoped local of the specified name. */
addScopedLocal(name: string, type: Type, reportNode?: Node | null): Local; addScopedLocal(name: string, type: Type, except?: Set<i32> | null): Local;
/** Adds a new scoped alias for the specified local. For example `super` aliased to the `this` local. */ /** Adds a new scoped alias for the specified local. For example `super` aliased to the `this` local. */
addScopedAlias(name: string, type: Type, index: i32, reportNode?: Node | null): Local; addScopedAlias(name: string, type: Type, index: i32, reportNode?: Node | null): Local;
/** Blocks any locals that might be used in an inlining operation. */
blockLocalsBeforeInlining(instance: Function): Local[];
/** Unblocks the specified locals. */
unblockLocals(temps: Local[]): void;
/** Frees this flow's scoped variables and returns its parent flow. */ /** Frees this flow's scoped variables and returns its parent flow. */
freeScopedLocals(): void; freeScopedLocals(): void;
/** Looks up the local of the specified name in the current scope. */ /** Looks up the local of the specified name in the current scope. */
@ -2621,6 +2621,8 @@ declare module 'assemblyscript/src/flow' {
canOverflow(expr: ExpressionRef, type: Type): bool; canOverflow(expr: ExpressionRef, type: Type): bool;
toString(): string; toString(): string;
} }
/** Finds all indexes of locals used in the specified expression. */
export function findUsedLocals(expr: ExpressionRef, used?: Set<i32>): Set<i32>;
} }
declare module 'assemblyscript/src/resolver' { declare module 'assemblyscript/src/resolver' {
@ -3672,6 +3674,8 @@ declare module 'assemblyscript/src/program' {
private _id; private _id;
/** Remembers acyclic state. */ /** Remembers acyclic state. */
private _acyclic; private _acyclic;
/** Runtime type information flags. */
rttiFlags: u32;
/** Gets the unique runtime id of this class. */ /** Gets the unique runtime id of this class. */
readonly id: u32; readonly id: u32;
/** Tests if this class is of a builtin array type (Array/TypedArray). */ /** Tests if this class is of a builtin array type (Array/TypedArray). */
@ -3791,9 +3795,9 @@ declare module 'assemblyscript/src/compiler' {
/** Runtime features to be activated by the compiler. */ /** Runtime features to be activated by the compiler. */
export const enum RuntimeFeatures { export const enum RuntimeFeatures {
NONE = 0, NONE = 0,
/** Requires HEAP_BASE and heap setup. */ /** Requires heap setup. */
HEAP = 1, HEAP = 1,
/** Requires RTTI_BASE and RTTI setup. */ /** Requires runtime type information setup. */
RTTI = 2, RTTI = 2,
/** Requires the built-in globals visitor. */ /** Requires the built-in globals visitor. */
visitGlobals = 4, visitGlobals = 4,
@ -3976,10 +3980,10 @@ declare module 'assemblyscript/src/compiler' {
*/ */
checkCallSignature(signature: Signature, numArguments: i32, hasThis: bool, reportNode: Node): bool; checkCallSignature(signature: Signature, numArguments: i32, hasThis: bool, reportNode: Node): bool;
/** Compiles a direct call to a concrete function. */ /** Compiles a direct call to a concrete function. */
compileCallDirect(instance: Function, argumentExpressions: Expression[], reportNode: Node, thisArg?: ExpressionRef, inlineCanAlias?: bool, contextualFlags?: ContextualFlags): ExpressionRef; compileCallDirect(instance: Function, argumentExpressions: Expression[], reportNode: Node, thisArg?: ExpressionRef, contextualFlags?: ContextualFlags): ExpressionRef;
compileCallInline(instance: Function, argumentExpressions: Expression[], thisArg: ExpressionRef, reportNode: Node, canAlias?: bool): ExpressionRef; compileCallInline(instance: Function, argumentExpressions: Expression[], thisArg: ExpressionRef, reportNode: Node, canAlias?: bool): ExpressionRef;
private compileCallInlinePrechecked; private compileCallInlinePrechecked;
makeCallInlinePrechecked(instance: Function, args: ExpressionRef[], thisArg?: ExpressionRef, canAlias?: bool, immediatelyDropped?: bool): ExpressionRef; makeCallInlinePrechecked(instance: Function, operands: ExpressionRef[] | null, thisArg?: ExpressionRef, immediatelyDropped?: bool): ExpressionRef;
/** Gets the trampoline for the specified function. */ /** Gets the trampoline for the specified function. */
ensureTrampoline(original: Function): Function; ensureTrampoline(original: Function): Function;
/** Makes sure that the argument count helper global is present and returns its name. */ /** Makes sure that the argument count helper global is present and returns its name. */
@ -4445,8 +4449,8 @@ declare module 'assemblyscript/src/builtins' {
const f64x2_convert_s_i64x2 = "~lib/builtins/f64x2.convert_s_i64x2"; const f64x2_convert_s_i64x2 = "~lib/builtins/f64x2.convert_s_i64x2";
const f64x2_convert_u_i64x2 = "~lib/builtins/f64x2.convert_u_i64x2"; const f64x2_convert_u_i64x2 = "~lib/builtins/f64x2.convert_u_i64x2";
const v8x16_shuffle = "~lib/builtins/v8x16.shuffle"; const v8x16_shuffle = "~lib/builtins/v8x16.shuffle";
const HEAP_BASE = "~lib/heap/HEAP_BASE"; const heap_base = "~lib/heap/__heap_base";
const RTTI_BASE = "~lib/rt/RTTI_BASE"; const rtti_base = "~lib/rt/__rtti_base";
const visit_globals = "~lib/rt/__visit_globals"; const visit_globals = "~lib/rt/__visit_globals";
const visit_members = "~lib/rt/__visit_members"; const visit_members = "~lib/rt/__visit_members";
const ERROR = "~lib/diagnostics/ERROR"; const ERROR = "~lib/diagnostics/ERROR";
@ -4531,32 +4535,33 @@ declare module 'assemblyscript/src/definitions' {
* Definition builders for WebIDL and TypeScript. * Definition builders for WebIDL and TypeScript.
* @module definitions * @module definitions
*/ /***/ */ /***/
import { Program, Element, Global, Enum, Field, Function, Class, Namespace, Interface } from 'assemblyscript/src/program'; import { Program, Element, Global, Enum, Field, Function, Class, Namespace, Interface, File } from 'assemblyscript/src/program';
import { Type } from 'assemblyscript/src/types'; abstract class ExportsWalker { import { Type } from 'assemblyscript/src/types'; abstract class ExportsWalker {
/** Program reference. */ /** Program reference. */
program: Program; program: Program;
/** Whether to include private members */ /** Whether to include private members */
includePrivate: bool; includePrivate: bool;
/** Elements still to do. */
todo: Element[];
/** Already seen elements. */ /** Already seen elements. */
seen: Set<Element>; seen: Map<Element, string>;
/** Constructs a new Element walker. */ /** Constructs a new Element walker. */
constructor(program: Program, includePrivate?: bool); constructor(program: Program, includePrivate?: bool);
/** Walks all elements and calls the respective handlers. */ /** Walks all elements and calls the respective handlers. */
walk(): void; walk(): void;
/** Visits all exported elements of a file. */
visitFile(file: File): void;
/** Visits an element.*/ /** Visits an element.*/
visitElement(element: Element): void; visitElement(name: string, element: Element): void;
private visitFunctionInstances; private visitFunctionInstances;
private visitClassInstances; private visitClassInstances;
private visitPropertyInstances; private visitPropertyInstances;
abstract visitGlobal(element: Global): void; abstract visitGlobal(name: string, element: Global): void;
abstract visitEnum(element: Enum): void; abstract visitEnum(name: string, element: Enum): void;
abstract visitFunction(element: Function): void; abstract visitFunction(name: string, element: Function): void;
abstract visitClass(element: Class): void; abstract visitClass(name: string, element: Class): void;
abstract visitInterface(element: Interface): void; abstract visitInterface(name: string, element: Interface): void;
abstract visitField(element: Field): void; abstract visitField(name: string, element: Field): void;
abstract visitNamespace(element: Element): void; abstract visitNamespace(name: string, element: Element): void;
abstract visitAlias(name: string, element: Element, originalName: string): void;
} }
/** A WebIDL definitions builder. */ /** A WebIDL definitions builder. */
export class IDLBuilder extends ExportsWalker { export class IDLBuilder extends ExportsWalker {
@ -4566,13 +4571,14 @@ declare module 'assemblyscript/src/definitions' {
private indentLevel; private indentLevel;
/** Constructs a new WebIDL builder. */ /** Constructs a new WebIDL builder. */
constructor(program: Program, includePrivate?: bool); constructor(program: Program, includePrivate?: bool);
visitGlobal(element: Global): void; visitGlobal(name: string, element: Global): void;
visitEnum(element: Enum): void; visitEnum(name: string, element: Enum): void;
visitFunction(element: Function): void; visitFunction(name: string, element: Function): void;
visitClass(element: Class): void; visitClass(name: string, element: Class): void;
visitInterface(element: Interface): void; visitInterface(name: string, element: Interface): void;
visitField(element: Field): void; visitField(name: string, element: Field): void;
visitNamespace(element: Namespace): void; visitNamespace(name: string, element: Namespace): void;
visitAlias(name: string, element: Element, originalName: string): void;
typeToString(type: Type): string; typeToString(type: Type): string;
build(): string; build(): string;
} }
@ -4582,15 +4588,17 @@ declare module 'assemblyscript/src/definitions' {
static build(program: Program): string; static build(program: Program): string;
private sb; private sb;
private indentLevel; private indentLevel;
private unknown;
/** Constructs a new WebIDL builder. */ /** Constructs a new WebIDL builder. */
constructor(program: Program, includePrivate?: bool); constructor(program: Program, includePrivate?: bool);
visitGlobal(element: Global): void; visitGlobal(name: string, element: Global): void;
visitEnum(element: Enum): void; visitEnum(name: string, element: Enum): void;
visitFunction(element: Function): void; visitFunction(name: string, element: Function): void;
visitClass(element: Class): void; visitClass(name: string, element: Class): void;
visitInterface(element: Interface): void; visitInterface(name: string, element: Interface): void;
visitField(element: Field): void; visitField(name: string, element: Field): void;
visitNamespace(element: Element): void; visitNamespace(name: string, element: Element): void;
visitAlias(name: string, element: Element, originalName: string): void;
typeToString(type: Type): string; typeToString(type: Type): string;
build(): string; build(): string;
} }
@ -4778,6 +4786,8 @@ declare module 'assemblyscript/src/index' {
export function buildIDL(program: Program): string; export function buildIDL(program: Program): string;
/** Builds TypeScript definitions for the specified program. */ /** Builds TypeScript definitions for the specified program. */
export function buildTSD(program: Program): string; export function buildTSD(program: Program): string;
/** Builds a JSON file of a program's runtime type information. */
export function buildRTTI(program: Program): string;
/** Prefix indicating a library file. */ /** Prefix indicating a library file. */
export { LIBRARY_PREFIX } from 'assemblyscript/src/common'; export { LIBRARY_PREFIX } from 'assemblyscript/src/common';
export * from 'assemblyscript/src/ast'; export * from 'assemblyscript/src/ast';

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -4190,6 +4190,7 @@ export function compileRTTI(compiler: Compiler): void {
flags |= TypeinfoFlags.VALUE_ALIGN_0 * typeToRuntimeFlags(typeArguments[1]); flags |= TypeinfoFlags.VALUE_ALIGN_0 * typeToRuntimeFlags(typeArguments[1]);
} }
writeI32(flags, data, off); off += 4; writeI32(flags, data, off); off += 4;
instance.rttiFlags = flags;
let base = instance.base; let base = instance.base;
writeI32(base ? base.id : 0, data, off); off += 4; writeI32(base ? base.id : 0, data, off); off += 4;
} }

View File

@ -148,6 +148,32 @@ export function buildTSD(program: Program): string {
return TSDBuilder.build(program); return TSDBuilder.build(program);
} }
/** Builds a JSON file of a program's runtime type information. */
export function buildRTTI(program: Program): string {
var sb = new Array<string>();
sb.push("{\n \"names\": [\n");
for (let cls of program.managedClasses.values()) {
sb.push(" \"");
sb.push(cls.internalName);
sb.push("\",\n");
}
sb.push(" ],\n \"base\": [\n");
for (let cls of program.managedClasses.values()) {
let base = cls.base;
sb.push(" ");
sb.push(base ? base.id.toString() : "0");
sb.push(",\n");
}
sb.push(" ],\n \"flags\": [\n");
for (let cls of program.managedClasses.values()) {
sb.push(" ");
sb.push(cls.rttiFlags.toString());
sb.push(",\n");
}
sb.push(" ]\n}\n");
return sb.join("");
}
/** Prefix indicating a library file. */ /** Prefix indicating a library file. */
export { LIBRARY_PREFIX } from "./common"; export { LIBRARY_PREFIX } from "./common";

View File

@ -3034,6 +3034,8 @@ export class Class extends TypedElement {
private _id: u32 = 0; private _id: u32 = 0;
/** Remembers acyclic state. */ /** Remembers acyclic state. */
private _acyclic: AcyclicState = AcyclicState.UNKNOWN; private _acyclic: AcyclicState = AcyclicState.UNKNOWN;
/** Runtime type information flags. */
rttiFlags: u32 = 0;
/** Gets the unique runtime id of this class. */ /** Gets the unique runtime id of this class. */
get id(): u32 { get id(): u32 {

View File

@ -135,7 +135,15 @@ export class Array<T> extends ArrayBufferView {
var length = this.length_; var length = this.length_;
start = start < 0 ? max(length + start, 0) : min(start, length); start = start < 0 ? max(length + start, 0) : min(start, length);
end = end < 0 ? max(length + end, 0) : min(end, length); end = end < 0 ? max(length + end, 0) : min(end, length);
if (sizeof<T>() == 1) { if (isManaged<T>()) {
for (; start < end; ++start) {
let oldRef: usize = load<usize>(dataStart + (<usize>start << alignof<T>()));
if (changetype<usize>(value) != oldRef) {
store<usize>(dataStart + (<usize>start << alignof<T>()), __retain(changetype<usize>(value)));
__release(oldRef);
}
}
} else if (sizeof<T>() == 1) {
if (start < end) { if (start < end) {
memory.fill( memory.fill(
dataStart + <usize>start, dataStart + <usize>start,

View File

@ -2015,7 +2015,7 @@
if if
i32.const 424 i32.const 424
i32.const 376 i32.const 376
i32.const 258 i32.const 266
i32.const 20 i32.const 20
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable

View File

@ -3784,7 +3784,7 @@
if if
i32.const 424 i32.const 424
i32.const 376 i32.const 376
i32.const 258 i32.const 266
i32.const 20 i32.const 20
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable

View File

@ -2858,7 +2858,7 @@
if if
i32.const 872 i32.const 872
i32.const 488 i32.const 488
i32.const 258 i32.const 266
i32.const 20 i32.const 20
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -2905,7 +2905,7 @@
call $~lib/rt/pure/__release call $~lib/rt/pure/__release
i32.const 272 i32.const 272
i32.const 488 i32.const 488
i32.const 205 i32.const 213
i32.const 59 i32.const 59
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -3144,7 +3144,7 @@
if if
i32.const 872 i32.const 872
i32.const 488 i32.const 488
i32.const 319 i32.const 327
i32.const 20 i32.const 20
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable

View File

@ -4881,7 +4881,7 @@
if if
i32.const 872 i32.const 872
i32.const 488 i32.const 488
i32.const 258 i32.const 266
i32.const 20 i32.const 20
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -4937,7 +4937,7 @@
block block
i32.const 272 i32.const 272
i32.const 488 i32.const 488
i32.const 205 i32.const 213
i32.const 59 i32.const 59
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -5300,7 +5300,7 @@
if if
i32.const 872 i32.const 872
i32.const 488 i32.const 488
i32.const 319 i32.const 327
i32.const 20 i32.const 20
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable