Make the transition to ArrayBuffer backed Arrays (#70)

* Traverse base classes when resolving overloads
* Implement preliminary TypedArray accessors
* Extract decorator flags from common flags to make space
* Add '**' overload
* Implement basic explicit inlining
* Support inlining of instance methods
* Reduce number of required locals when inlining
* Implement inlining of operator overloads
* Fix issues when inlining generic functions
This commit is contained in:
Daniel Wirtz 2018-04-11 23:35:19 +02:00 committed by GitHub
parent 0f49e054d2
commit 623597c23a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 13242 additions and 4945 deletions

View File

@ -198,32 +198,9 @@ export abstract class Node {
stmt.range = range;
stmt.name = expression; expression.parent = stmt;
stmt.arguments = args; if (args) setParent(args, stmt);
if (expression.kind == NodeKind.IDENTIFIER) {
switch ((<IdentifierExpression>expression).text) {
case "global": {
stmt.decoratorKind = DecoratorKind.GLOBAL;
break;
}
case "operator": {
stmt.decoratorKind = DecoratorKind.OPERATOR;
break;
}
case "unmanaged": {
stmt.decoratorKind = DecoratorKind.UNMANAGED;
break;
}
case "offset": {
stmt.decoratorKind = DecoratorKind.OFFSET;
break;
}
default: {
stmt.decoratorKind = DecoratorKind.CUSTOM;
break;
}
}
} else {
stmt.decoratorKind = DecoratorKind.CUSTOM;
}
stmt.decoratorKind = expression.kind == NodeKind.IDENTIFIER
? stringToDecoratorKind((<IdentifierExpression>expression).text)
: DecoratorKind.CUSTOM;
return stmt;
}
@ -1075,7 +1052,22 @@ export enum DecoratorKind {
GLOBAL,
OPERATOR,
UNMANAGED,
OFFSET
SEALED,
INLINE,
PRECOMPUTE
}
/** Returns the decorator kind represented by the specified string. */
export function stringToDecoratorKind(str: string): DecoratorKind {
switch (str) {
case "global": return DecoratorKind.GLOBAL;
case "operator": return DecoratorKind.OPERATOR;
case "unmanaged": return DecoratorKind.UNMANAGED;
case "sealed": return DecoratorKind.SEALED;
case "inline": return DecoratorKind.INLINE;
case "precompute": return DecoratorKind.PRECOMPUTE;
default: return DecoratorKind.CUSTOM;
}
}
/** Represents a decorator. */

View File

@ -43,7 +43,8 @@ import {
Global,
FunctionPrototype,
Class,
Field
Field,
OperatorKind
} from "./program";
/** Compiles a get of a built-in global. */
@ -146,7 +147,7 @@ export function compileCall(
compiler.currentType = Type.bool;
if (!type) return module.createUnreachable();
let classType = type.classReference;
return classType != null && classType.prototype.fnIndexedGet != null
return classType != null && classType.lookupOverload(OperatorKind.INDEXED_GET) != null
? module.createI32(1)
: module.createI32(0);
}
@ -1738,6 +1739,7 @@ export function compileCall(
DiagnosticCode.Expected_0_type_arguments_but_got_1,
reportNode.range, "1", typeArguments ? typeArguments.length.toString(10) : "0"
);
return module.createUnreachable();
}
let byteSize = (<Type[]>typeArguments)[0].byteSize;
let alignLog2: i32;

File diff suppressed because it is too large Load Diff

View File

