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.range = range;
stmt.name = expression; expression.parent = stmt; stmt.name = expression; expression.parent = stmt;
stmt.arguments = args; if (args) setParent(args, stmt); stmt.arguments = args; if (args) setParent(args, stmt);
if (expression.kind == NodeKind.IDENTIFIER) { stmt.decoratorKind = expression.kind == NodeKind.IDENTIFIER
switch ((<IdentifierExpression>expression).text) { ? stringToDecoratorKind((<IdentifierExpression>expression).text)
case "global": { : DecoratorKind.CUSTOM;
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;
}
return stmt; return stmt;
} }
@ -1075,7 +1052,22 @@ export enum DecoratorKind {
GLOBAL, GLOBAL,
OPERATOR, OPERATOR,
UNMANAGED, 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. */ /** Represents a decorator. */

View File

@ -43,7 +43,8 @@ import {
Global, Global,
FunctionPrototype, FunctionPrototype,
Class, Class,
Field Field,
OperatorKind
} from "./program"; } from "./program";
/** Compiles a get of a built-in global. */ /** Compiles a get of a built-in global. */
@ -146,7 +147,7 @@ export function compileCall(
compiler.currentType = Type.bool; compiler.currentType = Type.bool;
if (!type) return module.createUnreachable(); if (!type) return module.createUnreachable();
let classType = type.classReference; 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(1)
: module.createI32(0); : module.createI32(0);
} }
@ -1738,6 +1739,7 @@ export function compileCall(
DiagnosticCode.Expected_0_type_arguments_but_got_1, DiagnosticCode.Expected_0_type_arguments_but_got_1,
reportNode.range, "1", typeArguments ? typeArguments.length.toString(10) : "0" reportNode.range, "1", typeArguments ? typeArguments.length.toString(10) : "0"
); );
return module.createUnreachable();
} }
let byteSize = (<Type[]>typeArguments)[0].byteSize; let byteSize = (<Type[]>typeArguments)[0].byteSize;
let alignLog2: i32; 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, Basic_type_0_cannot_be_nullable = 204,
Cannot_export_a_mutable_global = 205, Cannot_export_a_mutable_global = 205,
Compiling_constant_with_non_constant_initializer_as_mutable = 206, Compiling_constant_with_non_constant_initializer_as_mutable = 206,
Structs_cannot_extend_classes_and_vice_versa = 207, Unmanaged_classes_cannot_extend_managed_classes_and_vice_versa = 207,
Structs_cannot_implement_interfaces = 208, Unmanaged_classes_cannot_implement_interfaces = 208,
Invalid_regular_expression_flags = 209, Invalid_regular_expression_flags = 209,
Implementation_0_must_match_the_signature_1 = 210, Implementation_0_must_match_the_signature_1 = 210,
Class_0_is_sealed_and_cannot_be_extended = 211, Class_0_is_sealed_and_cannot_be_extended = 211,
Decorator_0_is_not_valid_here = 212,
Duplicate_decorator = 213,
Unterminated_string_literal = 1002, Unterminated_string_literal = 1002,
Identifier_expected = 1003, Identifier_expected = 1003,
_0_expected = 1005, _0_expected = 1005,
@ -122,11 +124,13 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
case 204: return "Basic type '{0}' cannot be nullable."; case 204: return "Basic type '{0}' cannot be nullable.";
case 205: return "Cannot export a mutable global."; case 205: return "Cannot export a mutable global.";
case 206: return "Compiling constant with non-constant initializer as mutable."; case 206: return "Compiling constant with non-constant initializer as mutable.";
case 207: return "Structs cannot extend classes and vice-versa."; case 207: return "Unmanaged classes cannot extend managed classes and vice-versa.";
case 208: return "Structs cannot implement interfaces."; case 208: return "Unmanaged classes cannot implement interfaces.";
case 209: return "Invalid regular expression flags."; case 209: return "Invalid regular expression flags.";
case 210: return "Implementation '{0}' must match the signature '{1}'."; case 210: return "Implementation '{0}' must match the signature '{1}'.";
case 211: return "Class '{0}' is sealed and cannot be extended."; 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 1002: return "Unterminated string literal.";
case 1003: return "Identifier expected."; case 1003: return "Identifier expected.";
case 1005: return "'{0}' expected."; case 1005: return "'{0}' expected.";

View File

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

View File

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

View File

