Skip to content

Commit 1468923

Browse files
committed
fix rc in Array#fill, add rtti logging for debugging
1 parent 066ea1f commit 1468923

15 files changed

+129
-65
lines changed

cli/asc.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,9 @@ exports.main = function main(argv, options, callback) {
711711
if (args.measure) {
712712
printStats(stats, stderr);
713713
}
714+
if (args.printrtti) {
715+
printRTTI(program, stderr);
716+
}
714717
return callback(null);
715718

716719
function readFileNode(filename, baseDir) {
@@ -847,6 +850,15 @@ function printStats(stats, output) {
847850

848851
exports.printStats = printStats;
849852

853+
/** Prints runtime type information. */
854+
function printRTTI(program, output) {
855+
if (!output) output = process.stderr;
856+
output.write("# Runtime type information (RTTI)\n");
857+
output.write(assemblyscript.buildRTTI(program));
858+
}
859+
860+
exports.printRTTI = printRTTI;
861+
850862
var allocBuffer = typeof global !== "undefined" && global.Buffer
851863
? global.Buffer.allocUnsafe || function(len) { return new global.Buffer(len); }
852864
: function(len) { return new Uint8Array(len) };

cli/asc.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,11 @@
185185
"type": "b",
186186
"default": false
187187
},
188+
"printrtti": {
189+
"description": "Prints the module's runtime type information to stderr.",
190+
"type": "b",
191+
"default": false
192+
},
188193
"noColors": {
189194
"description": "Disables terminal colors.",
190195
"type": "b",

dist/asc.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/asc.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/assemblyscript.d.ts

Lines changed: 62 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ declare module 'assemblyscript/src/diagnosticMessages.generated' {
218218
Type_0_cannot_be_reinterpreted_as_type_1 = 203,
219219
Basic_type_0_cannot_be_nullable = 204,
220220
Cannot_export_a_mutable_global = 205,
221-
Compiling_constant_with_non_constant_initializer_as_mutable = 206,
221+
Mutable_value_cannot_be_inlined = 206,
222222
Unmanaged_classes_cannot_extend_managed_classes_and_vice_versa = 207,
223223
Unmanaged_classes_cannot_implement_interfaces = 208,
224224
Invalid_regular_expression_flags = 209,
@@ -2482,28 +2482,30 @@ declare module 'assemblyscript/src/flow' {
24822482
export enum LocalFlags {
24832483
/** No specific conditions. */
24842484
NONE = 0,
2485+
/** Local is constant. */
2486+
CONSTANT = 1,
24852487
/** Local is properly wrapped. Relevant for small integers. */
2486-
WRAPPED = 1,
2488+
WRAPPED = 2,
24872489
/** Local is non-null. */
2488-
NONNULL = 2,
2490+
NONNULL = 4,
24892491
/** Local is read from. */
2490-
READFROM = 4,
2492+
READFROM = 8,
24912493
/** Local is written to. */
2492-
WRITTENTO = 8,
2494+
WRITTENTO = 16,
24932495
/** Local is retained. */
2494-
RETAINED = 16,
2496+
RETAINED = 32,
24952497
/** Local is conditionally read from. */
2496-
CONDITIONALLY_READFROM = 32,
2498+
CONDITIONALLY_READFROM = 64,
24972499
/** Local is conditionally written to. */
2498-
CONDITIONALLY_WRITTENTO = 64,
2500+
CONDITIONALLY_WRITTENTO = 128,
24992501
/** Local must be conditionally retained. */
2500-
CONDITIONALLY_RETAINED = 128,
2502+
CONDITIONALLY_RETAINED = 256,
25012503
/** Any categorical flag. */
2502-
ANY_CATEGORICAL = 31,
2504+
ANY_CATEGORICAL = 63,
25032505
/** Any conditional flag. */
2504-
ANY_CONDITIONAL = 240,
2506+
ANY_CONDITIONAL = 480,
25052507
/** Any retained flag. */
2506-
ANY_RETAINED = 144
2508+
ANY_RETAINED = 288
25072509
}
25082510
export namespace LocalFlags {
25092511
function join(left: LocalFlags, right: LocalFlags): LocalFlags;
@@ -2568,21 +2570,19 @@ declare module 'assemblyscript/src/flow' {
25682570
/** Forks this flow to a child flow. */
25692571
fork(): Flow;
25702572
/** Gets a free temporary local of the specified type. */
2571-
getTempLocal(type: Type, except?: ExpressionRef): Local;
2573+
getTempLocal(type: Type, except?: Set<i32> | null): Local;
25722574
/** Gets a local that sticks around until this flow is exited, and then released. */
2573-
getAutoreleaseLocal(type: Type, except?: ExpressionRef): Local;
2575+
getAutoreleaseLocal(type: Type, except?: Set<i32> | null): Local;
25742576
/** Frees the temporary local for reuse. */
25752577
freeTempLocal(local: Local): void;
25762578
/** Gets and immediately frees a temporary local of the specified type. */
2577-
getAndFreeTempLocal(type: Type, except?: ExpressionRef): Local;
2579+
getAndFreeTempLocal(type: Type, except?: Set<i32> | null): Local;
2580+
/** Gets the scoped local of the specified name. */
2581+
getScopedLocal(name: string): Local | null;
25782582
/** Adds a new scoped local of the specified name. */
2579-
addScopedLocal(name: string, type: Type, reportNode?: Node | null): Local;
2583+
addScopedLocal(name: string, type: Type, except?: Set<i32> | null): Local;
25802584
/** Adds a new scoped alias for the specified local. For example `super` aliased to the `this` local. */
25812585
addScopedAlias(name: string, type: Type, index: i32, reportNode?: Node | null): Local;
2582-
/** Blocks any locals that might be used in an inlining operation. */
2583-
blockLocalsBeforeInlining(instance: Function): Local[];
2584-
/** Unblocks the specified locals. */
2585-
unblockLocals(temps: Local[]): void;
25862586
/** Frees this flow's scoped variables and returns its parent flow. */
25872587
freeScopedLocals(): void;
25882588
/** Looks up the local of the specified name in the current scope. */
@@ -2621,6 +2621,8 @@ declare module 'assemblyscript/src/flow' {
26212621
canOverflow(expr: ExpressionRef, type: Type): bool;
26222622
toString(): string;
26232623
}
2624+
/** Finds all indexes of locals used in the specified expression. */
2625+
export function findUsedLocals(expr: ExpressionRef, used?: Set<i32>): Set<i32>;
26242626

26252627
}
26262628
declare module 'assemblyscript/src/resolver' {
@@ -3672,6 +3674,8 @@ declare module 'assemblyscript/src/program' {
36723674
private _id;
36733675
/** Remembers acyclic state. */
36743676
private _acyclic;
3677+
/** Runtime type information flags. */
3678+
rttiFlags: u32;
36753679
/** Gets the unique runtime id of this class. */
36763680
readonly id: u32;
36773681
/** Tests if this class is of a builtin array type (Array/TypedArray). */
@@ -3791,9 +3795,9 @@ declare module 'assemblyscript/src/compiler' {
37913795
/** Runtime features to be activated by the compiler. */
37923796
export const enum RuntimeFeatures {
37933797
NONE = 0,
3794-
/** Requires HEAP_BASE and heap setup. */
3798+
/** Requires heap setup. */
37953799
HEAP = 1,
3796-
/** Requires RTTI_BASE and RTTI setup. */
3800+
/** Requires runtime type information setup. */
37973801
RTTI = 2,
37983802
/** Requires the built-in globals visitor. */
37993803
visitGlobals = 4,
@@ -3976,10 +3980,10 @@ declare module 'assemblyscript/src/compiler' {
39763980
*/
39773981
checkCallSignature(signature: Signature, numArguments: i32, hasThis: bool, reportNode: Node): bool;
39783982
/** Compiles a direct call to a concrete function. */
3979-
compileCallDirect(instance: Function, argumentExpressions: Expression[], reportNode: Node, thisArg?: ExpressionRef, inlineCanAlias?: bool, contextualFlags?: ContextualFlags): ExpressionRef;
3983+
compileCallDirect(instance: Function, argumentExpressions: Expression[], reportNode: Node, thisArg?: ExpressionRef, contextualFlags?: ContextualFlags): ExpressionRef;
39803984
compileCallInline(instance: Function, argumentExpressions: Expression[], thisArg: ExpressionRef, reportNode: Node, canAlias?: bool): ExpressionRef;
39813985
private compileCallInlinePrechecked;
3982-
makeCallInlinePrechecked(instance: Function, args: ExpressionRef[], thisArg?: ExpressionRef, canAlias?: bool, immediatelyDropped?: bool): ExpressionRef;
3986+
makeCallInlinePrechecked(instance: Function, operands: ExpressionRef[] | null, thisArg?: ExpressionRef, immediatelyDropped?: bool): ExpressionRef;
39833987
/** Gets the trampoline for the specified function. */
39843988
ensureTrampoline(original: Function): Function;
39853989
/** Makes sure that the argument count helper global is present and returns its name. */
@@ -4445,8 +4449,8 @@ declare module 'assemblyscript/src/builtins' {
44454449
const f64x2_convert_s_i64x2 = "~lib/builtins/f64x2.convert_s_i64x2";
44464450
const f64x2_convert_u_i64x2 = "~lib/builtins/f64x2.convert_u_i64x2";
44474451
const v8x16_shuffle = "~lib/builtins/v8x16.shuffle";
4448-
const HEAP_BASE = "~lib/heap/HEAP_BASE";
4449-
const RTTI_BASE = "~lib/rt/RTTI_BASE";
4452+
const heap_base = "~lib/heap/__heap_base";
4453+
const rtti_base = "~lib/rt/__rtti_base";
44504454
const visit_globals = "~lib/rt/__visit_globals";
44514455
const visit_members = "~lib/rt/__visit_members";
44524456
const ERROR = "~lib/diagnostics/ERROR";
@@ -4531,32 +4535,33 @@ declare module 'assemblyscript/src/definitions' {
45314535
* Definition builders for WebIDL and TypeScript.
45324536
* @module definitions
45334537
*/ /***/
4534-
import { Program, Element, Global, Enum, Field, Function, Class, Namespace, Interface } from 'assemblyscript/src/program';
4538+
import { Program, Element, Global, Enum, Field, Function, Class, Namespace, Interface, File } from 'assemblyscript/src/program';
45354539
import { Type } from 'assemblyscript/src/types'; abstract class ExportsWalker {
45364540
/** Program reference. */
45374541
program: Program;
45384542
/** Whether to include private members */
45394543
includePrivate: bool;
4540-
/** Elements still to do. */
4541-
todo: Element[];
45424544
/** Already seen elements. */
4543-
seen: Set<Element>;
4545+
seen: Map<Element, string>;
45444546
/** Constructs a new Element walker. */
45454547
constructor(program: Program, includePrivate?: bool);
45464548
/** Walks all elements and calls the respective handlers. */
45474549
walk(): void;
4550+
/** Visits all exported elements of a file. */
4551+
visitFile(file: File): void;
45484552
/** Visits an element.*/
4549-
visitElement(element: Element): void;
4553+
visitElement(name: string, element: Element): void;
45504554
private visitFunctionInstances;
45514555
private visitClassInstances;
45524556
private visitPropertyInstances;
4553-
abstract visitGlobal(element: Global): void;
4554-
abstract visitEnum(element: Enum): void;
4555-
abstract visitFunction(element: Function): void;
4556-
abstract visitClass(element: Class): void;
4557-
abstract visitInterface(element: Interface): void;
4558-
abstract visitField(element: Field): void;
4559-
abstract visitNamespace(element: Element): void;
4557+
abstract visitGlobal(name: string, element: Global): void;
4558+
abstract visitEnum(name: string, element: Enum): void;
4559+
abstract visitFunction(name: string, element: Function): void;
4560+
abstract visitClass(name: string, element: Class): void;
4561+
abstract visitInterface(name: string, element: Interface): void;
4562+
abstract visitField(name: string, element: Field): void;
4563+
abstract visitNamespace(name: string, element: Element): void;
4564+
abstract visitAlias(name: string, element: Element, originalName: string): void;
45604565
}
45614566
/** A WebIDL definitions builder. */
45624567
export class IDLBuilder extends ExportsWalker {
@@ -4566,13 +4571,14 @@ declare module 'assemblyscript/src/definitions' {
45664571
private indentLevel;
45674572
/** Constructs a new WebIDL builder. */
45684573
constructor(program: Program, includePrivate?: bool);
4569-
visitGlobal(element: Global): void;
4570-
visitEnum(element: Enum): void;
4571-
visitFunction(element: Function): void;
4572-
visitClass(element: Class): void;
4573-
visitInterface(element: Interface): void;
4574-
visitField(element: Field): void;
4575-
visitNamespace(element: Namespace): void;
4574+
visitGlobal(name: string, element: Global): void;
4575+
visitEnum(name: string, element: Enum): void;
4576+
visitFunction(name: string, element: Function): void;
4577+
visitClass(name: string, element: Class): void;
4578+
visitInterface(name: string, element: Interface): void;
4579+
visitField(name: string, element: Field): void;
4580+
visitNamespace(name: string, element: Namespace): void;
4581+
visitAlias(name: string, element: Element, originalName: string): void;
45764582
typeToString(type: Type): string;
45774583
build(): string;
45784584
}
@@ -4582,15 +4588,17 @@ declare module 'assemblyscript/src/definitions' {
45824588
static build(program: Program): string;
45834589
private sb;
45844590
private indentLevel;
4591+
private unknown;
45854592
/** Constructs a new WebIDL builder. */
45864593
constructor(program: Program, includePrivate?: bool);
4587-
visitGlobal(element: Global): void;
4588-
visitEnum(element: Enum): void;
4589-
visitFunction(element: Function): void;
4590-
visitClass(element: Class): void;
4591-
visitInterface(element: Interface): void;
4592-
visitField(element: Field): void;
4593-
visitNamespace(element: Element): void;
4594+
visitGlobal(name: string, element: Global): void;
4595+
visitEnum(name: string, element: Enum): void;
4596+
visitFunction(name: string, element: Function): void;
4597+
visitClass(name: string, element: Class): void;
4598+
visitInterface(name: string, element: Interface): void;
4599+
visitField(name: string, element: Field): void;
4600+
visitNamespace(name: string, element: Element): void;
4601+
visitAlias(name: string, element: Element, originalName: string): void;
45944602
typeToString(type: Type): string;
45954603
build(): string;
45964604
}
@@ -4778,6 +4786,8 @@ declare module 'assemblyscript/src/index' {
47784786
export function buildIDL(program: Program): string;
47794787
/** Builds TypeScript definitions for the specified program. */
47804788
export function buildTSD(program: Program): string;
4789+
/** Builds a JSON file of a program's runtime type information. */
4790+
export function buildRTTI(program: Program): string;
47814791
/** Prefix indicating a library file. */
47824792
export { LIBRARY_PREFIX } from 'assemblyscript/src/common';
47834793
export * from 'assemblyscript/src/ast';

dist/assemblyscript.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/assemblyscript.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/builtins.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4190,6 +4190,7 @@ export function compileRTTI(compiler: Compiler): void {
41904190
flags |= TypeinfoFlags.VALUE_ALIGN_0 * typeToRuntimeFlags(typeArguments[1]);
41914191
}
41924192
writeI32(flags, data, off); off += 4;
4193+
instance.rttiFlags = flags;
41934194
let base = instance.base;
41944195
writeI32(base ? base.id : 0, data, off); off += 4;
41954196
}

src/index.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,32 @@ export function buildTSD(program: Program): string {
148148
return TSDBuilder.build(program);
149149
}
150150

151+
/** Builds a JSON file of a program's runtime type information. */
152+
export function buildRTTI(program: Program): string {
153+
var sb = new Array<string>();
154+
sb.push("{\n \"names\": [\n");
155+
for (let cls of program.managedClasses.values()) {
156+
sb.push(" \"");
157+
sb.push(cls.internalName);
158+
sb.push("\",\n");
159+
}
160+
sb.push(" ],\n \"base\": [\n");
161+
for (let cls of program.managedClasses.values()) {
162+
let base = cls.base;
163+
sb.push(" ");
164+
sb.push(base ? base.id.toString() : "0");
165+
sb.push(",\n");
166+
}
167+
sb.push(" ],\n \"flags\": [\n");
168+
for (let cls of program.managedClasses.values()) {
169+
sb.push(" ");
170+
sb.push(cls.rttiFlags.toString());
171+
sb.push(",\n");
172+
}
173+
sb.push(" ]\n}\n");
174+
return sb.join("");
175+
}
176+
151177
/** Prefix indicating a library file. */
152178
export { LIBRARY_PREFIX } from "./common";
153179

src/program.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3034,6 +3034,8 @@ export class Class extends TypedElement {
30343034
private _id: u32 = 0;
30353035
/** Remembers acyclic state. */
30363036
private _acyclic: AcyclicState = AcyclicState.UNKNOWN;
3037+
/** Runtime type information flags. */
3038+
rttiFlags: u32 = 0;
30373039

30383040
/** Gets the unique runtime id of this class. */
30393041
get id(): u32 {

std/assembly/array.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,15 @@ export class Array<T> extends ArrayBufferView {
135135
var length = this.length_;
136136
start = start < 0 ? max(length + start, 0) : min(start, length);
137137
end = end < 0 ? max(length + end, 0) : min(end, length);
138-
if (sizeof<T>() == 1) {
138+
if (isManaged<T>()) {
139+
for (; start < end; ++start) {
140+
let oldRef: usize = load<usize>(dataStart + (<usize>start << alignof<T>()));
141+
if (changetype<usize>(value) != oldRef) {
142+
store<usize>(dataStart + (<usize>start << alignof<T>()), __retain(changetype<usize>(value)));
143+
__release(oldRef);
144+
}
145+
}
146+
} else if (sizeof<T>() == 1) {
139147
if (start < end) {
140148
memory.fill(
141149
dataStart + <usize>start,

tests/compiler/retain-release-sanity.optimized.wat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2015,7 +2015,7 @@
20152015
if
20162016
i32.const 424
20172017
i32.const 376
2018-
i32.const 258
2018+
i32.const 266
20192019
i32.const 20
20202020
call $~lib/builtins/abort
20212021
unreachable

tests/compiler/retain-release-sanity.untouched.wat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3784,7 +3784,7 @@
37843784
if
37853785
i32.const 424
37863786
i32.const 376
3787-
i32.const 258
3787+
i32.const 266
37883788
i32.const 20
37893789
call $~lib/builtins/abort
37903790
unreachable

tests/compiler/std/array.optimized.wat

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2858,7 +2858,7 @@
28582858
if
28592859
i32.const 872
28602860
i32.const 488
2861-
i32.const 258
2861+
i32.const 266
28622862
i32.const 20
28632863
call $~lib/builtins/abort
28642864
unreachable
@@ -2905,7 +2905,7 @@
29052905
call $~lib/rt/pure/__release
29062906
i32.const 272
29072907
i32.const 488
2908-
i32.const 205
2908+
i32.const 213
29092909
i32.const 59
29102910
call $~lib/builtins/abort
29112911
unreachable
@@ -3144,7 +3144,7 @@
31443144
if
31453145
i32.const 872
31463146
i32.const 488
3147-
i32.const 319
3147+
i32.const 327
31483148
i32.const 20
31493149
call $~lib/builtins/abort
31503150
unreachable

0 commit comments

Comments
 (0)