@ -16,11 +16,13 @@ export enum DiagnosticCode {
Basic_type_0_cannot_be_nullable = 204,
Cannot_export_a_mutable_global = 205,
Compiling_constant_with_non_constant_initializer_as_mutable = 206,
Structs_cannot_extend_classes_and_vice_versa = 207,
Structs_cannot_implement_interfaces = 208,
Unmanaged_classes_cannot_extend_managed_classes_and_vice_versa = 207,
Unmanaged_classes_cannot_implement_interfaces = 208,
Invalid_regular_expression_flags = 209,
Implementation_0_must_match_the_signature_1 = 210,
Class_0_is_sealed_and_cannot_be_extended = 211,
Decorator_0_is_not_valid_here = 212,
Duplicate_decorator = 213,
Unterminated_string_literal = 1002,
Identifier_expected = 1003,
_0_expected = 1005,
@ -122,11 +124,13 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
case 204: return "Basic type '{0}' cannot be nullable.";
case 205: return "Cannot export a mutable global.";
case 206: return "Compiling constant with non-constant initializer as mutable.";
case 207: return "Structs cannot extend classes and vice-versa.";
case 208: return "Structs cannot implement interfaces.";
case 207: return "Unmanaged classes cannot extend managed classes and vice-versa.";
case 208: return "Unmanaged classes cannot implement interfaces.";
case 209: return "Invalid regular expression flags.";
case 210: return "Implementation '{0}' must match the signature '{1}'.";
case 211: return "Class '{0}' is sealed and cannot be extended.";
case 212: return "Decorator '{0}' is not valid here.";
case 213: return "Duplicate decorator.";
case 1002: return "Unterminated string literal.";
case 1003: return "Identifier expected.";
case 1005: return "'{0}' expected.";

View File

@ -8,11 +8,13 @@
"Basic type '{0}' cannot be nullable.": 204,
"Cannot export a mutable global.": 205,
"Compiling constant with non-constant initializer as mutable.": 206,
"Structs cannot extend classes and vice-versa.": 207,
"Structs cannot implement interfaces.": 208,
"Unmanaged classes cannot extend managed classes and vice-versa.": 207,
"Unmanaged classes cannot implement interfaces.": 208,
"Invalid regular expression flags.": 209,
"Implementation '{0}' must match the signature '{1}'.": 210,
"Class '{0}' is sealed and cannot be extended.": 211,
"Decorator '{0}' is not valid here.": 212,
"Duplicate decorator.": 213,
"Unterminated string literal.": 1002,
"Identifier expected.": 1003,

View File

@ -206,12 +206,8 @@ export function formatDiagnosticContext(range: Range, useColors: bool = false):
var len = text.length;
var start = range.start;
var end = range.end;
while (start > 0 && !isLineBreak(text.charCodeAt(start - 1))) {
start--;
}
while (end < len && !isLineBreak(text.charCodeAt(end))) {
end++;
}
while (start > 0 && !isLineBreak(text.charCodeAt(start - 1))) start--;
while (end < len && !isLineBreak(text.charCodeAt(end))) end++;
var sb: string[] = [
"\n ",
text.substring(start, end),
@ -225,9 +221,7 @@ export function formatDiagnosticContext(range: Range, useColors: bool = false):
if (range.start == range.end) {
sb.push("^");
} else {
while (start++ < range.end) {
sb.push("~");
}
while (start++ < range.end) sb.push("~");
}
if (useColors) sb.push(COLOR_RESET);
return sb.join("");

View File

@ -75,7 +75,8 @@ import {
ParameterNode,
ParameterKind,
ExportMember,
SwitchCase
SwitchCase,
DeclarationStatement
} from "../ast";
import {
@ -912,7 +913,6 @@ export class ASTBuilder {
}
visitFieldDeclaration(node: FieldDeclaration): void {
this.serializeBuiltinDecorators(node);
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
@ -961,7 +961,6 @@ export class ASTBuilder {
visitFunctionDeclaration(node: FunctionDeclaration): void {
var sb = this.sb;
this.serializeBuiltinDecorators(node);
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
@ -1098,7 +1097,6 @@ export class ASTBuilder {
}
visitInterfaceDeclaration(node: InterfaceDeclaration): void {
this.serializeBuiltinDecorators(node);
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
@ -1138,7 +1136,6 @@ export class ASTBuilder {
}
visitMethodDeclaration(node: MethodDeclaration): void {
this.serializeBuiltinDecorators(node);
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
@ -1155,7 +1152,6 @@ export class ASTBuilder {
}
visitNamespaceDeclaration(node: NamespaceDeclaration): void {
this.serializeBuiltinDecorators(node);
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
@ -1315,7 +1311,6 @@ export class ASTBuilder {
}
visitVariableStatement(node: VariableStatement): void {
this.serializeBuiltinDecorators(node);
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
@ -1398,19 +1393,6 @@ export class ASTBuilder {
}
}
serializeBuiltinDecorators(node: Node): void {
var sb = this.sb;
var indentLevel = this.indentLevel;
if (node.is(CommonFlags.GLOBAL)) {
sb.push("@global\n");
indent(sb, indentLevel);
}
if (node.is(CommonFlags.UNMANAGED)) {
sb.push("@unmanaged\n");
indent(sb, indentLevel);
}
}
serializeExternalModifiers(node: Node): void {
var sb = this.sb;
if (node.is(CommonFlags.EXPORT)) {

View File

@ -1099,6 +1099,45 @@ export class Relooper {
}
}
// export function hasSideEffects(expr: ExpressionRef): bool {
// switch (_BinaryenExpressionGetId(expr)) {
// case ExpressionId.GetLocal:
// case ExpressionId.GetGlobal:
// case ExpressionId.Const:
// case ExpressionId.Nop:
// case ExpressionId.Unreachable: {
// return false;
// }
// case ExpressionId.Block: {
// for (let i = 0, k = _BinaryenBlockGetNumChildren(expr); i < k; ++i) {
// if (hasSideEffects(_BinaryenBlockGetChild(expr, i))) return true;
// }
// return false;
// }
// case ExpressionId.If: {
// return hasSideEffects(_BinaryenIfGetCondition(expr))
// || hasSideEffects(_BinaryenIfGetIfTrue(expr))
// || hasSideEffects(_BinaryenIfGetIfFalse(expr));
// }
// case ExpressionId.Unary: {
// return hasSideEffects(_BinaryenUnaryGetValue(expr));
// }
// case ExpressionId.Binary: {
// return hasSideEffects(_BinaryenBinaryGetLeft(expr))
// || hasSideEffects(_BinaryenBinaryGetRight(expr));
// }
// case ExpressionId.Drop: {
// return hasSideEffects(_BinaryenDropGetValue(expr));
// }
// case ExpressionId.Select: {
// return hasSideEffects(_BinaryenSelectGetIfTrue(expr))
// || hasSideEffects(_BinaryenSelectGetIfFalse(expr))
// || hasSideEffects(_BinaryenSelectGetCondition(expr));
// }
// }
// return true;
// }
// helpers
// can't do stack allocation here: STACKTOP is a global in WASM but a hidden variable in asm.js

View File

@ -27,7 +27,6 @@ import {
} from "./util";
import {
Node,
NodeKind,
Source,
@ -162,22 +161,9 @@ export class Parser extends DiagnosticEmitter {
while (tn.skip(Token.AT)) {
if (startPos < 0) startPos = tn.tokenPos;
let decorator = this.parseDecorator(tn);
if (!decorator) break;
let name = decorator.name;
if (name.kind == NodeKind.IDENTIFIER) {
let text = (<IdentifierExpression>name).text;
if (text == "global") {
flags |= CommonFlags.GLOBAL;
continue;
}
if (text == "unmananged") {
flags |= CommonFlags.UNMANAGED;
continue;
}
if (text == "sealed") {
flags |= CommonFlags.SEALED;
continue;
}
if (!decorator) {
this.skipStatement(tn);
continue;
}
if (!decorators) decorators = [];
decorators.push(decorator);

File diff suppressed because it is too large Load Diff

View File

@ -166,7 +166,7 @@ export enum Token {
ENDOFFILE
}
export function tokenFomKeyword(text: string): Token {
export function tokenFromKeyword(text: string): Token {
switch (text) {
case "abstract": return Token.ABSTRACT;
case "as": return Token.AS;
@ -805,7 +805,7 @@ export class Tokenizer extends DiagnosticEmitter {
}
}
let keywordText = text.substring(posBefore, this.pos);
let keywordToken = tokenFomKeyword(keywordText);
let keywordToken = tokenFromKeyword(keywordText);
if (
keywordToken != Token.INVALID &&
!(preferIdentifier && tokenIsAlsoIdentifier(keywordToken))

View File

@ -80,7 +80,9 @@ export const enum TypeFlags {
/** Is a reference type. */
REFERENCE = 1 << 8,
/** Is a nullable type. */
NULLABLE = 1 << 9
NULLABLE = 1 << 9,
/** Is the special 'this' type. */
THIS = 1 << 10
}
/** Represents a resolved type. */
@ -102,6 +104,8 @@ export class Type {
nullableType: Type | null = null;
/** Respective non-nullable type, if nullable. */
nonNullableType: Type;
/** Respective special 'this' type. */
thisType: Type | null = null;
/** Constructs a new resolved type. */
constructor(kind: TypeKind, flags: TypeFlags, size: i32) {
@ -157,6 +161,18 @@ export class Type {
return this.nullableType;
}
/** Composes the respective 'this' type of this type. */
asThis(): Type {
var thisType = this.thisType;
if (thisType) return thisType;
thisType = new Type(this.kind, this.flags | TypeFlags.THIS, this.size);
thisType.classReference = this.classReference;
thisType.nullableType = this.nullableType;
thisType.nonNullableType = this.nonNullableType;
this.thisType = thisType;
return thisType;
}
/** Tests if a value of this type is assignable to a target of the specified type. */
isAssignableTo(target: Type, signednessIsImportant: bool = false): bool {
var currentClass: Class | null;

6
std/assembly.d.ts vendored
View File

@ -298,6 +298,8 @@ declare abstract class TypedArray<T> implements ArrayBufferView<T> {
readonly byteLength: i32;
/** The length (in elements). */
readonly length: i32;
/** Returns a new TypedArray of this type on the same ArrayBuffer from begin inclusive to end exclusive. */
subarray(begin?: i32, end?: i32): this;
}
/** An array of twos-complement 8-bit signed integers. */
@ -534,5 +536,5 @@ declare function unmanaged(target: Function): any;
/** Annotates a class as being sealed / non-derivable. */
declare function sealed(target: Function): any;
/** Annotates a class field with an explicit offset. */
declare function offset(offset: usize): any;
/** Annotates a method or function as always inlined. */
declare function inline(target: any, propertyKey: any, descriptor: any): any;

View File

@ -1,3 +1,12 @@
import {
MAX_BLENGTH,
HEADER_SIZE as HEADER_SIZE_AB,
allocUnsafe,
reallocUnsafe,
loadUnsafe,
storeUnsafe
} from "./internal/arraybuffer";
import {
defaultComparator,
insertionSort,
@ -6,147 +15,130 @@ import {
export class Array<T> {
__memory: usize;
__capacity: i32; // capped to [0, 0x7fffffff]
__length: i32; // capped to [0, __capacity]
/* @internal */ buffer_: ArrayBuffer;
/* @internal */ length_: i32;
private __grow(newCapacity: i32): void {
var oldMemory = this.__memory;
var oldCapacity = this.__capacity;
assert(newCapacity > oldCapacity);
var newMemory = allocate_memory(<usize>newCapacity * sizeof<T>());
if (oldMemory) {
move_memory(newMemory, oldMemory, <usize>oldCapacity * sizeof<T>());
free_memory(oldMemory);
}
this.__memory = newMemory;
this.__capacity = newCapacity;
constructor(length: i32 = 0) {
const MAX_LENGTH = MAX_BLENGTH >>> alignof<T>();
if (<u32>length > <u32>MAX_LENGTH) throw new RangeError("Invalid array length");
this.buffer_ = allocUnsafe(length << alignof<T>());
this.length_ = length;
}
constructor(capacity: i32 = 0) {
if (capacity < 0) throw new RangeError("Invalid array length");
this.__memory = capacity
? allocate_memory(<usize>capacity * sizeof<T>())
: 0;
this.__capacity = capacity;
this.__length = capacity;
get length(): i32 {
return this.length_;
}
set length(length: i32) {
var buffer = this.buffer_;
var capacity = buffer.byteLength >>> alignof<T>();
if (<u32>length > <u32>capacity) {
const MAX_LENGTH = MAX_BLENGTH >>> alignof<T>();
if (<u32>length > <u32>MAX_LENGTH) throw new RangeError("Invalid array length");
buffer = reallocUnsafe(buffer, length << alignof<T>());
this.buffer_ = buffer;
}
this.length_ = length;
}
every(callbackfn: (element: T, index: i32, array: Array<T>) => bool): bool {
var toIndex: i32 = this.__length;
var i: i32 = 0;
while (i < toIndex && i < this.__length) {
if (!callbackfn(load<T>(this.__memory + <usize>i * sizeof<T>()), i, this)) {
return false;
}
i += 1;
var buffer = this.buffer_;
for (let index = 0, toIndex = this.length_; index < toIndex && index < this.length_; ++index) {
if (!callbackfn(loadUnsafe<T>(buffer, index), index, this)) return false;
}
return true;
}
findIndex(predicate: (element: T, index: i32, array: Array<T>) => bool): i32 {
var toIndex: i32 = this.__length;
var i: i32 = 0;
while (i < toIndex && i < this.__length) {
if (predicate(load<T>(this.__memory + <usize>i * sizeof<T>()), i, this)) {
return i;
}
i += 1;
var buffer = this.buffer_;
for (let index = 0, toIndex = this.length_; index < toIndex && index < this.length_; ++index) {
if (predicate(loadUnsafe<T>(buffer, index), index, this)) return index;
}
return -1;
}
get length(): i32 {
return this.__length;
}
set length(length: i32) {
if (length < 0) throw new RangeError("Invalid array length");
if (length > this.__capacity) this.__grow(max(length, this.__capacity << 1));
this.__length = length;
}
@operator("[]")
private __get(index: i32): T {
if (<u32>index >= <u32>this.__capacity) throw new Error("Index out of bounds");
return load<T>(this.__memory + <usize>index * sizeof<T>());
var buffer = this.buffer_;
var capacity = buffer.byteLength >>> alignof<T>();
if (<u32>index >= <u32>capacity) throw new Error("Index out of bounds");
// return load<T>(changetype<usize>(buffer) + (<usize>index << alignof<T>()), HEADER_SIZE_AB);
return loadUnsafe<T>(buffer, index);
}
@operator("[]=")
private __set(index: i32, value: T): void {
if (index < 0) throw new Error("Index out of bounds");
var capacity = this.__capacity;
if (index >= capacity) this.__grow(max(index + 1, capacity << 1));
store<T>(this.__memory + <usize>index * sizeof<T>(), value);
var buffer = this.buffer_;
var capacity = buffer.byteLength >>> alignof<T>();
if (<u32>index >= <u32>capacity) {
const MAX_LENGTH = MAX_BLENGTH >>> alignof<T>();
if (<u32>index >= <u32>MAX_LENGTH) throw new Error("Invalid array length");
buffer = reallocUnsafe(buffer, (index + 1) << alignof<T>());
this.buffer_ = buffer;
this.length_ = index + 1;
}
// store<T>(changetype<usize>(buffer) + (<usize>index << alignof<T>()), value, HEADER_SIZE_AB);
storeUnsafe<T>(buffer, index, value);
}
includes(searchElement: T, fromIndex: i32 = 0): bool {
var length = this.__length;
var length = this.length_;
if (length == 0 || fromIndex >= length) return false;
if (fromIndex < 0) {
fromIndex = length + fromIndex;
if (fromIndex < 0) {
fromIndex = 0;
}
}
if (fromIndex < 0) fromIndex = max(length + fromIndex, 0);
var buffer = this.buffer_;
while (fromIndex < length) {
if (load<T>(this.__memory + <usize>fromIndex * sizeof<T>()) == searchElement) return true;
if (loadUnsafe<T>(buffer, fromIndex) == searchElement) return true;
++fromIndex;
}
return false;
}
indexOf(searchElement: T, fromIndex: i32 = 0): i32 {
var length = this.__length;
if (length == 0 || fromIndex >= length) {
return -1;
}
if (fromIndex < 0) {
fromIndex = length + fromIndex;
if (fromIndex < 0) {
fromIndex = 0;
}
}
var memory = this.__memory;
var length = this.length_;
if (length == 0 || fromIndex >= length) return -1;
if (fromIndex < 0) fromIndex = max(length + fromIndex, 0);
var buffer = this.buffer_;
while (fromIndex < length) {
if (load<T>(memory + <usize>fromIndex * sizeof<T>()) == searchElement) return fromIndex;
if (loadUnsafe<T>(buffer, fromIndex) == searchElement) return fromIndex;
++fromIndex;
}
return -1;
}
lastIndexOf(searchElement: T, fromIndex: i32 = this.__length): i32 {
var length = this.__length;
lastIndexOf(searchElement: T, fromIndex: i32 = this.length_): i32 {
var length = this.length_;
if (length == 0) return -1;
if (fromIndex < 0) {
fromIndex = length + fromIndex;
} else if (fromIndex >= length) {
fromIndex = length - 1;
}
var memory = this.__memory;
while (fromIndex >= 0) {
if (load<T>(memory + <usize>fromIndex * sizeof<T>()) == searchElement) return fromIndex;
if (fromIndex < 0) fromIndex = length + fromIndex; // no need to clamp
else if (fromIndex >= length) fromIndex = length - 1;
var buffer = this.buffer_;
while (fromIndex >= 0) { // ^
if (loadUnsafe<T>(buffer, fromIndex) == searchElement) return fromIndex;
--fromIndex;
}
return -1;
}
push(element: T): i32 {
var capacity = this.__capacity;
var length = this.__length;
if (length == capacity) {
this.__grow(capacity ? capacity << 1 : 1);
var length = this.length_;
var buffer = this.buffer_;
var capacity = buffer.byteLength >>> alignof<T>();
var newLength = length + 1; // safe only if length is checked
if (<u32>length >= <u32>capacity) {
const MAX_LENGTH = MAX_BLENGTH >>> alignof<T>();
if (<u32>length >= <u32>MAX_LENGTH) throw new Error("Invalid array length");
buffer = reallocUnsafe(buffer, newLength << alignof<T>());
this.buffer_ = buffer;
}
store<T>(this.__memory + <usize>length * sizeof<T>(), element);
this.__length = ++length;
return length;
this.length_ = newLength;
storeUnsafe<T>(buffer, length, element);
return newLength;
}
pop(): T {
var length = this.__length;
var length = this.length_;
if (length < 1) throw new RangeError("Array is empty");
var element = load<T>(this.__memory + <usize>--length * sizeof<T>());
this.__length = length;
var element = loadUnsafe<T>(this.buffer_, --length);
this.length_ = length;
return element;
}
@ -154,158 +146,119 @@ export class Array<T> {
callbackfn: (previousValue: U, currentValue: T, currentIndex: i32, array: Array<T>) => U,
initialValue: U
): U {
var accumulator: U = initialValue;
var toIndex: i32 = this.__length;
var i: i32 = 0;
while (i < toIndex && i < /* might change */ this.__length) {
accumulator = callbackfn(accumulator, load<T>(this.__memory + <usize>i * sizeof<T>()), i, this);
i += 1;
var accum = initialValue;
var buffer = this.buffer_;
for (let index = 0, toIndex = this.length_; index < toIndex && index < this.length_; ++index) {
accum = callbackfn(accum, loadUnsafe<T>(buffer, index), index, this);
}
return accumulator;
return accum;
}
shift(): T {
var length = this.__length;
var length = this.length_;
if (length < 1) throw new RangeError("Array is empty");
var memory = this.__memory;
var capacity = this.__capacity;
var element = load<T>(memory);
var buffer = this.buffer_;
var element = loadUnsafe<T>(buffer, 0);
var lastIndex = length - 1;
move_memory(
memory,
memory + sizeof<T>(),
<usize>(capacity - 1) * sizeof<T>()
changetype<usize>(buffer) + HEADER_SIZE_AB,
changetype<usize>(buffer) + HEADER_SIZE_AB + sizeof<T>(),
<usize>lastIndex << alignof<T>()
);
set_memory(
memory + <usize>(capacity - 1) * sizeof<T>(),
0,
sizeof<T>()
);
this.__length = length - 1;
storeUnsafe<T>(buffer, lastIndex, isReference<T>() ? null : <T>0);
this.length_ = lastIndex;
return element;
}
some(callbackfn: (element: T, index: i32, array: Array<T>) => bool): bool {
var toIndex: i32 = this.__length;
var i: i32 = 0;
while (i < toIndex && i < /* might change */ this.__length) {
if (callbackfn(load<T>(this.__memory + <usize>i * sizeof<T>()), i, this)) return true;
i += 1;
var buffer = this.buffer_;
for (let index = 0, toIndex = this.length_; index < toIndex && index < this.length_; ++index) {
if (callbackfn(loadUnsafe<T>(buffer, index), index, this)) return true;
}
return false;
}
unshift(element: T): i32 {
var memory = this.__memory;
var capacity = this.__capacity;
var length = this.__length;
if (this.__length == capacity) {
// inlined __grow (avoids moving twice)
let newCapacity: i32 = capacity ? capacity << 1 : 1;
assert(newCapacity > capacity);
let newMemory = allocate_memory(<usize>newCapacity * sizeof<T>());
if (memory) {
move_memory(
newMemory + sizeof<T>(),
memory,
<usize>capacity * sizeof<T>()
);
free_memory(memory);
}
this.__memory = newMemory;
this.__capacity = newCapacity;
memory = newMemory;
} else {
move_memory(
memory + sizeof<T>(),
memory,
<usize>capacity * sizeof<T>()
);
var buffer = this.buffer_;
var capacity = buffer.byteLength >>> alignof<T>();
var length = this.length_;
var newLength = length + 1; // safe only if length is checked
if (<u32>length >= <u32>capacity) {
const MAX_LENGTH = MAX_BLENGTH >>> alignof<T>();
if (<u32>length >= <u32>MAX_LENGTH) throw new Error("Invalid array length");
buffer = reallocUnsafe(buffer, newLength << alignof<T>());
capacity = buffer.byteLength >>> alignof<T>();
this.buffer_ = buffer;
}
store<T>(memory, element);
this.__length = ++length;
return length;
move_memory(
changetype<usize>(buffer) + HEADER_SIZE_AB + sizeof<T>(),
changetype<usize>(buffer) + HEADER_SIZE_AB,
<usize>(capacity - 1) << alignof<T>()
);
storeUnsafe<T>(buffer, 0, element);
this.length_ = newLength;
return newLength;
}
slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Array<T> {
var length = this.__length;
if (begin < 0) {
begin = length + begin;
if (begin < 0) {
begin = 0;
}
} else if (begin > length) {
begin = length;
}
if (end < 0) {
end = length + end;
} else if (end > length) {
end = length;
}
if (end < begin) {
end = begin;
}
var capacity = end - begin;
assert(capacity >= 0);
var sliced = new Array<T>(capacity);
if (capacity) {
var length = this.length_;
if (begin < 0) begin = max(length + begin, 0);
else if (begin > length) begin = length;
if (end < 0) end = length + end; // no need to clamp
else if (end > length) end = length;
if (end < begin) end = begin; // ^
var newLength = end - begin;
assert(newLength >= 0);
var sliced = new Array<T>(newLength);
if (newLength) {
move_memory(
sliced.__memory,
this.__memory + <usize>begin * sizeof<T>(),
<usize>capacity * sizeof<T>()
changetype<usize>(sliced.buffer_) + HEADER_SIZE_AB,
changetype<usize>(this.buffer_) + HEADER_SIZE_AB + (<usize>begin << alignof<T>()),
<usize>newLength << alignof<T>()
);
}
return sliced;
}
splice(start: i32, deleteCount: i32 = i32.MAX_VALUE): void {
if (deleteCount < 1) {
return;
}
var length = this.__length;
if (start < 0) {
start = length + start;
if (start < 0) {
start = 0;
} else if (start >= length) {
return;
}
} else if (start >= length) {
return;
}
if (deleteCount < 1) return;
var length = this.length_;
if (start < 0) start = max(length + start, 0);
if (start >= length) return;
deleteCount = min(deleteCount, length - start);
var memory = this.__memory;
var buffer = this.buffer_;
move_memory(
memory + <usize>start * sizeof<T>(),
memory + <usize>(start + deleteCount) * sizeof<T>(),
<usize>deleteCount * sizeof<T>()
changetype<usize>(buffer) + HEADER_SIZE_AB + (<usize>start << alignof<T>()),
changetype<usize>(buffer) + HEADER_SIZE_AB + (<usize>(start + deleteCount) << alignof<T>()),
<usize>deleteCount << alignof<T>()
);
this.__length = length - deleteCount;
this.length_ = length - deleteCount;
}
reverse(): Array<T> {
var memory = this.__memory;
for (let front: usize = 0, back: usize = <usize>this.__length - 1; front < back; ++front, --back) {
let temp = load<T>(memory + front * sizeof<T>());
store<T>(memory + front * sizeof<T>(), load<T>(memory + back * sizeof<T>()));
store<T>(memory + back * sizeof<T>(), temp);
var buffer = this.buffer_;
for (let front = 0, back = this.length_ - 1; front < back; ++front, --back) {
let temp = loadUnsafe<T>(buffer, front);
storeUnsafe<T>(buffer, front, loadUnsafe<T>(buffer, back));
storeUnsafe<T>(buffer, back, temp);
}
return this;
}
sort(comparator: (a: T, b: T) => i32 = defaultComparator<T>()): Array<T> {
var len = this.length;
if (len <= 1) return this;
if (len == 2) {
let memory = this.__memory;
let a = load<T>(memory, sizeof<T>()); // var a = <T>arr[1];
let b = load<T>(memory, 0); // var b = <T>arr[0];
var length = this.length_;
if (length <= 1) return this;
var buffer = this.buffer_;
if (length == 2) {
let a = loadUnsafe<T>(buffer, 1); // a = arr[1]
let b = loadUnsafe<T>(buffer, 0); // b = arr[0]
if (comparator(a, b) < 0) {
store<T>(memory, b, sizeof<T>()); // arr[1] = b;
store<T>(memory, a, 0); // arr[0] = a;
storeUnsafe<T>(buffer, 1, b); // arr[1] = b;
storeUnsafe<T>(buffer, 0, a); // arr[0] = a;
}
return this;
}
return len <= 256
return length < 256
? insertionSort<T>(this, comparator)
: weakHeapSort<T>(this, comparator);
}

View File

@ -28,3 +28,12 @@ export class ArrayBuffer {
return buffer;
}
}
export declare interface FastArray<T> {}
export declare interface ArrayBufferView<T> {
readonly buffer: ArrayBuffer;
readonly byteOffset: i32;
readonly byteLength: i32;
readonly length: i32;
}

View File

@ -1,4 +1,11 @@
import { Array } from "../array";
import {
loadUnsafe,
storeUnsafe
} from "./arraybuffer";
import {
Array
} from "../array";
/** Obtains the default comparator for the specified type. */
export function defaultComparator<T>(): (a: T, b: T) => i32 {
@ -7,26 +14,23 @@ export function defaultComparator<T>(): (a: T, b: T) => i32 {
/** Sorts an Array with the 'Insertion Sort' algorithm. */
export function insertionSort<T>(arr: Array<T>, comparator: (a: T, b: T) => i32): Array<T> {
const shiftT = alignof<T>();
var memory = arr.__memory;
for (let i: i32 = 0, len: i32 = arr.length; i < len; i++) {
let a = load<T>(memory + (i << shiftT)); // a = arr[i]
var buffer = arr.buffer_;
for (let i: i32 = 0, length: i32 = arr.length; i < length; i++) {
let a = loadUnsafe<T>(buffer, i); // a = arr[i]
let j = i - 1;
while (j >= 0) {
let b = load<T>(memory + (j << shiftT)); // b = arr[j]
let b = loadUnsafe<T>(buffer, j); // b = arr[j]
if (comparator(a, b) < 0) {
store<T>(memory + ((j-- + 1) << shiftT), b); // arr[j + 1] = b
storeUnsafe<T>(buffer, j-- + 1, b); // arr[j + 1] = b
} else break;
}
store<T>(memory + ((j + 1) << shiftT), a); // arr[j + 1] = a
storeUnsafe<T>(buffer, j + 1, a); // arr[j + 1] = a
}
return arr;
}
/** Sorts an Array with the 'Weak Heap Sort' algorithm. */
export function weakHeapSort<T>(arr: Array<T>, comparator: (a: T, b: T) => i32): Array<T> {
const shiftT = alignof<T>();
const shift32 = alignof<i32>();
var length = arr.length;
@ -36,43 +40,43 @@ export function weakHeapSort<T>(arr: Array<T>, comparator: (a: T, b: T) => i32):
// see: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.21.1863&rep=rep1&type=pdf
var memory = arr.__memory;
var buffer = arr.buffer_;
for (let i = length - 1; i > 0; i--) {
let j = i;
while ((j & 1) == (load<i32>(bitset + (j >> 6 << shift32)) >> (j >> 1 & 31) & 1)) j >>= 1;
let p = j >> 1;
let a = load<T>(memory + (p << shiftT)); // a = arr[p]
let b = load<T>(memory + (i << shiftT)); // b = arr[i]
let a = loadUnsafe<T>(buffer, p); // a = arr[p]
let b = loadUnsafe<T>(buffer, i); // b = arr[i]
if (comparator(a, b) < 0) {
store<i32>(
bitset + (i >> 5 << shift32),
load<i32>(bitset + (i >> 5 << shift32)) ^ (1 << (i & 31))
);
store<T>(memory + (i << shiftT), a); // arr[i] = a
store<T>(memory + (p << shiftT), b); // arr[p] = b
storeUnsafe<T>(buffer, i, a); // arr[i] = a
storeUnsafe<T>(buffer, p, b); // arr[p] = b
}
}
for (let i = length - 1; i >= 2; i--) {
let a = load<T>(memory, 0); // a = arr[0]
store<T>(memory, load<T>(memory + (i << shiftT)), 0); // arr[0] = arr[1]
store<T>(memory + (i << shiftT), a); // arr[1] = a
let a = loadUnsafe<T>(buffer, 0); // a = arr[0]
storeUnsafe<T>(buffer, 0, loadUnsafe<T>(buffer, i)); // arr[0] = arr[i]
storeUnsafe<T>(buffer, i, a); // arr[i] = a
let x = 1, y: i32;
while ((y = (x << 1) + ((load<i32>(bitset + (x >> 5 << shift32)) >> (x & 31)) & 1)) < i) x = y;
while (x > 0) {
a = load<T>(memory, 0); // a = arr[0]
let b = load<T>(memory + (x << shiftT)); // b = arr[x]
a = loadUnsafe<T>(buffer, 0); // a = arr[0]
let b = loadUnsafe<T>(buffer, x); // b = arr[x]
if (comparator(a, b) < 0) {
store<i32>(
bitset + (x >> 5 << shift32),
load<i32>(bitset + (x >> 5 << shift32)) ^ (1 << (x & 31))
);
store<T>(memory + (x << shiftT), a); // arr[x] = a
store<T>(memory, b, 0); // arr[0] = b
storeUnsafe<T>(buffer, x, a); // arr[x] = a
storeUnsafe<T>(buffer, 0, b); // arr[0] = b
}
x >>= 1;
}
@ -80,8 +84,8 @@ export function weakHeapSort<T>(arr: Array<T>, comparator: (a: T, b: T) => i32):
free_memory(bitset);
var t = load<T>(memory, sizeof<T>()); // t = arr[1]
store<T>(memory, load<T>(memory, 0), sizeof<T>()); // arr[1] = arr[0]
store<T>(memory, t, 0); // arr[0] = t
var t = loadUnsafe<T>(buffer, 1); // t = arr[1]
storeUnsafe<T>(buffer, 1, loadUnsafe<T>(buffer, 0)); // arr[1] = arr[0]
storeUnsafe<T>(buffer, 0, t); // arr[0] = t
return arr;
}

View File

@ -30,11 +30,10 @@ export function reallocUnsafe(buffer: ArrayBuffer, newByteLength: i32): ArrayBuf
var oldByteLength = buffer.byteLength;
if (newByteLength > oldByteLength) {
assert(newByteLength <= MAX_BLENGTH);
let oldSize = computeSize(oldByteLength);
if (<i32>(oldSize - HEADER_SIZE) <= newByteLength) { // fast path: zero out additional space
if (newByteLength <= <i32>(computeSize(oldByteLength) - HEADER_SIZE)) { // fast path: zero out additional space
store<i32>(changetype<usize>(buffer), newByteLength, offsetof<ArrayBuffer>("byteLength"));
set_memory(
changetype<usize>(buffer) + HEADER_SIZE + oldByteLength,
changetype<usize>(buffer) + HEADER_SIZE + <usize>oldByteLength,
0,
<usize>(newByteLength - oldByteLength)
);
@ -43,7 +42,12 @@ export function reallocUnsafe(buffer: ArrayBuffer, newByteLength: i32): ArrayBuf
move_memory(
changetype<usize>(newBuffer) + HEADER_SIZE,
changetype<usize>(buffer) + HEADER_SIZE,
<usize>newByteLength
<usize>oldByteLength
);
set_memory(
changetype<usize>(newBuffer) + HEADER_SIZE + <usize>oldByteLength,
0,
<usize>(newByteLength - oldByteLength)
);
return newBuffer;
}
@ -55,10 +59,22 @@ export function reallocUnsafe(buffer: ArrayBuffer, newByteLength: i32): ArrayBuf
return buffer;
}
/** Common typed array interface. Not a global object. */
// export declare interface ArrayBufferView<T> {
// readonly buffer: ArrayBuffer;
// readonly byteOffset: i32;
// readonly byteLength: i32;
// readonly length: i32;
// }
@inline
export function loadUnsafe<T>(buffer: ArrayBuffer, index: i32): T {
return load<T>(changetype<usize>(buffer) + (<usize>index << alignof<T>()), HEADER_SIZE);
}
@inline
export function storeUnsafe<T>(buffer: ArrayBuffer, index: i32, value: T): void {
store<T>(changetype<usize>(buffer) + (<usize>index << alignof<T>()), value, HEADER_SIZE);
}
@inline
export function loadUnsafeWithOffset<T>(buffer: ArrayBuffer, index: i32, byteOffset: i32): T {
return load<T>(changetype<usize>(buffer) + <usize>byteOffset + (<usize>index << alignof<T>()), HEADER_SIZE);
}
@inline
export function storeUnsafeWithOffset<T>(buffer: ArrayBuffer, index: i32, value: T, byteOffset: i32): void {
store<T>(changetype<usize>(buffer) + <usize>byteOffset + (<usize>index << alignof<T>()), value, HEADER_SIZE);
}

View File

@ -1,12 +1,17 @@
import {
HEADER_SIZE,
HEADER_SIZE as HEADER_SIZE_AB,
MAX_BLENGTH,
allocUnsafe
// ArrayBufferView
allocUnsafe,
loadUnsafeWithOffset,
storeUnsafeWithOffset
} from "./arraybuffer";
import {
ArrayBufferView
} from "../arraybuffer";
/** Typed array base class. Not a global object. */
export abstract class TypedArray<T> /* implements ArrayBufferView<T> */ {
export abstract class TypedArray<T> implements ArrayBufferView<T> {
readonly buffer: ArrayBuffer;
readonly byteOffset: i32;
@ -17,21 +22,45 @@ export abstract class TypedArray<T> /* implements ArrayBufferView<T> */ {
if (<u32>length > MAX_LENGTH) throw new RangeError("Invalid typed array length");
var byteLength = length << alignof<T>();
var buffer = allocUnsafe(byteLength);
set_memory(changetype<usize>(buffer) + HEADER_SIZE, 0, <usize>byteLength);
set_memory(changetype<usize>(buffer) + HEADER_SIZE_AB, 0, <usize>byteLength);
this.buffer = buffer;
this.byteOffset = 0;
this.byteLength = byteLength;
}
get length(): i32 {
return this.byteLength >> alignof<T>();
return (this.byteLength - this.byteOffset) >> alignof<T>();
}
// @operator("[]") - maybe injected through ArrayBufferView?
@operator("[]")
private __get(index: i32): T {
var byteOffset = this.byteOffset;
var elementLength = (this.byteLength - byteOffset) >>> alignof<T>();
if (<u32>index >= <u32>elementLength) throw new Error("Index out of bounds");
return loadUnsafeWithOffset<T>(this.buffer, index, byteOffset);
}
// @operator("[]=") - maybe injected through ArrayBufferView?
@operator("[]=")
private __set(index: i32, value: T): void {
var byteOffset = this.byteOffset;
var elementLength = (this.byteLength - byteOffset) >>> alignof<T>();
if (<u32>index >= <u32>elementLength) throw new Error("Index out of bounds");
storeUnsafeWithOffset<T>(this.buffer, index, value, byteOffset);
}
// copyWithin(target: i32, start: i32, end: i32 = 0x7fffffff): TypedArray<T>
// copyWithin(target: i32, start: i32, end: i32 = this.length): this
// subarray(begin: i32 = 0, end: i32 = 0x7fffffff): TypedArray<T>
@inline
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): TypedArray<T> {
var length = this.length;
if (begin < 0) begin = max(length + begin, 0);
else begin = min(begin, length);
if (end < 0) end = max(length + end, begin);
else end = max(min(end, length), begin);
var slice = allocate_memory(offsetof<this>());
store<usize>(slice, this.buffer, offsetof<this>("buffer"));
store<i32>(slice, begin << alignof<T>(), offsetof<this>("byteOffset"));
store<i32>(slice, end << alignof<T>(), offsetof<this>("byteLength"));
return changetype<this>(slice);
}
}

View File

@ -4,40 +4,80 @@ import {
export class Int8Array extends TypedArray<i8> {
static readonly BYTES_PER_ELEMENT: usize = sizeof<i8>();
subarray(begin: i32 = 0, end: i32 = this.length): Int8Array {
return changetype<Int8Array>(super.subarray(begin, end));
}
}
export class Uint8Array extends TypedArray<u8> {
static readonly BYTES_PER_ELEMENT: usize = sizeof<u8>();
subarray(begin: i32 = 0, end: i32 = this.length): Uint8Array {
return changetype<Uint8Array>(super.subarray(begin, end));
}
}
export class Int16Array extends TypedArray<i16> {
static readonly BYTES_PER_ELEMENT: usize = sizeof<i16>();
subarray(begin: i32 = 0, end: i32 = this.length): Int16Array {
return changetype<Int16Array>(super.subarray(begin, end));
}
}
export class Uint16Array extends TypedArray<u16> {
static readonly BYTES_PER_ELEMENT: usize = sizeof<u16>();
subarray(begin: i32 = 0, end: i32 = this.length): Uint16Array {
return changetype<Uint16Array>(super.subarray(begin, end));
}
}
export class Int32Array extends TypedArray<i32> {
static readonly BYTES_PER_ELEMENT: usize = sizeof<i32>();
subarray(begin: i32 = 0, end: i32 = this.length): Int32Array {
return changetype<Int32Array>(super.subarray(begin, end));
}
}
export class Uint32Array extends TypedArray<u32> {
static readonly BYTES_PER_ELEMENT: usize = sizeof<u32>();
subarray(begin: i32 = 0, end: i32 = this.length): Uint32Array {
return changetype<Uint32Array>(super.subarray(begin, end));
}
}
export class Int64Array extends TypedArray<i64> {
static readonly BYTES_PER_ELEMENT: usize = sizeof<i64>();
subarray(begin: i32 = 0, end: i32 = this.length): Int64Array {
return changetype<Int64Array>(super.subarray(begin, end));
}
}
export class Uint64Array extends TypedArray<u64> {
static readonly BYTES_PER_ELEMENT: usize = sizeof<u64>();
subarray(begin: i32 = 0, end: i32 = this.length): Uint64Array {
return changetype<Uint64Array>(super.subarray(begin, end));
}
}
export class Float32Array extends TypedArray<f32> {
static readonly BYTES_PER_ELEMENT: usize = sizeof<f32>();
subarray(begin: i32 = 0, end: i32 = this.length): Float32Array {
return changetype<Float32Array>(super.subarray(begin, end));
}
}
export class Float64Array extends TypedArray<f64> {
static readonly BYTES_PER_ELEMENT: usize = sizeof<f64>();
subarray(begin: i32 = 0, end: i32 = this.length): Float64Array {
return changetype<Float64Array>(super.subarray(begin, end));
}
}

View File

@ -20,7 +20,7 @@ function test(file) {
return String.fromCharCode.apply(String, str);
}
require("./runner")(exports, 50, 20000);
require("./runner")(exports, 20, 20000);
console.log("mem final: " + exports.memory.buffer.byteLength);
console.log();

View File

@ -33,7 +33,15 @@
(return
(i32.const 1)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 37)
(i32.const 4)
)
(unreachable)
)
)
)
(func $start (; 4 ;) (type $v)

View File

@ -57,7 +57,15 @@
(return
(i32.const 1)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 37)
(i32.const 4)
)
(unreachable)
)
)
)
(func $start (; 5 ;) (type $v)

View File

@ -2,16 +2,199 @@
(type $i (func (result i32)))
(type $iiiiv (func (param i32 i32 i32 i32)))
(type $v (func))
(type $ii (func (param i32) (result i32)))
(import "env" "abort" (func $abort (param i32 i32 i32 i32)))
(global $argumentCount (mut i32) (i32.const 0))
(table 1 1 anyfunc)
(elem (i32.const 0) $inlining/test_funcs~anonymous|0)
(memory $0 1)
(data (i32.const 4) "\0b\00\00\00i\00n\00l\00i\00n\00i\00n\00g\00.\00t\00s")
(export "test" (func $inlining/test))
(export "memory" (memory $0))
(export "table" (table $0))
(start $start)
(func $inlining/test (; 1 ;) (type $i) (result i32)
(i32.const 3)
)
(func $start (; 2 ;) (type $v)
(func $inlining/test_funcs~anonymous|0 (; 2 ;) (type $ii) (param $0 i32) (result i32)
(get_local $0)
)
(func $inlining/test_funcs (; 3 ;) (type $v)
(local $0 i32)
(if
(i32.ne
(block $inlining/func_ii|inlined.0 (result i32)
(drop
(br_if $inlining/func_ii|inlined.0
(i32.const 1)
(i32.eq
(tee_local $0
(i32.const 42)
)
(i32.const 42)
)
)
)
(select
(i32.const 2)
(i32.const 3)
(i32.lt_s
(get_local $0)
(i32.const 42)
)
)
)
(i32.const 1)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 60)
(i32.const 2)
)
(unreachable)
)
)
(if
(i32.ne
(block $inlining/func_ii|inlined.1 (result i32)
(drop
(br_if $inlining/func_ii|inlined.1
(i32.const 1)
(i32.eq
(tee_local $0
(i32.const 41)
)
(i32.const 42)
)
)
)
(select
(i32.const 2)
(i32.const 3)
(i32.lt_s
(get_local $0)
(i32.const 42)
)
)
)
(i32.const 2)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 61)
(i32.const 2)
)
(unreachable)
)
)
(if
(i32.ne
(block $inlining/func_ii|inlined.2 (result i32)
(drop
(br_if $inlining/func_ii|inlined.2
(i32.const 1)
(i32.eq
(tee_local $0
(i32.const 43)
)
(i32.const 42)
)
)
)
(select
(i32.const 2)
(i32.const 3)
(i32.lt_s
(get_local $0)
(i32.const 42)
)
)
)
(i32.const 3)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 62)
(i32.const 2)
)
(unreachable)
)
)
(if
(i32.ne
(tee_local $0
(i32.add
(tee_local $0
(i32.const 2)
)
(i32.const 1)
)
)
(i32.const 3)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 65)
(i32.const 2)
)
(unreachable)
)
)
(if
(i32.ne
(tee_local $0
(i32.add
(tee_local $0
(i32.const 3)
)
(i32.const 1)
)
)
(i32.const 4)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 66)
(i32.const 2)
)
(unreachable)
)
)
(if
(block (result i32)
(set_global $argumentCount
(i32.const 1)
)
(i32.ne
(call_indirect (type $ii)
(i32.const 2)
(i32.const 0)
)
(i32.const 2)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 68)
(i32.const 2)
)
(unreachable)
)
)
)
(func $start (; 4 ;) (type $v)
(if
(i32.ne
(call $inlining/test)
@ -21,11 +204,12 @@
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 8)
(i32.const 10)
(i32.const 0)
)
(unreachable)
)
)
(call $inlining/test_funcs)
)
)

View File

@ -1,3 +1,5 @@
// Constant inlining
const constantGlobal = 1;
export function test(): i32 {
@ -6,3 +8,67 @@ export function test(): i32 {
}
assert(test() == 3);
// Function inlining
@inline
function func_ii(a: i32): i32 {
if (a == 42) return 1;
return a < 42 ? 2 : 3;
}
@inline
function func_ii_opt(a: i32 = 0): i32 {
return a;
}
@inline
function func_ii_loc(a: i32): i32 {
var b = a;
var e: i32;
if (true) {
let c = b;
let d = c;
e = d + 1;
}
return e;
}
@inline
function func_iv(a: i32): void {
}
@inline
function func_fe(): (a: i32) => i32 {
return (a: i32): i32 => a;
}
class Foo {
@inline
static method_static(a: i32, b: i32 = 2): i32 {
return a + b;
}
@inline
method_this(a: i32, b: i32 = 3): Foo {
return this;
}
}
function test_funcs(): void {
var a: f32 = -1, b: f64 = -2;
assert(func_ii(42) == 1);
assert(func_ii(41) == 2);
assert(func_ii(43) == 3);
assert(func_ii_opt() == 0);
assert(func_ii_opt(1) == 1);
assert(func_ii_loc(2) == 3);
assert(func_ii_loc(3) == 4);
func_iv(0);
assert(func_fe()(2) == 2);
assert(Foo.method_static(42) == 44);
var foo = changetype<Foo>(123);
assert(changetype<usize>(foo.method_this(43)) == 123);
}
test_funcs();

View File

@ -2,13 +2,18 @@
(type $i (func (result i32)))
(type $iiiiv (func (param i32 i32 i32 i32)))
(type $v (func))
(type $ii (func (param i32) (result i32)))
(import "env" "abort" (func $abort (param i32 i32 i32 i32)))
(global $inlining/constantGlobal i32 (i32.const 1))
(global $argumentCount (mut i32) (i32.const 0))
(global $HEAP_BASE i32 (i32.const 32))
(table 1 1 anyfunc)
(elem (i32.const 0) $inlining/test_funcs~anonymous|0)
(memory $0 1)
(data (i32.const 4) "\0b\00\00\00i\00n\00l\00i\00n\00i\00n\00g\00.\00t\00s\00")
(export "test" (func $inlining/test))
(export "memory" (memory $0))
(export "table" (table $0))
(start $start)
(func $inlining/test (; 1 ;) (type $i) (result i32)
(nop)
@ -19,7 +24,383 @@
)
)
)
(func $start (; 2 ;) (type $v)
(func $inlining/test_funcs~anonymous|0 (; 2 ;) (type $ii) (param $0 i32) (result i32)
(get_local $0)
)
(func $inlining/test_funcs (; 3 ;) (type $v)
(local $0 f32)
(local $1 f64)
(local $2 i32)
(local $3 i32)
(local $4 i32)
(local $5 i32)
(local $6 i32)
(local $7 i32)
(block
(set_local $0
(f32.const -1)
)
(set_local $1
(f64.const -2)
)
)
(if
(i32.eqz
(i32.eq
(block $inlining/func_ii|inlined.0 (result i32)
(set_local $2
(i32.const 42)
)
(if
(i32.eq
(get_local $2)
(i32.const 42)
)
(br $inlining/func_ii|inlined.0
(i32.const 1)
)
)
(br $inlining/func_ii|inlined.0
(if (result i32)
(i32.lt_s
(get_local $2)
(i32.const 42)
)
(i32.const 2)
(i32.const 3)
)
)
)
(i32.const 1)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 60)
(i32.const 2)
)
(unreachable)
)
)
(if
(i32.eqz
(i32.eq
(block $inlining/func_ii|inlined.1 (result i32)
(set_local $2
(i32.const 41)
)
(if
(i32.eq
(get_local $2)
(i32.const 42)
)
(br $inlining/func_ii|inlined.1
(i32.const 1)
)
)
(br $inlining/func_ii|inlined.1
(if (result i32)
(i32.lt_s
(get_local $2)
(i32.const 42)
)
(i32.const 2)
(i32.const 3)
)
)
)
(i32.const 2)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 61)
(i32.const 2)
)
(unreachable)
)
)
(if
(i32.eqz
(i32.eq
(block $inlining/func_ii|inlined.2 (result i32)
(set_local $2
(i32.const 43)
)
(if
(i32.eq
(get_local $2)
(i32.const 42)
)
(br $inlining/func_ii|inlined.2
(i32.const 1)
)
)
(br $inlining/func_ii|inlined.2
(if (result i32)
(i32.lt_s
(get_local $2)
(i32.const 42)
)
(i32.const 2)
(i32.const 3)
)
)
)
(i32.const 3)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 62)
(i32.const 2)
)
(unreachable)
)
)
(if
(i32.eqz
(i32.eq
(block $inlining/func_ii_opt|inlined.0 (result i32)
(set_local $2
(i32.const 0)
)
(br $inlining/func_ii_opt|inlined.0
(get_local $2)
)
)
(i32.const 0)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 63)
(i32.const 2)
)
(unreachable)
)
)
(if
(i32.eqz
(i32.eq
(block $inlining/func_ii_opt|inlined.1 (result i32)
(set_local $2
(i32.const 1)
)
(br $inlining/func_ii_opt|inlined.1
(get_local $2)
)
)
(i32.const 1)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 64)
(i32.const 2)
)
(unreachable)
)
)
(if
(i32.eqz
(i32.eq
(block $inlining/func_ii_loc|inlined.0 (result i32)
(set_local $2
(i32.const 2)
)
(set_local $3
(get_local $2)
)
(nop)
(if
(i32.const 1)
(block
(set_local $5
(get_local $3)
)
(set_local $6
(get_local $5)
)
(set_local $4
(i32.add
(get_local $6)
(i32.const 1)
)
)
)
)
(br $inlining/func_ii_loc|inlined.0
(get_local $4)
)
)
(i32.const 3)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 65)
(i32.const 2)
)
(unreachable)
)
)
(if
(i32.eqz
(i32.eq
(block $inlining/func_ii_loc|inlined.1 (result i32)
(set_local $4
(i32.const 3)
)
(set_local $3
(get_local $4)
)
(nop)
(if
(i32.const 1)
(block
(set_local $6
(get_local $3)
)
(set_local $5
(get_local $6)
)
(set_local $2
(i32.add
(get_local $5)
(i32.const 1)
)
)
)
)
(br $inlining/func_ii_loc|inlined.1
(get_local $2)
)
)
(i32.const 4)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 66)
(i32.const 2)
)
(unreachable)
)
)
(block $inlining/func_iv|inlined.0
(set_local $2
(i32.const 0)
)
)
(if
(i32.eqz
(i32.eq
(block (result i32)
(set_global $argumentCount
(i32.const 1)
)
(call_indirect (type $ii)
(i32.const 2)
(block $inlining/func_fe|inlined.0 (result i32)
(br $inlining/func_fe|inlined.0
(i32.const 0)
)
)
)
)
(i32.const 2)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 68)
(i32.const 2)
)
(unreachable)
)
)
(if
(i32.eqz
(i32.eq
(block $inlining/Foo.method_static|inlined.0 (result i32)
(set_local $2
(i32.const 42)
)
(set_local $3
(i32.const 2)
)
(br $inlining/Foo.method_static|inlined.0
(i32.add
(get_local $2)
(get_local $3)
)
)
)
(i32.const 44)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 69)
(i32.const 2)
)
(unreachable)
)
)
(set_local $7
(i32.const 123)
)
(if
(i32.eqz
(i32.eq
(block $inlining/Foo#method_this|inlined.0 (result i32)
(set_local $3
(get_local $7)
)
(set_local $2
(i32.const 43)
)
(set_local $4
(i32.const 3)
)
(br $inlining/Foo#method_this|inlined.0
(get_local $3)
)
)
(i32.const 123)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 71)
(i32.const 2)
)
(unreachable)
)
)
)
(func $start (; 4 ;) (type $v)
(if
(i32.eqz
(i32.eq
@ -31,11 +412,12 @@
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 8)
(i32.const 10)
(i32.const 0)
)
(unreachable)
)
)
(call $inlining/test_funcs)
)
)

View File

@ -1,13 +1,14 @@
(module
(type $ii (func (param i32) (result i32)))
(type $iii (func (param i32 i32) (result i32)))
(type $iiii (func (param i32 i32 i32) (result i32)))
(type $iiiiv (func (param i32 i32 i32 i32)))
(type $iiii (func (param i32 i32 i32) (result i32)))
(import "env" "abort" (func $abort (param i32 i32 i32 i32)))
(global $argumentCount (mut i32) (i32.const 0))
(memory $0 1)
(data (i32.const 8) "\0e\00\00\00~\00l\00i\00b\00/\00s\00t\00r\00i\00n\00g\00.\00t\00s")
(data (i32.const 40) "\04\00\00\00n\00u\00l\00l")
(data (i32.const 4) "\0d\00\00\00~\00l\00i\00b\00/\00a\00r\00r\00a\00y\00.\00t\00s")
(data (i32.const 40) "\0e\00\00\00~\00l\00i\00b\00/\00s\00t\00r\00i\00n\00g\00.\00t\00s")
(data (i32.const 72) "\04\00\00\00n\00u\00l\00l")
(export "i32ArrayArrayElementAccess" (func $std/array-access/i32ArrayArrayElementAccess))
(export "stringArrayPropertyAccess" (func $std/array-access/stringArrayPropertyAccess))
(export "stringArrayMethodCall" (func $std/array-access/stringArrayMethodCall))
@ -15,20 +16,34 @@
(export "stringArrayArrayMethodCall" (func $std/array-access/stringArrayArrayMethodCall))
(export "memory" (memory $0))
(func $~lib/array/Array<Array<i32>>#__get (; 1 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(if
(i32.ge_u
(get_local $1)
(i32.load offset=4
(get_local $0)
(i32.shr_u
(i32.load
(tee_local $2
(i32.load
(get_local $0)
)
)
)
(i32.const 2)
)
)
(unreachable)
)
(i32.load
(i32.add
(i32.load
(get_local $0)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 64)
(i32.const 37)
)
(unreachable)
)
)
(i32.load offset=8
(i32.add
(get_local $2)
(i32.shl
(get_local $1)
(i32.const 2)
@ -124,7 +139,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 8)
(i32.const 40)
(i32.const 234)
(i32.const 4)
)
@ -136,7 +151,7 @@
(get_local $1)
)
(set_local $1
(i32.const 40)
(i32.const 72)
)
)
(if
@ -234,7 +249,7 @@
(get_local $0)
(i32.const 0)
)
(i32.const 4)
(i32.const 36)
(i32.const 0)
)
)
@ -261,7 +276,7 @@
)
(i32.const 1)
)
(i32.const 4)
(i32.const 36)
(i32.const 0)
)
)

View File

@ -2,16 +2,21 @@
(type $ii (func (param i32) (result i32)))
(type $iii (func (param i32 i32) (result i32)))
(type $i (func (result i32)))
(type $iiii (func (param i32 i32 i32) (result i32)))
(type $iiiiv (func (param i32 i32 i32 i32)))
(type $iiii (func (param i32 i32 i32) (result i32)))
(import "env" "abort" (func $abort (param i32 i32 i32 i32)))
(global $~lib/internal/allocator/AL_BITS i32 (i32.const 3))
(global $~lib/internal/allocator/AL_SIZE i32 (i32.const 8))
(global $~lib/internal/allocator/AL_MASK i32 (i32.const 7))
(global $~lib/internal/arraybuffer/HEADER_SIZE i32 (i32.const 8))
(global $~lib/internal/string/HEADER_SIZE i32 (i32.const 4))
(global $argumentCount (mut i32) (i32.const 0))
(global $HEAP_BASE i32 (i32.const 52))
(global $HEAP_BASE i32 (i32.const 84))
(memory $0 1)
(data (i32.const 4) "\00\00\00\00")
(data (i32.const 8) "\0e\00\00\00~\00l\00i\00b\00/\00s\00t\00r\00i\00n\00g\00.\00t\00s\00")
(data (i32.const 40) "\04\00\00\00n\00u\00l\00l\00")
(data (i32.const 4) "\0d\00\00\00~\00l\00i\00b\00/\00a\00r\00r\00a\00y\00.\00t\00s\00")
(data (i32.const 36) "\00\00\00\00")
(data (i32.const 40) "\0e\00\00\00~\00l\00i\00b\00/\00s\00t\00r\00i\00n\00g\00.\00t\00s\00")
(data (i32.const 72) "\04\00\00\00n\00u\00l\00l\00")
(export "i32ArrayArrayElementAccess" (func $std/array-access/i32ArrayArrayElementAccess))
(export "stringArrayPropertyAccess" (func $std/array-access/stringArrayPropertyAccess))
(export "stringArrayMethodCall" (func $std/array-access/stringArrayMethodCall))
@ -19,48 +24,110 @@
(export "stringArrayArrayMethodCall" (func $std/array-access/stringArrayArrayMethodCall))
(export "memory" (memory $0))
(func $~lib/array/Array<Array<i32>>#__get (; 1 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(local $3 i32)
(local $4 i32)
(local $5 i32)
(set_local $2
(i32.load
(get_local $0)
)
)
(set_local $3
(i32.shr_u
(i32.load
(get_local $2)
)
(i32.const 2)
)
)
(if
(i32.ge_u
(get_local $1)
(i32.load offset=4
(get_local $0)
)
(get_local $3)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 64)
(i32.const 37)
)
(unreachable)
)
(unreachable)
)
(return
(i32.load
(i32.add
(i32.load
(get_local $0)
)
(i32.mul
(get_local $1)
(i32.const 4)
(block $~lib/internal/arraybuffer/loadUnsafe<Array<i32>>|inlined.0 (result i32)
(set_local $4
(get_local $2)
)
(set_local $5
(get_local $1)
)
(br $~lib/internal/arraybuffer/loadUnsafe<Array<i32>>|inlined.0
(i32.load offset=8
(i32.add
(get_local $4)
(i32.shl
(get_local $5)
(i32.const 2)
)
)
)
)
)
)
)
(func $~lib/array/Array<i32>#__get (; 2 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(local $3 i32)
(local $4 i32)
(local $5 i32)
(set_local $2
(i32.load
(get_local $0)
)
)
(set_local $3
(i32.shr_u
(i32.load
(get_local $2)
)
(i32.const 2)
)
)
(if
(i32.ge_u
(get_local $1)
(i32.load offset=4
(get_local $0)
)
(get_local $3)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 64)
(i32.const 37)
)
(unreachable)
)
(unreachable)
)
(return
(i32.load
(i32.add
(i32.load
(get_local $0)
)
(i32.mul
(get_local $1)
(i32.const 4)
(block $~lib/internal/arraybuffer/loadUnsafe<i32>|inlined.0 (result i32)
(set_local $4
(get_local $2)
)
(set_local $5
(get_local $1)
)
(br $~lib/internal/arraybuffer/loadUnsafe<i32>|inlined.0
(i32.load offset=8
(i32.add
(get_local $4)
(i32.shl
(get_local $5)
(i32.const 2)
)
)
)
)
)
@ -78,24 +145,55 @@
)
)
(func $~lib/array/Array<String>#__get (; 4 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(local $3 i32)
(local $4 i32)
(local $5 i32)
(set_local $2
(i32.load
(get_local $0)
)
)
(set_local $3
(i32.shr_u
(i32.load
(get_local $2)
)
(i32.const 2)
)
)
(if
(i32.ge_u
(get_local $1)
(i32.load offset=4
(get_local $0)
)
(get_local $3)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 64)
(i32.const 37)
)
(unreachable)
)
(unreachable)
)
(return
(i32.load
(i32.add
(i32.load
(get_local $0)
)
(i32.mul
(get_local $1)
(i32.const 4)
(block $~lib/internal/arraybuffer/loadUnsafe<String>|inlined.0 (result i32)
(set_local $4
(get_local $2)
)
(set_local $5
(get_local $1)
)
(br $~lib/internal/arraybuffer/loadUnsafe<String>|inlined.0
(i32.load offset=8
(i32.add
(get_local $4)
(i32.shl
(get_local $5)
(i32.const 2)
)
)
)
)
)
@ -194,7 +292,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 8)
(i32.const 40)
(i32.const 234)
(i32.const 4)
)
@ -207,7 +305,7 @@
(i32.const 0)
)
(set_local $1
(i32.const 40)
(i32.const 72)
)
)
(set_local $3
@ -319,31 +417,62 @@
(get_local $0)
(i32.const 0)
)
(i32.const 4)
(i32.const 36)
(i32.const 0)
)
)
)
)
(func $~lib/array/Array<Array<String>>#__get (; 10 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(local $3 i32)
(local $4 i32)
(local $5 i32)
(set_local $2
(i32.load
(get_local $0)
)
)
(set_local $3
(i32.shr_u
(i32.load
(get_local $2)
)
(i32.const 2)
)
)
(if
(i32.ge_u
(get_local $1)
(i32.load offset=4
(get_local $0)
)
(get_local $3)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 64)
(i32.const 37)
)
(unreachable)
)
(unreachable)
)
(return
(i32.load
(i32.add
(i32.load
(get_local $0)
)
(i32.mul
(get_local $1)
(i32.const 4)
(block $~lib/internal/arraybuffer/loadUnsafe<Array<String>>|inlined.0 (result i32)
(set_local $4
(get_local $2)
)
(set_local $5
(get_local $1)
)
(br $~lib/internal/arraybuffer/loadUnsafe<Array<String>>|inlined.0
(i32.load offset=8
(i32.add
(get_local $4)
(i32.shl
(get_local $5)
(i32.const 2)
)
)
)
)
)
@ -376,7 +505,7 @@
)
(i32.const 1)
)
(i32.const 4)
(i32.const 36)
(i32.const 0)
)
)