@ -75,7 +75,8 @@ import {
ParameterNode, ParameterNode,
ParameterKind, ParameterKind,
ExportMember, ExportMember,
SwitchCase SwitchCase,
DeclarationStatement
} from "../ast"; } from "../ast";
import { import {
@ -912,7 +913,6 @@ export class ASTBuilder {
} }
visitFieldDeclaration(node: FieldDeclaration): void { visitFieldDeclaration(node: FieldDeclaration): void {
this.serializeBuiltinDecorators(node);
var decorators = node.decorators; var decorators = node.decorators;
if (decorators) { if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) { for (let i = 0, k = decorators.length; i < k; ++i) {
@ -961,7 +961,6 @@ export class ASTBuilder {
visitFunctionDeclaration(node: FunctionDeclaration): void { visitFunctionDeclaration(node: FunctionDeclaration): void {
var sb = this.sb; var sb = this.sb;
this.serializeBuiltinDecorators(node);
var decorators = node.decorators; var decorators = node.decorators;
if (decorators) { if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) { for (let i = 0, k = decorators.length; i < k; ++i) {
@ -1098,7 +1097,6 @@ export class ASTBuilder {
} }
visitInterfaceDeclaration(node: InterfaceDeclaration): void { visitInterfaceDeclaration(node: InterfaceDeclaration): void {
this.serializeBuiltinDecorators(node);
var decorators = node.decorators; var decorators = node.decorators;
if (decorators) { if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) { for (let i = 0, k = decorators.length; i < k; ++i) {
@ -1138,7 +1136,6 @@ export class ASTBuilder {
} }
visitMethodDeclaration(node: MethodDeclaration): void { visitMethodDeclaration(node: MethodDeclaration): void {
this.serializeBuiltinDecorators(node);
var decorators = node.decorators; var decorators = node.decorators;
if (decorators) { if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) { for (let i = 0, k = decorators.length; i < k; ++i) {
@ -1155,7 +1152,6 @@ export class ASTBuilder {
} }
visitNamespaceDeclaration(node: NamespaceDeclaration): void { visitNamespaceDeclaration(node: NamespaceDeclaration): void {
this.serializeBuiltinDecorators(node);
var decorators = node.decorators; var decorators = node.decorators;
if (decorators) { if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) { for (let i = 0, k = decorators.length; i < k; ++i) {
@ -1315,7 +1311,6 @@ export class ASTBuilder {
} }
visitVariableStatement(node: VariableStatement): void { visitVariableStatement(node: VariableStatement): void {
this.serializeBuiltinDecorators(node);
var decorators = node.decorators; var decorators = node.decorators;
if (decorators) { if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) { 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 { serializeExternalModifiers(node: Node): void {
var sb = this.sb; var sb = this.sb;
if (node.is(CommonFlags.EXPORT)) { 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 // helpers
// can't do stack allocation here: STACKTOP is a global in WASM but a hidden variable in asm.js // 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"; } from "./util";
import { import {
Node, Node,
NodeKind, NodeKind,
Source, Source,
@ -162,23 +161,10 @@ export class Parser extends DiagnosticEmitter {
while (tn.skip(Token.AT)) { while (tn.skip(Token.AT)) {
if (startPos < 0) startPos = tn.tokenPos; if (startPos < 0) startPos = tn.tokenPos;
let decorator = this.parseDecorator(tn); let decorator = this.parseDecorator(tn);
if (!decorator) break; if (!decorator) {
let name = decorator.name; this.skipStatement(tn);
if (name.kind == NodeKind.IDENTIFIER) {
let text = (<IdentifierExpression>name).text;
if (text == "global") {
flags |= CommonFlags.GLOBAL;
continue; continue;
} }
if (text == "unmananged") {
flags |= CommonFlags.UNMANAGED;
continue;
}
if (text == "sealed") {
flags |= CommonFlags.SEALED;
continue;
}
}
if (!decorators) decorators = []; if (!decorators) decorators = [];
decorators.push(decorator); decorators.push(decorator);
} }

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -80,7 +80,9 @@ export const enum TypeFlags {
/** Is a reference type. */ /** Is a reference type. */
REFERENCE = 1 << 8, REFERENCE = 1 << 8,
/** Is a nullable type. */ /** Is a nullable type. */
NULLABLE = 1 << 9 NULLABLE = 1 << 9,
/** Is the special 'this' type. */
THIS = 1 << 10
} }
/** Represents a resolved type. */ /** Represents a resolved type. */
@ -102,6 +104,8 @@ export class Type {
nullableType: Type | null = null; nullableType: Type | null = null;
/** Respective non-nullable type, if nullable. */ /** Respective non-nullable type, if nullable. */
nonNullableType: Type; nonNullableType: Type;
/** Respective special 'this' type. */
thisType: Type | null = null;
/** Constructs a new resolved type. */ /** Constructs a new resolved type. */
constructor(kind: TypeKind, flags: TypeFlags, size: i32) { constructor(kind: TypeKind, flags: TypeFlags, size: i32) {
@ -157,6 +161,18 @@ export class Type {
return this.nullableType; 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. */ /** Tests if a value of this type is assignable to a target of the specified type. */
isAssignableTo(target: Type, signednessIsImportant: bool = false): bool { isAssignableTo(target: Type, signednessIsImportant: bool = false): bool {
var currentClass: Class | null; 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; readonly byteLength: i32;
/** The length (in elements). */ /** The length (in elements). */
readonly length: i32; 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. */ /** 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. */ /** Annotates a class as being sealed / non-derivable. */
declare function sealed(target: Function): any; declare function sealed(target: Function): any;
/** Annotates a class field with an explicit offset. */ /** Annotates a method or function as always inlined. */
declare function offset(offset: usize): any; 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 { import {
defaultComparator, defaultComparator,
insertionSort, insertionSort,
@ -6,147 +15,130 @@ import {
export class Array<T> { export class Array<T> {
__memory: usize; /* @internal */ buffer_: ArrayBuffer;
__capacity: i32; // capped to [0, 0x7fffffff] /* @internal */ length_: i32;
__length: i32; // capped to [0, __capacity]
private __grow(newCapacity: i32): void { constructor(length: i32 = 0) {
var oldMemory = this.__memory; const MAX_LENGTH = MAX_BLENGTH >>> alignof<T>();
var oldCapacity = this.__capacity; if (<u32>length > <u32>MAX_LENGTH) throw new RangeError("Invalid array length");
assert(newCapacity > oldCapacity); this.buffer_ = allocUnsafe(length << alignof<T>());
var newMemory = allocate_memory(<usize>newCapacity * sizeof<T>()); this.length_ = length;
if (oldMemory) {
move_memory(newMemory, oldMemory, <usize>oldCapacity * sizeof<T>());
free_memory(oldMemory);
}
this.__memory = newMemory;
this.__capacity = newCapacity;
} }
constructor(capacity: i32 = 0) { get length(): i32 {
if (capacity < 0) throw new RangeError("Invalid array length"); return this.length_;
this.__memory = capacity }
? allocate_memory(<usize>capacity * sizeof<T>())
: 0; set length(length: i32) {
this.__capacity = capacity; var buffer = this.buffer_;
this.__length = capacity; 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 { every(callbackfn: (element: T, index: i32, array: Array<T>) => bool): bool {
var toIndex: i32 = this.__length; var buffer = this.buffer_;
var i: i32 = 0; for (let index = 0, toIndex = this.length_; index < toIndex && index < this.length_; ++index) {
while (i < toIndex && i < this.__length) { if (!callbackfn(loadUnsafe<T>(buffer, index), index, this)) return false;
if (!callbackfn(load<T>(this.__memory + <usize>i * sizeof<T>()), i, this)) {
return false;
}
i += 1;
} }
return true; return true;
} }
findIndex(predicate: (element: T, index: i32, array: Array<T>) => bool): i32 { findIndex(predicate: (element: T, index: i32, array: Array<T>) => bool): i32 {
var toIndex: i32 = this.__length; var buffer = this.buffer_;
var i: i32 = 0; for (let index = 0, toIndex = this.length_; index < toIndex && index < this.length_; ++index) {
while (i < toIndex && i < this.__length) { if (predicate(loadUnsafe<T>(buffer, index), index, this)) return index;
if (predicate(load<T>(this.__memory + <usize>i * sizeof<T>()), i, this)) {
return i;
}
i += 1;
} }
return -1; 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("[]") @operator("[]")
private __get(index: i32): T { private __get(index: i32): T {
if (<u32>index >= <u32>this.__capacity) throw new Error("Index out of bounds"); var buffer = this.buffer_;
return load<T>(this.__memory + <usize>index * sizeof<T>()); 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("[]=") @operator("[]=")
private __set(index: i32, value: T): void { private __set(index: i32, value: T): void {
if (index < 0) throw new Error("Index out of bounds"); var buffer = this.buffer_;
var capacity = this.__capacity; var capacity = buffer.byteLength >>> alignof<T>();
if (index >= capacity) this.__grow(max(index + 1, capacity << 1)); if (<u32>index >= <u32>capacity) {
store<T>(this.__memory + <usize>index * sizeof<T>(), value); 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 { includes(searchElement: T, fromIndex: i32 = 0): bool {
var length = this.__length; var length = this.length_;
if (length == 0 || fromIndex >= length) return false; if (length == 0 || fromIndex >= length) return false;
if (fromIndex < 0) { if (fromIndex < 0) fromIndex = max(length + fromIndex, 0);
fromIndex = length + fromIndex; var buffer = this.buffer_;
if (fromIndex < 0) {
fromIndex = 0;
}
}
while (fromIndex < length) { while (fromIndex < length) {
if (load<T>(this.__memory + <usize>fromIndex * sizeof<T>()) == searchElement) return true; if (loadUnsafe<T>(buffer, fromIndex) == searchElement) return true;
++fromIndex; ++fromIndex;
} }
return false; return false;
} }
indexOf(searchElement: T, fromIndex: i32 = 0): i32 { indexOf(searchElement: T, fromIndex: i32 = 0): i32 {
var length = this.__length; var length = this.length_;
if (length == 0 || fromIndex >= length) { if (length == 0 || fromIndex >= length) return -1;
return -1; if (fromIndex < 0) fromIndex = max(length + fromIndex, 0);
} var buffer = this.buffer_;
if (fromIndex < 0) {
fromIndex = length + fromIndex;
if (fromIndex < 0) {
fromIndex = 0;
}
}
var memory = this.__memory;
while (fromIndex < length) { while (fromIndex < length) {
if (load<T>(memory + <usize>fromIndex * sizeof<T>()) == searchElement) return fromIndex; if (loadUnsafe<T>(buffer, fromIndex) == searchElement) return fromIndex;
++fromIndex; ++fromIndex;
} }
return -1; return -1;
} }
lastIndexOf(searchElement: T, fromIndex: i32 = this.__length): i32 { lastIndexOf(searchElement: T, fromIndex: i32 = this.length_): i32 {
var length = this.__length; var length = this.length_;
if (length == 0) return -1; if (length == 0) return -1;
if (fromIndex < 0) { if (fromIndex < 0) fromIndex = length + fromIndex; // no need to clamp
fromIndex = length + fromIndex; else if (fromIndex >= length) fromIndex = length - 1;
} else if (fromIndex >= length) { var buffer = this.buffer_;
fromIndex = length - 1; while (fromIndex >= 0) { // ^
} if (loadUnsafe<T>(buffer, fromIndex) == searchElement) return fromIndex;
var memory = this.__memory;
while (fromIndex >= 0) {
if (load<T>(memory + <usize>fromIndex * sizeof<T>()) == searchElement) return fromIndex;
--fromIndex; --fromIndex;
} }
return -1; return -1;
} }
push(element: T): i32 { push(element: T): i32 {
var capacity = this.__capacity; var length = this.length_;
var length = this.__length; var buffer = this.buffer_;
if (length == capacity) { var capacity = buffer.byteLength >>> alignof<T>();
this.__grow(capacity ? capacity << 1 : 1); 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_ = newLength;
this.__length = ++length; storeUnsafe<T>(buffer, length, element);
return length; return newLength;
} }
pop(): T { pop(): T {
var length = this.__length; var length = this.length_;
if (length < 1) throw new RangeError("Array is empty"); if (length < 1) throw new RangeError("Array is empty");
var element = load<T>(this.__memory + <usize>--length * sizeof<T>()); var element = loadUnsafe<T>(this.buffer_, --length);
this.__length = length; this.length_ = length;
return element; return element;
} }
@ -154,158 +146,119 @@ export class Array<T> {
callbackfn: (previousValue: U, currentValue: T, currentIndex: i32, array: Array<T>) => U, callbackfn: (previousValue: U, currentValue: T, currentIndex: i32, array: Array<T>) => U,
initialValue: U initialValue: U
): U { ): U {
var accumulator: U = initialValue; var accum = initialValue;
var toIndex: i32 = this.__length; var buffer = this.buffer_;
var i: i32 = 0; for (let index = 0, toIndex = this.length_; index < toIndex && index < this.length_; ++index) {
while (i < toIndex && i < /* might change */ this.__length) { accum = callbackfn(accum, loadUnsafe<T>(buffer, index), index, this);
accumulator = callbackfn(accumulator, load<T>(this.__memory + <usize>i * sizeof<T>()), i, this);
i += 1;
} }
return accumulator; return accum;
} }
shift(): T { shift(): T {
var length = this.__length; var length = this.length_;
if (length < 1) throw new RangeError("Array is empty"); if (length < 1) throw new RangeError("Array is empty");
var memory = this.__memory; var buffer = this.buffer_;
var capacity = this.__capacity; var element = loadUnsafe<T>(buffer, 0);
var element = load<T>(memory); var lastIndex = length - 1;
move_memory( move_memory(
memory, changetype<usize>(buffer) + HEADER_SIZE_AB,
memory + sizeof<T>(), changetype<usize>(buffer) + HEADER_SIZE_AB + sizeof<T>(),
<usize>(capacity - 1) * sizeof<T>() <usize>lastIndex << alignof<T>()
); );
set_memory( storeUnsafe<T>(buffer, lastIndex, isReference<T>() ? null : <T>0);
memory + <usize>(capacity - 1) * sizeof<T>(), this.length_ = lastIndex;
0,
sizeof<T>()
);
this.__length = length - 1;
return element; return element;
} }
some(callbackfn: (element: T, index: i32, array: Array<T>) => bool): bool { some(callbackfn: (element: T, index: i32, array: Array<T>) => bool): bool {
var toIndex: i32 = this.__length; var buffer = this.buffer_;
var i: i32 = 0; for (let index = 0, toIndex = this.length_; index < toIndex && index < this.length_; ++index) {
while (i < toIndex && i < /* might change */ this.__length) { if (callbackfn(loadUnsafe<T>(buffer, index), index, this)) return true;
if (callbackfn(load<T>(this.__memory + <usize>i * sizeof<T>()), i, this)) return true;
i += 1;
} }
return false; return false;
} }
unshift(element: T): i32 { unshift(element: T): i32 {
var memory = this.__memory; var buffer = this.buffer_;
var capacity = this.__capacity; var capacity = buffer.byteLength >>> alignof<T>();
var length = this.__length; var length = this.length_;
if (this.__length == capacity) { var newLength = length + 1; // safe only if length is checked
// inlined __grow (avoids moving twice) if (<u32>length >= <u32>capacity) {
let newCapacity: i32 = capacity ? capacity << 1 : 1; const MAX_LENGTH = MAX_BLENGTH >>> alignof<T>();
assert(newCapacity > capacity); if (<u32>length >= <u32>MAX_LENGTH) throw new Error("Invalid array length");
let newMemory = allocate_memory(<usize>newCapacity * sizeof<T>()); buffer = reallocUnsafe(buffer, newLength << alignof<T>());
if (memory) { capacity = buffer.byteLength >>> alignof<T>();
move_memory( this.buffer_ = buffer;
newMemory + sizeof<T>(),
memory,
<usize>capacity * sizeof<T>()
);
free_memory(memory);
} }
this.__memory = newMemory;
this.__capacity = newCapacity;
memory = newMemory;
} else {
move_memory( move_memory(
memory + sizeof<T>(), changetype<usize>(buffer) + HEADER_SIZE_AB + sizeof<T>(),
memory, changetype<usize>(buffer) + HEADER_SIZE_AB,
<usize>capacity * sizeof<T>() <usize>(capacity - 1) << alignof<T>()
); );
} storeUnsafe<T>(buffer, 0, element);
store<T>(memory, element); this.length_ = newLength;
this.__length = ++length; return newLength;
return length;
} }
slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Array<T> { slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Array<T> {
var length = this.__length; var length = this.length_;
if (begin < 0) { if (begin < 0) begin = max(length + begin, 0);
begin = length + begin; else if (begin > length) begin = length;
if (begin < 0) { if (end < 0) end = length + end; // no need to clamp
begin = 0; else if (end > length) end = length;
} if (end < begin) end = begin; // ^
} else if (begin > length) { var newLength = end - begin;
begin = length; assert(newLength >= 0);
} var sliced = new Array<T>(newLength);
if (end < 0) { if (newLength) {
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) {
move_memory( move_memory(
sliced.__memory, changetype<usize>(sliced.buffer_) + HEADER_SIZE_AB,
this.__memory + <usize>begin * sizeof<T>(), changetype<usize>(this.buffer_) + HEADER_SIZE_AB + (<usize>begin << alignof<T>()),
<usize>capacity * sizeof<T>() <usize>newLength << alignof<T>()
); );
} }
return sliced; return sliced;
} }
splice(start: i32, deleteCount: i32 = i32.MAX_VALUE): void { splice(start: i32, deleteCount: i32 = i32.MAX_VALUE): void {
if (deleteCount < 1) { if (deleteCount < 1) return;
return; var length = this.length_;
} if (start < 0) start = max(length + start, 0);
var length = this.__length; if (start >= length) return;
if (start < 0) {
start = length + start;
if (start < 0) {
start = 0;
} else if (start >= length) {
return;
}
} else if (start >= length) {
return;
}
deleteCount = min(deleteCount, length - start); deleteCount = min(deleteCount, length - start);
var memory = this.__memory; var buffer = this.buffer_;
move_memory( move_memory(
memory + <usize>start * sizeof<T>(), changetype<usize>(buffer) + HEADER_SIZE_AB + (<usize>start << alignof<T>()),
memory + <usize>(start + deleteCount) * sizeof<T>(), changetype<usize>(buffer) + HEADER_SIZE_AB + (<usize>(start + deleteCount) << alignof<T>()),
<usize>deleteCount * sizeof<T>() <usize>deleteCount << alignof<T>()
); );
this.__length = length - deleteCount; this.length_ = length - deleteCount;
} }
reverse(): Array<T> { reverse(): Array<T> {
var memory = this.__memory; var buffer = this.buffer_;
for (let front: usize = 0, back: usize = <usize>this.__length - 1; front < back; ++front, --back) { for (let front = 0, back = this.length_ - 1; front < back; ++front, --back) {
let temp = load<T>(memory + front * sizeof<T>()); let temp = loadUnsafe<T>(buffer, front);
store<T>(memory + front * sizeof<T>(), load<T>(memory + back * sizeof<T>())); storeUnsafe<T>(buffer, front, loadUnsafe<T>(buffer, back));
store<T>(memory + back * sizeof<T>(), temp); storeUnsafe<T>(buffer, back, temp);
} }
return this; return this;
} }
sort(comparator: (a: T, b: T) => i32 = defaultComparator<T>()): Array<T> { sort(comparator: (a: T, b: T) => i32 = defaultComparator<T>()): Array<T> {
var len = this.length; var length = this.length_;
if (len <= 1) return this; if (length <= 1) return this;
if (len == 2) { var buffer = this.buffer_;
let memory = this.__memory; if (length == 2) {
let a = load<T>(memory, sizeof<T>()); // var a = <T>arr[1]; let a = loadUnsafe<T>(buffer, 1); // a = arr[1]
let b = load<T>(memory, 0); // var b = <T>arr[0]; let b = loadUnsafe<T>(buffer, 0); // b = arr[0]
if (comparator(a, b) < 0) { if (comparator(a, b) < 0) {
store<T>(memory, b, sizeof<T>()); // arr[1] = b; storeUnsafe<T>(buffer, 1, b); // arr[1] = b;
store<T>(memory, a, 0); // arr[0] = a; storeUnsafe<T>(buffer, 0, a); // arr[0] = a;
} }
return this; return this;
} }
return len <= 256 return length < 256
? insertionSort<T>(this, comparator) ? insertionSort<T>(this, comparator)
: weakHeapSort<T>(this, comparator); : weakHeapSort<T>(this, comparator);
} }

View File

@ -28,3 +28,12 @@ export class ArrayBuffer {
return buffer; 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. */ /** Obtains the default comparator for the specified type. */
export function defaultComparator<T>(): (a: T, b: T) => i32 { 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. */ /** Sorts an Array with the 'Insertion Sort' algorithm. */
export function insertionSort<T>(arr: Array<T>, comparator: (a: T, b: T) => i32): Array<T> { export function insertionSort<T>(arr: Array<T>, comparator: (a: T, b: T) => i32): Array<T> {
const shiftT = alignof<T>(); var buffer = arr.buffer_;
for (let i: i32 = 0, length: i32 = arr.length; i < length; i++) {
var memory = arr.__memory; let a = loadUnsafe<T>(buffer, i); // a = arr[i]
for (let i: i32 = 0, len: i32 = arr.length; i < len; i++) {
let a = load<T>(memory + (i << shiftT)); // a = arr[i]
let j = i - 1; let j = i - 1;
while (j >= 0) { 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) { 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; } 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; return arr;
} }
/** Sorts an Array with the 'Weak Heap Sort' algorithm. */ /** Sorts an Array with the 'Weak Heap Sort' algorithm. */
export function weakHeapSort<T>(arr: Array<T>, comparator: (a: T, b: T) => i32): Array<T> { export function weakHeapSort<T>(arr: Array<T>, comparator: (a: T, b: T) => i32): Array<T> {
const shiftT = alignof<T>();
const shift32 = alignof<i32>(); const shift32 = alignof<i32>();
var length = arr.length; 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 // 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--) { for (let i = length - 1; i > 0; i--) {
let j = i; let j = i;
while ((j & 1) == (load<i32>(bitset + (j >> 6 << shift32)) >> (j >> 1 & 31) & 1)) j >>= 1; while ((j & 1) == (load<i32>(bitset + (j >> 6 << shift32)) >> (j >> 1 & 31) & 1)) j >>= 1;
let p = j >> 1; let p = j >> 1;
let a = load<T>(memory + (p << shiftT)); // a = arr[p] let a = loadUnsafe<T>(buffer, p); // a = arr[p]
let b = load<T>(memory + (i << shiftT)); // b = arr[i] let b = loadUnsafe<T>(buffer, i); // b = arr[i]
if (comparator(a, b) < 0) { if (comparator(a, b) < 0) {
store<i32>( store<i32>(
bitset + (i >> 5 << shift32), bitset + (i >> 5 << shift32),
load<i32>(bitset + (i >> 5 << shift32)) ^ (1 << (i & 31)) load<i32>(bitset + (i >> 5 << shift32)) ^ (1 << (i & 31))
); );
store<T>(memory + (i << shiftT), a); // arr[i] = a storeUnsafe<T>(buffer, i, a); // arr[i] = a
store<T>(memory + (p << shiftT), b); // arr[p] = b storeUnsafe<T>(buffer, p, b); // arr[p] = b
} }
} }
for (let i = length - 1; i >= 2; i--) { for (let i = length - 1; i >= 2; i--) {
let a = load<T>(memory, 0); // a = arr[0] let a = loadUnsafe<T>(buffer, 0); // a = arr[0]
store<T>(memory, load<T>(memory + (i << shiftT)), 0); // arr[0] = arr[1] storeUnsafe<T>(buffer, 0, loadUnsafe<T>(buffer, i)); // arr[0] = arr[i]
store<T>(memory + (i << shiftT), a); // arr[1] = a storeUnsafe<T>(buffer, i, a); // arr[i] = a
let x = 1, y: i32; let x = 1, y: i32;
while ((y = (x << 1) + ((load<i32>(bitset + (x >> 5 << shift32)) >> (x & 31)) & 1)) < i) x = y; while ((y = (x << 1) + ((load<i32>(bitset + (x >> 5 << shift32)) >> (x & 31)) & 1)) < i) x = y;
while (x > 0) { while (x > 0) {
a = load<T>(memory, 0); // a = arr[0] a = loadUnsafe<T>(buffer, 0); // a = arr[0]
let b = load<T>(memory + (x << shiftT)); // b = arr[x] let b = loadUnsafe<T>(buffer, x); // b = arr[x]
if (comparator(a, b) < 0) { if (comparator(a, b) < 0) {
store<i32>( store<i32>(
bitset + (x >> 5 << shift32), bitset + (x >> 5 << shift32),
load<i32>(bitset + (x >> 5 << shift32)) ^ (1 << (x & 31)) load<i32>(bitset + (x >> 5 << shift32)) ^ (1 << (x & 31))
); );
store<T>(memory + (x << shiftT), a); // arr[x] = a storeUnsafe<T>(buffer, x, a); // arr[x] = a
store<T>(memory, b, 0); // arr[0] = b storeUnsafe<T>(buffer, 0, b); // arr[0] = b
} }
x >>= 1; x >>= 1;
} }
@ -80,8 +84,8 @@ export function weakHeapSort<T>(arr: Array<T>, comparator: (a: T, b: T) => i32):
free_memory(bitset); free_memory(bitset);
var t = load<T>(memory, sizeof<T>()); // t = arr[1] var t = loadUnsafe<T>(buffer, 1); // t = arr[1]
store<T>(memory, load<T>(memory, 0), sizeof<T>()); // arr[1] = arr[0] storeUnsafe<T>(buffer, 1, loadUnsafe<T>(buffer, 0)); // arr[1] = arr[0]
store<T>(memory, t, 0); // arr[0] = t storeUnsafe<T>(buffer, 0, t); // arr[0] = t
return arr; return arr;
} }

View File

@ -30,11 +30,10 @@ export function reallocUnsafe(buffer: ArrayBuffer, newByteLength: i32): ArrayBuf
var oldByteLength = buffer.byteLength; var oldByteLength = buffer.byteLength;
if (newByteLength > oldByteLength) { if (newByteLength > oldByteLength) {
assert(newByteLength <= MAX_BLENGTH); assert(newByteLength <= MAX_BLENGTH);
let oldSize = computeSize(oldByteLength); if (newByteLength <= <i32>(computeSize(oldByteLength) - HEADER_SIZE)) { // fast path: zero out additional space
if (<i32>(oldSize - HEADER_SIZE) <= newByteLength) { // fast path: zero out additional space
store<i32>(changetype<usize>(buffer), newByteLength, offsetof<ArrayBuffer>("byteLength")); store<i32>(changetype<usize>(buffer), newByteLength, offsetof<ArrayBuffer>("byteLength"));
set_memory( set_memory(
changetype<usize>(buffer) + HEADER_SIZE + oldByteLength, changetype<usize>(buffer) + HEADER_SIZE + <usize>oldByteLength,
0, 0,
<usize>(newByteLength - oldByteLength) <usize>(newByteLength - oldByteLength)
); );
@ -43,7 +42,12 @@ export function reallocUnsafe(buffer: ArrayBuffer, newByteLength: i32): ArrayBuf
move_memory( move_memory(
changetype<usize>(newBuffer) + HEADER_SIZE, changetype<usize>(newBuffer) + HEADER_SIZE,
changetype<usize>(buffer) + 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; return newBuffer;
} }
@ -55,10 +59,22 @@ export function reallocUnsafe(buffer: ArrayBuffer, newByteLength: i32): ArrayBuf
return buffer; return buffer;
} }
/** Common typed array interface. Not a global object. */ @inline
// export declare interface ArrayBufferView<T> { export function loadUnsafe<T>(buffer: ArrayBuffer, index: i32): T {
// readonly buffer: ArrayBuffer; return load<T>(changetype<usize>(buffer) + (<usize>index << alignof<T>()), HEADER_SIZE);
// readonly byteOffset: i32; }
// readonly byteLength: i32;
// readonly length: i32; @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 { import {
HEADER_SIZE, HEADER_SIZE as HEADER_SIZE_AB,
MAX_BLENGTH, MAX_BLENGTH,
allocUnsafe allocUnsafe,
// ArrayBufferView loadUnsafeWithOffset,
storeUnsafeWithOffset
} from "./arraybuffer"; } from "./arraybuffer";
import {
ArrayBufferView
} from "../arraybuffer";
/** Typed array base class. Not a global object. */ /** 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 buffer: ArrayBuffer;
readonly byteOffset: i32; 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"); if (<u32>length > MAX_LENGTH) throw new RangeError("Invalid typed array length");
var byteLength = length << alignof<T>(); var byteLength = length << alignof<T>();
var buffer = allocUnsafe(byteLength); 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.buffer = buffer;
this.byteOffset = 0; this.byteOffset = 0;
this.byteLength = byteLength; this.byteLength = byteLength;
} }
get length(): i32 { 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 {
// @operator("[]=") - maybe injected through ArrayBufferView? var byteOffset = this.byteOffset;
var elementLength = (this.byteLength - byteOffset) >>> alignof<T>();
// copyWithin(target: i32, start: i32, end: i32 = 0x7fffffff): TypedArray<T> if (<u32>index >= <u32>elementLength) throw new Error("Index out of bounds");
return loadUnsafeWithOffset<T>(this.buffer, index, byteOffset);
// subarray(begin: i32 = 0, end: i32 = 0x7fffffff): TypedArray<T> }
@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 = this.length): this
@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> { export class Int8Array extends TypedArray<i8> {
static readonly BYTES_PER_ELEMENT: usize = sizeof<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> { export class Uint8Array extends TypedArray<u8> {
static readonly BYTES_PER_ELEMENT: usize = sizeof<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> { export class Int16Array extends TypedArray<i16> {
static readonly BYTES_PER_ELEMENT: usize = sizeof<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> { export class Uint16Array extends TypedArray<u16> {
static readonly BYTES_PER_ELEMENT: usize = sizeof<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> { export class Int32Array extends TypedArray<i32> {
static readonly BYTES_PER_ELEMENT: usize = sizeof<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> { export class Uint32Array extends TypedArray<u32> {
static readonly BYTES_PER_ELEMENT: usize = sizeof<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> { export class Int64Array extends TypedArray<i64> {
static readonly BYTES_PER_ELEMENT: usize = sizeof<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> { export class Uint64Array extends TypedArray<u64> {
static readonly BYTES_PER_ELEMENT: usize = sizeof<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> { export class Float32Array extends TypedArray<f32> {
static readonly BYTES_PER_ELEMENT: usize = sizeof<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> { export class Float64Array extends TypedArray<f64> {
static readonly BYTES_PER_ELEMENT: usize = sizeof<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); 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("mem final: " + exports.memory.buffer.byteLength);
console.log(); console.log();

View File

@ -33,9 +33,17 @@
(return (return
(i32.const 1) (i32.const 1)
) )
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 37)
(i32.const 4)
)
(unreachable) (unreachable)
) )
) )
)
(func $start (; 4 ;) (type $v) (func $start (; 4 ;) (type $v)
(if (if
(call $if/ifThenElse (call $if/ifThenElse

View File

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

View File

@ -2,16 +2,199 @@
(type $i (func (result i32))) (type $i (func (result i32)))
(type $iiiiv (func (param i32 i32 i32 i32))) (type $iiiiv (func (param i32 i32 i32 i32)))
(type $v (func)) (type $v (func))
(type $ii (func (param i32) (result i32)))
(import "env" "abort" (func $abort (param i32 i32 i32 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) (memory $0 1)
(data (i32.const 4) "\0b\00\00\00i\00n\00l\00i\00n\00i\00n\00g\00.\00t\00s") (data (i32.const 4) "\0b\00\00\00i\00n\00l\00i\00n\00i\00n\00g\00.\00t\00s")
(export "test" (func $inlining/test)) (export "test" (func $inlining/test))
(export "memory" (memory $0)) (export "memory" (memory $0))
(export "table" (table $0))
(start $start) (start $start)
(func $inlining/test (; 1 ;) (type $i) (result i32) (func $inlining/test (; 1 ;) (type $i) (result i32)
(i32.const 3) (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 (if
(i32.ne (i32.ne
(call $inlining/test) (call $inlining/test)
@ -21,11 +204,12 @@
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 4) (i32.const 4)
(i32.const 8) (i32.const 10)
(i32.const 0) (i32.const 0)
) )
(unreachable) (unreachable)
) )
) )
(call $inlining/test_funcs)
) )
) )

View File

@ -1,3 +1,5 @@
// Constant inlining
const constantGlobal = 1; const constantGlobal = 1;
export function test(): i32 { export function test(): i32 {
@ -6,3 +8,67 @@ export function test(): i32 {
} }
assert(test() == 3); 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 $i (func (result i32)))
(type $iiiiv (func (param i32 i32 i32 i32))) (type $iiiiv (func (param i32 i32 i32 i32)))
(type $v (func)) (type $v (func))
(type $ii (func (param i32) (result i32)))
(import "env" "abort" (func $abort (param i32 i32 i32 i32))) (import "env" "abort" (func $abort (param i32 i32 i32 i32)))
(global $inlining/constantGlobal i32 (i32.const 1)) (global $inlining/constantGlobal i32 (i32.const 1))
(global $argumentCount (mut i32) (i32.const 0))
(global $HEAP_BASE i32 (i32.const 32)) (global $HEAP_BASE i32 (i32.const 32))
(table 1 1 anyfunc)
(elem (i32.const 0) $inlining/test_funcs~anonymous|0)
(memory $0 1) (memory $0 1)
(data (i32.const 4) "\0b\00\00\00i\00n\00l\00i\00n\00i\00n\00g\00.\00t\00s\00") (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 "test" (func $inlining/test))
(export "memory" (memory $0)) (export "memory" (memory $0))
(export "table" (table $0))
(start $start) (start $start)
(func $inlining/test (; 1 ;) (type $i) (result i32) (func $inlining/test (; 1 ;) (type $i) (result i32)
(nop) (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 (if
(i32.eqz (i32.eqz
(i32.eq (i32.eq
@ -31,11 +412,12 @@
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 4) (i32.const 4)
(i32.const 8) (i32.const 10)
(i32.const 0) (i32.const 0)
) )
(unreachable) (unreachable)
) )
) )
(call $inlining/test_funcs)
) )
) )

View File

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

View File

@ -2,16 +2,21 @@
(type $ii (func (param i32) (result i32))) (type $ii (func (param i32) (result i32)))
(type $iii (func (param i32 i32) (result i32))) (type $iii (func (param i32 i32) (result i32)))
(type $i (func (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 $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))) (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 $~lib/internal/string/HEADER_SIZE i32 (i32.const 4))
(global $argumentCount (mut i32) (i32.const 0)) (global $argumentCount (mut i32) (i32.const 0))
(global $HEAP_BASE i32 (i32.const 52)) (global $HEAP_BASE i32 (i32.const 84))
(memory $0 1) (memory $0 1)
(data (i32.const 4) "\00\00\00\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 8) "\0e\00\00\00~\00l\00i\00b\00/\00s\00t\00r\00i\00n\00g\00.\00t\00s\00") (data (i32.const 36) "\00\00\00\00")
(data (i32.const 40) "\04\00\00\00n\00u\00l\00l\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 "i32ArrayArrayElementAccess" (func $std/array-access/i32ArrayArrayElementAccess))
(export "stringArrayPropertyAccess" (func $std/array-access/stringArrayPropertyAccess)) (export "stringArrayPropertyAccess" (func $std/array-access/stringArrayPropertyAccess))
(export "stringArrayMethodCall" (func $std/array-access/stringArrayMethodCall)) (export "stringArrayMethodCall" (func $std/array-access/stringArrayMethodCall))
@ -19,48 +24,110 @@
(export "stringArrayArrayMethodCall" (func $std/array-access/stringArrayArrayMethodCall)) (export "stringArrayArrayMethodCall" (func $std/array-access/stringArrayArrayMethodCall))
(export "memory" (memory $0)) (export "memory" (memory $0))
(func $~lib/array/Array<Array<i32>>#__get (; 1 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32) (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 (if
(i32.ge_u (i32.ge_u
(get_local $1) (get_local $1)
(i32.load offset=4 (get_local $3)
(get_local $0)
) )
(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 (return
(block $~lib/internal/arraybuffer/loadUnsafe<Array<i32>>|inlined.0 (result i32)
(set_local $4
(get_local $2)
)
(set_local $5
(get_local $1) (get_local $1)
(i32.const 4) )
(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) (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 (if
(i32.ge_u (i32.ge_u
(get_local $1) (get_local $1)
(i32.load offset=4 (get_local $3)
(get_local $0)
) )
(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 (return
(block $~lib/internal/arraybuffer/loadUnsafe<i32>|inlined.0 (result i32)
(set_local $4
(get_local $2)
)
(set_local $5
(get_local $1) (get_local $1)
(i32.const 4) )
(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) (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 (if
(i32.ge_u (i32.ge_u
(get_local $1) (get_local $1)
(i32.load offset=4 (get_local $3)
(get_local $0)
) )
(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 (return
(block $~lib/internal/arraybuffer/loadUnsafe<String>|inlined.0 (result i32)
(set_local $4
(get_local $2)
)
(set_local $5
(get_local $1) (get_local $1)
(i32.const 4) )
(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 (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 8) (i32.const 40)
(i32.const 234) (i32.const 234)
(i32.const 4) (i32.const 4)
) )
@ -207,7 +305,7 @@
(i32.const 0) (i32.const 0)
) )
(set_local $1 (set_local $1
(i32.const 40) (i32.const 72)
) )
) )
(set_local $3 (set_local $3
@ -319,31 +417,62 @@
(get_local $0) (get_local $0)
(i32.const 0) (i32.const 0)
) )
(i32.const 4) (i32.const 36)
(i32.const 0) (i32.const 0)
) )
) )
) )
) )
(func $~lib/array/Array<Array<String>>#__get (; 10 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32) (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 (if
(i32.ge_u (i32.ge_u
(get_local $1) (get_local $1)
(i32.load offset=4 (get_local $3)
(get_local $0)
) )
(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 (return
(block $~lib/internal/arraybuffer/loadUnsafe<Array<String>>|inlined.0 (result i32)
(set_local $4
(get_local $2)
)
(set_local $5
(get_local $1) (get_local $1)
(i32.const 4) )
(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 1)
) )
(i32.const 4) (i32.const 36)
(i32.const 0) (i32.const 0)
) )
) )

File diff suppressed because it is too large Load Diff

View File

@ -1,128 +1,61 @@
import "allocator/arena"; import "allocator/arena";
import { Array } from "array";
import { defaultComparator } from "internal/array";
// Default comparator // Obtains the internal capacity of an array from its backing buffer.
function createDefaultComparator<T>(): (a: T, b: T) => i32 { function internalCapacity<T>(array: Array<T>): i32 {
return (a: T, b: T): i32 => ( // the memory region used by the backing buffer might still be larger in that the ArrayBuffer
<i32>(a > b) - <i32>(a < b) // 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 var arr = new Array<i32>();
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;
}
// Check is equality for arrays // Array#push/pop //////////////////////////////////////////////////////////////////////////////////
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>()));
assert(arr.length == 0); assert(arr.length == 0);
assert(arr.__capacity == 0); assert(internalCapacity<i32>(arr) == 0);
arr.push(42); arr.push(42);
assert(arr[0] == 42); assert(arr[0] == 42);
assert(arr.length == 1); assert(arr.length == 1);
assert(arr.__capacity == 1); assert(internalCapacity<i32>(arr) == 1);
var i = arr.pop(); var i = arr.pop();
assert(i == 42); assert(i == 42);
assert(arr.length == 0); assert(arr.length == 0);
assert(arr.__capacity == 1); assert(internalCapacity<i32>(arr) == 1);
arr.push(43); arr.push(43);
assert(arr.length == 1); assert(arr.length == 1);
assert(arr.__capacity == 1); assert(internalCapacity<i32>(arr) == 1);
assert(arr[0] == 43); assert(arr[0] == 43);
arr.push(44); arr.push(44);
assert(arr.length == 2); assert(arr.length == 2);
assert(arr.__capacity == 2); assert(internalCapacity<i32>(arr) == 2);
assert(arr[0] == 43); assert(arr[0] == 43);
assert(arr[1] == 44); assert(arr[1] == 44);
arr.push(45); arr.push(45);
assert(arr.length == 3); assert(arr.length == 3);
assert(arr.__capacity == 4); assert(internalCapacity<i32>(arr) == 3);
assert(arr[0] == 43); assert(arr[0] == 43);
assert(arr[1] == 44); assert(arr[1] == 44);
assert(arr[2] == 45); assert(arr[2] == 45);
// Array#unshift ///////////////////////////////////////////////////////////////////////////////////
arr.unshift(42); arr.unshift(42);
assert(arr.length == 4); assert(arr.length == 4);
assert(arr.__capacity == 4); assert(internalCapacity<i32>(arr) == 4);
assert(arr[0] == 42); assert(arr[0] == 42);
assert(arr[1] == 43); assert(arr[1] == 43);
assert(arr[2] == 44); assert(arr[2] == 44);
@ -131,18 +64,20 @@ assert(arr[3] == 45);
arr.unshift(41); arr.unshift(41);
assert(arr.length == 5); assert(arr.length == 5);
assert(arr.__capacity == 8); assert(internalCapacity<i32>(arr) == 5);
assert(arr[0] == 41); assert(arr[0] == 41);
assert(arr[1] == 42); assert(arr[1] == 42);
assert(arr[2] == 43); assert(arr[2] == 43);
assert(arr[3] == 44); assert(arr[3] == 44);
assert(arr[4] == 45); assert(arr[4] == 45);
// Array#shift /////////////////////////////////////////////////////////////////////////////////////
i = arr.shift(); i = arr.shift();
assert(i == 41); assert(i == 41);
assert(arr.length == 4); assert(arr.length == 4);
assert(arr.__capacity == 8); assert(internalCapacity<i32>(arr) == 5);
assert(arr[0] == 42); assert(arr[0] == 42);
assert(arr[1] == 43); assert(arr[1] == 43);
assert(arr[2] == 44); assert(arr[2] == 44);
@ -152,15 +87,17 @@ i = arr.pop();
assert(i == 45); assert(i == 45);
assert(arr.length == 3); assert(arr.length == 3);
assert(arr.__capacity == 8); assert(internalCapacity<i32>(arr) == 5);
assert(arr[0] == 42); assert(arr[0] == 42);
assert(arr[1] == 43); assert(arr[1] == 43);
assert(arr[2] == 44); assert(arr[2] == 44);
// Array#reverse ///////////////////////////////////////////////////////////////////////////////////
arr.reverse(); arr.reverse();
assert(arr.length == 3); assert(arr.length == 3);
assert(arr.__capacity == 8); assert(internalCapacity<i32>(arr) == 5);
assert(arr[0] == 44); assert(arr[0] == 44);
assert(arr[1] == 43); assert(arr[1] == 43);
assert(arr[2] == 42); assert(arr[2] == 42);
@ -168,6 +105,8 @@ assert(arr[2] == 42);
arr.push(43); arr.push(43);
arr.push(44); arr.push(44);
// Array#indexOf ///////////////////////////////////////////////////////////////////////////////////
i = arr.indexOf(44); i = arr.indexOf(44);
assert(i == 0); assert(i == 0);
@ -208,6 +147,8 @@ i = arr.indexOf(43, 2);
assert(i == 3); assert(i == 3);
// Array#includes //////////////////////////////////////////////////////////////////////////////////
var includes = arr.includes(44); var includes = arr.includes(44);
assert(includes == true); assert(includes == true);
@ -251,16 +192,17 @@ assert(includes == true);
arr.splice(1, 1); arr.splice(1, 1);
assert(arr.length == 4); assert(arr.length == 4);
assert(arr.__capacity == 8); assert(internalCapacity<i32>(arr) == 5);
assert(arr[0] == 44); assert(arr[0] == 44);
assert(arr[1] == 42); assert(arr[1] == 42);
// Array#findIndex /////////////////////////////////////////////////////////////////////////////////
arr[0] = 0; arr[0] = 0;
arr[1] = 1; arr[1] = 1;
arr[2] = 2; arr[2] = 2;
arr[3] = 3; arr[3] = 3;
/*=============================== findIndex ==========================*/
i = arr.findIndex((value: i32, index: i32, array: Array<i32>): bool => value == 0); i = arr.findIndex((value: i32, index: i32, array: Array<i32>): bool => value == 0);
assert(i == 0); assert(i == 0);
@ -297,7 +239,9 @@ assert(arr.length == 2);
arr.push(2); arr.push(2);
arr.push(3); arr.push(3);
/*=============================== every ==========================*/
// Array#every /////////////////////////////////////////////////////////////////////////////////////
var every = arr.every((value: i32, index: i32, array: Array<i32>): bool => value >= 0); var every = arr.every((value: i32, index: i32, array: Array<i32>): bool => value >= 0);
assert(every == true); assert(every == true);
@ -331,7 +275,9 @@ assert(arr.length == 2);
arr.push(2); arr.push(2);
arr.push(3); arr.push(3);
/*=============================== some ==========================*/
// Array#some //////////////////////////////////////////////////////////////////////////////////////
var some = arr.some((value: i32, index: i32, array: Array<i32>): bool => value >= 3); var some = arr.some((value: i32, index: i32, array: Array<i32>): bool => value >= 3);
assert(some == true); assert(some == true);
@ -365,7 +311,8 @@ assert(arr.length == 2);
arr.push(2); arr.push(2);
arr.push(3); arr.push(3);
/*=============================== reduce ==========================*/
// Array#reduce ////////////////////////////////////////////////////////////////////////////////////
i = arr.reduce<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i32 => prev + current), 0); i = arr.reduce<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i32 => prev + current), 0);
assert(i == 6); assert(i == 6);
@ -405,46 +352,115 @@ i = arr.reduce<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i
assert(i == 1); assert(i == 1);
assert(arr.length == 2); assert(arr.length == 2);
/*=============================== sort ==========================*/ // Array#sort //////////////////////////////////////////////////////////////////////////////////////
var revesed0: Array<i32> = []; // Checks if an array is properly sorted
var revesed1: Array<i32> = [1]; function isSorted<T>(data: Array<T>, comparator: (a: T, b: T) => i32 = defaultComparator<T>()): bool {
var revesed2: Array<i32> = [2, 1]; for (let i: i32 = 1, len: i32 = data.length; i < len; i++) {
var revesed4: Array<i32> = [3, 2, 1, 0]; 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 expected4: Array<i32> = [0, 1, 2, 3];
var revesed64 = createReverseOrderedArray(64); var reversed64 = createReverseOrderedArray(64);
var revesed128 = createReverseOrderedArray(128); var reversed128 = createReverseOrderedArray(128);
var revesed1024 = createReverseOrderedArray(1024); var reversed1024 = createReverseOrderedArray(1024);
var revesed10000 = createReverseOrderedArray(10000); var reversed10000 = createReverseOrderedArray(10000);
var randomized512 = createRandomOrderedArray(512); var randomized512 = createRandomOrderedArray(512);
// Test sorting with with default comparator // Test sorting with with default comparator
assertSortedDefault<i32>(revesed0); assertSortedDefault<i32>(reversed0);
assertSortedDefault<i32>(revesed1); assertSortedDefault<i32>(reversed1);
assert(isArraysEqual<i32>(revesed1, <i32[]>[1])); assert(isArraysEqual<i32>(reversed1, <i32[]>[1]));
assertSortedDefault<i32>(revesed2); assertSortedDefault<i32>(reversed2);
assert(isArraysEqual<i32>(revesed2, <i32[]>[1, 2])); assert(isArraysEqual<i32>(reversed2, <i32[]>[1, 2]));
assertSortedDefault<i32>(revesed4); assertSortedDefault<i32>(reversed4);
assert(isArraysEqual<i32>(revesed4, expected4)); assert(isArraysEqual<i32>(reversed4, expected4));
assertSortedDefault<i32>(revesed64); assertSortedDefault<i32>(reversed64);
assert(isArraysEqual<i32>(revesed64, expected4, 4)); assert(isArraysEqual<i32>(reversed64, expected4, 4));
assertSortedDefault<i32>(revesed128); assertSortedDefault<i32>(reversed128);
assert(isArraysEqual<i32>(revesed128, expected4, 4)); assert(isArraysEqual<i32>(reversed128, expected4, 4));
assertSortedDefault<i32>(revesed1024); assertSortedDefault<i32>(reversed1024);
assert(isArraysEqual<i32>(revesed1024, expected4, 4)); assert(isArraysEqual<i32>(reversed1024, expected4, 4));
assertSortedDefault<i32>(revesed10000); assertSortedDefault<i32>(reversed10000);
assert(isArraysEqual<i32>(revesed10000, expected4, 4)); assert(isArraysEqual<i32>(reversed10000, expected4, 4));
assertSortedDefault<i32>(randomized512); assertSortedDefault<i32>(randomized512);

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
(module (module
(type $iii (func (param i32 i32) (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 $iiiiv (func (param i32 i32 i32 i32)))
(type $ii (func (param i32) (result i32)))
(type $iiiv (func (param i32 i32 i32))) (type $iiiv (func (param i32 i32 i32)))
(type $iiii (func (param i32 i32 i32) (result i32))) (type $iiii (func (param i32 i32 i32) (result i32)))
(type $v (func)) (type $v (func))
@ -11,10 +11,11 @@
(global $std/arraybuffer/buffer (mut i32) (i32.const 0)) (global $std/arraybuffer/buffer (mut i32) (i32.const 0))
(global $argumentCount (mut i32) (i32.const 0)) (global $argumentCount (mut i32) (i32.const 0))
(global $std/arraybuffer/sliced (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) (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 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 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 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)) (export "memory" (memory $0))
(start $start) (start $start)
(func $~lib/internal/arraybuffer/computeSize (; 1 ;) (type $ii) (param $0 i32) (result i32) (func $~lib/internal/arraybuffer/computeSize (; 1 ;) (type $ii) (param $0 i32) (result i32)
@ -130,7 +131,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 4) (i32.const 48)
(i32.const 22) (i32.const 22)
(i32.const 2) (i32.const 2)
) )
@ -489,8 +490,16 @@
(get_local $1) (get_local $1)
(i32.const 1073741816) (i32.const 1073741816)
) )
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 13)
(i32.const 40)
)
(unreachable) (unreachable)
) )
)
(call $~lib/memory/set_memory (call $~lib/memory/set_memory
(i32.add (i32.add
(tee_local $2 (tee_local $2
@ -2537,7 +2546,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 5) (i32.const 5)
(i32.const 0) (i32.const 0)
) )
@ -2566,7 +2575,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 9) (i32.const 9)
(i32.const 0) (i32.const 0)
) )
@ -2581,7 +2590,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 10) (i32.const 10)
(i32.const 0) (i32.const 0)
) )
@ -2610,7 +2619,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 14) (i32.const 14)
(i32.const 0) (i32.const 0)
) )
@ -2639,7 +2648,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 18) (i32.const 18)
(i32.const 0) (i32.const 0)
) )
@ -2663,7 +2672,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 22) (i32.const 22)
(i32.const 0) (i32.const 0)
) )
@ -2687,7 +2696,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 26) (i32.const 26)
(i32.const 0) (i32.const 0)
) )
@ -2711,7 +2720,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 30) (i32.const 30)
(i32.const 0) (i32.const 0)
) )
@ -2735,7 +2744,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 34) (i32.const 34)
(i32.const 0) (i32.const 0)
) )
@ -2761,7 +2770,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 38) (i32.const 38)
(i32.const 0) (i32.const 0)
) )
@ -2775,7 +2784,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 39) (i32.const 39)
(i32.const 0) (i32.const 0)
) )

View File

@ -1,8 +1,8 @@
(module (module
(type $i (func (result i32))) (type $i (func (result i32)))
(type $iii (func (param i32 i32) (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 $iiiiv (func (param i32 i32 i32 i32)))
(type $ii (func (param i32) (result i32)))
(type $iiiv (func (param i32 i32 i32))) (type $iiiv (func (param i32 i32 i32)))
(type $iiii (func (param i32 i32 i32) (result i32))) (type $iiii (func (param i32 i32 i32) (result i32)))
(type $v (func)) (type $v (func))
@ -18,10 +18,11 @@
(global $std/arraybuffer/buffer (mut i32) (i32.const 0)) (global $std/arraybuffer/buffer (mut i32) (i32.const 0))
(global $argumentCount (mut i32) (i32.const 0)) (global $argumentCount (mut i32) (i32.const 0))
(global $std/arraybuffer/sliced (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) (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 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 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 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)) (export "memory" (memory $0))
(start $start) (start $start)
(func $~lib/internal/arraybuffer/computeSize (; 1 ;) (type $ii) (param $0 i32) (result i32) (func $~lib/internal/arraybuffer/computeSize (; 1 ;) (type $ii) (param $0 i32) (result i32)
@ -165,7 +166,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 4) (i32.const 48)
(i32.const 22) (i32.const 22)
(i32.const 2) (i32.const 2)
) )
@ -543,8 +544,16 @@
(get_local $1) (get_local $1)
(i32.const 1073741816) (i32.const 1073741816)
) )
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 13)
(i32.const 40)
)
(unreachable) (unreachable)
) )
)
(set_local $2 (set_local $2
(call $~lib/internal/arraybuffer/allocUnsafe (call $~lib/internal/arraybuffer/allocUnsafe
(get_local $1) (get_local $1)
@ -2872,7 +2881,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 5) (i32.const 5)
(i32.const 0) (i32.const 0)
) )
@ -2903,7 +2912,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 9) (i32.const 9)
(i32.const 0) (i32.const 0)
) )
@ -2920,7 +2929,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 10) (i32.const 10)
(i32.const 0) (i32.const 0)
) )
@ -2951,7 +2960,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 14) (i32.const 14)
(i32.const 0) (i32.const 0)
) )
@ -2982,7 +2991,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 18) (i32.const 18)
(i32.const 0) (i32.const 0)
) )
@ -3008,7 +3017,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 22) (i32.const 22)
(i32.const 0) (i32.const 0)
) )
@ -3034,7 +3043,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 26) (i32.const 26)
(i32.const 0) (i32.const 0)
) )
@ -3060,7 +3069,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 30) (i32.const 30)
(i32.const 0) (i32.const 0)
) )
@ -3086,7 +3095,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 34) (i32.const 34)
(i32.const 0) (i32.const 0)
) )
@ -3117,7 +3126,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 38) (i32.const 38)
(i32.const 0) (i32.const 0)
) )
@ -3134,7 +3143,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 64) (i32.const 108)
(i32.const 39) (i32.const 39)
(i32.const 0) (i32.const 0)
) )

