Skip to content

Commit e31fc4f

Browse files
committed
Merge remote-tracking branch 'origin/master' into release
2 parents 6028dba + 104d2f5 commit e31fc4f

File tree

188 files changed

+44317
-25526
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

188 files changed

+44317
-25526
lines changed

src/compiler.ts

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,7 +1450,7 @@ export class Compiler extends DiagnosticEmitter {
14501450
// === Memory ===================================================================================
14511451

14521452
/** Adds a static memory segment with the specified data. */
1453-
addMemorySegment(buffer: Uint8Array, alignment: i32 = 8): MemorySegment {
1453+
addMemorySegment(buffer: Uint8Array, alignment: i32 = 16): MemorySegment {
14541454
var memoryOffset = i64_align(this.memoryOffset, alignment);
14551455
var segment = MemorySegment.create(buffer, memoryOffset);
14561456
this.memorySegments.push(segment);
@@ -7455,17 +7455,33 @@ export class Compiler extends DiagnosticEmitter {
74557455
switch (expression.literalKind) {
74567456
case LiteralKind.ARRAY: {
74577457
assert(!implicitlyNegate);
7458-
let classType = contextualType.classReference;
7459-
if (classType) {
7460-
if (classType.prototype == this.program.arrayPrototype) {
7461-
return this.compileArrayLiteral(
7462-
assert(classType.typeArguments)[0],
7463-
(<ArrayLiteralExpression>expression).elementExpressions,
7464-
constraints,
7465-
expression
7466-
);
7458+
let elementExpressions = (<ArrayLiteralExpression>expression).elementExpressions;
7459+
7460+
// Infer from first element in auto contexts
7461+
if (contextualType == Type.auto) {
7462+
return this.compileArrayLiteral(
7463+
Type.auto,
7464+
elementExpressions,
7465+
constraints,
7466+
expression
7467+
);
7468+
}
7469+
7470+
// Use contextual type if an array
7471+
if (contextualType.is(TypeFlags.REFERENCE)) {
7472+
let classType = contextualType.classReference;
7473+
if (classType) {
7474+
if (classType.prototype == this.program.arrayPrototype) {
7475+
return this.compileArrayLiteral(
7476+
assert(classType.typeArguments)[0],
7477+
elementExpressions,
7478+
constraints,
7479+
expression
7480+
);
7481+
}
74677482
}
74687483
}
7484+
74697485
this.error(
74707486
DiagnosticCode.The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly,
74717487
expression.range, "T"
@@ -7544,17 +7560,42 @@ export class Compiler extends DiagnosticEmitter {
75447560
var module = this.module;
75457561
var program = this.program;
75467562
var arrayPrototype = assert(program.arrayPrototype);
7547-
var arrayInstance = assert(this.resolver.resolveClass(arrayPrototype, [ elementType ]));
75487563
var arrayBufferInstance = assert(program.arrayBufferInstance);
7549-
var arrayType = arrayInstance.type;
75507564
var flow = this.currentFlow;
75517565

75527566
// block those here so compiling expressions doesn't conflict
7553-
var tempThis = flow.getTempLocal(arrayType);
7567+
var tempThis = flow.getTempLocal(this.options.usizeType);
75547568
var tempDataStart = flow.getTempLocal(arrayBufferInstance.type);
75557569

7556-
// compile value expressions and find out whether all are constant
7570+
// infer common element type in auto contexts
75577571
var length = expressions.length;
7572+
if (elementType == Type.auto) {
7573+
for (let i = 0; i < length; ++i) {
7574+
let expression = expressions[i];
7575+
if (expression) {
7576+
let currentType = this.resolver.resolveExpression(expression, this.currentFlow, elementType);
7577+
if (!currentType) return module.unreachable();
7578+
if (elementType == Type.auto) elementType = currentType;
7579+
else if (currentType != elementType) {
7580+
let commonType = Type.commonDenominator(elementType, currentType, false);
7581+
if (commonType) elementType = commonType;
7582+
// otherwise triggers error further down
7583+
}
7584+
}
7585+
}
7586+
if (elementType /* still */ == Type.auto) {
7587+
this.error(
7588+
DiagnosticCode.The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly,
7589+
reportNode.range, "T"
7590+
);
7591+
return module.unreachable();
7592+
}
7593+
}
7594+
7595+
var arrayInstance = assert(this.resolver.resolveClass(arrayPrototype, [ elementType ]));
7596+
var arrayType = arrayInstance.type;
7597+
7598+
// compile value expressions and find out whether all are constant
75587599
var values = new Array<ExpressionRef>(length);
75597600
var isStatic = true;
75607601
var nativeElementType = elementType.toNativeType();

std/assembly/index.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,6 +1290,8 @@ declare abstract class TypedArray<T> implements ArrayBufferView {
12901290
reverse(): this;
12911291
/** The join() method joins all elements of an array into a string. This method has the same algorithm as Array.prototype.join(). */
12921292
join(separator?: string): string;
1293+
/** The set() method stores multiple values in the typed array, reading input values from a specified array. */
1294+
set<U extends ArrayBufferView>(source: U, offset?: i32): void
12931295
/** The toString() method returns a string representing the specified array and its elements. This method has the same algorithm as Array.prototype.toString() */
12941296
toString(): string;
12951297
}

std/assembly/rt/stub.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export function __alloc(size: usize, id: u32): usize {
3131
maybeGrowMemory(ptr + actualSize);
3232
var block = changetype<BLOCK>(ptr - BLOCK_OVERHEAD);
3333
block.mmInfo = actualSize;
34-
if (DEBUG) block.gcInfo = -1;
34+
if (DEBUG) block.gcInfo = 1;
3535
block.rtId = id;
3636
block.rtSize = size;
3737
return ptr;
@@ -43,7 +43,7 @@ export function __realloc(ptr: usize, size: usize): usize {
4343
assert(ptr != 0 && !(ptr & AL_MASK)); // must exist and be aligned
4444
var block = changetype<BLOCK>(ptr - BLOCK_OVERHEAD);
4545
var actualSize = block.mmInfo;
46-
if (DEBUG) assert(block.gcInfo == -1);
46+
if (DEBUG) assert(block.gcInfo == 1);
4747
var isLast = ptr + actualSize == offset;
4848
var alignedSize = (size + AL_MASK) & ~AL_MASK;
4949
if (size > actualSize) {
@@ -69,7 +69,7 @@ export function __realloc(ptr: usize, size: usize): usize {
6969
export function __free(ptr: usize): void {
7070
assert(ptr != 0 && !(ptr & AL_MASK)); // must exist and be aligned
7171
var block = changetype<BLOCK>(ptr - BLOCK_OVERHEAD);
72-
if (DEBUG) assert(block.gcInfo == -1);
72+
if (DEBUG) assert(block.gcInfo == 1);
7373
if (ptr + block.mmInfo == offset) { // last block: discard
7474
offset = changetype<usize>(block);
7575
}

std/assembly/rt/tlsf.ts

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -459,22 +459,26 @@ function prepareSize(size: usize): usize {
459459
}
460460

461461
/** Initilizes the root structure. */
462-
export function initializeRoot(): void {
463-
var rootOffset = (__heap_base + AL_MASK) & ~AL_MASK;
464-
var pagesBefore = memory.size();
465-
var pagesNeeded = <i32>((((rootOffset + ROOT_SIZE) + 0xffff) & ~0xffff) >>> 16);
466-
if (pagesNeeded > pagesBefore && memory.grow(pagesNeeded - pagesBefore) < 0) unreachable();
467-
var root = changetype<Root>(rootOffset);
468-
root.flMap = 0;
469-
SETTAIL(root, changetype<Block>(0));
470-
for (let fl: usize = 0; fl < FL_BITS; ++fl) {
471-
SETSL(root, fl, 0);
472-
for (let sl: u32 = 0; sl < SL_SIZE; ++sl) {
473-
SETHEAD(root, fl, sl, null);
462+
export function maybeInitialize(): Root {
463+
var root = ROOT;
464+
if (!root) {
465+
const rootOffset = (__heap_base + AL_MASK) & ~AL_MASK;
466+
let pagesBefore = memory.size();
467+
let pagesNeeded = <i32>((((rootOffset + ROOT_SIZE) + 0xffff) & ~0xffff) >>> 16);
468+
if (pagesNeeded > pagesBefore && memory.grow(pagesNeeded - pagesBefore) < 0) unreachable();
469+
root = changetype<Root>(rootOffset);
470+
root.flMap = 0;
471+
SETTAIL(root, changetype<Block>(0));
472+
for (let fl: usize = 0; fl < FL_BITS; ++fl) {
473+
SETSL(root, fl, 0);
474+
for (let sl: u32 = 0; sl < SL_SIZE; ++sl) {
475+
SETHEAD(root, fl, sl, null);
476+
}
474477
}
478+
addMemory(root, (rootOffset + ROOT_SIZE + AL_MASK) & ~AL_MASK, memory.size() << 16);
479+
ROOT = root;
475480
}
476-
addMemory(root, (rootOffset + ROOT_SIZE + AL_MASK) & ~AL_MASK, memory.size() << 16);
477-
ROOT = root;
481+
return root;
478482
}
479483

480484
// @ts-ignore: decorator
@@ -551,9 +555,11 @@ export function reallocateBlock(root: Root, block: Block, size: usize): Block {
551555
var newBlock = allocateBlock(root, size);
552556
newBlock.rtId = block.rtId;
553557
memory.copy(changetype<usize>(newBlock) + BLOCK_OVERHEAD, changetype<usize>(block) + BLOCK_OVERHEAD, size);
554-
block.mmInfo = blockInfo | FREE;
555-
insertBlock(root, block);
556-
if (isDefined(ASC_RTRACE)) onfree(block);
558+
if (changetype<usize>(block) >= __heap_base) {
559+
block.mmInfo = blockInfo | FREE;
560+
insertBlock(root, block);
561+
if (isDefined(ASC_RTRACE)) onfree(block);
562+
}
557563
return newBlock;
558564
}
559565

@@ -569,28 +575,21 @@ export function freeBlock(root: Root, block: Block): void {
569575
// @ts-ignore: decorator
570576
@global @unsafe
571577
export function __alloc(size: usize, id: u32): usize {
572-
var root = ROOT;
573-
if (!root) {
574-
initializeRoot();
575-
root = ROOT;
576-
}
577-
var block = allocateBlock(root, size);
578+
var block = allocateBlock(maybeInitialize(), size);
578579
block.rtId = id;
579580
return changetype<usize>(block) + BLOCK_OVERHEAD;
580581
}
581582

582583
// @ts-ignore: decorator
583584
@global @unsafe
584585
export function __realloc(ref: usize, size: usize): usize {
585-
if (DEBUG) assert(ROOT); // must be initialized
586586
assert(ref != 0 && !(ref & AL_MASK)); // must exist and be aligned
587-
return changetype<usize>(reallocateBlock(ROOT, changetype<Block>(ref - BLOCK_OVERHEAD), size)) + BLOCK_OVERHEAD;
587+
return changetype<usize>(reallocateBlock(maybeInitialize(), changetype<Block>(ref - BLOCK_OVERHEAD), size)) + BLOCK_OVERHEAD;
588588
}
589589

590590
// @ts-ignore: decorator
591591
@global @unsafe
592592
export function __free(ref: usize): void {
593-
if (DEBUG) assert(ROOT); // must be initialized
594593
assert(ref != 0 && !(ref & AL_MASK)); // must exist and be aligned
595-
freeBlock(ROOT, changetype<Block>(ref - BLOCK_OVERHEAD));
594+
freeBlock(maybeInitialize(), changetype<Block>(ref - BLOCK_OVERHEAD));
596595
}

0 commit comments

Comments
 (0)