File diff suppressed because it is too large Load Diff

View File

@ -1,128 +1,61 @@
import "allocator/arena";
import { Array } from "array";
import { defaultComparator } from "internal/array";
// Default comparator
function createDefaultComparator<T>(): (a: T, b: T) => i32 {
return (a: T, b: T): i32 => (
<i32>(a > b) - <i32>(a < b)
);
// Obtains the internal capacity of an array from its backing buffer.
function internalCapacity<T>(array: Array<T>): i32 {
// the memory region used by the backing buffer might still be larger in that the ArrayBuffer
// pre-allocates a power of 2 sized buffer itself and reuses it as long as it isn't exceeded.
var buffer: ArrayBuffer = array.buffer_;
return buffer.byteLength >> alignof<T>();
}
// Check is array sorted
function isSorted<T>(data: Array<T>, comparator: (a: T, b: T) => i32 = createDefaultComparator<T>()): bool {
for (let i: i32 = 1, len: i32 = data.length; i < len; i++) {
if (comparator(data[i - 1], data[i]) > 0) {
return false;
}
}
return true;
}
var arr = new Array<i32>();
// Check is equality for arrays
function isArraysEqual<T>(a: Array<T>, b: Array<T>, maxLen: i32 = 0): bool {
var len = maxLen;
if (!maxLen) {
if (a.length != b.length) {
return false;
}
len = <i32>a.length;
}
for (let i: i32 = 0; i < len; i++) {
if (a[i] != b[i]) return false;
}
return true;
}
function createReverseOrderedArray(size: i32): Array<i32> {
var arr = new Array<i32>(size);
for (let i: i32 = 0; i < arr.length; i++) {
arr[i] = <i32>arr.length - 1 - i;
}
return arr;
}
NativeMath.seedRandom(reinterpret<u64>(JSMath.random()));
function createRandomOrderedArray(size: i32): Array<i32> {
var arr = new Array<i32>(size);
for (let i: i32 = 0; i < arr.length; i++) {
arr[i] = <i32>(NativeMath.random() * arr.length);
}
return arr;
}
/*
function createReverseOrderedNestedArray(size: i32): Array<Array<i32>> {
var arr = new Array<Array<i32>>(size);
for (let i: i32 = 0; i < arr.length; i++) {
arr[i] = new Array<i32>(1);
arr[i][0] = arr.length - 1 - i;
}
return arr;
}
class Proxy<T> {
constructor(public x: T) {}
}
function createReverseOrderedElementsArray(size: i32): Proxy<i32>[] {
var arr = new Array<Proxy<i32>>(size);
for (let i: i32 = 0; i < arr.length; i++) {
arr[i] = new Proxy<i32>(arr.length - 1 - i);
}
return arr;
}
*/
function assertSorted<T>(arr: Array<T>, comparator: (a: T, b: T) => i32): void {
assert(isSorted<T>(arr.sort<T>(comparator), comparator));
}
function assertSortedDefault<T>(arr: Array<T>): void {
assertSorted<T>(arr, createDefaultComparator<T>());
}
var arr = changetype<i32[]>(allocate_memory(sizeof<usize>() + 2 * sizeof<i32>()));
// Array#push/pop //////////////////////////////////////////////////////////////////////////////////
assert(arr.length == 0);
assert(arr.__capacity == 0);
assert(internalCapacity<i32>(arr) == 0);
arr.push(42);
assert(arr[0] == 42);
assert(arr.length == 1);
assert(arr.__capacity == 1);
assert(internalCapacity<i32>(arr) == 1);
var i = arr.pop();
assert(i == 42);
assert(arr.length == 0);
assert(arr.__capacity == 1);
assert(internalCapacity<i32>(arr) == 1);
arr.push(43);
assert(arr.length == 1);
assert(arr.__capacity == 1);
assert(internalCapacity<i32>(arr) == 1);
assert(arr[0] == 43);
arr.push(44);
assert(arr.length == 2);
assert(arr.__capacity == 2);
assert(internalCapacity<i32>(arr) == 2);
assert(arr[0] == 43);
assert(arr[1] == 44);
arr.push(45);
assert(arr.length == 3);
assert(arr.__capacity == 4);
assert(internalCapacity<i32>(arr) == 3);
assert(arr[0] == 43);
assert(arr[1] == 44);
assert(arr[2] == 45);
// Array#unshift ///////////////////////////////////////////////////////////////////////////////////
arr.unshift(42);
assert(arr.length == 4);
assert(arr.__capacity == 4);
assert(internalCapacity<i32>(arr) == 4);
assert(arr[0] == 42);
assert(arr[1] == 43);
assert(arr[2] == 44);
@ -131,18 +64,20 @@ assert(arr[3] == 45);
arr.unshift(41);
assert(arr.length == 5);
assert(arr.__capacity == 8);
assert(internalCapacity<i32>(arr) == 5);
assert(arr[0] == 41);
assert(arr[1] == 42);
assert(arr[2] == 43);
assert(arr[3] == 44);
assert(arr[4] == 45);
// Array#shift /////////////////////////////////////////////////////////////////////////////////////
i = arr.shift();
assert(i == 41);
assert(arr.length == 4);
assert(arr.__capacity == 8);
assert(internalCapacity<i32>(arr) == 5);
assert(arr[0] == 42);
assert(arr[1] == 43);
assert(arr[2] == 44);
@ -152,15 +87,17 @@ i = arr.pop();
assert(i == 45);
assert(arr.length == 3);
assert(arr.__capacity == 8);
assert(internalCapacity<i32>(arr) == 5);
assert(arr[0] == 42);
assert(arr[1] == 43);
assert(arr[2] == 44);
// Array#reverse ///////////////////////////////////////////////////////////////////////////////////
arr.reverse();
assert(arr.length == 3);
assert(arr.__capacity == 8);
assert(internalCapacity<i32>(arr) == 5);
assert(arr[0] == 44);
assert(arr[1] == 43);
assert(arr[2] == 42);
@ -168,6 +105,8 @@ assert(arr[2] == 42);
arr.push(43);
arr.push(44);
// Array#indexOf ///////////////////////////////////////////////////////////////////////////////////
i = arr.indexOf(44);
assert(i == 0);
@ -208,6 +147,8 @@ i = arr.indexOf(43, 2);
assert(i == 3);
// Array#includes //////////////////////////////////////////////////////////////////////////////////
var includes = arr.includes(44);
assert(includes == true);
@ -251,16 +192,17 @@ assert(includes == true);
arr.splice(1, 1);
assert(arr.length == 4);
assert(arr.__capacity == 8);
assert(internalCapacity<i32>(arr) == 5);
assert(arr[0] == 44);
assert(arr[1] == 42);
// Array#findIndex /////////////////////////////////////////////////////////////////////////////////
arr[0] = 0;
arr[1] = 1;
arr[2] = 2;
arr[3] = 3;
/*=============================== findIndex ==========================*/
i = arr.findIndex((value: i32, index: i32, array: Array<i32>): bool => value == 0);
assert(i == 0);
@ -272,7 +214,7 @@ assert(i == -1);
// Test side effect push
i = arr.findIndex((value: i32, index: i32, array: Array<i32>): bool => {
array.push(100); //push side effect should not affect this method by spec
array.push(100); // push side effect should not affect this method by spec
return value == 100;
});
// array should be changed, but this method result should be calculated for old array length
@ -288,7 +230,7 @@ arr.pop();
// Test side effect pop
i = arr.findIndex((value: i32, index: i32, array: Array<i32>): bool => {
array.pop(); //poped items shouldn't be looked up, and we shouldn't go out of bounds
array.pop(); // poped items shouldn't be looked up, and we shouldn't go out of bounds
return value == 100;
});
// only 2 first items was looked up, since last 2 was removed by .pop()
@ -297,7 +239,9 @@ assert(arr.length == 2);
arr.push(2);
arr.push(3);
/*=============================== every ==========================*/
// Array#every /////////////////////////////////////////////////////////////////////////////////////
var every = arr.every((value: i32, index: i32, array: Array<i32>): bool => value >= 0);
assert(every == true);
@ -306,7 +250,7 @@ assert(every == false);
// Test side effect push
every = arr.every((value: i32, index: i32, array: Array<i32>): bool => {
array.push(100); //push side effect should not affect this method by spec
array.push(100); // push side effect should not affect this method by spec
return value < 10;
});
// array should be changed, but this method result should be calculated for old array length
@ -331,7 +275,9 @@ assert(arr.length == 2);
arr.push(2);
arr.push(3);
/*=============================== some ==========================*/
// Array#some //////////////////////////////////////////////////////////////////////////////////////
var some = arr.some((value: i32, index: i32, array: Array<i32>): bool => value >= 3);
assert(some == true);
@ -340,7 +286,7 @@ assert(some == false);
// Test side effect push
some = arr.some((value: i32, index: i32, array: Array<i32>): bool => {
array.push(100); //push side effect should not affect this method by spec
array.push(100); // push side effect should not affect this method by spec
return value > 10;
});
// array should be changed, but this method result should be calculated for old array length
@ -356,7 +302,7 @@ arr.pop();
// Test side effect pop
some = arr.some((value: i32, index: i32, array: Array<i32>): bool => {
array.pop(); //poped items shouldn't be looked up, and we shouldn't go out of bounds
array.pop(); // poped items shouldn't be looked up, and we shouldn't go out of bounds
return value > 3;
});
// only 2 first items was looked up, since last 2 was removed by .pop()
@ -365,7 +311,8 @@ assert(arr.length == 2);
arr.push(2);
arr.push(3);
/*=============================== reduce ==========================*/
// Array#reduce ////////////////////////////////////////////////////////////////////////////////////
i = arr.reduce<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i32 => prev + current), 0);
assert(i == 6);
@ -382,7 +329,7 @@ assert(boolVal == false);
// Test side effect push
i = arr.reduce<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i32 => {
array.push(1); //push side effect should not affect this method by spec
array.push(1); // push side effect should not affect this method by spec
return prev + current;
}), 0);
// array should be changed, but this method result should be calculated for old array length
@ -405,46 +352,115 @@ i = arr.reduce<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i
assert(i == 1);
assert(arr.length == 2);
/*=============================== sort ==========================*/
// Array#sort //////////////////////////////////////////////////////////////////////////////////////
var revesed0: Array<i32> = [];
var revesed1: Array<i32> = [1];
var revesed2: Array<i32> = [2, 1];
var revesed4: Array<i32> = [3, 2, 1, 0];
// Checks if an array is properly sorted
function isSorted<T>(data: Array<T>, comparator: (a: T, b: T) => i32 = defaultComparator<T>()): bool {
for (let i: i32 = 1, len: i32 = data.length; i < len; i++) {
if (comparator(data[i - 1], data[i]) > 0) return false;
}
return true;
}
// Checks if two arrays are equal
function isArraysEqual<T>(a: Array<T>, b: Array<T>, len: i32 = 0): bool {
if (!len) {
if (a.length != b.length) return false;
len = a.length;
}
for (let i = 0; i < len; i++) {
if (a[i] != b[i]) return false;
}
return true;
}
function createReverseOrderedArray(size: i32): Array<i32> {
var arr = new Array<i32>(size);
for (let i = 0; i < arr.length; i++) {
arr[i] = arr.length - 1 - i;
}
return arr;
}
NativeMath.seedRandom(reinterpret<u64>(JSMath.random()));
function createRandomOrderedArray(size: i32): Array<i32> {
var arr = new Array<i32>(size);
for (let i = 0; i < arr.length; i++) {
arr[i] = <i32>(NativeMath.random() * arr.length);
}
return arr;
}
/*
function createReverseOrderedNestedArray(size: i32): Array<Array<i32>> {
var arr = new Array<Array<i32>>(size);
for (let i: i32 = 0; i < arr.length; i++) {
arr[i] = new Array<i32>(1);
arr[i][0] = arr.length - 1 - i;
}
return arr;
}
class Proxy<T> {
constructor(public x: T) {}
}
function createReverseOrderedElementsArray(size: i32): Proxy<i32>[] {
var arr = new Array<Proxy<i32>>(size);
for (let i: i32 = 0; i < arr.length; i++) {
arr[i] = new Proxy<i32>(arr.length - 1 - i);
}
return arr;
}
*/
function assertSorted<T>(arr: Array<T>, comparator: (a: T, b: T) => i32): void {
assert(isSorted<T>(arr.sort(comparator), comparator));
}
function assertSortedDefault<T>(arr: Array<T>): void {
assertSorted<T>(arr, defaultComparator<T>());
}
var reversed0: Array<i32> = [];
var reversed1: Array<i32> = [1];
var reversed2: Array<i32> = [2, 1];
var reversed4: Array<i32> = [3, 2, 1, 0];
var expected4: Array<i32> = [0, 1, 2, 3];
var revesed64 = createReverseOrderedArray(64);
var revesed128 = createReverseOrderedArray(128);
var revesed1024 = createReverseOrderedArray(1024);
var revesed10000 = createReverseOrderedArray(10000);
var reversed64 = createReverseOrderedArray(64);
var reversed128 = createReverseOrderedArray(128);
var reversed1024 = createReverseOrderedArray(1024);
var reversed10000 = createReverseOrderedArray(10000);
var randomized512 = createRandomOrderedArray(512);
// Test sorting with with default comparator
assertSortedDefault<i32>(revesed0);
assertSortedDefault<i32>(reversed0);
assertSortedDefault<i32>(revesed1);
assert(isArraysEqual<i32>(revesed1, <i32[]>[1]));
assertSortedDefault<i32>(reversed1);
assert(isArraysEqual<i32>(reversed1, <i32[]>[1]));
assertSortedDefault<i32>(revesed2);
assert(isArraysEqual<i32>(revesed2, <i32[]>[1, 2]));
assertSortedDefault<i32>(reversed2);
assert(isArraysEqual<i32>(reversed2, <i32[]>[1, 2]));
assertSortedDefault<i32>(revesed4);
assert(isArraysEqual<i32>(revesed4, expected4));
assertSortedDefault<i32>(reversed4);
assert(isArraysEqual<i32>(reversed4, expected4));
assertSortedDefault<i32>(revesed64);
assert(isArraysEqual<i32>(revesed64, expected4, 4));
assertSortedDefault<i32>(reversed64);
assert(isArraysEqual<i32>(reversed64, expected4, 4));
assertSortedDefault<i32>(revesed128);
assert(isArraysEqual<i32>(revesed128, expected4, 4));
assertSortedDefault<i32>(reversed128);
assert(isArraysEqual<i32>(reversed128, expected4, 4));
assertSortedDefault<i32>(revesed1024);
assert(isArraysEqual<i32>(revesed1024, expected4, 4));
assertSortedDefault<i32>(reversed1024);
assert(isArraysEqual<i32>(reversed1024, expected4, 4));
assertSortedDefault<i32>(revesed10000);
assert(isArraysEqual<i32>(revesed10000, expected4, 4));
assertSortedDefault<i32>(reversed10000);
assert(isArraysEqual<i32>(reversed10000, expected4, 4));
assertSortedDefault<i32>(randomized512);

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
(module
(type $iii (func (param i32 i32) (result i32)))
(type $ii (func (param i32) (result i32)))
(type $iiiiv (func (param i32 i32 i32 i32)))
(type $ii (func (param i32) (result i32)))
(type $iiiv (func (param i32 i32 i32)))
(type $iiii (func (param i32 i32 i32) (result i32)))
(type $v (func))
@ -11,10 +11,11 @@
(global $std/arraybuffer/buffer (mut i32) (i32.const 0))
(global $argumentCount (mut i32) (i32.const 0))
(global $std/arraybuffer/sliced (mut i32) (i32.const 0))
(global $HEAP_BASE i32 (i32.const 104))
(global $HEAP_BASE i32 (i32.const 148))
(memory $0 1)
(data (i32.const 4) "\1c\00\00\00~\00l\00i\00b\00/\00i\00n\00t\00e\00r\00n\00a\00l\00/\00a\00r\00r\00a\00y\00b\00u\00f\00f\00e\00r\00.\00t\00s")
(data (i32.const 64) "\12\00\00\00s\00t\00d\00/\00a\00r\00r\00a\00y\00b\00u\00f\00f\00e\00r\00.\00t\00s")
(data (i32.const 4) "\13\00\00\00~\00l\00i\00b\00/\00a\00r\00r\00a\00y\00b\00u\00f\00f\00e\00r\00.\00t\00s")
(data (i32.const 48) "\1c\00\00\00~\00l\00i\00b\00/\00i\00n\00t\00e\00r\00n\00a\00l\00/\00a\00r\00r\00a\00y\00b\00u\00f\00f\00e\00r\00.\00t\00s")
(data (i32.const 108) "\12\00\00\00s\00t\00d\00/\00a\00r\00r\00a\00y\00b\00u\00f\00f\00e\00r\00.\00t\00s")
(export "memory" (memory $0))
(start $start)
(func $~lib/internal/arraybuffer/computeSize (; 1 ;) (type $ii) (param $0 i32) (result i32)
@ -130,7 +131,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 48)
(i32.const 22)
(i32.const 2)
)
@ -489,7 +490,15 @@
(get_local $1)
(i32.const 1073741816)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 13)
(i32.const 40)
)
(unreachable)
)
)
(call $~lib/memory/set_memory
(i32.add
@ -2537,7 +2546,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 5)
(i32.const 0)
)
@ -2566,7 +2575,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 9)
(i32.const 0)
)
@ -2581,7 +2590,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 10)
(i32.const 0)
)
@ -2610,7 +2619,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 14)
(i32.const 0)
)
@ -2639,7 +2648,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 18)
(i32.const 0)
)
@ -2663,7 +2672,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 22)
(i32.const 0)
)
@ -2687,7 +2696,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 26)
(i32.const 0)
)
@ -2711,7 +2720,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 30)
(i32.const 0)
)
@ -2735,7 +2744,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 34)
(i32.const 0)
)
@ -2761,7 +2770,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 38)
(i32.const 0)
)
@ -2775,7 +2784,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 39)
(i32.const 0)
)