View File

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

View File

@ -14381,8 +14381,16 @@
(i32.eqz (i32.eqz
(get_global $~lib/math/random_seeded) (get_global $~lib/math/random_seeded)
) )
(block
(call $abort
(i32.const 0)
(i32.const 32)
(i32.const 1000)
(i32.const 24)
)
(unreachable) (unreachable)
) )
)
(set_local $0 (set_local $0
(get_global $~lib/math/random_state0) (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); 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('|') @operator('|')
static or(a: Tester, b: Tester): Tester { static or(a: Tester, b: Tester): Tester {
return new Tester(a.x | b.x, a.y | b.y); 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; var d = d1 / d2;
assert(d.x == 2 && d.y == 5); assert(d.x == 2 && d.y == 5);
// check fractional // check remainder
var f1 = new Tester(10, 10); var f1 = new Tester(10, 10);
var f2 = new Tester(6, 10); var f2 = new Tester(6, 10);
var f = f1 % f2; var f = f1 % f2;
assert(f.x == 4 && f.y == 0); 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 // check bitwise and
var n1 = new Tester(0xFF, 0x0F); var n1 = new Tester(0xFF, 0x0F);
var n2 = new Tester(0x0F, 0xFF); var n2 = new Tester(0x0F, 0xFF);
@ -166,3 +177,31 @@ var leq1 = new Tester(4, 3);
var leq2 = new Tester(4, 3); var leq2 = new Tester(4, 3);
var leq = leq1 <= leq2; var leq = leq1 <= leq2;
assert(leq == true); 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,8 +3725,16 @@
) )
(i32.const 1) (i32.const 1)
) )
(block
(call $abort
(i32.const 0)
(i32.const 72)
(i32.const 391)
(i32.const 6)
)
(unreachable) (unreachable)
) )
)
(if (if
(i32.and (i32.and
(if (result i32) (if (result i32)

View File

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

View File

@ -4,14 +4,17 @@
(type $iii (func (param i32 i32) (result i32))) (type $iii (func (param i32 i32) (result i32)))
(type $ii (func (param i32) (result i32))) (type $ii (func (param i32) (result i32)))
(type $iiiv (func (param i32 i32 i32))) (type $iiiv (func (param i32 i32 i32)))
(type $iiii (func (param i32 i32 i32) (result i32)))
(type $v (func)) (type $v (func))
(import "env" "abort" (func $abort (param i32 i32 i32 i32))) (import "env" "abort" (func $abort (param i32 i32 i32 i32)))
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0)) (global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
(global $~lib/allocator/arena/offset (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) (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 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)) (export "memory" (memory $0))
(start $start) (start $start)
(func $~lib/internal/arraybuffer/computeSize (; 1 ;) (type $ii) (param $0 i32) (result i32) (func $~lib/internal/arraybuffer/computeSize (; 1 ;) (type $ii) (param $0 i32) (result i32)
@ -127,7 +130,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 44) (i32.const 104)
(i32.const 22) (i32.const 22)
(i32.const 2) (i32.const 2)
) )
@ -486,8 +489,16 @@
(get_local $1) (get_local $1)
(i32.const 1073741816) (i32.const 1073741816)
) )
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable) (unreachable)
) )
)
(call $~lib/memory/set_memory (call $~lib/memory/set_memory
(i32.add (i32.add
(tee_local $2 (tee_local $2
@ -537,9 +548,14 @@
(get_local $0) (get_local $0)
) )
(func $~lib/internal/typedarray/TypedArray<i8>#get:length (; 6 ;) (type $ii) (param $0 i32) (result i32) (func $~lib/internal/typedarray/TypedArray<i8>#get:length (; 6 ;) (type $ii) (param $0 i32) (result i32)
(i32.sub
(i32.load offset=8 (i32.load offset=8
(get_local $0) (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) (func $~lib/internal/typedarray/TypedArray<i16>#constructor (; 7 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32) (local $2 i32)
@ -548,8 +564,16 @@
(get_local $1) (get_local $1)
(i32.const 536870908) (i32.const 536870908)
) )
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable) (unreachable)
) )
)
(call $~lib/memory/set_memory (call $~lib/memory/set_memory
(i32.add (i32.add
(tee_local $2 (tee_local $2
@ -605,9 +629,14 @@
) )
(func $~lib/internal/typedarray/TypedArray<i16>#get:length (; 8 ;) (type $ii) (param $0 i32) (result i32) (func $~lib/internal/typedarray/TypedArray<i16>#get:length (; 8 ;) (type $ii) (param $0 i32) (result i32)
(i32.shr_s (i32.shr_s
(i32.sub
(i32.load offset=8 (i32.load offset=8
(get_local $0) (get_local $0)
) )
(i32.load offset=4
(get_local $0)
)
)
(i32.const 1) (i32.const 1)
) )
) )
@ -618,8 +647,16 @@
(get_local $1) (get_local $1)
(i32.const 268435454) (i32.const 268435454)
) )
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable) (unreachable)
) )
)
(call $~lib/memory/set_memory (call $~lib/memory/set_memory
(i32.add (i32.add
(tee_local $2 (tee_local $2
@ -675,9 +712,14 @@
) )
(func $~lib/internal/typedarray/TypedArray<i32>#get:length (; 10 ;) (type $ii) (param $0 i32) (result i32) (func $~lib/internal/typedarray/TypedArray<i32>#get:length (; 10 ;) (type $ii) (param $0 i32) (result i32)
(i32.shr_s (i32.shr_s
(i32.sub
(i32.load offset=8 (i32.load offset=8
(get_local $0) (get_local $0)
) )
(i32.load offset=4
(get_local $0)
)
)
(i32.const 2) (i32.const 2)
) )
) )
@ -688,8 +730,16 @@
(get_local $1) (get_local $1)
(i32.const 134217727) (i32.const 134217727)
) )
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable) (unreachable)
) )
)
(call $~lib/memory/set_memory (call $~lib/memory/set_memory
(i32.add (i32.add
(tee_local $2 (tee_local $2
@ -745,9 +795,14 @@
) )
(func $~lib/internal/typedarray/TypedArray<i64>#get:length (; 12 ;) (type $ii) (param $0 i32) (result i32) (func $~lib/internal/typedarray/TypedArray<i64>#get:length (; 12 ;) (type $ii) (param $0 i32) (result i32)
(i32.shr_s (i32.shr_s
(i32.sub
(i32.load offset=8 (i32.load offset=8
(get_local $0) (get_local $0)
) )
(i32.load offset=4
(get_local $0)
)
)
(i32.const 3) (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 (set_global $~lib/allocator/arena/startOffset
(i32.and (i32.and
(i32.add (i32.add
@ -1327,6 +1592,205 @@
(call $std/typedarray/testInstantiate (call $std/typedarray/testInstantiate
(i32.const 5) (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 (drop
(call $~lib/internal/typedarray/TypedArray<i64>#constructor (call $~lib/internal/typedarray/TypedArray<i64>#constructor
(i32.const 0) (i32.const 0)

View File

@ -67,6 +67,23 @@ function testInstantiate(len: i32): void {
testInstantiate(0); testInstantiate(0);
testInstantiate(5); 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"; import { MAX_BLENGTH } from "internal/arraybuffer";
const MAX_F64LENGTH = <u32>MAX_BLENGTH >> alignof<f64>(); const MAX_F64LENGTH = <u32>MAX_BLENGTH >> alignof<f64>();

View File

@ -5,6 +5,7 @@
(type $iii (func (param i32 i32) (result i32))) (type $iii (func (param i32 i32) (result i32)))
(type $ii (func (param i32) (result i32))) (type $ii (func (param i32) (result i32)))
(type $iiiv (func (param i32 i32 i32))) (type $iiiv (func (param i32 i32 i32)))
(type $iiii (func (param i32 i32 i32) (result i32)))
(type $v (func)) (type $v (func))
(import "env" "abort" (func $abort (param i32 i32 i32 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_BITS i32 (i32.const 3))
@ -15,11 +16,13 @@
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0)) (global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
(global $~lib/internal/arraybuffer/HEADER_SIZE i32 (i32.const 8)) (global $~lib/internal/arraybuffer/HEADER_SIZE i32 (i32.const 8))
(global $~lib/internal/arraybuffer/MAX_BLENGTH i32 (i32.const 1073741816)) (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 $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) (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 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)) (export "memory" (memory $0))
(start $start) (start $start)
(func $~lib/internal/arraybuffer/computeSize (; 1 ;) (type $ii) (param $0 i32) (result i32) (func $~lib/internal/arraybuffer/computeSize (; 1 ;) (type $ii) (param $0 i32) (result i32)
@ -163,7 +166,7 @@
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 44) (i32.const 104)
(i32.const 22) (i32.const 22)
(i32.const 2) (i32.const 2)
) )
@ -545,8 +548,16 @@
(get_local $1) (get_local $1)
(i32.const 1073741816) (i32.const 1073741816)
) )
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable) (unreachable)
) )
)
(set_local $2 (set_local $2
(i32.shl (i32.shl
(get_local $1) (get_local $1)
@ -611,9 +622,14 @@
(func $~lib/internal/typedarray/TypedArray<i8>#get:length (; 6 ;) (type $ii) (param $0 i32) (result i32) (func $~lib/internal/typedarray/TypedArray<i8>#get:length (; 6 ;) (type $ii) (param $0 i32) (result i32)
(return (return
(i32.shr_s (i32.shr_s
(i32.sub
(i32.load offset=8 (i32.load offset=8
(get_local $0) (get_local $0)
) )
(i32.load offset=4
(get_local $0)
)
)
(i32.const 0) (i32.const 0)
) )
) )
@ -629,8 +645,16 @@
(get_local $1) (get_local $1)
(i32.const 1073741816) (i32.const 1073741816)
) )
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable) (unreachable)
) )
)
(set_local $2 (set_local $2
(i32.shl (i32.shl
(get_local $1) (get_local $1)
@ -695,9 +719,14 @@
(func $~lib/internal/typedarray/TypedArray<u8>#get:length (; 8 ;) (type $ii) (param $0 i32) (result i32) (func $~lib/internal/typedarray/TypedArray<u8>#get:length (; 8 ;) (type $ii) (param $0 i32) (result i32)
(return (return
(i32.shr_s (i32.shr_s
(i32.sub
(i32.load offset=8 (i32.load offset=8
(get_local $0) (get_local $0)
) )
(i32.load offset=4
(get_local $0)
)
)
(i32.const 0) (i32.const 0)
) )
) )
@ -713,8 +742,16 @@
(get_local $1) (get_local $1)
(i32.const 536870908) (i32.const 536870908)
) )
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable) (unreachable)
) )
)
(set_local $2 (set_local $2
(i32.shl (i32.shl
(get_local $1) (get_local $1)
@ -779,9 +816,14 @@
(func $~lib/internal/typedarray/TypedArray<i16>#get:length (; 10 ;) (type $ii) (param $0 i32) (result i32) (func $~lib/internal/typedarray/TypedArray<i16>#get:length (; 10 ;) (type $ii) (param $0 i32) (result i32)
(return (return
(i32.shr_s (i32.shr_s
(i32.sub
(i32.load offset=8 (i32.load offset=8
(get_local $0) (get_local $0)
) )
(i32.load offset=4
(get_local $0)
)
)
(i32.const 1) (i32.const 1)
) )
) )
@ -797,8 +839,16 @@
(get_local $1) (get_local $1)
(i32.const 536870908) (i32.const 536870908)
) )
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable) (unreachable)
) )
)
(set_local $2 (set_local $2
(i32.shl (i32.shl
(get_local $1) (get_local $1)
@ -863,9 +913,14 @@
(func $~lib/internal/typedarray/TypedArray<u16>#get:length (; 12 ;) (type $ii) (param $0 i32) (result i32) (func $~lib/internal/typedarray/TypedArray<u16>#get:length (; 12 ;) (type $ii) (param $0 i32) (result i32)
(return (return
(i32.shr_s (i32.shr_s
(i32.sub
(i32.load offset=8 (i32.load offset=8
(get_local $0) (get_local $0)
) )
(i32.load offset=4
(get_local $0)
)
)
(i32.const 1) (i32.const 1)
) )
) )
@ -881,8 +936,16 @@
(get_local $1) (get_local $1)
(i32.const 268435454) (i32.const 268435454)
) )
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable) (unreachable)
) )
)
(set_local $2 (set_local $2
(i32.shl (i32.shl
(get_local $1) (get_local $1)
@ -947,9 +1010,14 @@
(func $~lib/internal/typedarray/TypedArray<i32>#get:length (; 14 ;) (type $ii) (param $0 i32) (result i32) (func $~lib/internal/typedarray/TypedArray<i32>#get:length (; 14 ;) (type $ii) (param $0 i32) (result i32)
(return (return
(i32.shr_s (i32.shr_s
(i32.sub
(i32.load offset=8 (i32.load offset=8
(get_local $0) (get_local $0)
) )
(i32.load offset=4
(get_local $0)
)
)
(i32.const 2) (i32.const 2)
) )
) )
@ -965,8 +1033,16 @@
(get_local $1) (get_local $1)
(i32.const 268435454) (i32.const 268435454)
) )
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable) (unreachable)
) )
)
(set_local $2 (set_local $2
(i32.shl (i32.shl
(get_local $1) (get_local $1)
@ -1031,9 +1107,14 @@
(func $~lib/internal/typedarray/TypedArray<u32>#get:length (; 16 ;) (type $ii) (param $0 i32) (result i32) (func $~lib/internal/typedarray/TypedArray<u32>#get:length (; 16 ;) (type $ii) (param $0 i32) (result i32)
(return (return
(i32.shr_s (i32.shr_s
(i32.sub
(i32.load offset=8 (i32.load offset=8
(get_local $0) (get_local $0)
) )
(i32.load offset=4
(get_local $0)
)
)
(i32.const 2) (i32.const 2)
) )
) )
@ -1049,8 +1130,16 @@
(get_local $1) (get_local $1)
(i32.const 134217727) (i32.const 134217727)
) )
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable) (unreachable)
) )
)
(set_local $2 (set_local $2
(i32.shl (i32.shl
(get_local $1) (get_local $1)
@ -1115,9 +1204,14 @@
(func $~lib/internal/typedarray/TypedArray<i64>#get:length (; 18 ;) (type $ii) (param $0 i32) (result i32) (func $~lib/internal/typedarray/TypedArray<i64>#get:length (; 18 ;) (type $ii) (param $0 i32) (result i32)
(return (return
(i32.shr_s (i32.shr_s
(i32.sub
(i32.load offset=8 (i32.load offset=8
(get_local $0) (get_local $0)
) )
(i32.load offset=4
(get_local $0)
)
)
(i32.const 3) (i32.const 3)
) )
) )
@ -1133,8 +1227,16 @@
(get_local $1) (get_local $1)
(i32.const 134217727) (i32.const 134217727)
) )
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable) (unreachable)
) )
)
(set_local $2 (set_local $2
(i32.shl (i32.shl
(get_local $1) (get_local $1)
@ -1199,9 +1301,14 @@
(func $~lib/internal/typedarray/TypedArray<u64>#get:length (; 20 ;) (type $ii) (param $0 i32) (result i32) (func $~lib/internal/typedarray/TypedArray<u64>#get:length (; 20 ;) (type $ii) (param $0 i32) (result i32)
(return (return
(i32.shr_s (i32.shr_s
(i32.sub
(i32.load offset=8 (i32.load offset=8
(get_local $0) (get_local $0)
) )
(i32.load offset=4
(get_local $0)
)
)
(i32.const 3) (i32.const 3)
) )
) )
@ -1217,8 +1324,16 @@
(get_local $1) (get_local $1)
(i32.const 268435454) (i32.const 268435454)
) )
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable) (unreachable)
) )
)
(set_local $2 (set_local $2
(i32.shl (i32.shl
(get_local $1) (get_local $1)
@ -1283,9 +1398,14 @@
(func $~lib/internal/typedarray/TypedArray<f32>#get:length (; 22 ;) (type $ii) (param $0 i32) (result i32) (func $~lib/internal/typedarray/TypedArray<f32>#get:length (; 22 ;) (type $ii) (param $0 i32) (result i32)
(return (return
(i32.shr_s (i32.shr_s
(i32.sub
(i32.load offset=8 (i32.load offset=8
(get_local $0) (get_local $0)
) )
(i32.load offset=4
(get_local $0)
)
)
(i32.const 2) (i32.const 2)
) )
) )
@ -1301,8 +1421,16 @@
(get_local $1) (get_local $1)
(i32.const 134217727) (i32.const 134217727)
) )
(block
(call $abort
(i32.const 0)
(i32.const 44)
(i32.const 22)
(i32.const 34)
)
(unreachable) (unreachable)
) )
)
(set_local $2 (set_local $2
(i32.shl (i32.shl
(get_local $1) (get_local $1)
@ -1367,9 +1495,14 @@
(func $~lib/internal/typedarray/TypedArray<f64>#get:length (; 24 ;) (type $ii) (param $0 i32) (result i32) (func $~lib/internal/typedarray/TypedArray<f64>#get:length (; 24 ;) (type $ii) (param $0 i32) (result i32)
(return (return
(i32.shr_s (i32.shr_s
(i32.sub
(i32.load offset=8 (i32.load offset=8
(get_local $0) (get_local $0)
) )
(i32.load offset=4
(get_local $0)
)
)
(i32.const 3) (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 (if
(i32.eqz (i32.eqz
(i32.eq (i32.eq
@ -2238,6 +2645,237 @@
(call $std/typedarray/testInstantiate (call $std/typedarray/testInstantiate
(i32.const 5) (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 (drop
(call $~lib/internal/typedarray/TypedArray<f64>#constructor (call $~lib/internal/typedarray/TypedArray<f64>#constructor
(i32.const 0) (i32.const 0)