View File

@ -1,8 +1,8 @@
(module
(type $i (func (result i32)))
(type $iii (func (param i32 i32) (result i32)))
(type $ii (func (param i32) (result i32)))
(type $iiiiv (func (param i32 i32 i32 i32)))
(type $ii (func (param i32) (result i32)))
(type $iiiv (func (param i32 i32 i32)))
(type $iiii (func (param i32 i32 i32) (result i32)))
(type $v (func))
@ -18,10 +18,11 @@
(global $std/arraybuffer/buffer (mut i32) (i32.const 0))
(global $argumentCount (mut i32) (i32.const 0))
(global $std/arraybuffer/sliced (mut i32) (i32.const 0))
(global $HEAP_BASE i32 (i32.const 104))
(global $HEAP_BASE i32 (i32.const 148))
(memory $0 1)
(data (i32.const 4) "\1c\00\00\00~\00l\00i\00b\00/\00i\00n\00t\00e\00r\00n\00a\00l\00/\00a\00r\00r\00a\00y\00b\00u\00f\00f\00e\00r\00.\00t\00s\00")
(data (i32.const 64) "\12\00\00\00s\00t\00d\00/\00a\00r\00r\00a\00y\00b\00u\00f\00f\00e\00r\00.\00t\00s\00")
(data (i32.const 4) "\13\00\00\00~\00l\00i\00b\00/\00a\00r\00r\00a\00y\00b\00u\00f\00f\00e\00r\00.\00t\00s\00")
(data (i32.const 48) "\1c\00\00\00~\00l\00i\00b\00/\00i\00n\00t\00e\00r\00n\00a\00l\00/\00a\00r\00r\00a\00y\00b\00u\00f\00f\00e\00r\00.\00t\00s\00")
(data (i32.const 108) "\12\00\00\00s\00t\00d\00/\00a\00r\00r\00a\00y\00b\00u\00f\00f\00e\00r\00.\00t\00s\00")
(export "memory" (memory $0))
(start $start)
(func $~lib/internal/arraybuffer/computeSize (; 1 ;) (type $ii) (param $0 i32) (result i32)
@ -165,7 +166,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 48)
(i32.const 22)
(i32.const 2)
)
@ -543,7 +544,15 @@
(get_local $1)
(i32.const 1073741816)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 13)
(i32.const 40)
)
(unreachable)
)
)
(set_local $2
(call $~lib/internal/arraybuffer/allocUnsafe
@ -2872,7 +2881,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 5)
(i32.const 0)
)
@ -2903,7 +2912,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 9)
(i32.const 0)
)
@ -2920,7 +2929,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 10)
(i32.const 0)
)
@ -2951,7 +2960,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 14)
(i32.const 0)
)
@ -2982,7 +2991,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 18)
(i32.const 0)
)
@ -3008,7 +3017,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 22)
(i32.const 0)
)
@ -3034,7 +3043,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 26)
(i32.const 0)
)
@ -3060,7 +3069,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 30)
(i32.const 0)
)
@ -3086,7 +3095,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 34)
(i32.const 0)
)
@ -3117,7 +3126,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 38)
(i32.const 0)
)
@ -3134,7 +3143,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 64)
(i32.const 108)
(i32.const 39)
(i32.const 0)
)

View File

@ -12161,7 +12161,15 @@
(i32.eqz
(get_global $~lib/math/random_seeded)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 32)
(i32.const 1000)
(i32.const 24)
)
(unreachable)
)
)
(set_local $0
(get_global $~lib/math/random_state0)

View File

@ -14381,7 +14381,15 @@
(i32.eqz
(get_global $~lib/math/random_seeded)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 32)
(i32.const 1000)
(i32.const 24)
)
(unreachable)
)
)
(set_local $0
(get_global $~lib/math/random_state0)

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,11 @@ class Tester {
return new Tester(a.x % b.x, a.y % b.y);
}
@operator('**')
static pow(a: Tester, b: Tester): Tester {
return new Tester(<i32>(a.x ** b.x), <i32>(a.y ** b.y));
}
@operator('|')
static or(a: Tester, b: Tester): Tester {
return new Tester(a.x | b.x, a.y | b.y);
@ -99,12 +104,18 @@ var d2 = new Tester(3, 10);
var d = d1 / d2;
assert(d.x == 2 && d.y == 5);
// check fractional
// check remainder
var f1 = new Tester(10, 10);
var f2 = new Tester(6, 10);
var f = f1 % f2;
assert(f.x == 4 && f.y == 0);
// check power
var p1 = new Tester(2, 3);
var p2 = new Tester(4, 5);
var p = p1 ** p2;
assert(p.x == 16 && p.y == 243);
// check bitwise and
var n1 = new Tester(0xFF, 0x0F);
var n2 = new Tester(0x0F, 0xFF);
@ -166,3 +177,31 @@ var leq1 = new Tester(4, 3);
var leq2 = new Tester(4, 3);
var leq = leq1 <= leq2;
assert(leq == true);
// check inlined static
class TesterInlineStatic {
constructor(public x: i32, public y: i32) {
}
@inline @operator('+')
static add(a: TesterInlineStatic, b: TesterInlineStatic): TesterInlineStatic {
return new TesterInlineStatic(a.x + b.x, a.y + b.y);
}
}
var ais1 = new TesterInlineStatic(1, 2);
var ais2 = new TesterInlineStatic(2, 3);
var ais = ais1 + ais2;
assert(ais.x == 3 && ais.y == 5);
// check inlined instance
class TesterInlineInstance {
constructor(public x: i32, public y: i32) {
}
@inline @operator('+')
add(b: TesterInlineInstance): TesterInlineInstance {
return new TesterInlineInstance(this.x + b.x, this.y + b.y);
}
}
var aii1 = new TesterInlineInstance(1, 2);
var aii2 = new TesterInlineInstance(2, 3);
var aii = aii1 + aii2;
assert(aii.x == 3 && aii.y == 5);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -3725,7 +3725,15 @@
)
(i32.const 1)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 72)
(i32.const 391)
(i32.const 6)
)
(unreachable)
)
)
(if
(i32.and

View File

@ -4290,7 +4290,15 @@
)
(i32.const 1)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 72)
(i32.const 391)
(i32.const 6)
)
(unreachable)
)
)
(if
(i32.and

View File

@ -4,14 +4,17 @@
(type $iii (func (param i32 i32) (result i32)))
(type $ii (func (param i32) (result i32)))
(type $iiiv (func (param i32 i32 i32)))
(type $iiii (func (param i32 i32 i32) (result i32)))
(type $v (func))
(import "env" "abort" (func $abort (param i32 i32 i32 i32)))
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
(global $HEAP_BASE i32 (i32.const 104))
(global $std/typedarray/arr (mut i32) (i32.const 0))
(global $HEAP_BASE i32 (i32.const 164))
(memory $0 1)
(data (i32.const 4) "\11\00\00\00s\00t\00d\00/\00t\00y\00p\00e\00d\00a\00r\00r\00a\00y\00.\00t\00s")
(data (i32.const 44) "\1c\00\00\00~\00l\00i\00b\00/\00i\00n\00t\00e\00r\00n\00a\00l\00/\00a\00r\00r\00a\00y\00b\00u\00f\00f\00e\00r\00.\00t\00s")
(data (i32.const 44) "\1b\00\00\00~\00l\00i\00b\00/\00i\00n\00t\00e\00r\00n\00a\00l\00/\00t\00y\00p\00e\00d\00a\00r\00r\00a\00y\00.\00t\00s")
(data (i32.const 104) "\1c\00\00\00~\00l\00i\00b\00/\00i\00n\00t\00e\00r\00n\00a\00l\00/\00a\00r\00r\00a\00y\00b\00u\00f\00f\00e\00r\00.\00t\00s")
(export "memory" (memory $0))
(start $start)
(func $~lib/internal/arraybuffer/computeSize (; 1 ;) (type $ii) (param $0 i32) (result i32)
@ -127,7 +130,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 104)
(i32.const 22)
(i32.const 2)
)
@ -486,7 +489,15 @@
(get_local $1)
(i32.const 1073741816)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable)
)
)
(call $~lib/memory/set_memory
(i32.add
@ -537,8 +548,13 @@
(get_local $0)
)
(func $~lib/internal/typedarray/TypedArray<i8>#get:length (; 6 ;) (type $ii) (param $0 i32) (result i32)
(i32.load offset=8
(get_local $0)
(i32.sub
(i32.load offset=8
(get_local $0)
)
(i32.load offset=4
(get_local $0)
)
)
)
(func $~lib/internal/typedarray/TypedArray<i16>#constructor (; 7 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
@ -548,7 +564,15 @@
(get_local $1)
(i32.const 536870908)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable)
)
)
(call $~lib/memory/set_memory
(i32.add
@ -605,8 +629,13 @@
)
(func $~lib/internal/typedarray/TypedArray<i16>#get:length (; 8 ;) (type $ii) (param $0 i32) (result i32)
(i32.shr_s
(i32.load offset=8
(get_local $0)
(i32.sub
(i32.load offset=8
(get_local $0)
)
(i32.load offset=4
(get_local $0)
)
)
(i32.const 1)
)
@ -618,7 +647,15 @@
(get_local $1)
(i32.const 268435454)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable)
)
)
(call $~lib/memory/set_memory
(i32.add
@ -675,8 +712,13 @@
)
(func $~lib/internal/typedarray/TypedArray<i32>#get:length (; 10 ;) (type $ii) (param $0 i32) (result i32)
(i32.shr_s
(i32.load offset=8
(get_local $0)
(i32.sub
(i32.load offset=8
(get_local $0)
)
(i32.load offset=4
(get_local $0)
)
)
(i32.const 2)
)
@ -688,7 +730,15 @@
(get_local $1)
(i32.const 134217727)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable)
)
)
(call $~lib/memory/set_memory
(i32.add
@ -745,8 +795,13 @@
)
(func $~lib/internal/typedarray/TypedArray<i64>#get:length (; 12 ;) (type $ii) (param $0 i32) (result i32)
(i32.shr_s
(i32.load offset=8
(get_local $0)
(i32.sub
(i32.load offset=8
(get_local $0)
)
(i32.load offset=4
(get_local $0)
)
)
(i32.const 3)
)
@ -1308,7 +1363,217 @@
)
)
)
(func $start (; 14 ;) (type $v)
(func $~lib/internal/typedarray/TypedArray<i32>#__set (; 14 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
(local $3 i32)
(if
(i32.ge_u
(get_local $1)
(i32.shr_u
(i32.sub
(i32.load offset=8
(get_local $0)
)
(tee_local $3
(i32.load offset=4
(get_local $0)
)
)
)
(i32.const 2)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 47)
(i32.const 42)
)
(unreachable)
)
)
(i32.store offset=8
(i32.add
(i32.add
(i32.load
(get_local $0)
)
(get_local $3)
)
(i32.shl
(get_local $1)
(i32.const 2)
)
)
(get_local $2)
)
)
(func $~lib/internal/typedarray/TypedArray<i32>#__get (; 15 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(if
(i32.ge_u
(get_local $1)
(i32.shr_u
(i32.sub
(i32.load offset=8
(get_local $0)
)
(tee_local $2
(i32.load offset=4
(get_local $0)
)
)
)
(i32.const 2)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 39)
(i32.const 42)
)
(unreachable)
)
)
(i32.load offset=8
(i32.add
(i32.add
(i32.load
(get_local $0)
)
(get_local $2)
)
(i32.shl
(get_local $1)
(i32.const 2)
)
)
)
)
(func $~lib/typedarray/Int32Array#subarray (; 16 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
(local $3 i32)
(local $4 i32)
(local $5 i32)
(set_local $3
(get_local $2)
)
(set_local $4
(call $~lib/internal/typedarray/TypedArray<i32>#get:length
(tee_local $5
(get_local $0)
)
)
)
(set_local $1
(if (result i32)
(i32.lt_s
(get_local $1)
(i32.const 0)
)
(select
(tee_local $2
(i32.add
(get_local $4)
(get_local $1)
)
)
(tee_local $0
(i32.const 0)
)
(i32.gt_s
(get_local $2)
(get_local $0)
)
)
(select
(tee_local $2
(get_local $1)
)
(tee_local $0
(get_local $4)
)
(i32.lt_s
(get_local $2)
(get_local $0)
)
)
)
)
(set_local $3
(if (result i32)
(i32.lt_s
(get_local $3)
(i32.const 0)
)
(select
(tee_local $2
(i32.add
(get_local $4)
(get_local $3)
)
)
(tee_local $0
(get_local $1)
)
(i32.gt_s
(get_local $2)
(get_local $0)
)
)
(select
(tee_local $2
(select
(tee_local $2
(get_local $3)
)
(tee_local $0
(get_local $4)
)
(i32.lt_s
(get_local $2)
(get_local $0)
)
)
)
(tee_local $0
(get_local $1)
)
(i32.gt_s
(get_local $2)
(get_local $0)
)
)
)
)
(i32.store
(tee_local $2
(call $~lib/allocator/arena/allocate_memory
(i32.const 12)
)
)
(i32.load
(get_local $5)
)
)
(i32.store offset=4
(get_local $2)
(i32.shl
(get_local $1)
(i32.const 2)
)
)
(i32.store offset=8
(get_local $2)
(i32.shl
(get_local $3)
(i32.const 2)
)
)
(get_local $2)
)
(func $start (; 17 ;) (type $v)
(set_global $~lib/allocator/arena/startOffset
(i32.and
(i32.add
@ -1327,6 +1592,205 @@
(call $std/typedarray/testInstantiate
(i32.const 5)
)
(set_global $std/typedarray/arr
(call $~lib/internal/typedarray/TypedArray<i32>#constructor
(i32.const 0)
(i32.const 3)
)
)
(call $~lib/internal/typedarray/TypedArray<i32>#__set
(get_global $std/typedarray/arr)
(i32.const 0)
(i32.const 1)
)
(call $~lib/internal/typedarray/TypedArray<i32>#__set
(get_global $std/typedarray/arr)
(i32.const 1)
(i32.const 2)
)
(call $~lib/internal/typedarray/TypedArray<i32>#__set
(get_global $std/typedarray/arr)
(i32.const 2)
(i32.const 3)
)
(if
(i32.ne
(call $~lib/internal/typedarray/TypedArray<i32>#get:length
(get_global $std/typedarray/arr)
)
(i32.const 3)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 74)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.load offset=4
(get_global $std/typedarray/arr)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 75)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.ne
(i32.load offset=8
(get_global $std/typedarray/arr)
)
(i32.const 12)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 76)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.ne
(call $~lib/internal/typedarray/TypedArray<i32>#__get
(get_global $std/typedarray/arr)
(i32.const 0)
)
(i32.const 1)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 77)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.ne
(call $~lib/internal/typedarray/TypedArray<i32>#__get
(get_global $std/typedarray/arr)
(i32.const 1)
)
(i32.const 2)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 78)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.ne
(call $~lib/internal/typedarray/TypedArray<i32>#__get
(get_global $std/typedarray/arr)
(i32.const 2)
)
(i32.const 3)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 79)
(i32.const 0)
)
(unreachable)
)
)
(set_global $std/typedarray/arr
(call $~lib/typedarray/Int32Array#subarray
(get_global $std/typedarray/arr)
(i32.const 1)
(i32.const 2)
)
)
(if
(i32.ne
(call $~lib/internal/typedarray/TypedArray<i32>#get:length
(get_global $std/typedarray/arr)
)
(i32.const 1)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 82)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.ne
(i32.load offset=4
(get_global $std/typedarray/arr)
)
(i32.const 4)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 83)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.ne
(i32.load offset=8
(get_global $std/typedarray/arr)
)
(i32.const 8)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 84)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.ne
(call $~lib/internal/typedarray/TypedArray<i32>#__get
(get_global $std/typedarray/arr)
(i32.const 0)
)
(i32.const 2)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 85)
(i32.const 0)
)
(unreachable)
)
)
(drop
(call $~lib/internal/typedarray/TypedArray<i64>#constructor
(i32.const 0)

View File

@ -67,6 +67,23 @@ function testInstantiate(len: i32): void {
testInstantiate(0);
testInstantiate(5);
var arr = new Int32Array(3);
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
assert(arr.length == 3);
assert(arr.byteOffset == 0);
assert(arr.byteLength == 3 * sizeof<i32>());
assert(arr[0] == 1);
assert(arr[1] == 2);
assert(arr[2] == 3);
arr = arr.subarray(1, 2);
assert(arr.length == 1);
assert(arr.byteOffset == 1 * sizeof<i32>());
assert(arr.byteLength == 2 * sizeof<i32>());
assert(arr[0] == 2);
import { MAX_BLENGTH } from "internal/arraybuffer";
const MAX_F64LENGTH = <u32>MAX_BLENGTH >> alignof<f64>();

View File

@ -5,6 +5,7 @@
(type $iii (func (param i32 i32) (result i32)))
(type $ii (func (param i32) (result i32)))
(type $iiiv (func (param i32 i32 i32)))
(type $iiii (func (param i32 i32 i32) (result i32)))
(type $v (func))
(import "env" "abort" (func $abort (param i32 i32 i32 i32)))
(global $~lib/internal/allocator/AL_BITS i32 (i32.const 3))
@ -15,11 +16,13 @@
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
(global $~lib/internal/arraybuffer/HEADER_SIZE i32 (i32.const 8))
(global $~lib/internal/arraybuffer/MAX_BLENGTH i32 (i32.const 1073741816))
(global $std/typedarray/arr (mut i32) (i32.const 0))
(global $std/typedarray/MAX_F64LENGTH i32 (i32.const 134217727))
(global $HEAP_BASE i32 (i32.const 104))
(global $HEAP_BASE i32 (i32.const 164))
(memory $0 1)
(data (i32.const 4) "\11\00\00\00s\00t\00d\00/\00t\00y\00p\00e\00d\00a\00r\00r\00a\00y\00.\00t\00s\00")
(data (i32.const 44) "\1c\00\00\00~\00l\00i\00b\00/\00i\00n\00t\00e\00r\00n\00a\00l\00/\00a\00r\00r\00a\00y\00b\00u\00f\00f\00e\00r\00.\00t\00s\00")
(data (i32.const 44) "\1b\00\00\00~\00l\00i\00b\00/\00i\00n\00t\00e\00r\00n\00a\00l\00/\00t\00y\00p\00e\00d\00a\00r\00r\00a\00y\00.\00t\00s\00")
(data (i32.const 104) "\1c\00\00\00~\00l\00i\00b\00/\00i\00n\00t\00e\00r\00n\00a\00l\00/\00a\00r\00r\00a\00y\00b\00u\00f\00f\00e\00r\00.\00t\00s\00")
(export "memory" (memory $0))
(start $start)
(func $~lib/internal/arraybuffer/computeSize (; 1 ;) (type $ii) (param $0 i32) (result i32)
@ -163,7 +166,7 @@
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 104)
(i32.const 22)
(i32.const 2)
)
@ -545,7 +548,15 @@
(get_local $1)
(i32.const 1073741816)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable)
)
)
(set_local $2
(i32.shl
@ -611,8 +622,13 @@
(func $~lib/internal/typedarray/TypedArray<i8>#get:length (; 6 ;) (type $ii) (param $0 i32) (result i32)
(return
(i32.shr_s
(i32.load offset=8
(get_local $0)
(i32.sub
(i32.load offset=8
(get_local $0)
)
(i32.load offset=4
(get_local $0)
)
)
(i32.const 0)
)
@ -629,7 +645,15 @@
(get_local $1)
(i32.const 1073741816)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable)
)
)
(set_local $2
(i32.shl
@ -695,8 +719,13 @@
(func $~lib/internal/typedarray/TypedArray<u8>#get:length (; 8 ;) (type $ii) (param $0 i32) (result i32)
(return
(i32.shr_s
(i32.load offset=8
(get_local $0)
(i32.sub
(i32.load offset=8
(get_local $0)
)
(i32.load offset=4
(get_local $0)
)
)
(i32.const 0)
)
@ -713,7 +742,15 @@
(get_local $1)
(i32.const 536870908)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable)
)
)
(set_local $2
(i32.shl
@ -779,8 +816,13 @@
(func $~lib/internal/typedarray/TypedArray<i16>#get:length (; 10 ;) (type $ii) (param $0 i32) (result i32)
(return
(i32.shr_s
(i32.load offset=8
(get_local $0)
(i32.sub
(i32.load offset=8
(get_local $0)
)
(i32.load offset=4
(get_local $0)
)
)
(i32.const 1)
)
@ -797,7 +839,15 @@
(get_local $1)
(i32.const 536870908)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable)
)
)
(set_local $2
(i32.shl
@ -863,8 +913,13 @@
(func $~lib/internal/typedarray/TypedArray<u16>#get:length (; 12 ;) (type $ii) (param $0 i32) (result i32)
(return
(i32.shr_s
(i32.load offset=8
(get_local $0)
(i32.sub
(i32.load offset=8
(get_local $0)
)
(i32.load offset=4
(get_local $0)
)
)
(i32.const 1)
)
@ -881,7 +936,15 @@
(get_local $1)
(i32.const 268435454)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable)
)
)
(set_local $2
(i32.shl
@ -947,8 +1010,13 @@
(func $~lib/internal/typedarray/TypedArray<i32>#get:length (; 14 ;) (type $ii) (param $0 i32) (result i32)
(return
(i32.shr_s
(i32.load offset=8
(get_local $0)
(i32.sub
(i32.load offset=8
(get_local $0)
)
(i32.load offset=4
(get_local $0)
)
)
(i32.const 2)
)
@ -965,7 +1033,15 @@
(get_local $1)
(i32.const 268435454)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable)
)
)
(set_local $2
(i32.shl
@ -1031,8 +1107,13 @@
(func $~lib/internal/typedarray/TypedArray<u32>#get:length (; 16 ;) (type $ii) (param $0 i32) (result i32)
(return
(i32.shr_s
(i32.load offset=8
(get_local $0)
(i32.sub
(i32.load offset=8
(get_local $0)
)
(i32.load offset=4
(get_local $0)
)
)
(i32.const 2)
)
@ -1049,7 +1130,15 @@
(get_local $1)
(i32.const 134217727)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable)
)
)
(set_local $2
(i32.shl
@ -1115,8 +1204,13 @@
(func $~lib/internal/typedarray/TypedArray<i64>#get:length (; 18 ;) (type $ii) (param $0 i32) (result i32)
(return
(i32.shr_s
(i32.load offset=8
(get_local $0)
(i32.sub
(i32.load offset=8
(get_local $0)
)
(i32.load offset=4
(get_local $0)
)
)
(i32.const 3)
)
@ -1133,7 +1227,15 @@
(get_local $1)
(i32.const 134217727)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable)
)
)
(set_local $2
(i32.shl
@ -1199,8 +1301,13 @@
(func $~lib/internal/typedarray/TypedArray<u64>#get:length (; 20 ;) (type $ii) (param $0 i32) (result i32)
(return
(i32.shr_s
(i32.load offset=8
(get_local $0)
(i32.sub
(i32.load offset=8
(get_local $0)
)
(i32.load offset=4
(get_local $0)
)
)
(i32.const 3)
)
@ -1217,7 +1324,15 @@
(get_local $1)
(i32.const 268435454)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable)
)
)
(set_local $2
(i32.shl
@ -1283,8 +1398,13 @@
(func $~lib/internal/typedarray/TypedArray<f32>#get:length (; 22 ;) (type $ii) (param $0 i32) (result i32)
(return
(i32.shr_s
(i32.load offset=8
(get_local $0)
(i32.sub
(i32.load offset=8
(get_local $0)
)
(i32.load offset=4
(get_local $0)
)
)
(i32.const 2)
)
@ -1301,7 +1421,15 @@
(get_local $1)
(i32.const 134217727)
)
(unreachable)
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable)
)
)
(set_local $2
(i32.shl
@ -1367,8 +1495,13 @@
(func $~lib/internal/typedarray/TypedArray<f64>#get:length (; 24 ;) (type $ii) (param $0 i32) (result i32)
(return
(i32.shr_s
(i32.load offset=8
(get_local $0)
(i32.sub
(i32.load offset=8
(get_local $0)
)
(i32.load offset=4
(get_local $0)
)
)
(i32.const 3)
)
@ -2046,7 +2179,281 @@
)
)
)
(func $start (; 26 ;) (type $v)
(func $~lib/internal/typedarray/TypedArray<i32>#__set (; 26 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
(local $3 i32)
(local $4 i32)
(local $5 i32)
(local $6 i32)
(local $7 i32)
(local $8 i32)
(set_local $3
(i32.load offset=4
(get_local $0)
)
)
(set_local $4
(i32.shr_u
(i32.sub
(i32.load offset=8
(get_local $0)
)
(get_local $3)
)
(i32.const 2)
)
)
(if
(i32.ge_u
(get_local $1)
(get_local $4)
)
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 47)
(i32.const 42)
)
(unreachable)
)
)
(block $~lib/internal/arraybuffer/storeUnsafeWithOffset<i32>|inlined.0
(set_local $5
(i32.load
(get_local $0)
)
)
(set_local $6
(get_local $1)
)
(set_local $7
(get_local $2)
)
(set_local $8
(get_local $3)
)
(i32.store offset=8
(i32.add
(i32.add
(get_local $5)
(get_local $8)
)
(i32.shl
(get_local $6)
(i32.const 2)
)
)
(get_local $7)
)
)
)
(func $~lib/internal/typedarray/TypedArray<i32>#__get (; 27 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(local $3 i32)
(local $4 i32)
(local $5 i32)
(local $6 i32)
(set_local $2
(i32.load offset=4
(get_local $0)
)
)
(set_local $3
(i32.shr_u
(i32.sub
(i32.load offset=8
(get_local $0)
)
(get_local $2)
)
(i32.const 2)
)
)
(if
(i32.ge_u
(get_local $1)
(get_local $3)
)
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 39)
(i32.const 42)
)
(unreachable)
)
)
(return
(block $~lib/internal/arraybuffer/loadUnsafeWithOffset<i32>|inlined.0 (result i32)
(set_local $4
(i32.load
(get_local $0)
)
)
(set_local $5
(get_local $1)
)
(set_local $6
(get_local $2)
)
(br $~lib/internal/arraybuffer/loadUnsafeWithOffset<i32>|inlined.0
(i32.load offset=8
(i32.add
(i32.add
(get_local $4)
(get_local $6)
)
(i32.shl
(get_local $5)
(i32.const 2)
)
)
)
)
)
)
)
(func $~lib/typedarray/Int32Array#subarray (; 28 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
(local $3 i32)
(local $4 i32)
(local $5 i32)
(local $6 i32)
(local $7 i32)
(local $8 i32)
(return
(block $~lib/internal/typedarray/TypedArray<i32>#subarray|inlined.0 (result i32)
(set_local $3
(get_local $0)
)
(set_local $4
(get_local $1)
)
(set_local $5
(get_local $2)
)
(set_local $6
(call $~lib/internal/typedarray/TypedArray<i32>#get:length
(get_local $3)
)
)
(if
(i32.lt_s
(get_local $4)
(i32.const 0)
)
(set_local $4
(select
(tee_local $7
(i32.add
(get_local $6)
(get_local $4)
)
)
(tee_local $8
(i32.const 0)
)
(i32.gt_s
(get_local $7)
(get_local $8)
)
)
)
(set_local $4
(select
(tee_local $7
(get_local $4)
)
(tee_local $8
(get_local $6)
)
(i32.lt_s
(get_local $7)
(get_local $8)
)
)
)
)
(if
(i32.lt_s
(get_local $5)
(i32.const 0)
)
(set_local $5
(select
(tee_local $7
(i32.add
(get_local $6)
(get_local $5)
)
)
(tee_local $8
(get_local $4)
)
(i32.gt_s
(get_local $7)
(get_local $8)
)
)
)
(set_local $5
(select
(tee_local $7
(select
(tee_local $7
(get_local $5)
)
(tee_local $8
(get_local $6)
)
(i32.lt_s
(get_local $7)
(get_local $8)
)
)
)
(tee_local $8
(get_local $4)
)
(i32.gt_s
(get_local $7)
(get_local $8)
)
)
)
)
(set_local $7
(call $~lib/allocator/arena/allocate_memory
(i32.const 12)
)
)
(i32.store
(get_local $7)
(i32.load
(get_local $3)
)
)
(i32.store offset=4
(get_local $7)
(i32.shl
(get_local $4)
(i32.const 2)
)
)
(i32.store offset=8
(get_local $7)
(i32.shl
(get_local $5)
(i32.const 2)
)
)
(br $~lib/internal/typedarray/TypedArray<i32>#subarray|inlined.0
(get_local $7)
)
)
)
)
(func $start (; 29 ;) (type $v)
(if
(i32.eqz
(i32.eq
@ -2238,6 +2645,237 @@
(call $std/typedarray/testInstantiate
(i32.const 5)
)
(set_global $std/typedarray/arr
(call $~lib/internal/typedarray/TypedArray<i32>#constructor
(i32.const 0)
(i32.const 3)
)
)
(call $~lib/internal/typedarray/TypedArray<i32>#__set
(get_global $std/typedarray/arr)
(i32.const 0)
(i32.const 1)
)
(call $~lib/internal/typedarray/TypedArray<i32>#__set
(get_global $std/typedarray/arr)
(i32.const 1)
(i32.const 2)
)
(call $~lib/internal/typedarray/TypedArray<i32>#__set
(get_global $std/typedarray/arr)
(i32.const 2)
(i32.const 3)
)
(if
(i32.eqz
(i32.eq
(call $~lib/internal/typedarray/TypedArray<i32>#get:length
(get_global $std/typedarray/arr)
)
(i32.const 3)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 74)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(i32.eq
(i32.load offset=4
(get_global $std/typedarray/arr)
)
(i32.const 0)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 75)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(i32.eq
(i32.load offset=8
(get_global $std/typedarray/arr)
)
(i32.mul
(i32.const 3)
(i32.const 4)
)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 76)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(i32.eq
(call $~lib/internal/typedarray/TypedArray<i32>#__get
(get_global $std/typedarray/arr)
(i32.const 0)
)
(i32.const 1)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 77)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(i32.eq
(call $~lib/internal/typedarray/TypedArray<i32>#__get
(get_global $std/typedarray/arr)
(i32.const 1)
)
(i32.const 2)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 78)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(i32.eq
(call $~lib/internal/typedarray/TypedArray<i32>#__get
(get_global $std/typedarray/arr)
(i32.const 2)
)
(i32.const 3)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 79)
(i32.const 0)
)
(unreachable)
)
)
(set_global $std/typedarray/arr
(call $~lib/typedarray/Int32Array#subarray
(get_global $std/typedarray/arr)
(i32.const 1)
(i32.const 2)
)
)
(if
(i32.eqz
(i32.eq
(call $~lib/internal/typedarray/TypedArray<i32>#get:length
(get_global $std/typedarray/arr)
)
(i32.const 1)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 82)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(i32.eq
(i32.load offset=4
(get_global $std/typedarray/arr)
)
(i32.mul
(i32.const 1)
(i32.const 4)
)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 83)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(i32.eq
(i32.load offset=8
(get_global $std/typedarray/arr)
)
(i32.mul
(i32.const 2)
(i32.const 4)
)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 84)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(i32.eq
(call $~lib/internal/typedarray/TypedArray<i32>#__get
(get_global $std/typedarray/arr)
(i32.const 0)
)
(i32.const 2)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 85)
(i32.const 0)
)
(unreachable)
)
)
(drop
(call $~lib/internal/typedarray/TypedArray<f64>#constructor
(i32.const 0)