mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 07:02:13 +00:00
Implement optional type parameters (#360)
* Add a NATIVE<T> macro type to simplify use of a native WebAssembly type * Add default type parameters for internal helpers for explicit loads and stores * Unify loadUnsafe/loadUnsafeWithOffset etc. into one * Renamed loadUnsafe etc. into just LOAD, like a macro * Implement parsing of index signatures, but ignore them, for properly linting code * Refactor TypedArray<T> to use macros
This commit is contained in:
parent
d7f4874650
commit
ebae7cbd73
27
src/ast.ts
27
src/ast.ts
@ -87,6 +87,7 @@ export enum NodeKind {
|
||||
FIELDDECLARATION,
|
||||
FUNCTIONDECLARATION,
|
||||
IMPORTDECLARATION,
|
||||
INDEXSIGNATUREDECLARATION,
|
||||
INTERFACEDECLARATION,
|
||||
METHODDECLARATION,
|
||||
NAMESPACEDECLARATION,
|
||||
@ -181,12 +182,14 @@ export abstract class Node {
|
||||
static createTypeParameter(
|
||||
name: IdentifierExpression,
|
||||
extendsType: TypeNode | null,
|
||||
defaultType: TypeNode | null,
|
||||
range: Range
|
||||
): TypeParameterNode {
|
||||
var elem = new TypeParameterNode();
|
||||
elem.range = range;
|
||||
elem.name = name; name.parent = elem;
|
||||
elem.extendsType = extendsType; if (extendsType) extendsType.parent = elem;
|
||||
elem.defaultType = defaultType; if (defaultType) defaultType.parent = elem;
|
||||
return elem;
|
||||
}
|
||||
|
||||
@ -871,6 +874,18 @@ export abstract class Node {
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static createIndexSignatureDeclaration(
|
||||
keyType: TypeNode,
|
||||
valueType: CommonTypeNode,
|
||||
range: Range
|
||||
): IndexSignatureDeclaration {
|
||||
var elem = new IndexSignatureDeclaration();
|
||||
elem.range = range;
|
||||
elem.keyType = keyType; keyType.parent = elem;
|
||||
elem.valueType = valueType; valueType.parent = elem;
|
||||
return elem;
|
||||
}
|
||||
|
||||
static createMethodDeclaration(
|
||||
name: IdentifierExpression,
|
||||
typeParameters: TypeParameterNode[] | null,
|
||||
@ -1070,6 +1085,8 @@ export class TypeParameterNode extends Node {
|
||||
name: IdentifierExpression;
|
||||
/** Extended type reference, if any. */
|
||||
extendsType: TypeNode | null; // can't be a function
|
||||
/** Default type if omitted, if any. */
|
||||
defaultType: TypeNode | null; // can't be a function
|
||||
}
|
||||
|
||||
/** Represents the kind of a parameter. */
|
||||
@ -1622,6 +1639,16 @@ export abstract class DeclarationStatement extends Statement {
|
||||
}
|
||||
}
|
||||
|
||||
/** Represents an index signature declaration. */
|
||||
export class IndexSignatureDeclaration extends DeclarationStatement {
|
||||
kind = NodeKind.INDEXSIGNATUREDECLARATION;
|
||||
|
||||
/** Key type. */
|
||||
keyType: TypeNode;
|
||||
/** Value type. */
|
||||
valueType: CommonTypeNode;
|
||||
}
|
||||
|
||||
/** Base class of all variable-like declaration statements. */
|
||||
export abstract class VariableLikeDeclarationStatement extends DeclarationStatement {
|
||||
|
||||
|
@ -162,7 +162,8 @@ import {
|
||||
writeI32,
|
||||
writeI64,
|
||||
writeF32,
|
||||
writeF64
|
||||
writeF64,
|
||||
makeMap
|
||||
} from "./util";
|
||||
|
||||
/** Compilation target. */
|
||||
@ -619,7 +620,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
(noTreeShaking || (isEntry && statement.is(CommonFlags.EXPORT))) &&
|
||||
!(<ClassDeclaration>statement).isGeneric
|
||||
) {
|
||||
this.compileClassDeclaration(<ClassDeclaration>statement, [], null);
|
||||
this.compileClassDeclaration(<ClassDeclaration>statement, []);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -958,16 +959,15 @@ export class Compiler extends DiagnosticEmitter {
|
||||
/** Compiles a top-level function given its declaration. */
|
||||
compileFunctionDeclaration(
|
||||
declaration: FunctionDeclaration,
|
||||
typeArguments: TypeNode[],
|
||||
contextualTypeArguments: Map<string,Type> | null = null
|
||||
typeArguments: TypeNode[]
|
||||
): Function | null {
|
||||
var element = assert(this.program.elementsLookup.get(declaration.fileLevelInternalName));
|
||||
assert(element.kind == ElementKind.FUNCTION_PROTOTYPE);
|
||||
return this.compileFunctionUsingTypeArguments( // reports
|
||||
<FunctionPrototype>element,
|
||||
typeArguments,
|
||||
contextualTypeArguments,
|
||||
null, // no outer scope (is top level)
|
||||
makeMap<string,Type>(),
|
||||
null,
|
||||
(<FunctionPrototype>element).declaration.name
|
||||
);
|
||||
}
|
||||
@ -976,7 +976,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
compileFunctionUsingTypeArguments(
|
||||
prototype: FunctionPrototype,
|
||||
typeArguments: TypeNode[],
|
||||
contextualTypeArguments: Map<string,Type> | null,
|
||||
contextualTypeArguments: Map<string,Type>,
|
||||
outerScope: Flow | null,
|
||||
reportNode: Node
|
||||
): Function | null {
|
||||
@ -1234,7 +1234,11 @@ export class Compiler extends DiagnosticEmitter {
|
||||
(<ClassPrototype>element).is(CommonFlags.EXPORT)
|
||||
) && !(<ClassPrototype>element).is(CommonFlags.GENERIC)
|
||||
) {
|
||||
this.compileClassUsingTypeArguments(<ClassPrototype>element, []);
|
||||
this.compileClassUsingTypeArguments(
|
||||
<ClassPrototype>element,
|
||||
[],
|
||||
makeMap<string,Type>()
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1252,8 +1256,8 @@ export class Compiler extends DiagnosticEmitter {
|
||||
this.compileFunctionUsingTypeArguments(
|
||||
<FunctionPrototype>element,
|
||||
[],
|
||||
null, // no contextual type arguments
|
||||
null, // no outer scope
|
||||
makeMap<string,Type>(),
|
||||
null,
|
||||
(<FunctionPrototype>element).declaration.name
|
||||
);
|
||||
}
|
||||
@ -1286,7 +1290,11 @@ export class Compiler extends DiagnosticEmitter {
|
||||
switch (element.kind) {
|
||||
case ElementKind.CLASS_PROTOTYPE: {
|
||||
if (!(<ClassPrototype>element).is(CommonFlags.GENERIC)) {
|
||||
this.compileClassUsingTypeArguments(<ClassPrototype>element, []);
|
||||
this.compileClassUsingTypeArguments(
|
||||
<ClassPrototype>element,
|
||||
[],
|
||||
makeMap<string,Type>()
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1302,8 +1310,8 @@ export class Compiler extends DiagnosticEmitter {
|
||||
this.compileFunctionUsingTypeArguments(
|
||||
<FunctionPrototype>element,
|
||||
[],
|
||||
null, // no contextual type arguments
|
||||
null, // no outer scope
|
||||
makeMap<string,Type>(),
|
||||
null,
|
||||
(<FunctionPrototype>element).declaration.name
|
||||
);
|
||||
}
|
||||
@ -1325,15 +1333,14 @@ export class Compiler extends DiagnosticEmitter {
|
||||
|
||||
compileClassDeclaration(
|
||||
declaration: ClassDeclaration,
|
||||
typeArguments: TypeNode[],
|
||||
contextualTypeArguments: Map<string,Type> | null = null
|
||||
typeArguments: TypeNode[]
|
||||
): void {
|
||||
var element = assert(this.program.elementsLookup.get(declaration.fileLevelInternalName));
|
||||
assert(element.kind == ElementKind.CLASS_PROTOTYPE);
|
||||
this.compileClassUsingTypeArguments(
|
||||
<ClassPrototype>element,
|
||||
typeArguments,
|
||||
contextualTypeArguments,
|
||||
makeMap<string,Type>(),
|
||||
declaration
|
||||
);
|
||||
}
|
||||
@ -1341,7 +1348,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
compileClassUsingTypeArguments(
|
||||
prototype: ClassPrototype,
|
||||
typeArguments: TypeNode[],
|
||||
contextualTypeArguments: Map<string,Type> | null = null,
|
||||
contextualTypeArguments: Map<string,Type>,
|
||||
alternativeReportNode: Node | null = null
|
||||
): void {
|
||||
var instance = this.resolver.resolveClassInclTypeArguments(
|
||||
@ -1372,7 +1379,9 @@ export class Compiler extends DiagnosticEmitter {
|
||||
) {
|
||||
this.compileFunctionUsingTypeArguments(
|
||||
<FunctionPrototype>element,
|
||||
[], null, null,
|
||||
[],
|
||||
makeMap<string,Type>(),
|
||||
null,
|
||||
(<FunctionPrototype>element).declaration.name
|
||||
);
|
||||
}
|
||||
@ -1383,7 +1392,9 @@ export class Compiler extends DiagnosticEmitter {
|
||||
if (getter) {
|
||||
this.compileFunctionUsingTypeArguments(
|
||||
getter,
|
||||
[], null, null,
|
||||
[],
|
||||
makeMap<string,Type>(),
|
||||
null,
|
||||
getter.declaration.name
|
||||
);
|
||||
}
|
||||
@ -1391,7 +1402,9 @@ export class Compiler extends DiagnosticEmitter {
|
||||
if (setter) {
|
||||
this.compileFunctionUsingTypeArguments(
|
||||
setter,
|
||||
[], null, null,
|
||||
[],
|
||||
makeMap<string,Type>(),
|
||||
null,
|
||||
setter.declaration.name
|
||||
);
|
||||
}
|
||||
@ -1413,8 +1426,8 @@ export class Compiler extends DiagnosticEmitter {
|
||||
this.compileFunctionUsingTypeArguments(
|
||||
<FunctionPrototype>element,
|
||||
[],
|
||||
instance.contextualTypeArguments,
|
||||
null, // no outer scope
|
||||
makeMap<string,Type>(instance.contextualTypeArguments),
|
||||
null,
|
||||
(<FunctionPrototype>element).declaration.name
|
||||
);
|
||||
}
|
||||
@ -1429,7 +1442,9 @@ export class Compiler extends DiagnosticEmitter {
|
||||
if (getter) {
|
||||
this.compileFunctionUsingTypeArguments(
|
||||
getter,
|
||||
[], instance.contextualTypeArguments, null,
|
||||
[],
|
||||
makeMap<string,Type>(instance.contextualTypeArguments),
|
||||
null,
|
||||
getter.declaration.name
|
||||
);
|
||||
}
|
||||
@ -1437,7 +1452,9 @@ export class Compiler extends DiagnosticEmitter {
|
||||
if (setter) {
|
||||
this.compileFunctionUsingTypeArguments(
|
||||
setter,
|
||||
[], instance.contextualTypeArguments, null,
|
||||
[],
|
||||
makeMap<string,Type>(instance.contextualTypeArguments),
|
||||
null,
|
||||
setter.declaration.name
|
||||
);
|
||||
}
|
||||
@ -5014,7 +5031,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
instance = this.resolver.resolveFunctionInclTypeArguments(
|
||||
prototype,
|
||||
typeArguments,
|
||||
this.currentFunction.flow.contextualTypeArguments,
|
||||
makeMap<string,Type>(this.currentFunction.flow.contextualTypeArguments),
|
||||
expression
|
||||
);
|
||||
|
||||
@ -5088,7 +5105,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
instance = this.resolver.resolveFunction(
|
||||
prototype,
|
||||
resolvedTypeArguments,
|
||||
this.currentFunction.flow.contextualTypeArguments
|
||||
makeMap<string,Type>(this.currentFunction.flow.contextualTypeArguments)
|
||||
);
|
||||
if (!instance) return this.module.createUnreachable();
|
||||
return this.makeCallDirect(instance, argumentExprs);
|
||||
@ -5098,11 +5115,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
|
||||
// otherwise resolve the non-generic call as usual
|
||||
} else {
|
||||
instance = this.resolver.resolveFunction(
|
||||
prototype,
|
||||
null,
|
||||
this.currentFunction.flow.contextualTypeArguments
|
||||
);
|
||||
instance = this.resolver.resolveFunction(prototype, null);
|
||||
}
|
||||
if (!instance) return this.module.createUnreachable();
|
||||
|
||||
@ -5241,7 +5254,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
typeArguments = this.resolver.resolveTypeArguments(
|
||||
assert(prototype.declaration.typeParameters),
|
||||
typeArgumentNodes,
|
||||
this.currentFunction.flow.contextualTypeArguments,
|
||||
makeMap<string,Type>(this.currentFunction.flow.contextualTypeArguments),
|
||||
expression
|
||||
);
|
||||
}
|
||||
@ -5932,7 +5945,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
var instance = this.compileFunctionUsingTypeArguments(
|
||||
prototype,
|
||||
[],
|
||||
flow.contextualTypeArguments,
|
||||
makeMap<string,Type>(flow.contextualTypeArguments),
|
||||
flow,
|
||||
declaration
|
||||
);
|
||||
@ -6093,7 +6106,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
let instance = this.resolver.resolveFunction(
|
||||
<FunctionPrototype>target,
|
||||
null,
|
||||
currentFunction.flow.contextualTypeArguments
|
||||
makeMap<string,Type>(currentFunction.flow.contextualTypeArguments)
|
||||
);
|
||||
if (!(instance && this.compileFunction(instance))) return module.createUnreachable();
|
||||
let index = this.ensureFunctionTableEntry(instance);
|
||||
@ -6438,7 +6451,11 @@ export class Compiler extends DiagnosticEmitter {
|
||||
|
||||
// create the Array segment and return a pointer to it
|
||||
var arrayPrototype = assert(program.arrayPrototype);
|
||||
var arrayInstance = assert(this.resolver.resolveClass(arrayPrototype, [ elementType ]));
|
||||
var arrayInstance = assert(this.resolver.resolveClass(
|
||||
arrayPrototype,
|
||||
[ elementType ],
|
||||
makeMap<string,Type>()
|
||||
));
|
||||
var arrayHeaderSize = (arrayInstance.currentMemoryOffset + 7) & ~7;
|
||||
if (hasGC) {
|
||||
buf = new Uint8Array(gcHeaderSize + arrayHeaderSize);
|
||||
@ -6506,9 +6523,11 @@ export class Compiler extends DiagnosticEmitter {
|
||||
|
||||
// otherwise obtain the array type
|
||||
var arrayPrototype = assert(this.program.arrayPrototype);
|
||||
if (!arrayPrototype || arrayPrototype.kind != ElementKind.CLASS_PROTOTYPE) return module.createUnreachable();
|
||||
var arrayInstance = this.resolver.resolveClass(<ClassPrototype>arrayPrototype, [ elementType ]);
|
||||
if (!arrayInstance) return module.createUnreachable();
|
||||
var arrayInstance = assert(this.resolver.resolveClass(
|
||||
<ClassPrototype>arrayPrototype,
|
||||
[ elementType ],
|
||||
makeMap<string,Type>()
|
||||
));
|
||||
var arrayType = arrayInstance.type;
|
||||
|
||||
// and compile an explicit instantiation
|
||||
@ -6660,13 +6679,13 @@ export class Compiler extends DiagnosticEmitter {
|
||||
classInstance = this.resolver.resolveClass(
|
||||
classPrototype,
|
||||
classReference.typeArguments,
|
||||
currentFunction.flow.contextualTypeArguments
|
||||
makeMap<string,Type>(currentFunction.flow.contextualTypeArguments)
|
||||
);
|
||||
} else {
|
||||
classInstance = this.resolver.resolveClassInclTypeArguments(
|
||||
classPrototype,
|
||||
typeArguments,
|
||||
currentFunction.flow.contextualTypeArguments,
|
||||
makeMap<string,Type>(currentFunction.flow.contextualTypeArguments),
|
||||
expression
|
||||
);
|
||||
}
|
||||
|
@ -121,6 +121,7 @@ export enum DiagnosticCode {
|
||||
Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration = 2673,
|
||||
Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration = 2674,
|
||||
Namespace_0_has_no_exported_member_1 = 2694,
|
||||
Required_type_parameters_may_not_follow_optional_type_parameters = 2706,
|
||||
File_0_not_found = 6054,
|
||||
Numeric_separators_are_not_allowed_here = 6188,
|
||||
Multiple_consecutive_numeric_separators_are_not_permitted = 6189
|
||||
@ -243,6 +244,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
|
||||
case 2673: return "Constructor of class '{0}' is private and only accessible within the class declaration.";
|
||||
case 2674: return "Constructor of class '{0}' is protected and only accessible within the class declaration.";
|
||||
case 2694: return "Namespace '{0}' has no exported member '{1}'.";
|
||||
case 2706: return "Required type parameters may not follow optional type parameters.";
|
||||
case 6054: return "File '{0}' not found.";
|
||||
case 6188: return "Numeric separators are not allowed here.";
|
||||
case 6189: return "Multiple consecutive numeric separators are not permitted.";
|
||||
|
@ -115,6 +115,7 @@
|
||||
"Constructor of class '{0}' is private and only accessible within the class declaration.": 2673,
|
||||
"Constructor of class '{0}' is protected and only accessible within the class declaration.": 2674,
|
||||
"Namespace '{0}' has no exported member '{1}'.": 2694,
|
||||
"Required type parameters may not follow optional type parameters.": 2706,
|
||||
|
||||
"File '{0}' not found.": 6054,
|
||||
"Numeric separators are not allowed here.": 6188,
|
||||
|
@ -68,6 +68,7 @@ import {
|
||||
FieldDeclaration,
|
||||
FunctionDeclaration,
|
||||
ImportDeclaration,
|
||||
IndexSignatureDeclaration,
|
||||
InterfaceDeclaration,
|
||||
MethodDeclaration,
|
||||
NamespaceDeclaration,
|
||||
@ -295,6 +296,10 @@ export class ASTBuilder {
|
||||
this.visitImportDeclaration(<ImportDeclaration>node);
|
||||
break;
|
||||
}
|
||||
case NodeKind.INDEXSIGNATUREDECLARATION: {
|
||||
this.visitIndexSignatureDeclaration(<IndexSignatureDeclaration>node);
|
||||
break;
|
||||
}
|
||||
case NodeKind.INTERFACEDECLARATION: {
|
||||
this.visitInterfaceDeclaration(<InterfaceDeclaration>node);
|
||||
break;
|
||||
@ -379,6 +384,11 @@ export class ASTBuilder {
|
||||
this.sb.push(" extends ");
|
||||
this.visitTypeNode(extendsType);
|
||||
}
|
||||
var defaultType = node.defaultType;
|
||||
if (defaultType) {
|
||||
this.sb.push("=");
|
||||
this.visitTypeNode(defaultType);
|
||||
}
|
||||
}
|
||||
|
||||
visitSignatureNode(node: SignatureNode): void {
|
||||
@ -1176,6 +1186,14 @@ export class ASTBuilder {
|
||||
this.visitStringLiteralExpression(node.path);
|
||||
}
|
||||
|
||||
visitIndexSignatureDeclaration(node: IndexSignatureDeclaration): void {
|
||||
var sb = this.sb;
|
||||
sb.push("[key: ");
|
||||
this.visitTypeNode(node.keyType);
|
||||
sb.push("]: ");
|
||||
this.visitTypeNode(node.valueType);
|
||||
}
|
||||
|
||||
visitInterfaceDeclaration(node: InterfaceDeclaration): void {
|
||||
var decorators = node.decorators;
|
||||
if (decorators) {
|
||||
|
189
src/parser.ts
189
src/parser.ts
@ -83,7 +83,8 @@ import {
|
||||
|
||||
mangleInternalPath,
|
||||
nodeIsCallable,
|
||||
nodeIsGenericCallable
|
||||
nodeIsGenericCallable,
|
||||
IndexSignatureDeclaration
|
||||
} from "./ast";
|
||||
|
||||
/** Parser interface. */
|
||||
@ -926,9 +927,19 @@ export class Parser extends DiagnosticEmitter {
|
||||
// at '<': TypeParameter (',' TypeParameter)* '>'
|
||||
|
||||
var typeParameters = new Array<TypeParameterNode>();
|
||||
var seenOptional = false;
|
||||
while (!tn.skip(Token.GREATERTHAN)) {
|
||||
let typeParameter = this.parseTypeParameter(tn);
|
||||
if (!typeParameter) return null;
|
||||
if (typeParameter.defaultType !== null) {
|
||||
seenOptional = true;
|
||||
} else if (seenOptional) {
|
||||
this.error(
|
||||
DiagnosticCode.Required_type_parameters_may_not_follow_optional_type_parameters,
|
||||
typeParameter.range
|
||||
);
|
||||
typeParameter.defaultType = null;
|
||||
}
|
||||
typeParameters.push(<TypeParameterNode>typeParameter);
|
||||
if (!tn.skip(Token.COMMA)) {
|
||||
if (tn.skip(Token.GREATERTHAN)) {
|
||||
@ -955,7 +966,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
tn: Tokenizer
|
||||
): TypeParameterNode | null {
|
||||
|
||||
// before: Identifier ('extends' Type)?
|
||||
// before: Identifier ('extends' Type)? ('=' Type)?
|
||||
|
||||
if (tn.next() == Token.IDENTIFIER) {
|
||||
let identifier = Node.createIdentifierExpression(
|
||||
@ -975,9 +986,23 @@ export class Parser extends DiagnosticEmitter {
|
||||
}
|
||||
extendsType = <TypeNode>t;
|
||||
}
|
||||
let defaultType: TypeNode | null = null;
|
||||
if (tn.skip(Token.EQUALS)) {
|
||||
let t = this.parseType(tn);
|
||||
if (!t) return null;
|
||||
if (t.kind != NodeKind.TYPE) {
|
||||
this.error(
|
||||
DiagnosticCode.Operation_not_supported,
|
||||
t.range
|
||||
);
|
||||
return null;
|
||||
}
|
||||
defaultType = <TypeNode>t;
|
||||
}
|
||||
return Node.createTypeParameter(
|
||||
identifier,
|
||||
extendsType,
|
||||
defaultType,
|
||||
Range.join(identifier.range, tn.range())
|
||||
);
|
||||
} else {
|
||||
@ -1602,16 +1627,18 @@ export class Parser extends DiagnosticEmitter {
|
||||
var isInterface = parent.kind == NodeKind.INTERFACEDECLARATION;
|
||||
|
||||
var decorators = new Array<DecoratorNode>();
|
||||
while (tn.skip(Token.AT)) {
|
||||
let decorator = this.parseDecorator(tn);
|
||||
if (!decorator) break;
|
||||
if (tn.skip(Token.AT)) {
|
||||
do {
|
||||
let decorator = this.parseDecorator(tn);
|
||||
if (!decorator) break;
|
||||
decorators.push(<DecoratorNode>decorator);
|
||||
} while (tn.skip(Token.AT));
|
||||
if (isInterface) {
|
||||
this.error(
|
||||
DiagnosticCode.Decorators_are_not_valid_here,
|
||||
decorator.range
|
||||
Range.join(decorators[0].range, decorators[decorators.length - 1].range)
|
||||
);
|
||||
}
|
||||
decorators.push(<DecoratorNode>decorator);
|
||||
}
|
||||
|
||||
// inherit ambient status
|
||||
@ -1620,6 +1647,8 @@ export class Parser extends DiagnosticEmitter {
|
||||
// implemented methods are virtual
|
||||
if (isInterface) flags |= CommonFlags.VIRTUAL;
|
||||
|
||||
var accessStart = 0;
|
||||
var accessEnd = 0;
|
||||
if (tn.skip(Token.PUBLIC)) {
|
||||
if (isInterface) {
|
||||
this.error(
|
||||
@ -1628,6 +1657,8 @@ export class Parser extends DiagnosticEmitter {
|
||||
);
|
||||
}
|
||||
flags |= CommonFlags.PUBLIC;
|
||||
accessStart = tn.tokenPos;
|
||||
accessEnd = tn.pos;
|
||||
} else if (tn.skip(Token.PRIVATE)) {
|
||||
if (isInterface) {
|
||||
this.error(
|
||||
@ -1636,6 +1667,8 @@ export class Parser extends DiagnosticEmitter {
|
||||
);
|
||||
}
|
||||
flags |= CommonFlags.PRIVATE;
|
||||
accessStart = tn.tokenPos;
|
||||
accessEnd = tn.pos;
|
||||
} else if (tn.skip(Token.PROTECTED)) {
|
||||
if (isInterface) {
|
||||
this.error(
|
||||
@ -1644,12 +1677,14 @@ export class Parser extends DiagnosticEmitter {
|
||||
);
|
||||
}
|
||||
flags |= CommonFlags.PROTECTED;
|
||||
accessStart = tn.tokenPos;
|
||||
accessEnd = tn.pos;
|
||||
}
|
||||
|
||||
var staticStart: i32 = 0;
|
||||
var staticEnd: i32 = 0;
|
||||
var abstractStart: i32 = 0;
|
||||
var abstractEnd: i32 = 0;
|
||||
var staticStart = 0;
|
||||
var staticEnd = 0;
|
||||
var abstractStart = 0;
|
||||
var abstractEnd = 0;
|
||||
if (tn.skip(Token.STATIC)) {
|
||||
if (isInterface) {
|
||||
this.error(
|
||||
@ -1673,9 +1708,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
abstractStart = tn.tokenPos;
|
||||
abstractEnd = tn.pos;
|
||||
}
|
||||
if (parent.flags & CommonFlags.GENERIC) {
|
||||
flags |= CommonFlags.GENERIC_CONTEXT;
|
||||
}
|
||||
if (parent.flags & CommonFlags.GENERIC) flags |= CommonFlags.GENERIC_CONTEXT;
|
||||
}
|
||||
|
||||
var readonlyStart: i32 = 0;
|
||||
@ -1713,7 +1746,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
}
|
||||
} else if (tn.skip(Token.SET)) {
|
||||
if (tn.peek(true, IdentifierHandling.PREFER) == Token.IDENTIFIER && !tn.nextTokenOnNewLine) {
|
||||
flags |= CommonFlags.SET | CommonFlags.SET;
|
||||
flags |= CommonFlags.SET;
|
||||
isSetter = true;
|
||||
setStart = tn.tokenPos;
|
||||
setEnd = tn.pos;
|
||||
@ -1750,17 +1783,60 @@ export class Parser extends DiagnosticEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
if (!isConstructor && !tn.skipIdentifier()) {
|
||||
this.error(
|
||||
DiagnosticCode.Identifier_expected,
|
||||
tn.range()
|
||||
);
|
||||
return null;
|
||||
var name: IdentifierExpression;
|
||||
if (isConstructor) {
|
||||
name = Node.createConstructorExpression(tn.range());
|
||||
} else {
|
||||
if (!(isGetter || isSetter) && tn.skip(Token.OPENBRACKET)) {
|
||||
// TODO: also handle symbols, which might have some of these modifiers
|
||||
if (flags & CommonFlags.PUBLIC) {
|
||||
this.error(
|
||||
DiagnosticCode._0_modifier_cannot_be_used_here,
|
||||
tn.range(accessStart, accessEnd), "public"
|
||||
); // recoverable
|
||||
} else if (flags & CommonFlags.PROTECTED) {
|
||||
this.error(
|
||||
DiagnosticCode._0_modifier_cannot_be_used_here,
|
||||
tn.range(accessStart, accessEnd), "protected"
|
||||
); // recoverable
|
||||
} else if (flags & CommonFlags.PRIVATE) {
|
||||
this.error(
|
||||
DiagnosticCode._0_modifier_cannot_be_used_here,
|
||||
tn.range(accessStart, accessEnd), "protected"
|
||||
); // recoverable
|
||||
}
|
||||
if (flags & CommonFlags.STATIC) {
|
||||
this.error(
|
||||
DiagnosticCode._0_modifier_cannot_be_used_here,
|
||||
tn.range(staticStart, staticEnd), "static"
|
||||
); // recoverable
|
||||
}
|
||||
if (flags & CommonFlags.ABSTRACT) {
|
||||
this.error(
|
||||
DiagnosticCode._0_modifier_cannot_be_used_here,
|
||||
tn.range(abstractStart, abstractEnd), "abstract"
|
||||
); // recoverable
|
||||
}
|
||||
if (flags & CommonFlags.READONLY) {
|
||||
this.error(
|
||||
DiagnosticCode._0_modifier_cannot_be_used_here,
|
||||
tn.range(readonlyStart, readonlyEnd), "readonly"
|
||||
); // recoverable
|
||||
}
|
||||
let retIndex = this.parseIndexSignatureDeclaration(tn, decorators);
|
||||
if (!retIndex) return null;
|
||||
tn.skip(Token.SEMICOLON);
|
||||
return retIndex;
|
||||
}
|
||||
if (!tn.skipIdentifier()) {
|
||||
this.error(
|
||||
DiagnosticCode.Identifier_expected,
|
||||
tn.range()
|
||||
);
|
||||
return null;
|
||||
}
|
||||
name = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());
|
||||
}
|
||||
|
||||
var name = isConstructor
|
||||
? Node.createConstructorExpression(tn.range())
|
||||
: Node.createIdentifierExpression(tn.readIdentifier(), tn.range());
|
||||
var typeParameters: TypeParameterNode[] | null = null;
|
||||
if (tn.skip(Token.LESSTHAN)) {
|
||||
let typeParametersStart = tn.tokenPos;
|
||||
@ -1979,6 +2055,69 @@ export class Parser extends DiagnosticEmitter {
|
||||
return null;
|
||||
}
|
||||
|
||||
parseIndexSignatureDeclaration(tn: Tokenizer, decorators: DecoratorNode[]): IndexSignatureDeclaration | null {
|
||||
|
||||
// at: '[': 'key' ':' Type ']' ':' Type
|
||||
|
||||
if (decorators.length) {
|
||||
this.error(
|
||||
DiagnosticCode.Decorators_are_not_valid_here,
|
||||
Range.join(decorators[0].range, decorators[decorators.length - 1].range)
|
||||
); // recoverable
|
||||
}
|
||||
|
||||
var start = tn.tokenPos;
|
||||
if (tn.skipIdentifier()) {
|
||||
let id = tn.readIdentifier();
|
||||
if (id == "key") {
|
||||
if (tn.skip(Token.COLON)) {
|
||||
let keyType = this.parseType(tn);
|
||||
if (!keyType) return null;
|
||||
if (keyType.kind != NodeKind.TYPE) {
|
||||
this.error(
|
||||
DiagnosticCode.Type_expected,
|
||||
tn.range()
|
||||
);
|
||||
return null;
|
||||
}
|
||||
if (tn.skip(Token.CLOSEBRACKET)) {
|
||||
if (tn.skip(Token.COLON)) {
|
||||
let valueType = this.parseType(tn);
|
||||
if (!valueType) return null;
|
||||
return Node.createIndexSignatureDeclaration(<TypeNode>keyType, valueType, tn.range(start, tn.pos));
|
||||
} else {
|
||||
this.error(
|
||||
DiagnosticCode._0_expected,
|
||||
tn.range(), ":"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.error(
|
||||
DiagnosticCode._0_expected,
|
||||
tn.range(), "]"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.error(
|
||||
DiagnosticCode._0_expected,
|
||||
tn.range(), ":"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.error(
|
||||
DiagnosticCode._0_expected,
|
||||
tn.range(), "key"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.error(
|
||||
DiagnosticCode.Identifier_expected,
|
||||
tn.range()
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
parseNamespace(
|
||||
tn: Tokenizer,
|
||||
flags: CommonFlags,
|
||||
|
@ -965,6 +965,7 @@ export class Program extends DiagnosticEmitter {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NodeKind.INDEXSIGNATUREDECLARATION: break; // ignored for now
|
||||
default: {
|
||||
assert(false); // should have been reported while parsing
|
||||
return;
|
||||
@ -2413,6 +2414,21 @@ export class FunctionPrototype extends Element {
|
||||
this.decoratorFlags = decoratorFlags;
|
||||
}
|
||||
|
||||
/** Applies class type arguments to the context of a partially resolved instance method. */
|
||||
applyClassTypeArguments(contextualTypeArguments: Map<string,Type>): void {
|
||||
var classTypeArguments = assert(this.classTypeArguments); // set only if partial
|
||||
var classDeclaration = assert(this.classPrototype).declaration;
|
||||
var classTypeParameters = classDeclaration.typeParameters;
|
||||
var numClassTypeParameters = classTypeParameters.length;
|
||||
assert(numClassTypeParameters == classTypeArguments.length);
|
||||
for (let i = 0; i < numClassTypeParameters; ++i) {
|
||||
contextualTypeArguments.set(
|
||||
classTypeParameters[i].name.text,
|
||||
classTypeArguments[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
toString(): string { return this.simpleName; }
|
||||
}
|
||||
|
||||
|
262
src/resolver.ts
262
src/resolver.ts
@ -51,7 +51,8 @@ import {
|
||||
import {
|
||||
Type,
|
||||
Signature,
|
||||
typesToString
|
||||
typesToString,
|
||||
TypeKind
|
||||
} from "./types";
|
||||
|
||||
import {
|
||||
@ -60,6 +61,10 @@ import {
|
||||
CommonFlags
|
||||
} from "./common";
|
||||
|
||||
import {
|
||||
makeMap
|
||||
} from "./util";
|
||||
|
||||
/** Indicates whether errors are reported or not. */
|
||||
export enum ReportMode {
|
||||
/** Report errors. */
|
||||
@ -78,6 +83,8 @@ export class Resolver extends DiagnosticEmitter {
|
||||
currentThisExpression: Expression | null = null;
|
||||
/** Element expression of the previously resolved element access. */
|
||||
currentElementExpression : Expression | null = null;
|
||||
/** Whether the last resolved type has been resolved from a placeholder, i.e. `T`. */
|
||||
currentTypeIsPlaceholder: bool = false;
|
||||
|
||||
/** Constructs the resolver for the specified program. */
|
||||
constructor(program: Program) {
|
||||
@ -131,7 +138,7 @@ export class Resolver extends DiagnosticEmitter {
|
||||
let instance = this.resolveClassInclTypeArguments(
|
||||
<ClassPrototype>element,
|
||||
typeNode.typeArguments,
|
||||
contextualTypeArguments,
|
||||
makeMap<string,Type>(contextualTypeArguments),
|
||||
node
|
||||
); // reports
|
||||
if (!instance) return null;
|
||||
@ -148,30 +155,29 @@ export class Resolver extends DiagnosticEmitter {
|
||||
}
|
||||
|
||||
// resolve parameters
|
||||
{
|
||||
let typeArgumentNodes = typeNode.typeArguments;
|
||||
if (typeArgumentNodes) {
|
||||
let numTypeArguments = typeArgumentNodes.length;
|
||||
let paramTypes = new Array<Type>(numTypeArguments);
|
||||
for (let i = 0; i < numTypeArguments; ++i) {
|
||||
let paramType = this.resolveType( // reports
|
||||
typeArgumentNodes[i],
|
||||
contextualTypeArguments,
|
||||
reportMode
|
||||
);
|
||||
if (!paramType) return null;
|
||||
paramTypes[i] = paramType;
|
||||
}
|
||||
if (numTypeArguments) { // can't be a placeholder if it has parameters
|
||||
let instanceKey = typesToString(paramTypes);
|
||||
if (instanceKey.length) {
|
||||
localName += "<" + instanceKey + ">";
|
||||
globalName += "<" + instanceKey + ">";
|
||||
}
|
||||
} else if (contextualTypeArguments) {
|
||||
let placeholderType = contextualTypeArguments.get(globalName);
|
||||
if (placeholderType) return placeholderType;
|
||||
var typeArgumentNodes = typeNode.typeArguments;
|
||||
var typeArguments: Type[] | null = null;
|
||||
if (typeArgumentNodes) {
|
||||
let numTypeArguments = typeArgumentNodes.length;
|
||||
typeArguments = new Array<Type>(numTypeArguments);
|
||||
for (let i = 0; i < numTypeArguments; ++i) {
|
||||
let paramType = this.resolveType( // reports
|
||||
typeArgumentNodes[i],
|
||||
contextualTypeArguments,
|
||||
reportMode
|
||||
);
|
||||
if (!paramType) return null;
|
||||
typeArguments[i] = paramType;
|
||||
}
|
||||
if (numTypeArguments) { // can't be a placeholder if it has parameters
|
||||
let instanceKey = typesToString(typeArguments);
|
||||
if (instanceKey.length) {
|
||||
localName += "<" + instanceKey + ">";
|
||||
globalName += "<" + instanceKey + ">";
|
||||
}
|
||||
} else if (contextualTypeArguments) {
|
||||
let placeholderType = contextualTypeArguments.get(globalName);
|
||||
if (placeholderType) return placeholderType;
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,6 +193,36 @@ export class Resolver extends DiagnosticEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
// check built-in macro types
|
||||
if (simpleName == "NATIVE") {
|
||||
if (!(typeArguments && typeArguments.length == 1)) {
|
||||
if (reportMode == ReportMode.REPORT) {
|
||||
this.error(
|
||||
DiagnosticCode.Expected_0_type_arguments_but_got_1,
|
||||
typeNode.range, "1", (typeArgumentNodes ? typeArgumentNodes.length : 1).toString(10)
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
switch (typeArguments[0].kind) {
|
||||
case TypeKind.I8:
|
||||
case TypeKind.I16:
|
||||
case TypeKind.I32: return Type.i32;
|
||||
case TypeKind.ISIZE: if (!this.program.options.isWasm64) return Type.i32;
|
||||
case TypeKind.I64: return Type.i64;
|
||||
case TypeKind.U8:
|
||||
case TypeKind.U16:
|
||||
case TypeKind.U32:
|
||||
case TypeKind.BOOL: return Type.u32;
|
||||
case TypeKind.USIZE: if (!this.program.options.isWasm64) return Type.u32;
|
||||
case TypeKind.U64: return Type.u64;
|
||||
case TypeKind.F32: return Type.f32;
|
||||
case TypeKind.F64: return Type.f64;
|
||||
case TypeKind.VOID: return Type.void;
|
||||
default: assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (reportMode == ReportMode.REPORT) {
|
||||
this.error(
|
||||
DiagnosticCode.Cannot_find_name_0,
|
||||
@ -255,39 +291,47 @@ export class Resolver extends DiagnosticEmitter {
|
||||
resolveTypeArguments(
|
||||
typeParameters: TypeParameterNode[],
|
||||
typeArgumentNodes: CommonTypeNode[] | null,
|
||||
contextualTypeArguments: Map<string,Type> | null = null,
|
||||
contextualTypeArguments: Map<string,Type>,
|
||||
alternativeReportNode: Node | null = null,
|
||||
reportMode: ReportMode = ReportMode.REPORT
|
||||
): Type[] | null {
|
||||
var parameterCount = typeParameters.length;
|
||||
var minParameterCount = 0;
|
||||
var maxParameterCount = 0;
|
||||
for (let i = 0; i < typeParameters.length; ++i) {
|
||||
if (!typeParameters[i].defaultType) ++minParameterCount;
|
||||
++maxParameterCount;
|
||||
}
|
||||
var argumentCount = typeArgumentNodes ? typeArgumentNodes.length : 0;
|
||||
if (parameterCount != argumentCount) {
|
||||
if (argumentCount) {
|
||||
this.error(
|
||||
DiagnosticCode.Expected_0_type_arguments_but_got_1,
|
||||
Range.join(
|
||||
(<TypeNode[]>typeArgumentNodes)[0].range,
|
||||
(<TypeNode[]>typeArgumentNodes)[argumentCount - 1].range
|
||||
),
|
||||
parameterCount.toString(10), argumentCount.toString(10)
|
||||
);
|
||||
} else if (alternativeReportNode) {
|
||||
this.error(
|
||||
DiagnosticCode.Expected_0_type_arguments_but_got_1,
|
||||
alternativeReportNode.range.atEnd, parameterCount.toString(10), "0"
|
||||
);
|
||||
}
|
||||
if (argumentCount < minParameterCount || argumentCount > maxParameterCount) {
|
||||
this.error(
|
||||
DiagnosticCode.Expected_0_type_arguments_but_got_1,
|
||||
argumentCount
|
||||
? Range.join(
|
||||
(<TypeNode[]>typeArgumentNodes)[0].range,
|
||||
(<TypeNode[]>typeArgumentNodes)[argumentCount - 1].range
|
||||
)
|
||||
: assert(alternativeReportNode).range.atEnd,
|
||||
(argumentCount < minParameterCount ? minParameterCount : maxParameterCount).toString(10),
|
||||
argumentCount.toString(10)
|
||||
);
|
||||
return null;
|
||||
}
|
||||
var typeArguments = new Array<Type>(parameterCount);
|
||||
for (let i = 0; i < parameterCount; ++i) {
|
||||
let type = this.resolveType( // reports
|
||||
(<TypeNode[]>typeArgumentNodes)[i],
|
||||
contextualTypeArguments,
|
||||
reportMode
|
||||
);
|
||||
var typeArguments = new Array<Type>(maxParameterCount);
|
||||
for (let i = 0; i < maxParameterCount; ++i) {
|
||||
let type = i < argumentCount
|
||||
? this.resolveType( // reports
|
||||
(<TypeNode[]>typeArgumentNodes)[i],
|
||||
contextualTypeArguments,
|
||||
reportMode
|
||||
)
|
||||
: this.resolveType( // reports
|
||||
assert(typeParameters[i].defaultType),
|
||||
contextualTypeArguments,
|
||||
reportMode
|
||||
);
|
||||
if (!type) return null;
|
||||
// TODO: check extendsType
|
||||
contextualTypeArguments.set(typeParameters[i].name.text, type);
|
||||
typeArguments[i] = type;
|
||||
}
|
||||
return typeArguments;
|
||||
@ -407,7 +451,7 @@ export class Resolver extends DiagnosticEmitter {
|
||||
let getter = this.resolveFunction(
|
||||
assert((<Property>target).getterPrototype),
|
||||
null,
|
||||
null,
|
||||
makeMap<string,Type>(),
|
||||
reportMode
|
||||
);
|
||||
if (!getter) return null;
|
||||
@ -662,7 +706,7 @@ export class Resolver extends DiagnosticEmitter {
|
||||
let instance = this.resolveFunctionInclTypeArguments(
|
||||
<FunctionPrototype>target,
|
||||
(<CallExpression>expression).typeArguments,
|
||||
contextualFunction.flow.contextualTypeArguments,
|
||||
makeMap<string,Type>(contextualFunction.flow.contextualTypeArguments),
|
||||
expression,
|
||||
reportMode
|
||||
);
|
||||
@ -710,10 +754,10 @@ export class Resolver extends DiagnosticEmitter {
|
||||
resolveFunction(
|
||||
prototype: FunctionPrototype,
|
||||
typeArguments: Type[] | null,
|
||||
contextualTypeArguments: Map<string,Type> | null = null,
|
||||
contextualTypeArguments: Map<string,Type> = makeMap<string,Type>(),
|
||||
reportMode: ReportMode = ReportMode.REPORT
|
||||
): Function | null {
|
||||
var classTypeArguments = prototype.classTypeArguments;
|
||||
var classTypeArguments = prototype.classTypeArguments; // set only if partially resolved
|
||||
var classInstanceKey = classTypeArguments ? typesToString(classTypeArguments) : "";
|
||||
var instanceKey = typeArguments ? typesToString(typeArguments) : "";
|
||||
var classInstances = prototype.instances.get(classInstanceKey);
|
||||
@ -726,34 +770,8 @@ export class Resolver extends DiagnosticEmitter {
|
||||
var isInstance = prototype.is(CommonFlags.INSTANCE);
|
||||
var classPrototype = prototype.classPrototype;
|
||||
|
||||
// inherit contextual type arguments as provided. might be overridden.
|
||||
var inheritedTypeArguments = contextualTypeArguments;
|
||||
contextualTypeArguments = new Map();
|
||||
if (inheritedTypeArguments) {
|
||||
for (let [inheritedName, inheritedType] of inheritedTypeArguments) {
|
||||
contextualTypeArguments.set(
|
||||
inheritedName,
|
||||
inheritedType
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// override with class type arguments if a partially resolved instance method
|
||||
if (classTypeArguments) { // set only if partially resolved
|
||||
assert(prototype.is(CommonFlags.INSTANCE));
|
||||
let classDeclaration = assert(classPrototype).declaration;
|
||||
let classTypeParameters = classDeclaration.typeParameters;
|
||||
let numClassTypeParameters = classTypeParameters.length;
|
||||
assert(numClassTypeParameters == classTypeArguments.length);
|
||||
for (let i = 0; i < numClassTypeParameters; ++i) {
|
||||
contextualTypeArguments.set(
|
||||
classTypeParameters[i].name.text,
|
||||
classTypeArguments[i]
|
||||
);
|
||||
}
|
||||
} else {
|
||||
assert(!classTypeArguments);
|
||||
}
|
||||
// apply class type arguments if a partially resolved instance method
|
||||
if (classTypeArguments) prototype.applyClassTypeArguments(contextualTypeArguments);
|
||||
|
||||
// override with function specific type arguments
|
||||
var signatureNode = declaration.signature;
|
||||
@ -869,13 +887,21 @@ export class Resolver extends DiagnosticEmitter {
|
||||
resolveFunctionInclTypeArguments(
|
||||
prototype: FunctionPrototype,
|
||||
typeArgumentNodes: CommonTypeNode[] | null,
|
||||
contextualTypeArguments: Map<string,Type> | null,
|
||||
contextualTypeArguments: Map<string,Type>,
|
||||
reportNode: Node,
|
||||
reportMode: ReportMode = ReportMode.REPORT
|
||||
): Function | null {
|
||||
var resolvedTypeArguments: Type[] | null = null;
|
||||
|
||||
// Resolve type arguments if generic
|
||||
if (prototype.is(CommonFlags.GENERIC)) {
|
||||
assert(typeArgumentNodes != null && typeArgumentNodes.length != 0);
|
||||
|
||||
// apply class type arguments if a partially resolved instance method
|
||||
// FIXME: this is done once more in resolveFunction. required here for resolveTypeArguments,
|
||||
// required there for just resolving a function no matter if a partial or not.
|
||||
let classTypeArguments = prototype.classTypeArguments;
|
||||
if (classTypeArguments) prototype.applyClassTypeArguments(contextualTypeArguments);
|
||||
|
||||
resolvedTypeArguments = this.resolveTypeArguments( // reports
|
||||
assert(prototype.declaration.typeParameters),
|
||||
typeArgumentNodes,
|
||||
@ -884,7 +910,21 @@ export class Resolver extends DiagnosticEmitter {
|
||||
reportMode
|
||||
);
|
||||
if (!resolvedTypeArguments) return null;
|
||||
|
||||
// Otherwise make sure that no type arguments have been specified
|
||||
} else {
|
||||
if (typeArgumentNodes !== null && typeArgumentNodes.length) {
|
||||
if (reportMode == ReportMode.REPORT) {
|
||||
this.error(
|
||||
DiagnosticCode.Type_0_is_not_generic,
|
||||
reportNode.range, prototype.internalName
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Continue with concrete types
|
||||
return this.resolveFunction(
|
||||
prototype,
|
||||
resolvedTypeArguments,
|
||||
@ -897,7 +937,7 @@ export class Resolver extends DiagnosticEmitter {
|
||||
resolveClass(
|
||||
prototype: ClassPrototype,
|
||||
typeArguments: Type[] | null,
|
||||
contextualTypeArguments: Map<string,Type> | null = null,
|
||||
contextualTypeArguments: Map<string,Type> = makeMap<string,Type>(),
|
||||
reportMode: ReportMode = ReportMode.REPORT
|
||||
): Class | null {
|
||||
var instanceKey = typeArguments ? typesToString(typeArguments) : "";
|
||||
@ -906,15 +946,6 @@ export class Resolver extends DiagnosticEmitter {
|
||||
var instance = prototype.instances.get(instanceKey);
|
||||
if (instance) return instance;
|
||||
|
||||
// Copy contextual type arguments so we don't pollute the original map
|
||||
var inheritedTypeArguments = contextualTypeArguments;
|
||||
contextualTypeArguments = new Map();
|
||||
if (inheritedTypeArguments) {
|
||||
for (let [inheritedName, inheritedType] of inheritedTypeArguments) {
|
||||
contextualTypeArguments.set(inheritedName, inheritedType);
|
||||
}
|
||||
}
|
||||
|
||||
// Insert contextual type arguments for this operation. Internally, this method is always
|
||||
// called with matching type parameter / argument counts.
|
||||
var declaration = prototype.declaration;
|
||||
@ -993,14 +1024,20 @@ export class Resolver extends DiagnosticEmitter {
|
||||
}
|
||||
|
||||
// Resolve constructor by first applying the class type arguments
|
||||
if (prototype.constructorPrototype) {
|
||||
var constructorPrototype = prototype.constructorPrototype;
|
||||
if (constructorPrototype) {
|
||||
let constructorPartial = this.resolveFunctionPartially(
|
||||
prototype.constructorPrototype,
|
||||
constructorPrototype,
|
||||
typeArguments,
|
||||
reportMode
|
||||
);
|
||||
if (!constructorPartial) return null;
|
||||
instance.constructorInstance = this.resolveFunction(constructorPartial, null, null, reportMode);
|
||||
instance.constructorInstance = this.resolveFunction(
|
||||
constructorPartial,
|
||||
null,
|
||||
makeMap<string,Type>(),
|
||||
reportMode
|
||||
);
|
||||
}
|
||||
|
||||
// Resolve instance members
|
||||
@ -1125,9 +1162,19 @@ export class Resolver extends DiagnosticEmitter {
|
||||
reportMode
|
||||
);
|
||||
if (!operatorPartial) continue;
|
||||
operatorInstance = this.resolveFunction(operatorPartial, null, null, reportMode);
|
||||
operatorInstance = this.resolveFunction(
|
||||
operatorPartial,
|
||||
null,
|
||||
makeMap<string,Type>(),
|
||||
reportMode
|
||||
);
|
||||
} else {
|
||||
operatorInstance = this.resolveFunction(overloadPrototype, null, null, reportMode);
|
||||
operatorInstance = this.resolveFunction(
|
||||
overloadPrototype,
|
||||
null,
|
||||
makeMap<string,Type>(),
|
||||
reportMode
|
||||
);
|
||||
}
|
||||
if (!operatorInstance) continue;
|
||||
let overloads = instance.overloads;
|
||||
@ -1141,7 +1188,7 @@ export class Resolver extends DiagnosticEmitter {
|
||||
resolveClassInclTypeArguments(
|
||||
prototype: ClassPrototype,
|
||||
typeArgumentNodes: CommonTypeNode[] | null,
|
||||
contextualTypeArguments: Map<string,Type> | null,
|
||||
contextualTypeArguments: Map<string,Type>,
|
||||
reportNode: Node,
|
||||
reportMode: ReportMode = ReportMode.REPORT
|
||||
): Class | null {
|
||||
@ -1149,21 +1196,8 @@ export class Resolver extends DiagnosticEmitter {
|
||||
|
||||
// Resolve type arguments if generic
|
||||
if (prototype.is(CommonFlags.GENERIC)) {
|
||||
let typeParameterNodes = prototype.declaration.typeParameters;
|
||||
let expectedTypeArguments = typeParameterNodes.length;
|
||||
assert(expectedTypeArguments > 0);
|
||||
let actualTypeArguments = typeArgumentNodes !== null ? typeArgumentNodes.length : 0;
|
||||
if (expectedTypeArguments != actualTypeArguments) {
|
||||
if (reportMode == ReportMode.REPORT) {
|
||||
this.error(
|
||||
DiagnosticCode.Expected_0_type_arguments_but_got_1,
|
||||
reportNode.range, expectedTypeArguments.toString(10), actualTypeArguments.toString(10)
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
resolvedTypeArguments = this.resolveTypeArguments(
|
||||
typeParameterNodes,
|
||||
assert(prototype.declaration.typeParameters),
|
||||
typeArgumentNodes,
|
||||
contextualTypeArguments,
|
||||
reportNode,
|
||||
|
26
src/util/collections.ts
Normal file
26
src/util/collections.ts
Normal file
@ -0,0 +1,26 @@
|
||||
export function makeArray<V>(original: Array<V> | null = null): Array<V> {
|
||||
if (original) {
|
||||
let cloned = new Array<V>(original.length);
|
||||
for (let i = 0, k = original.length; i < k; ++i) unchecked(cloned[i] = original[i]);
|
||||
return cloned;
|
||||
}
|
||||
return new Array<V>();
|
||||
}
|
||||
|
||||
export function makeSet<V>(original: Set<V> | null = null): Set<V> {
|
||||
if (original) {
|
||||
let cloned = new Set<V>();
|
||||
for (let v of original) cloned.add(v);
|
||||
return cloned;
|
||||
}
|
||||
return new Set<V>();
|
||||
}
|
||||
|
||||
export function makeMap<K,V>(original: Map<K,V> | null = null): Map<K,V> {
|
||||
if (original) {
|
||||
let cloned = new Map<K,V>();
|
||||
for (let [k, v] of original) cloned.set(k, v);
|
||||
return cloned;
|
||||
}
|
||||
return new Map<K,V>();
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
*//***/
|
||||
|
||||
export * from "./charcode";
|
||||
export * from "./collections";
|
||||
export * from "./path";
|
||||
export * from "./text";
|
||||
export * from "./binary";
|
||||
|
@ -3,8 +3,8 @@ import {
|
||||
HEADER_SIZE,
|
||||
allocateUnsafe,
|
||||
reallocateUnsafe,
|
||||
loadUnsafe,
|
||||
storeUnsafe
|
||||
LOAD,
|
||||
STORE
|
||||
} from "./internal/arraybuffer";
|
||||
|
||||
import {
|
||||
@ -32,6 +32,7 @@ import {
|
||||
} from "./builtins";
|
||||
|
||||
export class Array<T> {
|
||||
[key: number]: T; // compatibility only
|
||||
|
||||
/* @internal */ buffer_: ArrayBuffer;
|
||||
/* @internal */ length_: i32;
|
||||
@ -74,7 +75,7 @@ export class Array<T> {
|
||||
every(callbackfn: (element: T, index: i32, array: Array<T>) => bool): bool {
|
||||
var buffer = this.buffer_;
|
||||
for (let index = 0, toIndex = this.length_; index < toIndex && index < this.length_; ++index) {
|
||||
if (!callbackfn(loadUnsafe<T,T>(buffer, index), index, this)) return false;
|
||||
if (!callbackfn(LOAD<T>(buffer, index), index, this)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -82,7 +83,7 @@ export class Array<T> {
|
||||
findIndex(predicate: (element: T, index: i32, array: Array<T>) => bool): i32 {
|
||||
var buffer = this.buffer_;
|
||||
for (let index = 0, toIndex = this.length_; index < toIndex && index < this.length_; ++index) {
|
||||
if (predicate(loadUnsafe<T,T>(buffer, index), index, this)) return index;
|
||||
if (predicate(LOAD<T>(buffer, index), index, this)) return index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -91,13 +92,13 @@ export class Array<T> {
|
||||
private __get(index: i32): T {
|
||||
var buffer = this.buffer_;
|
||||
return <u32>index < <u32>(buffer.byteLength >>> alignof<T>())
|
||||
? loadUnsafe<T,T>(buffer, index)
|
||||
? LOAD<T>(buffer, index)
|
||||
: <T>unreachable();
|
||||
}
|
||||
|
||||
@operator("{}")
|
||||
private __unchecked_get(index: i32): T {
|
||||
return loadUnsafe<T,T>(this.buffer_, index);
|
||||
return LOAD<T>(this.buffer_, index);
|
||||
}
|
||||
|
||||
@operator("[]=")
|
||||
@ -111,13 +112,13 @@ export class Array<T> {
|
||||
this.buffer_ = buffer;
|
||||
this.length_ = index + 1;
|
||||
}
|
||||
storeUnsafe<T,T>(buffer, index, value);
|
||||
STORE<T>(buffer, index, value);
|
||||
if (isManaged<T>()) __gc_link(changetype<usize>(this), changetype<usize>(value)); // tslint:disable-line
|
||||
}
|
||||
|
||||
@operator("{}=")
|
||||
private __unchecked_set(index: i32, value: T): void {
|
||||
storeUnsafe<T,T>(this.buffer_, index, value);
|
||||
STORE<T>(this.buffer_, index, value);
|
||||
if (isManaged<T>()) __gc_link(changetype<usize>(this), changetype<usize>(value)); // tslint:disable-line
|
||||
}
|
||||
|
||||
@ -138,7 +139,7 @@ export class Array<T> {
|
||||
}
|
||||
} else {
|
||||
for (; start < end; ++start) {
|
||||
storeUnsafe<T,T>(buffer, start, value);
|
||||
STORE<T>(buffer, start, value);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
@ -155,7 +156,7 @@ export class Array<T> {
|
||||
if (fromIndex < 0) fromIndex = max(length + fromIndex, 0);
|
||||
var buffer = this.buffer_;
|
||||
while (fromIndex < length) {
|
||||
if (loadUnsafe<T,T>(buffer, fromIndex) == searchElement) return fromIndex;
|
||||
if (LOAD<T>(buffer, fromIndex) == searchElement) return fromIndex;
|
||||
++fromIndex;
|
||||
}
|
||||
return -1;
|
||||
@ -168,7 +169,7 @@ export class Array<T> {
|
||||
else if (fromIndex >= length) fromIndex = length - 1;
|
||||
var buffer = this.buffer_;
|
||||
while (fromIndex >= 0) { // ^
|
||||
if (loadUnsafe<T,T>(buffer, fromIndex) == searchElement) return fromIndex;
|
||||
if (LOAD<T>(buffer, fromIndex) == searchElement) return fromIndex;
|
||||
--fromIndex;
|
||||
}
|
||||
return -1;
|
||||
@ -186,7 +187,7 @@ export class Array<T> {
|
||||
this.buffer_ = buffer;
|
||||
}
|
||||
this.length_ = newLength;
|
||||
storeUnsafe<T,T>(buffer, length, element);
|
||||
STORE<T>(buffer, length, element);
|
||||
if (isManaged<T>()) __gc_link(changetype<usize>(this), changetype<usize>(element)); // tslint:disable-line
|
||||
return newLength;
|
||||
}
|
||||
@ -228,7 +229,7 @@ export class Array<T> {
|
||||
from += count - 1;
|
||||
to += count - 1;
|
||||
while (count) {
|
||||
storeUnsafe<T,T>(buffer, to, loadUnsafe<T,T>(buffer, from));
|
||||
STORE<T>(buffer, to, LOAD<T>(buffer, from));
|
||||
--from, --to, --count;
|
||||
}
|
||||
} else {
|
||||
@ -244,7 +245,7 @@ export class Array<T> {
|
||||
pop(): T {
|
||||
var length = this.length_;
|
||||
if (length < 1) throw new RangeError("Array is empty");
|
||||
var element = loadUnsafe<T,T>(this.buffer_, --length);
|
||||
var element = LOAD<T>(this.buffer_, --length);
|
||||
this.length_ = length;
|
||||
return element;
|
||||
}
|
||||
@ -252,7 +253,7 @@ export class Array<T> {
|
||||
forEach(callbackfn: (value: T, index: i32, array: Array<T>) => void): void {
|
||||
var buffer = this.buffer_;
|
||||
for (let index = 0, toIndex = this.length_; index < toIndex && index < this.length_; ++index) {
|
||||
callbackfn(loadUnsafe<T,T>(buffer, index), index, this);
|
||||
callbackfn(LOAD<T>(buffer, index), index, this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -262,7 +263,7 @@ export class Array<T> {
|
||||
var result = new Array<U>(length);
|
||||
var resultBuffer = result.buffer_;
|
||||
for (let index = 0; index < length && index < this.length_; ++index) {
|
||||
storeUnsafe<U,U>(resultBuffer, index, callbackfn(loadUnsafe<T,T>(buffer, index), index, this));
|
||||
STORE<U>(resultBuffer, index, callbackfn(LOAD<T>(buffer, index), index, this));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -272,7 +273,7 @@ export class Array<T> {
|
||||
var length = this.length_;
|
||||
var result = new Array<T>();
|
||||
for (let index = 0; index < length && index < this.length_; ++index) {
|
||||
let value = loadUnsafe<T,T>(buffer, index);
|
||||
let value = LOAD<T>(buffer, index);
|
||||
if (callbackfn(value, index, this)) result.push(value);
|
||||
}
|
||||
return result;
|
||||
@ -285,7 +286,7 @@ export class Array<T> {
|
||||
var accum = initialValue;
|
||||
var buffer = this.buffer_;
|
||||
for (let index = 0, toIndex = this.length_; index < toIndex && index < this.length_; ++index) {
|
||||
accum = callbackfn(accum, loadUnsafe<T,T>(buffer, index), index, this);
|
||||
accum = callbackfn(accum, LOAD<T>(buffer, index), index, this);
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
@ -297,7 +298,7 @@ export class Array<T> {
|
||||
var accum = initialValue;
|
||||
var buffer = this.buffer_;
|
||||
for (let index: i32 = this.length_ - 1; index >= 0; --index) {
|
||||
accum = callbackfn(accum, loadUnsafe<T,T>(buffer, index), index, this);
|
||||
accum = callbackfn(accum, LOAD<T>(buffer, index), index, this);
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
@ -306,14 +307,14 @@ export class Array<T> {
|
||||
var length = this.length_;
|
||||
if (length < 1) throw new RangeError("Array is empty");
|
||||
var buffer = this.buffer_;
|
||||
var element = loadUnsafe<T,T>(buffer, 0);
|
||||
var element = LOAD<T>(buffer, 0);
|
||||
var lastIndex = length - 1;
|
||||
memory.copy(
|
||||
changetype<usize>(buffer) + HEADER_SIZE,
|
||||
changetype<usize>(buffer) + HEADER_SIZE + sizeof<T>(),
|
||||
<usize>lastIndex << alignof<T>()
|
||||
);
|
||||
storeUnsafe<T,T>(buffer, lastIndex, <T>null);
|
||||
STORE<T>(buffer, lastIndex, <T>null);
|
||||
this.length_ = lastIndex;
|
||||
return element;
|
||||
}
|
||||
@ -321,7 +322,7 @@ export class Array<T> {
|
||||
some(callbackfn: (element: T, index: i32, array: Array<T>) => bool): bool {
|
||||
var buffer = this.buffer_;
|
||||
for (let index = 0, toIndex = this.length_; index < toIndex && index < this.length_; ++index) {
|
||||
if (callbackfn(loadUnsafe<T,T>(buffer, index), index, this)) return true;
|
||||
if (callbackfn(LOAD<T>(buffer, index), index, this)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -343,7 +344,7 @@ export class Array<T> {
|
||||
changetype<usize>(buffer) + HEADER_SIZE,
|
||||
<usize>(capacity - 1) << alignof<T>()
|
||||
);
|
||||
storeUnsafe<T,T>(buffer, 0, element);
|
||||
STORE<T>(buffer, 0, element);
|
||||
this.length_ = newLength;
|
||||
if (isManaged<T>()) __gc_link(changetype<usize>(this), changetype<usize>(element)); // tslint:disable-line
|
||||
return newLength;
|
||||
@ -396,9 +397,9 @@ export class Array<T> {
|
||||
reverse(): Array<T> {
|
||||
var buffer = this.buffer_;
|
||||
for (let front = 0, back = this.length_ - 1; front < back; ++front, --back) {
|
||||
let temp = loadUnsafe<T,T>(buffer, front);
|
||||
storeUnsafe<T,T>(buffer, front, loadUnsafe<T,T>(buffer, back));
|
||||
storeUnsafe<T,T>(buffer, back, temp);
|
||||
let temp = LOAD<T>(buffer, front);
|
||||
STORE<T>(buffer, front, LOAD<T>(buffer, back));
|
||||
STORE<T>(buffer, back, temp);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -411,11 +412,11 @@ export class Array<T> {
|
||||
if (length <= 1) return this;
|
||||
var buffer = this.buffer_;
|
||||
if (length == 2) {
|
||||
let a = loadUnsafe<T,T>(buffer, 1); // a = arr[1]
|
||||
let b = loadUnsafe<T,T>(buffer, 0); // b = arr[0]
|
||||
let a = LOAD<T>(buffer, 1); // a = arr[1]
|
||||
let b = LOAD<T>(buffer, 0); // b = arr[0]
|
||||
if (comparator(a, b) < 0) {
|
||||
storeUnsafe<T,T>(buffer, 1, b); // arr[1] = b;
|
||||
storeUnsafe<T,T>(buffer, 0, a); // arr[0] = a;
|
||||
STORE<T>(buffer, 1, b); // arr[1] = b;
|
||||
STORE<T>(buffer, 0, a); // arr[0] = a;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -444,14 +445,14 @@ export class Array<T> {
|
||||
var hasSeparator = sepLen != 0;
|
||||
if (value instanceof bool) {
|
||||
if (!lastIndex) {
|
||||
return select<string>("true", "false", loadUnsafe<T,bool>(buffer, 0));
|
||||
return select<string>("true", "false", LOAD<T,bool>(buffer, 0));
|
||||
}
|
||||
let valueLen = 5; // max possible length of element len("false")
|
||||
let estLen = (valueLen + sepLen) * lastIndex + valueLen;
|
||||
let result = allocateUnsafeString(estLen);
|
||||
let offset = 0;
|
||||
for (let i = 0; i < lastIndex; ++i) {
|
||||
value = loadUnsafe<T,bool>(buffer, i);
|
||||
value = LOAD<T,bool>(buffer, i);
|
||||
valueLen = 4 + <i32>(!value);
|
||||
copyUnsafeString(result, offset, select<string>("true", "false", value), 0, valueLen);
|
||||
offset += valueLen;
|
||||
@ -460,7 +461,7 @@ export class Array<T> {
|
||||
offset += sepLen;
|
||||
}
|
||||
}
|
||||
value = loadUnsafe<T,bool>(buffer, lastIndex);
|
||||
value = LOAD<T,bool>(buffer, lastIndex);
|
||||
valueLen = 4 + <i32>(!value);
|
||||
copyUnsafeString(result, offset, select<string>("true", "false", value), 0, valueLen);
|
||||
offset += valueLen;
|
||||
@ -473,21 +474,21 @@ export class Array<T> {
|
||||
return out;
|
||||
} else if (isInteger<T>()) {
|
||||
if (!lastIndex) {
|
||||
return changetype<string>(itoa<T>(loadUnsafe<T,T>(buffer, 0)));
|
||||
return changetype<string>(itoa<T>(LOAD<T>(buffer, 0)));
|
||||
}
|
||||
const valueLen = (sizeof<T>() <= 4 ? 10 : 20) + <i32>isSigned<T>();
|
||||
let estLen = (valueLen + sepLen) * lastIndex + valueLen;
|
||||
let result = allocateUnsafeString(estLen);
|
||||
let offset = 0;
|
||||
for (let i = 0; i < lastIndex; ++i) {
|
||||
value = loadUnsafe<T,T>(buffer, i);
|
||||
value = LOAD<T>(buffer, i);
|
||||
offset += itoa_stream<T>(changetype<usize>(result), offset, value);
|
||||
if (hasSeparator) {
|
||||
copyUnsafeString(result, offset, separator, 0, sepLen);
|
||||
offset += sepLen;
|
||||
}
|
||||
}
|
||||
value = loadUnsafe<T,T>(buffer, lastIndex);
|
||||
value = LOAD<T>(buffer, lastIndex);
|
||||
offset += itoa_stream<T>(changetype<usize>(result), offset, value);
|
||||
let out = result;
|
||||
if (estLen > offset) {
|
||||
@ -497,21 +498,21 @@ export class Array<T> {
|
||||
return out;
|
||||
} else if (isFloat<T>()) {
|
||||
if (!lastIndex) {
|
||||
return changetype<string>(dtoa(loadUnsafe<T,f64>(buffer, 0)));
|
||||
return changetype<string>(dtoa(LOAD<T,f64>(buffer, 0)));
|
||||
}
|
||||
const valueLen = MAX_DOUBLE_LENGTH;
|
||||
let estLen = (valueLen + sepLen) * lastIndex + valueLen;
|
||||
let result = allocateUnsafeString(estLen);
|
||||
let offset = 0;
|
||||
for (let i = 0; i < lastIndex; ++i) {
|
||||
value = loadUnsafe<T,f64>(buffer, i);
|
||||
value = LOAD<T,f64>(buffer, i);
|
||||
offset += dtoa_stream(changetype<usize>(result), offset, value);
|
||||
if (hasSeparator) {
|
||||
copyUnsafeString(result, offset, separator, 0, sepLen);
|
||||
offset += sepLen;
|
||||
}
|
||||
}
|
||||
value = loadUnsafe<T,f64>(buffer, lastIndex);
|
||||
value = LOAD<T,f64>(buffer, lastIndex);
|
||||
offset += dtoa_stream(changetype<usize>(result), offset, value);
|
||||
let out = result;
|
||||
if (estLen > offset) {
|
||||
@ -521,16 +522,16 @@ export class Array<T> {
|
||||
return out;
|
||||
} else if (isString<T>()) {
|
||||
if (!lastIndex) {
|
||||
return loadUnsafe<T,string>(buffer, 0);
|
||||
return LOAD<string>(buffer, 0);
|
||||
}
|
||||
let estLen = 0;
|
||||
for (let i = 0, len = lastIndex + 1; i < len; ++i) {
|
||||
estLen += loadUnsafe<T,string>(buffer, i).length;
|
||||
estLen += LOAD<string>(buffer, i).length;
|
||||
}
|
||||
let offset = 0;
|
||||
let result = allocateUnsafeString(estLen + sepLen * lastIndex);
|
||||
for (let i = 0; i < lastIndex; ++i) {
|
||||
value = loadUnsafe<T,String>(buffer, i);
|
||||
value = LOAD<string>(buffer, i);
|
||||
if (value) {
|
||||
let valueLen = value.length; // tslint:disable-line:no-unsafe-any
|
||||
copyUnsafeString(result, offset, value, 0, valueLen); // tslint:disable-line:no-unsafe-any
|
||||
@ -541,7 +542,7 @@ export class Array<T> {
|
||||
offset += sepLen;
|
||||
}
|
||||
}
|
||||
value = loadUnsafe<T,String>(buffer, lastIndex);
|
||||
value = LOAD<string>(buffer, lastIndex);
|
||||
if (value) {
|
||||
let valueLen = value.length; // tslint:disable-line:no-unsafe-any
|
||||
copyUnsafeString(result, offset, value, 0, valueLen); // tslint:disable-line:no-unsafe-any
|
||||
@ -549,15 +550,15 @@ export class Array<T> {
|
||||
return result;
|
||||
} else if (isArray<T>()) {
|
||||
if (!lastIndex) {
|
||||
value = loadUnsafe<T,T>(buffer, 0);
|
||||
value = LOAD<T>(buffer, 0);
|
||||
return value ? value.join(separator) : ""; // tslint:disable-line:no-unsafe-any
|
||||
}
|
||||
for (let i = 0; i < lastIndex; ++i) {
|
||||
value = loadUnsafe<T,T>(buffer, i);
|
||||
value = LOAD<T>(buffer, i);
|
||||
if (value) result += value.join(separator); // tslint:disable-line:no-unsafe-any
|
||||
if (hasSeparator) result += separator;
|
||||
}
|
||||
value = loadUnsafe<T,T>(buffer, lastIndex);
|
||||
value = LOAD<T>(buffer, lastIndex);
|
||||
if (value) result += value.join(separator); // tslint:disable-line:no-unsafe-any
|
||||
return result;
|
||||
} else if (isReference<T>()) { // References
|
||||
@ -567,7 +568,7 @@ export class Array<T> {
|
||||
let result = allocateUnsafeString(estLen);
|
||||
let offset = 0;
|
||||
for (let i = 0; i < lastIndex; ++i) {
|
||||
value = loadUnsafe<T,T>(buffer, i);
|
||||
value = LOAD<T>(buffer, i);
|
||||
if (value) {
|
||||
copyUnsafeString(result, offset, changetype<String>("[object Object]"), 0, valueLen);
|
||||
offset += valueLen;
|
||||
@ -577,7 +578,7 @@ export class Array<T> {
|
||||
offset += sepLen;
|
||||
}
|
||||
}
|
||||
if (loadUnsafe<T,T>(buffer, lastIndex)) {
|
||||
if (LOAD<T>(buffer, lastIndex)) {
|
||||
copyUnsafeString(result, offset, changetype<String>("[object Object]"), 0, valueLen);
|
||||
offset += valueLen;
|
||||
}
|
||||
|
2
std/assembly/index.d.ts
vendored
2
std/assembly/index.d.ts
vendored
@ -365,6 +365,8 @@ declare namespace f64 {
|
||||
/** Converts A string to an integer. */
|
||||
export function parseInt(string: string, radix?: i32): f64;
|
||||
}
|
||||
/** Macro type evaluating to the underlying native WebAssembly type. */
|
||||
declare type NATIVE<T> = T;
|
||||
|
||||
// User-defined diagnostic macros
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {
|
||||
loadUnsafeWithOffset,
|
||||
storeUnsafeWithOffset
|
||||
LOAD,
|
||||
STORE
|
||||
} from "./arraybuffer";
|
||||
|
||||
import {
|
||||
@ -52,15 +52,15 @@ export function insertionSort<T>(
|
||||
comparator: (a: T, b: T) => i32
|
||||
): void {
|
||||
for (let i = 0; i < length; i++) {
|
||||
let a = loadUnsafeWithOffset<T,T>(buffer, i, byteOffset); // a = arr[i]
|
||||
let a = LOAD<T>(buffer, i, byteOffset); // a = arr[i]
|
||||
let j = i - 1;
|
||||
while (j >= 0) {
|
||||
let b = loadUnsafeWithOffset<T,T>(buffer, j, byteOffset); // b = arr[j]
|
||||
let b = LOAD<T>(buffer, j, byteOffset); // b = arr[j]
|
||||
if (comparator(a, b) < 0) {
|
||||
storeUnsafeWithOffset<T,T>(buffer, j-- + 1, b, byteOffset); // arr[j + 1] = b
|
||||
STORE<T>(buffer, j-- + 1, b, byteOffset); // arr[j + 1] = b
|
||||
} else break;
|
||||
}
|
||||
storeUnsafeWithOffset<T,T>(buffer, j + 1, a, byteOffset); // arr[j + 1] = a
|
||||
STORE<T>(buffer, j + 1, a, byteOffset); // arr[j + 1] = a
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,37 +84,37 @@ export function weakHeapSort<T>(
|
||||
while ((j & 1) == (load<u32>(bitset + (j >> 6 << shift32)) >> (j >> 1 & 31) & 1)) j >>= 1;
|
||||
|
||||
let p = j >> 1;
|
||||
let a = loadUnsafeWithOffset<T,T>(buffer, p, byteOffset); // a = arr[p]
|
||||
let b = loadUnsafeWithOffset<T,T>(buffer, i, byteOffset); // b = arr[i]
|
||||
let a = LOAD<T>(buffer, p, byteOffset); // a = arr[p]
|
||||
let b = LOAD<T>(buffer, i, byteOffset); // b = arr[i]
|
||||
if (comparator(a, b) < 0) {
|
||||
store<u32>(
|
||||
bitset + (i >> 5 << shift32),
|
||||
load<u32>(bitset + (i >> 5 << shift32)) ^ (1 << (i & 31))
|
||||
);
|
||||
storeUnsafeWithOffset<T,T>(buffer, i, a, byteOffset); // arr[i] = a
|
||||
storeUnsafeWithOffset<T,T>(buffer, p, b, byteOffset); // arr[p] = b
|
||||
STORE<T>(buffer, i, a, byteOffset); // arr[i] = a
|
||||
STORE<T>(buffer, p, b, byteOffset); // arr[p] = b
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = length - 1; i >= 2; i--) {
|
||||
let a = loadUnsafeWithOffset<T,T>(buffer, 0, byteOffset);
|
||||
storeUnsafeWithOffset<T,T>(buffer, 0, loadUnsafeWithOffset<T,T>(buffer, i, byteOffset), byteOffset);
|
||||
storeUnsafeWithOffset<T,T>(buffer, i, a, byteOffset);
|
||||
let a = LOAD<T>(buffer, 0, byteOffset);
|
||||
STORE<T>(buffer, 0, LOAD<T>(buffer, i, byteOffset), byteOffset);
|
||||
STORE<T>(buffer, i, a, byteOffset);
|
||||
|
||||
let x = 1, y: i32;
|
||||
while ((y = (x << 1) + ((load<u32>(bitset + (x >> 5 << shift32)) >> (x & 31)) & 1)) < i) x = y;
|
||||
|
||||
while (x > 0) {
|
||||
a = loadUnsafeWithOffset<T,T>(buffer, 0, byteOffset); // a = arr[0]
|
||||
let b = loadUnsafeWithOffset<T,T>(buffer, x, byteOffset); // b = arr[x]
|
||||
a = LOAD<T>(buffer, 0, byteOffset); // a = arr[0]
|
||||
let b = LOAD<T>(buffer, x, byteOffset); // b = arr[x]
|
||||
|
||||
if (comparator(a, b) < 0) {
|
||||
store<u32>(
|
||||
bitset + (x >> 5 << shift32),
|
||||
load<u32>(bitset + (x >> 5 << shift32)) ^ (1 << (x & 31))
|
||||
);
|
||||
storeUnsafeWithOffset<T,T>(buffer, x, a, byteOffset); // arr[x] = a
|
||||
storeUnsafeWithOffset<T,T>(buffer, 0, b, byteOffset); // arr[0] = b
|
||||
STORE<T>(buffer, x, a, byteOffset); // arr[x] = a
|
||||
STORE<T>(buffer, 0, b, byteOffset); // arr[0] = b
|
||||
}
|
||||
x >>= 1;
|
||||
}
|
||||
@ -122,7 +122,7 @@ export function weakHeapSort<T>(
|
||||
|
||||
memory.free(bitset);
|
||||
|
||||
var t = loadUnsafeWithOffset<T,T>(buffer, 1, byteOffset); // t = arr[1]
|
||||
storeUnsafeWithOffset<T,T>(buffer, 1, loadUnsafeWithOffset<T,T>(buffer, 0, byteOffset), byteOffset);
|
||||
storeUnsafeWithOffset<T,T>(buffer, 0, t, byteOffset); // arr[0] = t
|
||||
var t = LOAD<T>(buffer, 1, byteOffset); // t = arr[1]
|
||||
STORE<T>(buffer, 1, LOAD<T>(buffer, 0, byteOffset), byteOffset);
|
||||
STORE<T>(buffer, 0, t, byteOffset); // arr[0] = t
|
||||
}
|
||||
|
@ -71,33 +71,13 @@ export function reallocateUnsafe(buffer: ArrayBuffer, newByteLength: i32): Array
|
||||
// * `i32.load8` ^= `<i32>load<i8>(...)` that reads an i8 but returns an i32, or
|
||||
// * `i64.load32_s` ^= `<i64>load<i32>(...)`) that reads a 32-bit as a 64-bit integer
|
||||
//
|
||||
// without having to emit an additional instruction for conversion purposes. This is useful for
|
||||
// small integers only of course. When dealing with reference types like classes, both parameters
|
||||
// are usually the same, even though it looks ugly.
|
||||
//
|
||||
// TODO: is there a better way to model this?
|
||||
// without having to emit an additional instruction for conversion purposes. The second parameter
|
||||
// can be omitted for references and other loads and stores that simply return the exact type.
|
||||
|
||||
@inline export function loadUnsafe<T,TOut>(buffer: ArrayBuffer, index: i32): TOut {
|
||||
return <TOut>load<T>(changetype<usize>(buffer) + (<usize>index << alignof<T>()), HEADER_SIZE);
|
||||
@inline export function LOAD<T,TOut = T>(buffer: ArrayBuffer, index: i32, byteOffset: i32 = 0): TOut {
|
||||
return <TOut>load<T>(changetype<usize>(buffer) + (<usize>index << alignof<T>()) + <usize>byteOffset, HEADER_SIZE);
|
||||
}
|
||||
|
||||
@inline export function storeUnsafe<T,TIn>(buffer: ArrayBuffer, index: i32, value: TIn): void {
|
||||
store<T>(changetype<usize>(buffer) + (<usize>index << alignof<T>()), value, HEADER_SIZE);
|
||||
}
|
||||
|
||||
@inline export function loadUnsafeWithOffset<T,TOut>(
|
||||
buffer: ArrayBuffer,
|
||||
index: i32,
|
||||
byteOffset: i32
|
||||
): TOut {
|
||||
return <TOut>load<T>(changetype<usize>(buffer) + <usize>byteOffset + (<usize>index << alignof<T>()), HEADER_SIZE);
|
||||
}
|
||||
|
||||
@inline export function storeUnsafeWithOffset<T,TIn>(
|
||||
buffer: ArrayBuffer,
|
||||
index: i32,
|
||||
value: TIn,
|
||||
byteOffset: i32
|
||||
): void {
|
||||
store<T>(changetype<usize>(buffer) + <usize>byteOffset + (<usize>index << alignof<T>()), value, HEADER_SIZE);
|
||||
@inline export function STORE<T,TIn = T>(buffer: ArrayBuffer, index: i32, value: TIn, byteOffset: i32 = 0): void {
|
||||
store<T>(changetype<usize>(buffer) + (<usize>index << alignof<T>()) + <usize>byteOffset, value, HEADER_SIZE);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
} from "./string";
|
||||
|
||||
import {
|
||||
loadUnsafe
|
||||
LOAD
|
||||
} from "./arraybuffer";
|
||||
|
||||
export const MAX_DOUBLE_LENGTH = 28;
|
||||
@ -124,7 +124,7 @@ export function decimalCount32(value: u32): u32 {
|
||||
let t = l * 1233 >>> 12; // log10
|
||||
|
||||
let lutbuf = <ArrayBuffer>POWERS10().buffer_;
|
||||
let power = loadUnsafe<u32,u32>(lutbuf, t);
|
||||
let power = LOAD<u32>(lutbuf, t);
|
||||
t -= <u32>(value < power);
|
||||
return t + 1;
|
||||
} else {
|
||||
@ -154,7 +154,7 @@ export function decimalCount64(value: u64): u32 {
|
||||
let t = l * 1233 >>> 12; // log10
|
||||
|
||||
let lutbuf = <ArrayBuffer>POWERS10().buffer_;
|
||||
let power = loadUnsafe<u32,u64>(lutbuf, t - 10);
|
||||
let power = LOAD<u32,u64>(lutbuf, t - 10);
|
||||
t -= <u32>(value < 10000000000 * power);
|
||||
return t + 1;
|
||||
} else {
|
||||
@ -188,8 +188,8 @@ function utoa32_lut(buffer: usize, num: u32, offset: usize): void {
|
||||
let d1 = r / 100;
|
||||
let d2 = r % 100;
|
||||
|
||||
let digits1 = loadUnsafe<u32,u64>(lutbuf, d1);
|
||||
let digits2 = loadUnsafe<u32,u64>(lutbuf, d2);
|
||||
let digits1 = LOAD<u32,u64>(lutbuf, d1);
|
||||
let digits2 = LOAD<u32,u64>(lutbuf, d2);
|
||||
|
||||
offset -= 4;
|
||||
store<u64>(buffer + (offset << 1), digits1 | (digits2 << 32), STRING_HEADER_SIZE);
|
||||
@ -200,13 +200,13 @@ function utoa32_lut(buffer: usize, num: u32, offset: usize): void {
|
||||
let d1 = num % 100;
|
||||
num = t;
|
||||
offset -= 2;
|
||||
let digits = loadUnsafe<u32,u32>(lutbuf, d1);
|
||||
let digits = LOAD<u32>(lutbuf, d1);
|
||||
store<u32>(buffer + (offset << 1), digits, STRING_HEADER_SIZE);
|
||||
}
|
||||
|
||||
if (num >= 10) {
|
||||
offset -= 2;
|
||||
let digits = loadUnsafe<u32,u32>(lutbuf, num);
|
||||
let digits = LOAD<u32>(lutbuf, num);
|
||||
store<u32>(buffer + (offset << 1), digits, STRING_HEADER_SIZE);
|
||||
} else {
|
||||
offset -= 1;
|
||||
@ -231,14 +231,14 @@ function utoa64_lut(buffer: usize, num: u64, offset: usize): void {
|
||||
let c1 = c / 100;
|
||||
let c2 = c % 100;
|
||||
|
||||
let digits1 = loadUnsafe<u32,u64>(lutbuf, c1);
|
||||
let digits2 = loadUnsafe<u32,u64>(lutbuf, c2);
|
||||
let digits1 = LOAD<u32,u64>(lutbuf, c1);
|
||||
let digits2 = LOAD<u32,u64>(lutbuf, c2);
|
||||
|
||||
offset -= 4;
|
||||
store<u64>(buffer + (offset << 1), digits1 | (digits2 << 32), STRING_HEADER_SIZE);
|
||||
|
||||
digits1 = loadUnsafe<u32,u64>(lutbuf, b1);
|
||||
digits2 = loadUnsafe<u32,u64>(lutbuf, b2);
|
||||
digits1 = LOAD<u32,u64>(lutbuf, b1);
|
||||
digits2 = LOAD<u32,u64>(lutbuf, b2);
|
||||
|
||||
offset -= 4;
|
||||
store<u64>(buffer + (offset << 1), digits1 | (digits2 << 32), STRING_HEADER_SIZE);
|
||||
@ -438,8 +438,8 @@ function getCachedPower(minExp: i32): void {
|
||||
_K = 348 - (index << 3); // decimal exponent no need lookup table
|
||||
var frcPowers = <ArrayBuffer>FRC_POWERS().buffer_;
|
||||
var expPowers = <ArrayBuffer>EXP_POWERS().buffer_;
|
||||
_frc_pow = loadUnsafe<u64,u64>(frcPowers, index);
|
||||
_exp_pow = loadUnsafe<i16,i32>(expPowers, index);
|
||||
_frc_pow = LOAD<u64>(frcPowers, index);
|
||||
_exp_pow = LOAD<i16,i32>(expPowers, index);
|
||||
}
|
||||
|
||||
@inline
|
||||
@ -513,7 +513,7 @@ function genDigits(buffer: usize, w_frc: u64, w_exp: i32, mp_frc: u64, mp_exp: i
|
||||
let tmp = ((<u64>p1) << one_exp) + p2;
|
||||
if (tmp <= delta) {
|
||||
_K += kappa;
|
||||
grisuRound(buffer, len, delta, tmp, loadUnsafe<u32,u64>(powers10, kappa) << one_exp, wp_w_frc);
|
||||
grisuRound(buffer, len, delta, tmp, LOAD<u32,u64>(powers10, kappa) << one_exp, wp_w_frc);
|
||||
return len;
|
||||
}
|
||||
}
|
||||
@ -529,7 +529,7 @@ function genDigits(buffer: usize, w_frc: u64, w_exp: i32, mp_frc: u64, mp_exp: i
|
||||
--kappa;
|
||||
if (p2 < delta) {
|
||||
_K += kappa;
|
||||
wp_w_frc *= loadUnsafe<u32,u64>(powers10, -kappa);
|
||||
wp_w_frc *= LOAD<u32,u64>(powers10, -kappa);
|
||||
grisuRound(buffer, len, delta, p2, one_frc, wp_w_frc);
|
||||
return len;
|
||||
}
|
||||
|
@ -2,21 +2,18 @@ import {
|
||||
HEADER_SIZE as AB_HEADER_SIZE,
|
||||
MAX_BLENGTH as AB_MAX_BLENGTH,
|
||||
allocateUnsafe,
|
||||
loadUnsafeWithOffset,
|
||||
storeUnsafeWithOffset
|
||||
LOAD,
|
||||
STORE
|
||||
} from "./arraybuffer";
|
||||
|
||||
import {
|
||||
insertionSort,
|
||||
weakHeapSort,
|
||||
defaultComparator
|
||||
weakHeapSort
|
||||
} from "./array";
|
||||
|
||||
// The internal TypedArray class uses two type parameters for the same reason as `loadUnsafe` and
|
||||
// `storeUnsafe` in 'internal/arraybuffer.ts'. See the documentation there for details.
|
||||
|
||||
/** Typed array base class. Not a global object. */
|
||||
export abstract class TypedArray<T,TNative> {
|
||||
export abstract class TypedArray<T> {
|
||||
[key: number]: T; // compatibility only
|
||||
|
||||
readonly buffer: ArrayBuffer;
|
||||
readonly byteOffset: i32;
|
||||
@ -41,116 +38,142 @@ export abstract class TypedArray<T,TNative> {
|
||||
@operator("[]")
|
||||
protected __get(index: i32): T {
|
||||
if (<u32>index >= <u32>(this.byteLength >>> alignof<T>())) throw new Error("Index out of bounds");
|
||||
return loadUnsafeWithOffset<T,T>(this.buffer, index, this.byteOffset);
|
||||
return LOAD<T>(this.buffer, index, this.byteOffset);
|
||||
}
|
||||
|
||||
@inline @operator("{}")
|
||||
protected __unchecked_get(index: i32): T {
|
||||
return loadUnsafeWithOffset<T,T>(this.buffer, index, this.byteOffset);
|
||||
return LOAD<T>(this.buffer, index, this.byteOffset);
|
||||
}
|
||||
|
||||
@operator("[]=")
|
||||
protected __set(index: i32, value: TNative): void {
|
||||
protected __set(index: i32, value: NATIVE<T>): void {
|
||||
if (<u32>index >= <u32>(this.byteLength >>> alignof<T>())) throw new Error("Index out of bounds");
|
||||
storeUnsafeWithOffset<T,TNative>(this.buffer, index, value, this.byteOffset);
|
||||
STORE<T,NATIVE<T>>(this.buffer, index, value, this.byteOffset);
|
||||
}
|
||||
|
||||
@inline @operator("{}=")
|
||||
protected __unchecked_set(index: i32, value: TNative): void {
|
||||
storeUnsafeWithOffset<T,TNative>(this.buffer, index, value, this.byteOffset);
|
||||
protected __unchecked_set(index: i32, value: NATIVE<T>): void {
|
||||
STORE<T,NATIVE<T>>(this.buffer, index, value, this.byteOffset);
|
||||
}
|
||||
|
||||
// copyWithin(target: i32, start: i32, end: i32 = this.length): this
|
||||
}
|
||||
|
||||
fill(value: TNative, start: i32 = 0, end: i32 = i32.MAX_VALUE): this {
|
||||
var buffer = this.buffer;
|
||||
var byteOffset = this.byteOffset;
|
||||
var len = this.length;
|
||||
start = start < 0 ? max(len + start, 0) : min(start, len);
|
||||
end = end < 0 ? max(len + end, 0) : min(end, len);
|
||||
if (sizeof<T>() == 1) {
|
||||
if (start < end) {
|
||||
memory.fill(
|
||||
changetype<usize>(buffer) + start + byteOffset + AB_HEADER_SIZE,
|
||||
<u8>value,
|
||||
<usize>(end - start)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
for (; start < end; ++start) {
|
||||
storeUnsafeWithOffset<T,TNative>(buffer, start, value, byteOffset);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@inline
|
||||
subarray(begin: i32 = 0, end: i32 = i32.MAX_VALUE): TypedArray<T,TNative> {
|
||||
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 = memory.allocate(offsetof<this>());
|
||||
store<usize>(slice, this.buffer, offsetof<this>("buffer"));
|
||||
store<i32>(slice, this.byteOffset + (begin << alignof<T>()), offsetof<this>("byteOffset"));
|
||||
store<i32>(slice, (end - begin) << alignof<T>(), offsetof<this>("byteLength"));
|
||||
return changetype<this>(slice);
|
||||
}
|
||||
|
||||
sort(comparator: (a: T, b: T) => i32 = defaultComparator<T>()): this {
|
||||
var byteOffset = this.byteOffset;
|
||||
var length = this.length;
|
||||
if (length <= 1) return this;
|
||||
var buffer = this.buffer;
|
||||
if (length == 2) {
|
||||
let a = loadUnsafeWithOffset<T,T>(buffer, 1, byteOffset);
|
||||
let b = loadUnsafeWithOffset<T,T>(buffer, 0, byteOffset);
|
||||
if (comparator(a, b) < 0) {
|
||||
storeUnsafeWithOffset<T,T>(buffer, 1, b, byteOffset);
|
||||
storeUnsafeWithOffset<T,T>(buffer, 0, a, byteOffset);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
if (isReference<T>()) {
|
||||
// TODO replace this to faster stable sort (TimSort) when it implemented
|
||||
insertionSort<T>(buffer, byteOffset, length, comparator);
|
||||
return this;
|
||||
} else {
|
||||
if (length < 256) {
|
||||
insertionSort<T>(buffer, byteOffset, length, comparator);
|
||||
} else {
|
||||
weakHeapSort<T>(buffer, byteOffset, length, comparator);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TypedArray reduce implementation. This is a method that will be called from the parent,
|
||||
* passing types down from the child class using the typed parameters TypedArrayType and
|
||||
* ReturnType respectively. This implementation requires an initial value, and the direction.
|
||||
* When direction is true, reduce will reduce from the right side.
|
||||
*/
|
||||
@inline
|
||||
protected reduce_internal<TypedArrayType, ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: T, index: i32, array: TypedArrayType) => ReturnType,
|
||||
array: TypedArrayType,
|
||||
initialValue: ReturnType,
|
||||
direction: bool = false,
|
||||
): ReturnType {
|
||||
var index: i32 = direction ? this.length - 1 : 0;
|
||||
var length: i32 = direction ? -1 : this.length;
|
||||
while (index != length) {
|
||||
initialValue = callbackfn(
|
||||
initialValue,
|
||||
this.__unchecked_get(index),
|
||||
index,
|
||||
array,
|
||||
@inline
|
||||
export function FILL<TArray extends TypedArray<T>, T>(
|
||||
array: TArray,
|
||||
value: NATIVE<T>,
|
||||
start: i32,
|
||||
end: i32
|
||||
): TArray {
|
||||
var buffer = array.buffer;
|
||||
var byteOffset = array.byteOffset;
|
||||
var len = array.length;
|
||||
start = start < 0 ? max(len + start, 0) : min(start, len);
|
||||
end = end < 0 ? max(len + end, 0) : min(end, len);
|
||||
if (sizeof<T>() == 1) {
|
||||
if (start < end) {
|
||||
memory.fill(
|
||||
changetype<usize>(buffer) + start + byteOffset + AB_HEADER_SIZE,
|
||||
<u8>value,
|
||||
<usize>(end - start)
|
||||
);
|
||||
index = direction ? index - 1 : index + 1;
|
||||
}
|
||||
return initialValue;
|
||||
} else {
|
||||
for (; start < end; ++start) {
|
||||
STORE<T,NATIVE<T>>(buffer, start, value, byteOffset);
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
@inline
|
||||
export function SORT<TArray extends TypedArray<T>, T>(
|
||||
array: TArray,
|
||||
comparator: (a: T, b: T) => i32
|
||||
): TArray {
|
||||
var byteOffset = array.byteOffset;
|
||||
var length = array.length;
|
||||
if (length <= 1) return array;
|
||||
var buffer = array.buffer;
|
||||
if (length == 2) {
|
||||
let a = LOAD<T>(buffer, 1, byteOffset);
|
||||
let b = LOAD<T>(buffer, 0, byteOffset);
|
||||
if (comparator(a, b) < 0) {
|
||||
STORE<T>(buffer, 1, b, byteOffset);
|
||||
STORE<T>(buffer, 0, a, byteOffset);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
if (isReference<T>()) {
|
||||
// TODO replace this to faster stable sort (TimSort) when it implemented
|
||||
insertionSort<T>(buffer, byteOffset, length, comparator);
|
||||
return array;
|
||||
} else {
|
||||
if (length < 256) {
|
||||
insertionSort<T>(buffer, byteOffset, length, comparator);
|
||||
} else {
|
||||
weakHeapSort<T>(buffer, byteOffset, length, comparator);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
@inline
|
||||
export function SUBARRAY<TArray extends TypedArray<T>, T>(
|
||||
array: TArray,
|
||||
begin: i32,
|
||||
end: i32
|
||||
): TArray {
|
||||
var length = <i32>array.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 = memory.allocate(offsetof<TArray>());
|
||||
store<usize>(slice, array.buffer, offsetof<TArray>("buffer"));
|
||||
store<i32>(slice, <i32>array.byteOffset + (begin << alignof<T>()), offsetof<TArray>("byteOffset"));
|
||||
store<i32>(slice, (end - begin) << alignof<T>(), offsetof<TArray>("byteLength"));
|
||||
return changetype<TArray>(slice);
|
||||
}
|
||||
|
||||
@inline
|
||||
export function REDUCE<TArray extends TypedArray<T>, T, TRet>(
|
||||
array: TArray,
|
||||
callbackfn: (accumulator: TRet, value: T, index: i32, array: TArray) => TRet,
|
||||
initialValue: TRet
|
||||
): TRet {
|
||||
var index = 0;
|
||||
var length = <i32>array.length;
|
||||
while (index != length) {
|
||||
initialValue = callbackfn(
|
||||
initialValue,
|
||||
unchecked(array[index]),
|
||||
index,
|
||||
array,
|
||||
);
|
||||
++index;
|
||||
}
|
||||
return initialValue;
|
||||
}
|
||||
|
||||
@inline
|
||||
export function REDUCE_RIGHT<TArray extends TypedArray<T>, T, TRet>(
|
||||
array: TArray,
|
||||
callbackfn: (accumulator: TRet, value: T, index: i32, array: TArray) => TRet,
|
||||
initialValue: TRet
|
||||
): TRet {
|
||||
var index = <i32>array.length - 1;
|
||||
var length = -1;
|
||||
while (index != length) {
|
||||
initialValue = callbackfn(
|
||||
initialValue,
|
||||
unchecked(array[index]),
|
||||
index,
|
||||
array,
|
||||
);
|
||||
--index;
|
||||
}
|
||||
return initialValue;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
} from "./internal/string";
|
||||
|
||||
import {
|
||||
storeUnsafe as storeUnsafeArray
|
||||
STORE
|
||||
} from "./internal/arraybuffer";
|
||||
|
||||
@sealed
|
||||
@ -436,7 +436,7 @@ export class String {
|
||||
),
|
||||
HEADER_SIZE
|
||||
);
|
||||
storeUnsafeArray<String,String>(buffer, i, char);
|
||||
STORE<String>(buffer, i, char);
|
||||
}
|
||||
return result;
|
||||
} else if (!length) {
|
||||
|
@ -1,52 +1,77 @@
|
||||
import {
|
||||
TypedArray
|
||||
TypedArray,
|
||||
FILL,
|
||||
SORT,
|
||||
SUBARRAY,
|
||||
REDUCE,
|
||||
REDUCE_RIGHT
|
||||
} from "./internal/typedarray";
|
||||
|
||||
export class Int8Array extends TypedArray<i8,i32> {
|
||||
import {
|
||||
defaultComparator
|
||||
} from "./internal/array";
|
||||
|
||||
export class Int8Array extends TypedArray<i8> {
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<i8>();
|
||||
|
||||
fill(value: i32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Int8Array {
|
||||
return FILL<Int8Array, i8>(this, value, start, end);
|
||||
}
|
||||
|
||||
sort(comparator: (a: i8, b: i8) => i32 = defaultComparator<i8>()): Int8Array {
|
||||
return SORT<Int8Array, i8>(this, comparator);
|
||||
}
|
||||
|
||||
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Int8Array {
|
||||
return changetype<Int8Array>(super.subarray(begin, end));
|
||||
return SUBARRAY<Int8Array, i8>(this, begin, end);
|
||||
}
|
||||
|
||||
reduce<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: i8, index: i32, array: Int8Array) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Int8Array, ReturnType>(callbackfn, this, initialValue);
|
||||
reduce<T>(
|
||||
callbackfn: (accumulator: T, value: i8, index: i32, array: Int8Array) => T,
|
||||
initialValue: T,
|
||||
): T {
|
||||
return REDUCE<Int8Array, i8, T>(this, callbackfn, initialValue);
|
||||
}
|
||||
|
||||
reduceRight<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: i8, index: i32, array: Int8Array) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Int8Array, ReturnType>(callbackfn, this, initialValue, true);
|
||||
reduceRight<T>(
|
||||
callbackfn: (accumulator: T, value: i8, index: i32, array: Int8Array) => T,
|
||||
initialValue: T,
|
||||
): T {
|
||||
return REDUCE_RIGHT<Int8Array, i8, T>(this, callbackfn, initialValue);
|
||||
}
|
||||
}
|
||||
|
||||
export class Uint8Array extends TypedArray<u8,u32> {
|
||||
export class Uint8Array extends TypedArray<u8> {
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<u8>();
|
||||
|
||||
fill(value: u32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint8Array {
|
||||
return FILL<Uint8Array, u8>(this, value, start, end);
|
||||
}
|
||||
|
||||
sort(comparator: (a: u8, b: u8) => i32 = defaultComparator<u8>()): Uint8Array {
|
||||
return SORT<Uint8Array, u8>(this, comparator);
|
||||
}
|
||||
|
||||
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Uint8Array {
|
||||
return changetype<Uint8Array>(super.subarray(begin, end));
|
||||
return SUBARRAY<Uint8Array, u8>(this, begin, end);
|
||||
}
|
||||
|
||||
reduce<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: u8, index: i32, array: Uint8Array) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Uint8Array, ReturnType>(callbackfn, this, initialValue);
|
||||
reduce<T>(
|
||||
callbackfn: (accumulator: T, value: u8, index: i32, array: Uint8Array) => T,
|
||||
initialValue: T,
|
||||
): T {
|
||||
return REDUCE<Uint8Array, u8, T>(this, callbackfn, initialValue);
|
||||
}
|
||||
|
||||
reduceRight<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: u8, index: i32, array: Uint8Array) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Uint8Array, ReturnType>(callbackfn, this, initialValue, true);
|
||||
reduceRight<T>(
|
||||
callbackfn: (accumulator: T, value: u8, index: i32, array: Uint8Array) => T,
|
||||
initialValue: T,
|
||||
): T {
|
||||
return REDUCE_RIGHT<Uint8Array, u8, T>(this, callbackfn, initialValue);
|
||||
}
|
||||
}
|
||||
|
||||
export class Uint8ClampedArray extends TypedArray<u8,u32> {
|
||||
export class Uint8ClampedArray extends Uint8Array {
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<u8>();
|
||||
|
||||
@inline @operator("[]=")
|
||||
@ -58,202 +83,244 @@ export class Uint8ClampedArray extends TypedArray<u8,u32> {
|
||||
protected __unchecked_set(index: i32, value: i32): void {
|
||||
super.__unchecked_set(index, max(min(value, 255), 0));
|
||||
}
|
||||
|
||||
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Uint8ClampedArray {
|
||||
return changetype<Uint8ClampedArray>(super.subarray(begin, end));
|
||||
}
|
||||
|
||||
reduce<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: u8, index: i32, array: Uint8ClampedArray) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Uint8ClampedArray, ReturnType>(callbackfn, this, initialValue);
|
||||
}
|
||||
|
||||
reduceRight<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: u8, index: i32, array: Uint8ClampedArray) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Uint8ClampedArray, ReturnType>(callbackfn, this, initialValue, true);
|
||||
}
|
||||
}
|
||||
|
||||
export class Int16Array extends TypedArray<i16,i32> {
|
||||
export class Int16Array extends TypedArray<i16> {
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<i16>();
|
||||
|
||||
fill(value: i32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Int16Array {
|
||||
return FILL<Int16Array, i16>(this, value, start, end);
|
||||
}
|
||||
|
||||
sort(comparator: (a: i16, b: i16) => i32 = defaultComparator<i16>()): Int16Array {
|
||||
return SORT<Int16Array, i16>(this, comparator);
|
||||
}
|
||||
|
||||
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Int16Array {
|
||||
return changetype<Int16Array>(super.subarray(begin, end));
|
||||
return SUBARRAY<Int16Array, i16>(this, begin, end);
|
||||
}
|
||||
|
||||
reduce<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: i16, index: i32, array: Int16Array) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Int16Array, ReturnType>(callbackfn, this, initialValue);
|
||||
reduce<T>(
|
||||
callbackfn: (accumulator: T, value: i16, index: i32, array: Int16Array) => T,
|
||||
initialValue: T,
|
||||
): T {
|
||||
return REDUCE<Int16Array, i16, T>(this, callbackfn, initialValue);
|
||||
}
|
||||
|
||||
reduceRight<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: i16, index: i32, array: Int16Array) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Int16Array, ReturnType>(callbackfn, this, initialValue, true);
|
||||
reduceRight<T>(
|
||||
callbackfn: (accumulator: T, value: i16, index: i32, array: Int16Array) => T,
|
||||
initialValue: T,
|
||||
): T {
|
||||
return REDUCE_RIGHT<Int16Array, i16, T>(this, callbackfn, initialValue);
|
||||
}
|
||||
}
|
||||
|
||||
export class Uint16Array extends TypedArray<u16,u32> {
|
||||
export class Uint16Array extends TypedArray<u16> {
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<u16>();
|
||||
|
||||
fill(value: u32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint16Array {
|
||||
return FILL<Uint16Array, u16>(this, value, start, end);
|
||||
}
|
||||
|
||||
sort(comparator: (a: u16, b: u16) => i32 = defaultComparator<u16>()): Uint16Array {
|
||||
return SORT<Uint16Array, u16>(this, comparator);
|
||||
}
|
||||
|
||||
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Uint16Array {
|
||||
return changetype<Uint16Array>(super.subarray(begin, end));
|
||||
return SUBARRAY<Uint16Array, u16>(this, begin, end);
|
||||
}
|
||||
|
||||
reduce<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: u16, index: i32, array: Uint16Array) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Uint16Array, ReturnType>(callbackfn, this, initialValue);
|
||||
reduce<T>(
|
||||
callbackfn: (accumulator: T, value: u16, index: i32, array: Uint16Array) => T,
|
||||
initialValue: T,
|
||||
): T {
|
||||
return REDUCE<Uint16Array, u16, T>(this, callbackfn, initialValue);
|
||||
}
|
||||
|
||||
reduceRight<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: u16, index: i32, array: Uint16Array) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Uint16Array, ReturnType>(callbackfn, this, initialValue, true);
|
||||
reduceRight<T>(
|
||||
callbackfn: (accumulator: T, value: u16, index: i32, array: Uint16Array) => T,
|
||||
initialValue: T,
|
||||
): T {
|
||||
return REDUCE_RIGHT<Uint16Array, u16, T>(this, callbackfn, initialValue);
|
||||
}
|
||||
}
|
||||
|
||||
export class Int32Array extends TypedArray<i32,i32> {
|
||||
export class Int32Array extends TypedArray<i32> {
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<i32>();
|
||||
|
||||
fill(value: i32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Int32Array {
|
||||
return FILL<Int32Array, i32>(this, value, start, end);
|
||||
}
|
||||
|
||||
sort(comparator: (a: i32, b: i32) => i32 = defaultComparator<i32>()): Int32Array {
|
||||
return SORT<Int32Array, i32>(this, comparator);
|
||||
}
|
||||
|
||||
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Int32Array {
|
||||
return changetype<Int32Array>(super.subarray(begin, end));
|
||||
return SUBARRAY<Int32Array, i32>(this, begin, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callbackfn {function} - a function that reduces each value to a ReturnType
|
||||
* @param initialValue {ReturnType} - the initial ReturnType value to be passed to the callbackfn
|
||||
*/
|
||||
reduce<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: i32, index: i32, array: Int32Array) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Int32Array, ReturnType>(callbackfn, this, initialValue);
|
||||
reduce<T>(
|
||||
callbackfn: (accumulator: T, value: i32, index: i32, array: Int32Array) => T,
|
||||
initialValue: T,
|
||||
): T {
|
||||
return REDUCE<Int32Array, i32, T>(this, callbackfn, initialValue);
|
||||
}
|
||||
|
||||
reduceRight<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: i32, index: i32, array: Int32Array) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Int32Array, ReturnType>(callbackfn, this, initialValue, true);
|
||||
reduceRight<T>(
|
||||
callbackfn: (accumulator: T, value: i32, index: i32, array: Int32Array) => T,
|
||||
initialValue: T,
|
||||
): T {
|
||||
return REDUCE_RIGHT<Int32Array, i32, T>(this, callbackfn, initialValue);
|
||||
}
|
||||
}
|
||||
|
||||
export class Uint32Array extends TypedArray<u32,u32> {
|
||||
export class Uint32Array extends TypedArray<u32> {
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<u32>();
|
||||
|
||||
fill(value: u32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint32Array {
|
||||
return FILL<Uint32Array, u32>(this, value, start, end);
|
||||
}
|
||||
|
||||
sort(comparator: (a: u32, b: u32) => i32 = defaultComparator<u32>()): Uint32Array {
|
||||
return SORT<Uint32Array, u32>(this, comparator);
|
||||
}
|
||||
|
||||
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Uint32Array {
|
||||
return changetype<Uint32Array>(super.subarray(begin, end));
|
||||
return SUBARRAY<Uint32Array, u32>(this, begin, end);
|
||||
}
|
||||
|
||||
reduce<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: u32, index: i32, array: Uint32Array) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Uint32Array, ReturnType>(callbackfn, this, initialValue);
|
||||
reduce<T>(
|
||||
callbackfn: (accumulator: T, value: u32, index: i32, array: Uint32Array) => T,
|
||||
initialValue: T,
|
||||
): T {
|
||||
return REDUCE<Uint32Array, u32, T>(this, callbackfn, initialValue);
|
||||
}
|
||||
|
||||
reduceRight<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: u32, index: i32, array: Uint32Array) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Uint32Array, ReturnType>(callbackfn, this, initialValue, true);
|
||||
reduceRight<T>(
|
||||
callbackfn: (accumulator: T, value: u32, index: i32, array: Uint32Array) => T,
|
||||
initialValue: T,
|
||||
): T {
|
||||
return REDUCE_RIGHT<Uint32Array, u32, T>(this, callbackfn, initialValue);
|
||||
}
|
||||
}
|
||||
|
||||
export class Int64Array extends TypedArray<i64,i64> {
|
||||
export class Int64Array extends TypedArray<i64> {
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<i64>();
|
||||
|
||||
fill(value: i64, start: i32 = 0, end: i32 = i32.MAX_VALUE): Int64Array {
|
||||
return FILL<Int64Array, i64>(this, value, start, end);
|
||||
}
|
||||
|
||||
sort(comparator: (a: i64, b: i64) => i32 = defaultComparator<i64>()): Int64Array {
|
||||
return SORT<Int64Array, i64>(this, comparator);
|
||||
}
|
||||
|
||||
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Int64Array {
|
||||
return changetype<Int64Array>(super.subarray(begin, end));
|
||||
return SUBARRAY<Int64Array, i64>(this, begin, end);
|
||||
}
|
||||
|
||||
reduce<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: i64, index: i32, array: Int64Array) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Int64Array, ReturnType>(callbackfn, this, initialValue);
|
||||
reduce<T>(
|
||||
callbackfn: (accumulator: T, value: i64, index: i32, array: Int64Array) => T,
|
||||
initialValue: T,
|
||||
): T {
|
||||
return REDUCE<Int64Array, i64, T>(this, callbackfn, initialValue);
|
||||
}
|
||||
|
||||
reduceRight<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: i64, index: i32, array: Int64Array) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Int64Array, ReturnType>(callbackfn, this, initialValue, true);
|
||||
reduceRight<T>(
|
||||
callbackfn: (accumulator: T, value: i64, index: i32, array: Int64Array) => T,
|
||||
initialValue: T,
|
||||
): T {
|
||||
return REDUCE_RIGHT<Int64Array, i64, T>(this, callbackfn, initialValue);
|
||||
}
|
||||
}
|
||||
|
||||
export class Uint64Array extends TypedArray<u64,u64> {
|
||||
export class Uint64Array extends TypedArray<u64> {
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<u64>();
|
||||
|
||||
fill(value: u64, start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint64Array {
|
||||
return FILL<Uint64Array, u64>(this, value, start, end);
|
||||
}
|
||||
|
||||
sort(comparator: (a: u64, b: u64) => i32 = defaultComparator<u64>()): Uint64Array {
|
||||
return SORT<Uint64Array, u64>(this, comparator);
|
||||
}
|
||||
|
||||
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Uint64Array {
|
||||
return changetype<Uint64Array>(super.subarray(begin, end));
|
||||
return SUBARRAY<Uint64Array, u64>(this, begin, end);
|
||||
}
|
||||
|
||||
reduce<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: u64, index: i32, array: Uint64Array) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Uint64Array, ReturnType>(callbackfn, this, initialValue);
|
||||
reduce<T>(
|
||||
callbackfn: (accumulator: T, value: u64, index: i32, array: Uint64Array) => T,
|
||||
initialValue: T,
|
||||
): T {
|
||||
return REDUCE<Uint64Array, u64, T>(this, callbackfn, initialValue);
|
||||
}
|
||||
|
||||
reduceRight<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: u64, index: i32, array: Uint64Array) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Uint64Array, ReturnType>(callbackfn, this, initialValue, true);
|
||||
reduceRight<T>(
|
||||
callbackfn: (accumulator: T, value: u64, index: i32, array: Uint64Array) => T,
|
||||
initialValue: T,
|
||||
): T {
|
||||
return REDUCE_RIGHT<Uint64Array, u64, T>(this, callbackfn, initialValue);
|
||||
}
|
||||
}
|
||||
|
||||
export class Float32Array extends TypedArray<f32,f32> {
|
||||
export class Float32Array extends TypedArray<f32> {
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<f32>();
|
||||
|
||||
fill(value: f32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Float32Array {
|
||||
return FILL<Float32Array, f32>(this, value, start, end);
|
||||
}
|
||||
|
||||
sort(comparator: (a: f32, b: f32) => i32 = defaultComparator<f32>()): Float32Array {
|
||||
return SORT<Float32Array, f32>(this, comparator);
|
||||
}
|
||||
|
||||
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Float32Array {
|
||||
return changetype<Float32Array>(super.subarray(begin, end));
|
||||
return SUBARRAY<Float32Array, f32>(this, begin, end);
|
||||
}
|
||||
|
||||
reduce<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: f32, index: i32, array: Float32Array) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Float32Array, ReturnType>(callbackfn, this, initialValue);
|
||||
reduce<T>(
|
||||
callbackfn: (accumulator: T, value: f32, index: i32, array: Float32Array) => T,
|
||||
initialValue: T,
|
||||
): T {
|
||||
return REDUCE<Float32Array, f32, T>(this, callbackfn, initialValue);
|
||||
}
|
||||
|
||||
reduceRight<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: f32, index: i32, array: Float32Array) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Float32Array, ReturnType>(callbackfn, this, initialValue, true);
|
||||
reduceRight<T>(
|
||||
callbackfn: (accumulator: T, value: f32, index: i32, array: Float32Array) => T,
|
||||
initialValue: T,
|
||||
): T {
|
||||
return REDUCE_RIGHT<Float32Array, f32, T>(this, callbackfn, initialValue);
|
||||
}
|
||||
}
|
||||
|
||||
export class Float64Array extends TypedArray<f64,f64> {
|
||||
export class Float64Array extends TypedArray<f64> {
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<f64>();
|
||||
|
||||
fill(value: f64, start: i32 = 0, end: i32 = i32.MAX_VALUE): Float64Array {
|
||||
return FILL<Float64Array, f64>(this, value, start, end);
|
||||
}
|
||||
|
||||
sort(comparator: (a: f64, b: f64) => i32 = defaultComparator<f64>()): Float64Array {
|
||||
return SORT<Float64Array, f64>(this, comparator);
|
||||
}
|
||||
|
||||
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Float64Array {
|
||||
return changetype<Float64Array>(super.subarray(begin, end));
|
||||
return SUBARRAY<Float64Array, f64>(this, begin, end);
|
||||
}
|
||||
|
||||
reduce<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: f64, index: i32, array: Float64Array) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Float64Array, ReturnType>(callbackfn, this, initialValue);
|
||||
reduce<T>(
|
||||
callbackfn: (accumulator: T, value: f64, index: i32, array: Float64Array) => T,
|
||||
initialValue: T,
|
||||
): T {
|
||||
return REDUCE<Float64Array, f64, T>(this, callbackfn, initialValue);
|
||||
}
|
||||
|
||||
reduceRight<ReturnType>(
|
||||
callbackfn: (accumulator: ReturnType, value: f64, index: i32, array: Float64Array) => ReturnType,
|
||||
initialValue: ReturnType,
|
||||
): ReturnType {
|
||||
return super.reduce_internal<Float64Array, ReturnType>(callbackfn, this, initialValue, true);
|
||||
reduceRight<T>(
|
||||
callbackfn: (accumulator: T, value: f64, index: i32, array: Float64Array) => T,
|
||||
initialValue: T,
|
||||
): T {
|
||||
return REDUCE_RIGHT<Float64Array, f64, T>(this, callbackfn, initialValue);
|
||||
}
|
||||
}
|
||||
|
91
tests/compiler/optional-typeparameters.optimized.wat
Normal file
91
tests/compiler/optional-typeparameters.optimized.wat
Normal file
@ -0,0 +1,91 @@
|
||||
(module
|
||||
(type $ii (func (param i32) (result i32)))
|
||||
(type $v (func))
|
||||
(memory $0 0)
|
||||
(table $0 1 anyfunc)
|
||||
(elem (i32.const 0) $null)
|
||||
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
|
||||
(global $optional-typeparameters/tConcrete (mut i32) (i32.const 0))
|
||||
(global $optional-typeparameters/tDerived (mut i32) (i32.const 0))
|
||||
(export "memory" (memory $0))
|
||||
(export "table" (table $0))
|
||||
(start $start)
|
||||
(func $~lib/allocator/arena/__memory_allocate (; 0 ;) (type $ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
get_local $0
|
||||
i32.const 1073741824
|
||||
i32.gt_u
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
get_global $~lib/allocator/arena/offset
|
||||
tee_local $1
|
||||
get_local $0
|
||||
i32.const 1
|
||||
get_local $0
|
||||
i32.const 1
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.add
|
||||
i32.const -8
|
||||
i32.and
|
||||
tee_local $2
|
||||
current_memory
|
||||
tee_local $3
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
get_local $3
|
||||
get_local $2
|
||||
get_local $1
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
i32.const -65536
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
tee_local $0
|
||||
get_local $3
|
||||
get_local $0
|
||||
i32.gt_s
|
||||
select
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
get_local $0
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
get_local $2
|
||||
set_global $~lib/allocator/arena/offset
|
||||
get_local $1
|
||||
)
|
||||
(func $start (; 1 ;) (type $v)
|
||||
i32.const 8
|
||||
set_global $~lib/allocator/arena/startOffset
|
||||
get_global $~lib/allocator/arena/startOffset
|
||||
set_global $~lib/allocator/arena/offset
|
||||
i32.const 0
|
||||
call $~lib/allocator/arena/__memory_allocate
|
||||
set_global $optional-typeparameters/tConcrete
|
||||
i32.const 0
|
||||
call $~lib/allocator/arena/__memory_allocate
|
||||
set_global $optional-typeparameters/tDerived
|
||||
)
|
||||
(func $null (; 2 ;) (type $v)
|
||||
nop
|
||||
)
|
||||
)
|
28
tests/compiler/optional-typeparameters.ts
Normal file
28
tests/compiler/optional-typeparameters.ts
Normal file
@ -0,0 +1,28 @@
|
||||
function testConcrete<T,U = i32>(a: T): U {
|
||||
return a;
|
||||
}
|
||||
|
||||
function testDerived<T,U = T>(a: T): U {
|
||||
return a;
|
||||
}
|
||||
|
||||
testConcrete<i32>(1);
|
||||
testDerived<i32>(2);
|
||||
|
||||
class TestConcrete<T,U = i32> {
|
||||
test<V = i32>(a: T, b: U): V {
|
||||
return a + b;
|
||||
}
|
||||
}
|
||||
|
||||
class TestDerived<T,U = T> {
|
||||
test<V = U>(a: T, b: U): V {
|
||||
return a + b;
|
||||
}
|
||||
}
|
||||
|
||||
import "allocator/arena";
|
||||
var tConcrete = new TestConcrete<i32>();
|
||||
tConcrete.test<i32>(1, 2);
|
||||
var tDerived = new TestDerived<f64>()
|
||||
tDerived.test<f64>(1, 2);
|
166
tests/compiler/optional-typeparameters.untouched.wat
Normal file
166
tests/compiler/optional-typeparameters.untouched.wat
Normal file
@ -0,0 +1,166 @@
|
||||
(module
|
||||
(type $ii (func (param i32) (result i32)))
|
||||
(type $iiii (func (param i32 i32 i32) (result i32)))
|
||||
(type $iFFF (func (param i32 f64 f64) (result f64)))
|
||||
(type $v (func))
|
||||
(memory $0 0)
|
||||
(table $0 1 anyfunc)
|
||||
(elem (i32.const 0) $null)
|
||||
(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/allocator/MAX_SIZE_32 i32 (i32.const 1073741824))
|
||||
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
|
||||
(global $optional-typeparameters/tConcrete (mut i32) (i32.const 0))
|
||||
(global $optional-typeparameters/tDerived (mut i32) (i32.const 0))
|
||||
(global $HEAP_BASE i32 (i32.const 8))
|
||||
(export "memory" (memory $0))
|
||||
(export "table" (table $0))
|
||||
(start $start)
|
||||
(func $optional-typeparameters/testConcrete<i32,i32> (; 0 ;) (type $ii) (param $0 i32) (result i32)
|
||||
get_local $0
|
||||
)
|
||||
(func $optional-typeparameters/testDerived<i32,i32> (; 1 ;) (type $ii) (param $0 i32) (result i32)
|
||||
get_local $0
|
||||
)
|
||||
(func $~lib/allocator/arena/__memory_allocate (; 2 ;) (type $ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
(local $6 i32)
|
||||
get_local $0
|
||||
get_global $~lib/internal/allocator/MAX_SIZE_32
|
||||
i32.gt_u
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
get_global $~lib/allocator/arena/offset
|
||||
set_local $1
|
||||
get_local $1
|
||||
get_local $0
|
||||
tee_local $2
|
||||
i32.const 1
|
||||
tee_local $3
|
||||
get_local $2
|
||||
get_local $3
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
get_global $~lib/internal/allocator/AL_MASK
|
||||
i32.add
|
||||
get_global $~lib/internal/allocator/AL_MASK
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
set_local $4
|
||||
current_memory
|
||||
set_local $5
|
||||
get_local $4
|
||||
get_local $5
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
get_local $4
|
||||
get_local $1
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
i32.const 65535
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
set_local $2
|
||||
get_local $5
|
||||
tee_local $3
|
||||
get_local $2
|
||||
tee_local $6
|
||||
get_local $3
|
||||
get_local $6
|
||||
i32.gt_s
|
||||
select
|
||||
set_local $3
|
||||
get_local $3
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
get_local $2
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
get_local $4
|
||||
set_global $~lib/allocator/arena/offset
|
||||
get_local $1
|
||||
)
|
||||
(func $~lib/memory/memory.allocate (; 3 ;) (type $ii) (param $0 i32) (result i32)
|
||||
get_local $0
|
||||
call $~lib/allocator/arena/__memory_allocate
|
||||
return
|
||||
)
|
||||
(func $optional-typeparameters/TestConcrete<i32,i32>#test<i32> (; 4 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
|
||||
get_local $1
|
||||
get_local $2
|
||||
i32.add
|
||||
)
|
||||
(func $optional-typeparameters/TestDerived<f64,f64>#test<f64> (; 5 ;) (type $iFFF) (param $0 i32) (param $1 f64) (param $2 f64) (result f64)
|
||||
get_local $1
|
||||
get_local $2
|
||||
f64.add
|
||||
)
|
||||
(func $start (; 6 ;) (type $v)
|
||||
(local $0 i32)
|
||||
i32.const 1
|
||||
call $optional-typeparameters/testConcrete<i32,i32>
|
||||
drop
|
||||
i32.const 2
|
||||
call $optional-typeparameters/testDerived<i32,i32>
|
||||
drop
|
||||
get_global $HEAP_BASE
|
||||
get_global $~lib/internal/allocator/AL_MASK
|
||||
i32.add
|
||||
get_global $~lib/internal/allocator/AL_MASK
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
set_global $~lib/allocator/arena/startOffset
|
||||
get_global $~lib/allocator/arena/startOffset
|
||||
set_global $~lib/allocator/arena/offset
|
||||
block (result i32)
|
||||
i32.const 0
|
||||
call $~lib/memory/memory.allocate
|
||||
set_local $0
|
||||
get_local $0
|
||||
end
|
||||
set_global $optional-typeparameters/tConcrete
|
||||
get_global $optional-typeparameters/tConcrete
|
||||
i32.const 1
|
||||
i32.const 2
|
||||
call $optional-typeparameters/TestConcrete<i32,i32>#test<i32>
|
||||
drop
|
||||
block (result i32)
|
||||
i32.const 0
|
||||
call $~lib/memory/memory.allocate
|
||||
set_local $0
|
||||
get_local $0
|
||||
end
|
||||
set_global $optional-typeparameters/tDerived
|
||||
get_global $optional-typeparameters/tDerived
|
||||
f64.const 1
|
||||
f64.const 2
|
||||
call $optional-typeparameters/TestDerived<f64,f64>#test<f64>
|
||||
drop
|
||||
)
|
||||
(func $null (; 7 ;) (type $v)
|
||||
)
|
||||
)
|
@ -27,6 +27,7 @@
|
||||
(export "stringArrayArrayMethodCall" (func $std/array-access/stringArrayArrayMethodCall))
|
||||
(func $~lib/array/Array<Array<i32>>#__get (; 1 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
get_local $0
|
||||
i32.load
|
||||
set_local $2
|
||||
@ -37,11 +38,15 @@
|
||||
i32.shr_u
|
||||
i32.lt_u
|
||||
if (result i32)
|
||||
i32.const 0
|
||||
set_local $3
|
||||
get_local $2
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $3
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
else
|
||||
unreachable
|
||||
@ -49,6 +54,7 @@
|
||||
)
|
||||
(func $~lib/array/Array<i32>#__get (; 2 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
get_local $0
|
||||
i32.load
|
||||
set_local $2
|
||||
@ -59,11 +65,15 @@
|
||||
i32.shr_u
|
||||
i32.lt_u
|
||||
if (result i32)
|
||||
i32.const 0
|
||||
set_local $3
|
||||
get_local $2
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $3
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
else
|
||||
unreachable
|
||||
@ -78,6 +88,7 @@
|
||||
)
|
||||
(func $~lib/array/Array<String>#__get (; 4 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
get_local $0
|
||||
i32.load
|
||||
set_local $2
|
||||
@ -88,11 +99,15 @@
|
||||
i32.shr_u
|
||||
i32.lt_u
|
||||
if (result i32)
|
||||
i32.const 0
|
||||
set_local $3
|
||||
get_local $2
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $3
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
else
|
||||
unreachable
|
||||
@ -234,6 +249,7 @@
|
||||
)
|
||||
(func $~lib/array/Array<Array<String>>#__get (; 9 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
get_local $0
|
||||
i32.load
|
||||
set_local $2
|
||||
@ -244,11 +260,15 @@
|
||||
i32.shr_u
|
||||
i32.lt_u
|
||||
if (result i32)
|
||||
i32.const 0
|
||||
set_local $3
|
||||
get_local $2
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $3
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
else
|
||||
unreachable
|
||||
|
@ -39,6 +39,7 @@
|
||||
(start $start)
|
||||
(func $~lib/array/Array<i8>#__get (; 1 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
get_local $0
|
||||
i32.load
|
||||
set_local $2
|
||||
@ -49,11 +50,15 @@
|
||||
i32.shr_u
|
||||
i32.lt_u
|
||||
if (result i32)
|
||||
i32.const 0
|
||||
set_local $3
|
||||
get_local $2
|
||||
get_local $1
|
||||
i32.const 0
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $3
|
||||
i32.add
|
||||
i32.load8_s offset=8
|
||||
else
|
||||
unreachable
|
||||
@ -61,6 +66,7 @@
|
||||
)
|
||||
(func $~lib/array/Array<i32>#__get (; 2 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
get_local $0
|
||||
i32.load
|
||||
set_local $2
|
||||
@ -71,11 +77,15 @@
|
||||
i32.shr_u
|
||||
i32.lt_u
|
||||
if (result i32)
|
||||
i32.const 0
|
||||
set_local $3
|
||||
get_local $2
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $3
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
else
|
||||
unreachable
|
||||
@ -471,7 +481,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 136
|
||||
i32.const 45
|
||||
i32.const 46
|
||||
i32.const 39
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -521,14 +531,19 @@
|
||||
)
|
||||
(func $~lib/array/Array<i8>#__unchecked_set (; 9 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
get_local $0
|
||||
i32.load
|
||||
set_local $3
|
||||
i32.const 0
|
||||
set_local $4
|
||||
get_local $3
|
||||
get_local $1
|
||||
i32.const 0
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $4
|
||||
i32.add
|
||||
get_local $2
|
||||
i32.store8 offset=8
|
||||
)
|
||||
@ -543,7 +558,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 136
|
||||
i32.const 45
|
||||
i32.const 46
|
||||
i32.const 39
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -593,14 +608,19 @@
|
||||
)
|
||||
(func $~lib/array/Array<i32>#__unchecked_set (; 11 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
get_local $0
|
||||
i32.load
|
||||
set_local $3
|
||||
i32.const 0
|
||||
set_local $4
|
||||
get_local $3
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $4
|
||||
i32.add
|
||||
get_local $2
|
||||
i32.store offset=8
|
||||
)
|
||||
@ -615,7 +635,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 136
|
||||
i32.const 45
|
||||
i32.const 46
|
||||
i32.const 39
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -665,14 +685,19 @@
|
||||
)
|
||||
(func $~lib/array/Array<Ref>#__unchecked_set (; 13 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
get_local $0
|
||||
i32.load
|
||||
set_local $3
|
||||
i32.const 0
|
||||
set_local $4
|
||||
get_local $3
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $4
|
||||
i32.add
|
||||
get_local $2
|
||||
i32.store offset=8
|
||||
)
|
||||
@ -703,7 +728,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 136
|
||||
i32.const 45
|
||||
i32.const 46
|
||||
i32.const 39
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -753,14 +778,19 @@
|
||||
)
|
||||
(func $~lib/array/Array<RefWithCtor>#__unchecked_set (; 16 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
get_local $0
|
||||
i32.load
|
||||
set_local $3
|
||||
i32.const 0
|
||||
set_local $4
|
||||
get_local $3
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $4
|
||||
i32.add
|
||||
get_local $2
|
||||
i32.store offset=8
|
||||
)
|
||||
|
@ -729,7 +729,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 8
|
||||
i32.const 45
|
||||
i32.const 46
|
||||
i32.const 39
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -997,10 +997,10 @@
|
||||
i32.ge_s
|
||||
i32.eqz
|
||||
if
|
||||
get_local $6
|
||||
get_local $2
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $6
|
||||
i32.add
|
||||
get_local $1
|
||||
i32.store offset=8
|
||||
@ -2344,7 +2344,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 8
|
||||
i32.const 184
|
||||
i32.const 185
|
||||
i32.const 42
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -2361,10 +2361,10 @@
|
||||
get_local $0
|
||||
get_local $3
|
||||
i32.store offset=4
|
||||
get_local $4
|
||||
get_local $2
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $4
|
||||
i32.add
|
||||
get_local $1
|
||||
i32.store offset=8
|
||||
@ -2381,7 +2381,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 8
|
||||
i32.const 246
|
||||
i32.const 247
|
||||
i32.const 20
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -2582,15 +2582,15 @@
|
||||
loop $continue|0
|
||||
get_local $3
|
||||
if
|
||||
get_local $6
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $6
|
||||
i32.add
|
||||
get_local $6
|
||||
get_local $2
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $6
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
i32.store offset=8
|
||||
@ -2679,7 +2679,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 8
|
||||
i32.const 336
|
||||
i32.const 337
|
||||
i32.const 42
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -2731,7 +2731,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 8
|
||||
i32.const 307
|
||||
i32.const 308
|
||||
i32.const 20
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -2784,29 +2784,29 @@
|
||||
get_local $2
|
||||
i32.ge_s
|
||||
br_if $break|0
|
||||
get_local $3
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
set_local $4
|
||||
get_local $3
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
get_local $3
|
||||
get_local $2
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
i32.store offset=8
|
||||
get_local $3
|
||||
get_local $2
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
get_local $4
|
||||
i32.store offset=8
|
||||
@ -2866,10 +2866,10 @@
|
||||
get_local $4
|
||||
i32.lt_s
|
||||
if
|
||||
get_local $0
|
||||
get_local $2
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $0
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
get_local $1
|
||||
@ -3019,7 +3019,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 8
|
||||
i32.const 109
|
||||
i32.const 110
|
||||
i32.const 41
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -3039,10 +3039,10 @@
|
||||
get_local $4
|
||||
i32.store offset=4
|
||||
end
|
||||
get_local $3
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
get_local $2
|
||||
i32.store offset=8
|
||||
@ -3080,10 +3080,10 @@
|
||||
br_if $break|0
|
||||
i32.const 3
|
||||
set_global $~argc
|
||||
get_local $4
|
||||
get_local $2
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $4
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
get_local $2
|
||||
@ -3166,10 +3166,10 @@
|
||||
br_if $break|0
|
||||
i32.const 3
|
||||
set_global $~argc
|
||||
get_local $4
|
||||
get_local $2
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $4
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
get_local $2
|
||||
@ -3252,10 +3252,10 @@
|
||||
br_if $break|0
|
||||
i32.const 3
|
||||
set_global $~argc
|
||||
get_local $4
|
||||
get_local $2
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $4
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
get_local $2
|
||||
@ -3339,10 +3339,10 @@
|
||||
br_if $break|0
|
||||
i32.const 3
|
||||
set_global $~argc
|
||||
get_local $4
|
||||
get_local $2
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $4
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
get_local $2
|
||||
@ -3483,15 +3483,15 @@
|
||||
br_if $break|0
|
||||
i32.const 3
|
||||
set_global $~argc
|
||||
get_local $2
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $7
|
||||
i32.add
|
||||
get_local $2
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $4
|
||||
get_local $2
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
get_local $2
|
||||
@ -3561,10 +3561,10 @@
|
||||
get_local $3
|
||||
i32.eqz
|
||||
br_if $break|0
|
||||
get_local $5
|
||||
get_local $2
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $5
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
set_local $3
|
||||
@ -3659,10 +3659,10 @@
|
||||
i32.const 4
|
||||
set_global $~argc
|
||||
get_local $2
|
||||
get_local $5
|
||||
get_local $3
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $5
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
get_local $3
|
||||
@ -3736,10 +3736,10 @@
|
||||
i32.const 4
|
||||
set_global $~argc
|
||||
get_local $2
|
||||
get_local $4
|
||||
get_local $3
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $4
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
get_local $3
|
||||
@ -4074,14 +4074,12 @@
|
||||
get_local $3
|
||||
i32.const 2
|
||||
i32.shl
|
||||
tee_local $1
|
||||
get_local $0
|
||||
i32.add
|
||||
tee_local $1
|
||||
f32.load offset=8
|
||||
f32.store offset=8
|
||||
get_local $0
|
||||
get_local $1
|
||||
i32.add
|
||||
get_local $6
|
||||
f32.store offset=8
|
||||
i32.const 1
|
||||
@ -4183,12 +4181,11 @@
|
||||
get_local $0
|
||||
i32.const 4
|
||||
i32.add
|
||||
tee_local $2
|
||||
tee_local $1
|
||||
f32.load offset=8
|
||||
set_local $6
|
||||
get_local $2
|
||||
get_local $1
|
||||
get_local $0
|
||||
tee_local $1
|
||||
f32.load offset=8
|
||||
f32.store offset=8
|
||||
get_local $0
|
||||
@ -4205,7 +4202,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 8
|
||||
i32.const 408
|
||||
i32.const 409
|
||||
i32.const 4
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -4648,14 +4645,12 @@
|
||||
get_local $3
|
||||
i32.const 3
|
||||
i32.shl
|
||||
tee_local $1
|
||||
get_local $0
|
||||
i32.add
|
||||
tee_local $1
|
||||
f64.load offset=8
|
||||
f64.store offset=8
|
||||
get_local $0
|
||||
get_local $1
|
||||
i32.add
|
||||
get_local $6
|
||||
f64.store offset=8
|
||||
i32.const 1
|
||||
@ -4757,12 +4752,11 @@
|
||||
get_local $0
|
||||
i32.const 8
|
||||
i32.add
|
||||
tee_local $2
|
||||
tee_local $1
|
||||
f64.load offset=8
|
||||
set_local $6
|
||||
get_local $2
|
||||
get_local $1
|
||||
get_local $0
|
||||
tee_local $1
|
||||
f64.load offset=8
|
||||
f64.store offset=8
|
||||
get_local $0
|
||||
@ -4779,7 +4773,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 8
|
||||
i32.const 408
|
||||
i32.const 409
|
||||
i32.const 4
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -5106,19 +5100,19 @@
|
||||
get_local $1
|
||||
i32.const 1
|
||||
i32.sub
|
||||
set_local $4
|
||||
set_local $3
|
||||
loop $repeat|0
|
||||
get_local $4
|
||||
get_local $3
|
||||
i32.const 0
|
||||
i32.gt_s
|
||||
if
|
||||
get_local $4
|
||||
set_local $3
|
||||
get_local $3
|
||||
set_local $4
|
||||
loop $continue|1
|
||||
get_local $3
|
||||
get_local $4
|
||||
i32.const 1
|
||||
i32.and
|
||||
get_local $3
|
||||
get_local $4
|
||||
i32.const 6
|
||||
i32.shr_s
|
||||
i32.const 2
|
||||
@ -5126,7 +5120,7 @@
|
||||
get_local $7
|
||||
i32.add
|
||||
i32.load
|
||||
get_local $3
|
||||
get_local $4
|
||||
i32.const 1
|
||||
i32.shr_s
|
||||
i32.const 31
|
||||
@ -5136,14 +5130,14 @@
|
||||
i32.and
|
||||
i32.eq
|
||||
if
|
||||
get_local $3
|
||||
get_local $4
|
||||
i32.const 1
|
||||
i32.shr_s
|
||||
set_local $3
|
||||
set_local $4
|
||||
br $continue|1
|
||||
end
|
||||
end
|
||||
get_local $3
|
||||
get_local $4
|
||||
i32.const 1
|
||||
i32.shr_s
|
||||
tee_local $5
|
||||
@ -5152,8 +5146,8 @@
|
||||
get_local $0
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
set_local $3
|
||||
get_local $4
|
||||
set_local $4
|
||||
get_local $3
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $0
|
||||
@ -5162,14 +5156,14 @@
|
||||
set_local $6
|
||||
i32.const 2
|
||||
set_global $~argc
|
||||
get_local $3
|
||||
get_local $4
|
||||
get_local $6
|
||||
get_local $2
|
||||
call_indirect (type $iii)
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
get_local $4
|
||||
get_local $3
|
||||
i32.const 5
|
||||
i32.shr_s
|
||||
i32.const 2
|
||||
@ -5180,18 +5174,18 @@
|
||||
get_local $8
|
||||
i32.load
|
||||
i32.const 1
|
||||
get_local $4
|
||||
get_local $3
|
||||
i32.const 31
|
||||
i32.and
|
||||
i32.shl
|
||||
i32.xor
|
||||
i32.store
|
||||
get_local $4
|
||||
get_local $3
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $0
|
||||
i32.add
|
||||
get_local $3
|
||||
get_local $4
|
||||
i32.store offset=8
|
||||
get_local $5
|
||||
i32.const 2
|
||||
@ -5201,19 +5195,19 @@
|
||||
get_local $6
|
||||
i32.store offset=8
|
||||
end
|
||||
get_local $4
|
||||
get_local $3
|
||||
i32.const 1
|
||||
i32.sub
|
||||
set_local $4
|
||||
set_local $3
|
||||
br $repeat|0
|
||||
end
|
||||
end
|
||||
get_local $1
|
||||
i32.const 1
|
||||
i32.sub
|
||||
set_local $4
|
||||
set_local $3
|
||||
loop $repeat|2
|
||||
get_local $4
|
||||
get_local $3
|
||||
i32.const 2
|
||||
i32.ge_s
|
||||
if
|
||||
@ -5221,17 +5215,15 @@
|
||||
i32.load offset=8
|
||||
set_local $6
|
||||
get_local $0
|
||||
get_local $4
|
||||
get_local $3
|
||||
i32.const 2
|
||||
i32.shl
|
||||
tee_local $1
|
||||
get_local $0
|
||||
i32.add
|
||||
tee_local $1
|
||||
i32.load offset=8
|
||||
i32.store offset=8
|
||||
get_local $0
|
||||
get_local $1
|
||||
i32.add
|
||||
get_local $6
|
||||
i32.store offset=8
|
||||
i32.const 1
|
||||
@ -5255,11 +5247,11 @@
|
||||
i32.const 1
|
||||
i32.shl
|
||||
i32.add
|
||||
tee_local $3
|
||||
get_local $4
|
||||
tee_local $4
|
||||
get_local $3
|
||||
i32.lt_s
|
||||
if
|
||||
get_local $3
|
||||
get_local $4
|
||||
set_local $5
|
||||
br $continue|3
|
||||
end
|
||||
@ -5278,11 +5270,11 @@
|
||||
get_local $0
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
set_local $3
|
||||
set_local $4
|
||||
i32.const 2
|
||||
set_global $~argc
|
||||
get_local $6
|
||||
get_local $3
|
||||
get_local $4
|
||||
get_local $2
|
||||
call_indirect (type $iii)
|
||||
i32.const 0
|
||||
@ -5313,7 +5305,7 @@
|
||||
get_local $6
|
||||
i32.store offset=8
|
||||
get_local $0
|
||||
get_local $3
|
||||
get_local $4
|
||||
i32.store offset=8
|
||||
end
|
||||
get_local $5
|
||||
@ -5323,22 +5315,21 @@
|
||||
br $continue|4
|
||||
end
|
||||
end
|
||||
get_local $4
|
||||
get_local $3
|
||||
i32.const 1
|
||||
i32.sub
|
||||
set_local $4
|
||||
set_local $3
|
||||
br $repeat|2
|
||||
end
|
||||
end
|
||||
get_local $0
|
||||
i32.const 4
|
||||
i32.add
|
||||
tee_local $3
|
||||
tee_local $2
|
||||
i32.load offset=8
|
||||
set_local $1
|
||||
get_local $3
|
||||
get_local $2
|
||||
get_local $0
|
||||
tee_local $2
|
||||
i32.load offset=8
|
||||
i32.store offset=8
|
||||
get_local $0
|
||||
@ -5354,7 +5345,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 8
|
||||
i32.const 408
|
||||
i32.const 409
|
||||
i32.const 4
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -5743,7 +5734,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 8
|
||||
i32.const 408
|
||||
i32.const 409
|
||||
i32.const 4
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -6639,20 +6630,20 @@
|
||||
i32.shl
|
||||
get_local $0
|
||||
i32.add
|
||||
get_local $3
|
||||
get_local $4
|
||||
i32.const 100
|
||||
i32.div_u
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
get_local $3
|
||||
get_local $4
|
||||
i32.const 100
|
||||
i32.rem_u
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
i64.const 32
|
||||
@ -6682,10 +6673,10 @@
|
||||
i32.shl
|
||||
get_local $0
|
||||
i32.add
|
||||
get_local $3
|
||||
get_local $4
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
i32.store offset=4
|
||||
@ -6701,10 +6692,10 @@
|
||||
i32.shl
|
||||
get_local $0
|
||||
i32.add
|
||||
get_local $3
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
i32.store offset=4
|
||||
@ -7283,10 +7274,10 @@
|
||||
get_local $9
|
||||
i32.add
|
||||
set_global $~lib/internal/number/_K
|
||||
get_local $12
|
||||
get_local $9
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $12
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
get_local $11
|
||||
@ -7412,12 +7403,12 @@
|
||||
get_local $9
|
||||
i32.add
|
||||
set_global $~lib/internal/number/_K
|
||||
get_local $12
|
||||
i32.const 0
|
||||
get_local $9
|
||||
i32.sub
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $12
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
get_local $8
|
||||
@ -7430,9 +7421,9 @@
|
||||
i32.shl
|
||||
get_local $0
|
||||
i32.add
|
||||
tee_local $4
|
||||
tee_local $7
|
||||
i32.load16_u offset=4
|
||||
set_local $7
|
||||
set_local $4
|
||||
loop $continue|4
|
||||
get_local $1
|
||||
get_local $8
|
||||
@ -7470,10 +7461,10 @@
|
||||
end
|
||||
get_local $2
|
||||
if
|
||||
get_local $7
|
||||
get_local $4
|
||||
i32.const 1
|
||||
i32.sub
|
||||
set_local $7
|
||||
set_local $4
|
||||
get_local $1
|
||||
get_local $10
|
||||
i64.add
|
||||
@ -7481,8 +7472,8 @@
|
||||
br $continue|4
|
||||
end
|
||||
end
|
||||
get_local $4
|
||||
get_local $7
|
||||
get_local $4
|
||||
i32.store16 offset=4
|
||||
get_local $6
|
||||
else
|
||||
@ -7888,10 +7879,10 @@
|
||||
i32.add
|
||||
i64.load offset=8
|
||||
set_global $~lib/internal/number/_frc_pow
|
||||
get_local $4
|
||||
get_local $5
|
||||
i32.const 1
|
||||
i32.shl
|
||||
get_local $4
|
||||
i32.add
|
||||
i32.load16_s offset=8
|
||||
set_global $~lib/internal/number/_exp_pow
|
||||
@ -8368,10 +8359,10 @@
|
||||
get_local $2
|
||||
i32.ge_s
|
||||
br_if $break|0
|
||||
get_local $6
|
||||
get_local $0
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $6
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
i32.load
|
||||
@ -8402,10 +8393,10 @@
|
||||
get_local $5
|
||||
i32.ge_s
|
||||
br_if $break|1
|
||||
get_local $6
|
||||
get_local $3
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $6
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
tee_local $4
|
||||
@ -8443,10 +8434,10 @@
|
||||
br $repeat|1
|
||||
end
|
||||
end
|
||||
get_local $6
|
||||
get_local $5
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $6
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
tee_local $4
|
||||
@ -8504,20 +8495,22 @@
|
||||
i32.add
|
||||
tee_local $7
|
||||
call $~lib/internal/string/allocateUnsafe
|
||||
set_local $2
|
||||
i32.const 0
|
||||
set_local $0
|
||||
loop $repeat|0
|
||||
get_local $2
|
||||
get_local $0
|
||||
get_local $3
|
||||
i32.lt_s
|
||||
if
|
||||
get_local $2
|
||||
get_local $0
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $5
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
if
|
||||
get_local $0
|
||||
get_local $2
|
||||
get_local $1
|
||||
i32.const 6792
|
||||
i32.const 0
|
||||
@ -8530,7 +8523,7 @@
|
||||
end
|
||||
get_local $6
|
||||
if
|
||||
get_local $0
|
||||
get_local $2
|
||||
get_local $1
|
||||
i32.const 4136
|
||||
i32.const 0
|
||||
@ -8541,10 +8534,10 @@
|
||||
i32.add
|
||||
set_local $1
|
||||
end
|
||||
get_local $2
|
||||
get_local $0
|
||||
i32.const 1
|
||||
i32.add
|
||||
set_local $2
|
||||
set_local $0
|
||||
br $repeat|0
|
||||
end
|
||||
end
|
||||
@ -8555,7 +8548,7 @@
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
if
|
||||
get_local $0
|
||||
get_local $2
|
||||
get_local $1
|
||||
i32.const 6792
|
||||
i32.const 0
|
||||
@ -8566,17 +8559,17 @@
|
||||
i32.add
|
||||
set_local $1
|
||||
end
|
||||
get_local $0
|
||||
set_local $2
|
||||
get_local $2
|
||||
set_local $0
|
||||
get_local $7
|
||||
get_local $1
|
||||
i32.gt_s
|
||||
if
|
||||
get_local $0
|
||||
get_local $2
|
||||
get_local $1
|
||||
call $~lib/string/String#substring
|
||||
set_local $2
|
||||
get_local $0
|
||||
set_local $0
|
||||
get_local $2
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
@ -8587,7 +8580,7 @@
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
get_local $2
|
||||
get_local $0
|
||||
)
|
||||
(func $~lib/internal/number/itoa_stream<i8> (; 128 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
|
||||
(local $3 i32)
|
||||
@ -8999,6 +8992,7 @@
|
||||
i32.shl
|
||||
get_local $0
|
||||
i32.add
|
||||
get_local $3
|
||||
get_local $4
|
||||
i32.const 10000
|
||||
i32.rem_u
|
||||
@ -9007,15 +9001,14 @@
|
||||
i32.div_u
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
get_local $3
|
||||
get_local $4
|
||||
i32.const 100
|
||||
i32.rem_u
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
i64.const 32
|
||||
@ -9030,16 +9023,16 @@
|
||||
i32.shl
|
||||
get_local $0
|
||||
i32.add
|
||||
get_local $3
|
||||
get_local $6
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
get_local $3
|
||||
get_local $5
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
i64.const 32
|
||||
@ -9869,10 +9862,10 @@
|
||||
get_local $4
|
||||
i32.ge_s
|
||||
br_if $break|0
|
||||
get_local $5
|
||||
get_local $0
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $5
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
tee_local $3
|
||||
@ -9898,10 +9891,10 @@
|
||||
br $repeat|0
|
||||
end
|
||||
end
|
||||
get_local $5
|
||||
get_local $4
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $5
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
tee_local $3
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -339,7 +339,7 @@
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $~lib/internal/typedarray/TypedArray<u8,u32>#constructor (; 4 ;) (type $FUNCSIG$i) (result i32)
|
||||
(func $~lib/internal/typedarray/TypedArray<u8>#constructor (; 4 ;) (type $FUNCSIG$i) (result i32)
|
||||
(local $0 i32)
|
||||
(local $1 i32)
|
||||
i32.const 8
|
||||
@ -371,7 +371,7 @@
|
||||
i32.store offset=8
|
||||
get_local $0
|
||||
)
|
||||
(func $~lib/internal/typedarray/TypedArray<u8,u32>#__set (; 5 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(func $~lib/internal/typedarray/TypedArray<u8>#__set (; 5 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
get_local $1
|
||||
get_local $0
|
||||
i32.load offset=8
|
||||
@ -379,16 +379,16 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 8
|
||||
i32.const 54
|
||||
i32.const 51
|
||||
i32.const 63
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
end
|
||||
get_local $0
|
||||
i32.load offset=4
|
||||
get_local $1
|
||||
get_local $0
|
||||
i32.load
|
||||
get_local $0
|
||||
i32.load offset=4
|
||||
i32.add
|
||||
i32.add
|
||||
get_local $2
|
||||
@ -1092,40 +1092,40 @@
|
||||
set_global $~lib/allocator/arena/startOffset
|
||||
get_global $~lib/allocator/arena/startOffset
|
||||
set_global $~lib/allocator/arena/offset
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#constructor
|
||||
call $~lib/internal/typedarray/TypedArray<u8>#constructor
|
||||
set_global $std/dataview/array
|
||||
get_global $std/dataview/array
|
||||
i32.const 0
|
||||
i32.const 246
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__set
|
||||
call $~lib/internal/typedarray/TypedArray<u8>#__set
|
||||
get_global $std/dataview/array
|
||||
i32.const 1
|
||||
i32.const 224
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__set
|
||||
call $~lib/internal/typedarray/TypedArray<u8>#__set
|
||||
get_global $std/dataview/array
|
||||
i32.const 2
|
||||
i32.const 88
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__set
|
||||
call $~lib/internal/typedarray/TypedArray<u8>#__set
|
||||
get_global $std/dataview/array
|
||||
i32.const 3
|
||||
i32.const 159
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__set
|
||||
call $~lib/internal/typedarray/TypedArray<u8>#__set
|
||||
get_global $std/dataview/array
|
||||
i32.const 4
|
||||
i32.const 130
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__set
|
||||
call $~lib/internal/typedarray/TypedArray<u8>#__set
|
||||
get_global $std/dataview/array
|
||||
i32.const 5
|
||||
i32.const 101
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__set
|
||||
call $~lib/internal/typedarray/TypedArray<u8>#__set
|
||||
get_global $std/dataview/array
|
||||
i32.const 6
|
||||
i32.const 67
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__set
|
||||
call $~lib/internal/typedarray/TypedArray<u8>#__set
|
||||
get_global $std/dataview/array
|
||||
i32.const 7
|
||||
i32.const 95
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__set
|
||||
call $~lib/internal/typedarray/TypedArray<u8>#__set
|
||||
get_global $std/dataview/array
|
||||
i32.load
|
||||
get_global $std/dataview/array
|
||||
|
@ -415,7 +415,7 @@
|
||||
call $~lib/allocator/arena/__memory_allocate
|
||||
return
|
||||
)
|
||||
(func $~lib/internal/typedarray/TypedArray<u8,u32>#constructor (; 6 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(func $~lib/internal/typedarray/TypedArray<u8>#constructor (; 6 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
@ -426,7 +426,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 8
|
||||
i32.const 27
|
||||
i32.const 24
|
||||
i32.const 34
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -480,7 +480,7 @@
|
||||
i32.store offset=8
|
||||
get_local $0
|
||||
)
|
||||
(func $~lib/internal/typedarray/TypedArray<u8,u32>#__set (; 7 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(func $~lib/internal/typedarray/TypedArray<u8>#__set (; 7 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
get_local $1
|
||||
@ -492,7 +492,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 8
|
||||
i32.const 54
|
||||
i32.const 51
|
||||
i32.const 63
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -504,12 +504,12 @@
|
||||
i32.load offset=4
|
||||
set_local $4
|
||||
get_local $3
|
||||
get_local $4
|
||||
i32.add
|
||||
get_local $1
|
||||
i32.const 0
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $4
|
||||
i32.add
|
||||
get_local $2
|
||||
i32.store8 offset=8
|
||||
)
|
||||
@ -1703,40 +1703,40 @@
|
||||
set_global $~lib/allocator/arena/offset
|
||||
i32.const 0
|
||||
i32.const 8
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#constructor
|
||||
call $~lib/internal/typedarray/TypedArray<u8>#constructor
|
||||
set_global $std/dataview/array
|
||||
get_global $std/dataview/array
|
||||
i32.const 0
|
||||
i32.const 246
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__set
|
||||
call $~lib/internal/typedarray/TypedArray<u8>#__set
|
||||
get_global $std/dataview/array
|
||||
i32.const 1
|
||||
i32.const 224
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__set
|
||||
call $~lib/internal/typedarray/TypedArray<u8>#__set
|
||||
get_global $std/dataview/array
|
||||
i32.const 2
|
||||
i32.const 88
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__set
|
||||
call $~lib/internal/typedarray/TypedArray<u8>#__set
|
||||
get_global $std/dataview/array
|
||||
i32.const 3
|
||||
i32.const 159
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__set
|
||||
call $~lib/internal/typedarray/TypedArray<u8>#__set
|
||||
get_global $std/dataview/array
|
||||
i32.const 4
|
||||
i32.const 130
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__set
|
||||
call $~lib/internal/typedarray/TypedArray<u8>#__set
|
||||
get_global $std/dataview/array
|
||||
i32.const 5
|
||||
i32.const 101
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__set
|
||||
call $~lib/internal/typedarray/TypedArray<u8>#__set
|
||||
get_global $std/dataview/array
|
||||
i32.const 6
|
||||
i32.const 67
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__set
|
||||
call $~lib/internal/typedarray/TypedArray<u8>#__set
|
||||
get_global $std/dataview/array
|
||||
i32.const 7
|
||||
i32.const 95
|
||||
call $~lib/internal/typedarray/TypedArray<u8,u32>#__set
|
||||
call $~lib/internal/typedarray/TypedArray<u8>#__set
|
||||
i32.const 0
|
||||
get_global $std/dataview/array
|
||||
i32.load
|
||||
|
@ -1900,7 +1900,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 72
|
||||
i32.const 109
|
||||
i32.const 110
|
||||
i32.const 41
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -1920,10 +1920,10 @@
|
||||
get_local $4
|
||||
i32.store offset=4
|
||||
end
|
||||
get_local $3
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
get_local $2
|
||||
i32.store offset=8
|
||||
|
@ -2412,6 +2412,7 @@
|
||||
(func $~lib/array/Array<Foo>#__set (; 28 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
get_local $0
|
||||
i32.load
|
||||
set_local $3
|
||||
@ -2430,7 +2431,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 72
|
||||
i32.const 109
|
||||
i32.const 110
|
||||
i32.const 41
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -2452,11 +2453,15 @@
|
||||
i32.add
|
||||
i32.store offset=4
|
||||
end
|
||||
i32.const 0
|
||||
set_local $5
|
||||
get_local $3
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $5
|
||||
i32.add
|
||||
get_local $2
|
||||
i32.store offset=8
|
||||
get_local $0
|
||||
|
@ -43,6 +43,7 @@
|
||||
(start $start)
|
||||
(func $~lib/array/Array<i32>#__get (; 1 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
get_local $0
|
||||
i32.load
|
||||
set_local $2
|
||||
@ -53,11 +54,15 @@
|
||||
i32.shr_u
|
||||
i32.lt_u
|
||||
if (result i32)
|
||||
i32.const 0
|
||||
set_local $3
|
||||
get_local $2
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $3
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
else
|
||||
unreachable
|
||||
@ -1978,6 +1983,7 @@
|
||||
(func $~lib/array/Array<i32>#__set (; 9 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
get_local $0
|
||||
i32.load
|
||||
set_local $3
|
||||
@ -1996,7 +2002,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 184
|
||||
i32.const 109
|
||||
i32.const 110
|
||||
i32.const 41
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -2018,16 +2024,21 @@
|
||||
i32.add
|
||||
i32.store offset=4
|
||||
end
|
||||
i32.const 0
|
||||
set_local $5
|
||||
get_local $3
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $5
|
||||
i32.add
|
||||
get_local $2
|
||||
i32.store offset=8
|
||||
)
|
||||
(func $~lib/array/Array<i64>#__get (; 10 ;) (type $iiI) (param $0 i32) (param $1 i32) (result i64)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
get_local $0
|
||||
i32.load
|
||||
set_local $2
|
||||
@ -2038,11 +2049,15 @@
|
||||
i32.shr_u
|
||||
i32.lt_u
|
||||
if (result i64)
|
||||
i32.const 0
|
||||
set_local $3
|
||||
get_local $2
|
||||
get_local $1
|
||||
i32.const 3
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $3
|
||||
i32.add
|
||||
i64.load offset=8
|
||||
else
|
||||
unreachable
|
||||
@ -2051,6 +2066,7 @@
|
||||
(func $~lib/array/Array<i64>#__set (; 11 ;) (type $iiIv) (param $0 i32) (param $1 i32) (param $2 i64)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
get_local $0
|
||||
i32.load
|
||||
set_local $3
|
||||
@ -2069,7 +2085,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 184
|
||||
i32.const 109
|
||||
i32.const 110
|
||||
i32.const 41
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -2091,16 +2107,21 @@
|
||||
i32.add
|
||||
i32.store offset=4
|
||||
end
|
||||
i32.const 0
|
||||
set_local $5
|
||||
get_local $3
|
||||
get_local $1
|
||||
i32.const 3
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $5
|
||||
i32.add
|
||||
get_local $2
|
||||
i64.store offset=8
|
||||
)
|
||||
(func $~lib/array/Array<f32>#__get (; 12 ;) (type $iif) (param $0 i32) (param $1 i32) (result f32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
get_local $0
|
||||
i32.load
|
||||
set_local $2
|
||||
@ -2111,11 +2132,15 @@
|
||||
i32.shr_u
|
||||
i32.lt_u
|
||||
if (result f32)
|
||||
i32.const 0
|
||||
set_local $3
|
||||
get_local $2
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $3
|
||||
i32.add
|
||||
f32.load offset=8
|
||||
else
|
||||
unreachable
|
||||
@ -2124,6 +2149,7 @@
|
||||
(func $~lib/array/Array<f32>#__set (; 13 ;) (type $iifv) (param $0 i32) (param $1 i32) (param $2 f32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
get_local $0
|
||||
i32.load
|
||||
set_local $3
|
||||
@ -2142,7 +2168,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 184
|
||||
i32.const 109
|
||||
i32.const 110
|
||||
i32.const 41
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -2164,16 +2190,21 @@
|
||||
i32.add
|
||||
i32.store offset=4
|
||||
end
|
||||
i32.const 0
|
||||
set_local $5
|
||||
get_local $3
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $5
|
||||
i32.add
|
||||
get_local $2
|
||||
f32.store offset=8
|
||||
)
|
||||
(func $~lib/array/Array<f64>#__get (; 14 ;) (type $iiF) (param $0 i32) (param $1 i32) (result f64)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
get_local $0
|
||||
i32.load
|
||||
set_local $2
|
||||
@ -2184,11 +2215,15 @@
|
||||
i32.shr_u
|
||||
i32.lt_u
|
||||
if (result f64)
|
||||
i32.const 0
|
||||
set_local $3
|
||||
get_local $2
|
||||
get_local $1
|
||||
i32.const 3
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $3
|
||||
i32.add
|
||||
f64.load offset=8
|
||||
else
|
||||
unreachable
|
||||
@ -2197,6 +2232,7 @@
|
||||
(func $~lib/array/Array<f64>#__set (; 15 ;) (type $iiFv) (param $0 i32) (param $1 i32) (param $2 f64)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
get_local $0
|
||||
i32.load
|
||||
set_local $3
|
||||
@ -2215,7 +2251,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 184
|
||||
i32.const 109
|
||||
i32.const 110
|
||||
i32.const 41
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -2237,11 +2273,15 @@
|
||||
i32.add
|
||||
i32.store offset=4
|
||||
end
|
||||
i32.const 0
|
||||
set_local $5
|
||||
get_local $3
|
||||
get_local $1
|
||||
i32.const 3
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $5
|
||||
i32.add
|
||||
get_local $2
|
||||
f64.store offset=8
|
||||
)
|
||||
|
@ -3304,7 +3304,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 976
|
||||
i32.const 45
|
||||
i32.const 46
|
||||
i32.const 39
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -3452,7 +3452,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 976
|
||||
i32.const 184
|
||||
i32.const 185
|
||||
i32.const 42
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -3469,10 +3469,10 @@
|
||||
get_local $0
|
||||
get_local $3
|
||||
i32.store offset=4
|
||||
get_local $4
|
||||
get_local $2
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $4
|
||||
i32.add
|
||||
get_local $1
|
||||
i32.store offset=8
|
||||
@ -3787,20 +3787,20 @@
|
||||
i32.shl
|
||||
get_local $0
|
||||
i32.add
|
||||
get_local $3
|
||||
get_local $4
|
||||
i32.const 100
|
||||
i32.div_u
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
get_local $3
|
||||
get_local $4
|
||||
i32.const 100
|
||||
i32.rem_u
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
i64.const 32
|
||||
@ -3830,10 +3830,10 @@
|
||||
i32.shl
|
||||
get_local $0
|
||||
i32.add
|
||||
get_local $3
|
||||
get_local $4
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
i32.store offset=4
|
||||
@ -3849,10 +3849,10 @@
|
||||
i32.shl
|
||||
get_local $0
|
||||
i32.add
|
||||
get_local $3
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
i32.store offset=4
|
||||
@ -4022,6 +4022,7 @@
|
||||
i32.shl
|
||||
get_local $0
|
||||
i32.add
|
||||
get_local $3
|
||||
get_local $4
|
||||
i32.const 10000
|
||||
i32.rem_u
|
||||
@ -4030,15 +4031,14 @@
|
||||
i32.div_u
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
get_local $3
|
||||
get_local $4
|
||||
i32.const 100
|
||||
i32.rem_u
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
i64.const 32
|
||||
@ -4053,16 +4053,16 @@
|
||||
i32.shl
|
||||
get_local $0
|
||||
i32.add
|
||||
get_local $3
|
||||
get_local $6
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
get_local $3
|
||||
get_local $5
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $3
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
i64.const 32
|
||||
@ -4374,10 +4374,10 @@
|
||||
get_local $9
|
||||
i32.add
|
||||
set_global $~lib/internal/number/_K
|
||||
get_local $12
|
||||
get_local $9
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $12
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
get_local $11
|
||||
@ -4503,12 +4503,12 @@
|
||||
get_local $9
|
||||
i32.add
|
||||
set_global $~lib/internal/number/_K
|
||||
get_local $12
|
||||
i32.const 0
|
||||
get_local $9
|
||||
i32.sub
|
||||
i32.const 2
|
||||
i32.shl
|
||||
get_local $12
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
get_local $8
|
||||
@ -4521,9 +4521,9 @@
|
||||
i32.shl
|
||||
get_local $0
|
||||
i32.add
|
||||
tee_local $4
|
||||
tee_local $7
|
||||
i32.load16_u offset=4
|
||||
set_local $7
|
||||
set_local $4
|
||||
loop $continue|4
|
||||
get_local $1
|
||||
get_local $8
|
||||
@ -4561,10 +4561,10 @@
|
||||
end
|
||||
get_local $2
|
||||
if
|
||||
get_local $7
|
||||
get_local $4
|
||||
i32.const 1
|
||||
i32.sub
|
||||
set_local $7
|
||||
set_local $4
|
||||
get_local $1
|
||||
get_local $10
|
||||
i64.add
|
||||
@ -4572,8 +4572,8 @@
|
||||
br $continue|4
|
||||
end
|
||||
end
|
||||
get_local $4
|
||||
get_local $7
|
||||
get_local $4
|
||||
i32.store16 offset=4
|
||||
get_local $6
|
||||
else
|
||||
@ -4979,10 +4979,10 @@
|
||||
i32.add
|
||||
i64.load offset=8
|
||||
set_global $~lib/internal/number/_frc_pow
|
||||
get_local $4
|
||||
get_local $5
|
||||
i32.const 1
|
||||
i32.shl
|
||||
get_local $4
|
||||
i32.add
|
||||
i32.load16_s offset=8
|
||||
set_global $~lib/internal/number/_exp_pow
|
||||
|
@ -4103,7 +4103,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 976
|
||||
i32.const 45
|
||||
i32.const 46
|
||||
i32.const 39
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -4153,14 +4153,19 @@
|
||||
)
|
||||
(func $~lib/array/Array<String>#__unchecked_set (; 39 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
get_local $0
|
||||
i32.load
|
||||
set_local $3
|
||||
i32.const 0
|
||||
set_local $4
|
||||
get_local $3
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $4
|
||||
i32.add
|
||||
get_local $2
|
||||
i32.store offset=8
|
||||
)
|
||||
@ -4279,6 +4284,7 @@
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
(local $6 i32)
|
||||
get_local $0
|
||||
i32.load offset=4
|
||||
set_local $2
|
||||
@ -4304,7 +4310,7 @@
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 976
|
||||
i32.const 184
|
||||
i32.const 185
|
||||
i32.const 42
|
||||
call $~lib/env/abort
|
||||
unreachable
|
||||
@ -4322,11 +4328,15 @@
|
||||
get_local $0
|
||||
get_local $5
|
||||
i32.store offset=4
|
||||
i32.const 0
|
||||
set_local $6
|
||||
get_local $3
|
||||
get_local $2
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $6
|
||||
i32.add
|
||||
get_local $1
|
||||
i32.store offset=8
|
||||
get_local $5
|
||||
@ -4344,6 +4354,7 @@
|
||||
(local $12 i32)
|
||||
(local $13 i32)
|
||||
(local $14 i32)
|
||||
(local $15 i32)
|
||||
get_local $0
|
||||
i32.const 0
|
||||
i32.ne
|
||||
@ -4442,11 +4453,15 @@
|
||||
i32.add
|
||||
i32.load16_u offset=4
|
||||
i32.store16 offset=4
|
||||
i32.const 0
|
||||
set_local $9
|
||||
get_local $6
|
||||
get_local $7
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $9
|
||||
i32.add
|
||||
get_local $8
|
||||
i32.store offset=8
|
||||
end
|
||||
@ -4472,26 +4487,26 @@
|
||||
i32.const 0
|
||||
i32.const 0
|
||||
call $~lib/array/Array<String>#constructor
|
||||
set_local $9
|
||||
i32.const 0
|
||||
set_local $10
|
||||
i32.const 0
|
||||
set_local $11
|
||||
i32.const 0
|
||||
set_local $12
|
||||
i32.const 0
|
||||
set_local $13
|
||||
block $break|1
|
||||
loop $continue|1
|
||||
get_local $0
|
||||
get_local $1
|
||||
get_local $11
|
||||
get_local $12
|
||||
call $~lib/string/String#indexOf
|
||||
tee_local $10
|
||||
tee_local $11
|
||||
i32.const -1
|
||||
i32.ne
|
||||
if
|
||||
block
|
||||
get_local $10
|
||||
get_local $11
|
||||
get_local $12
|
||||
i32.sub
|
||||
set_local $6
|
||||
get_local $6
|
||||
@ -4504,82 +4519,82 @@
|
||||
get_local $3
|
||||
i32.const 0
|
||||
get_local $0
|
||||
get_local $11
|
||||
get_local $12
|
||||
get_local $6
|
||||
call $~lib/internal/string/copyUnsafe
|
||||
get_local $9
|
||||
get_local $10
|
||||
get_local $3
|
||||
call $~lib/array/Array<String>#push
|
||||
drop
|
||||
else
|
||||
get_local $9
|
||||
get_local $10
|
||||
i32.const 256
|
||||
call $~lib/array/Array<String>#push
|
||||
drop
|
||||
end
|
||||
get_local $12
|
||||
get_local $13
|
||||
i32.const 1
|
||||
i32.add
|
||||
tee_local $12
|
||||
tee_local $13
|
||||
get_local $2
|
||||
i32.eq
|
||||
if
|
||||
get_local $9
|
||||
get_local $10
|
||||
return
|
||||
end
|
||||
get_local $10
|
||||
get_local $11
|
||||
get_local $5
|
||||
i32.add
|
||||
set_local $11
|
||||
set_local $12
|
||||
end
|
||||
br $continue|1
|
||||
end
|
||||
end
|
||||
end
|
||||
get_local $11
|
||||
get_local $12
|
||||
i32.eqz
|
||||
if
|
||||
block (result i32)
|
||||
i32.const 0
|
||||
i32.const 1
|
||||
call $~lib/array/Array<String>#constructor
|
||||
set_local $13
|
||||
get_local $13
|
||||
set_local $14
|
||||
get_local $14
|
||||
i32.const 0
|
||||
get_local $0
|
||||
call $~lib/array/Array<String>#__unchecked_set
|
||||
get_local $13
|
||||
get_local $14
|
||||
end
|
||||
return
|
||||
end
|
||||
get_local $4
|
||||
get_local $11
|
||||
get_local $12
|
||||
i32.sub
|
||||
set_local $14
|
||||
get_local $14
|
||||
set_local $15
|
||||
get_local $15
|
||||
i32.const 0
|
||||
i32.gt_s
|
||||
if
|
||||
get_local $14
|
||||
get_local $15
|
||||
call $~lib/internal/string/allocateUnsafe
|
||||
set_local $13
|
||||
get_local $13
|
||||
set_local $14
|
||||
get_local $14
|
||||
i32.const 0
|
||||
get_local $0
|
||||
get_local $11
|
||||
get_local $14
|
||||
get_local $12
|
||||
get_local $15
|
||||
call $~lib/internal/string/copyUnsafe
|
||||
get_local $9
|
||||
get_local $13
|
||||
get_local $10
|
||||
get_local $14
|
||||
call $~lib/array/Array<String>#push
|
||||
drop
|
||||
else
|
||||
get_local $9
|
||||
get_local $10
|
||||
i32.const 256
|
||||
call $~lib/array/Array<String>#push
|
||||
drop
|
||||
end
|
||||
get_local $9
|
||||
get_local $10
|
||||
)
|
||||
(func $~lib/string/String#split|trampoline (; 43 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
|
||||
block $2of2
|
||||
@ -4604,6 +4619,7 @@
|
||||
)
|
||||
(func $~lib/array/Array<String>#__get (; 44 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
get_local $0
|
||||
i32.load
|
||||
set_local $2
|
||||
@ -4614,11 +4630,15 @@
|
||||
i32.shr_u
|
||||
i32.lt_u
|
||||
if (result i32)
|
||||
i32.const 0
|
||||
set_local $3
|
||||
get_local $2
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $3
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
else
|
||||
unreachable
|
||||
@ -4699,8 +4719,9 @@
|
||||
(local $5 i32)
|
||||
(local $6 i32)
|
||||
(local $7 i32)
|
||||
(local $8 i64)
|
||||
(local $8 i32)
|
||||
(local $9 i64)
|
||||
(local $10 i64)
|
||||
block $~lib/internal/number/DIGITS|inlined.0 (result i32)
|
||||
i32.const 1720
|
||||
end
|
||||
@ -4731,24 +4752,32 @@
|
||||
i32.const 100
|
||||
i32.rem_u
|
||||
set_local $7
|
||||
block $~lib/internal/arraybuffer/loadUnsafe<u32,u64>|inlined.0 (result i64)
|
||||
block $~lib/internal/arraybuffer/LOAD<u32,u64>|inlined.0 (result i64)
|
||||
i32.const 0
|
||||
set_local $8
|
||||
get_local $3
|
||||
get_local $6
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $8
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
end
|
||||
set_local $8
|
||||
block $~lib/internal/arraybuffer/loadUnsafe<u32,u64>|inlined.1 (result i64)
|
||||
set_local $9
|
||||
block $~lib/internal/arraybuffer/LOAD<u32,u64>|inlined.1 (result i64)
|
||||
i32.const 0
|
||||
set_local $8
|
||||
get_local $3
|
||||
get_local $7
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $8
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
end
|
||||
set_local $9
|
||||
set_local $10
|
||||
get_local $2
|
||||
i32.const 4
|
||||
i32.sub
|
||||
@ -4758,8 +4787,8 @@
|
||||
i32.const 1
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $8
|
||||
get_local $9
|
||||
get_local $10
|
||||
i64.const 32
|
||||
i64.shl
|
||||
i64.or
|
||||
@ -4787,12 +4816,16 @@
|
||||
i32.const 2
|
||||
i32.sub
|
||||
set_local $2
|
||||
block $~lib/internal/arraybuffer/loadUnsafe<u32,u32>|inlined.0 (result i32)
|
||||
block $~lib/internal/arraybuffer/LOAD<u32,u32>|inlined.0 (result i32)
|
||||
i32.const 0
|
||||
set_local $5
|
||||
get_local $3
|
||||
get_local $6
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $5
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
end
|
||||
set_local $5
|
||||
@ -4812,12 +4845,16 @@
|
||||
i32.const 2
|
||||
i32.sub
|
||||
set_local $2
|
||||
block $~lib/internal/arraybuffer/loadUnsafe<u32,u32>|inlined.1 (result i32)
|
||||
block $~lib/internal/arraybuffer/LOAD<u32,u32>|inlined.1 (result i32)
|
||||
i32.const 0
|
||||
set_local $5
|
||||
get_local $3
|
||||
get_local $1
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $5
|
||||
i32.add
|
||||
i32.load offset=8
|
||||
end
|
||||
set_local $5
|
||||
@ -4987,8 +5024,9 @@
|
||||
(local $9 i32)
|
||||
(local $10 i32)
|
||||
(local $11 i32)
|
||||
(local $12 i64)
|
||||
(local $12 i32)
|
||||
(local $13 i64)
|
||||
(local $14 i64)
|
||||
block $~lib/internal/number/DIGITS|inlined.1 (result i32)
|
||||
i32.const 2512
|
||||
end
|
||||
@ -5038,24 +5076,32 @@
|
||||
i32.const 100
|
||||
i32.rem_u
|
||||
set_local $11
|
||||
block $~lib/internal/arraybuffer/loadUnsafe<u32,u64>|inlined.2 (result i64)
|
||||
block $~lib/internal/arraybuffer/LOAD<u32,u64>|inlined.2 (result i64)
|
||||
i32.const 0
|
||||
set_local $12
|
||||
get_local $3
|
||||
get_local $10
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $12
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
end
|
||||
set_local $12
|
||||
block $~lib/internal/arraybuffer/loadUnsafe<u32,u64>|inlined.3 (result i64)
|
||||
set_local $13
|
||||
block $~lib/internal/arraybuffer/LOAD<u32,u64>|inlined.3 (result i64)
|
||||
i32.const 0
|
||||
set_local $12
|
||||
get_local $3
|
||||
get_local $11
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $12
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
end
|
||||
set_local $13
|
||||
set_local $14
|
||||
get_local $2
|
||||
i32.const 4
|
||||
i32.sub
|
||||
@ -5065,30 +5111,38 @@
|
||||
i32.const 1
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $12
|
||||
get_local $13
|
||||
get_local $14
|
||||
i64.const 32
|
||||
i64.shl
|
||||
i64.or
|
||||
i64.store offset=4
|
||||
block $~lib/internal/arraybuffer/loadUnsafe<u32,u64>|inlined.4 (result i64)
|
||||
block $~lib/internal/arraybuffer/LOAD<u32,u64>|inlined.4 (result i64)
|
||||
i32.const 0
|
||||
set_local $12
|
||||
get_local $3
|
||||
get_local $8
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $12
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
end
|
||||
set_local $12
|
||||
block $~lib/internal/arraybuffer/loadUnsafe<u32,u64>|inlined.5 (result i64)
|
||||
set_local $13
|
||||
block $~lib/internal/arraybuffer/LOAD<u32,u64>|inlined.5 (result i64)
|
||||
i32.const 0
|
||||
set_local $12
|
||||
get_local $3
|
||||
get_local $9
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $12
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
end
|
||||
set_local $13
|
||||
set_local $14
|
||||
get_local $2
|
||||
i32.const 4
|
||||
i32.sub
|
||||
@ -5098,8 +5152,8 @@
|
||||
i32.const 1
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $12
|
||||
get_local $13
|
||||
get_local $14
|
||||
i64.const 32
|
||||
i64.shl
|
||||
i64.or
|
||||
@ -5539,12 +5593,16 @@
|
||||
get_local $14
|
||||
i32.add
|
||||
set_global $~lib/internal/number/_K
|
||||
block $~lib/internal/arraybuffer/loadUnsafe<u32,u64>|inlined.6 (result i64)
|
||||
block $~lib/internal/arraybuffer/LOAD<u32,u64>|inlined.6 (result i64)
|
||||
i32.const 0
|
||||
set_local $18
|
||||
get_local $16
|
||||
get_local $14
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $18
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
end
|
||||
get_local $7
|
||||
@ -5689,16 +5747,20 @@
|
||||
i32.add
|
||||
set_global $~lib/internal/number/_K
|
||||
get_local $10
|
||||
block $~lib/internal/arraybuffer/loadUnsafe<u32,u64>|inlined.7 (result i64)
|
||||
block $~lib/internal/arraybuffer/LOAD<u32,u64>|inlined.7 (result i64)
|
||||
i32.const 0
|
||||
get_local $14
|
||||
i32.sub
|
||||
set_local $17
|
||||
i32.const 0
|
||||
set_local $21
|
||||
get_local $16
|
||||
get_local $17
|
||||
i32.const 2
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $21
|
||||
i32.add
|
||||
i64.load32_u offset=8
|
||||
end
|
||||
i64.mul
|
||||
@ -5710,10 +5772,10 @@
|
||||
i32.const 1
|
||||
i32.shl
|
||||
i32.add
|
||||
set_local $17
|
||||
get_local $17
|
||||
i32.load16_u offset=4
|
||||
set_local $21
|
||||
get_local $21
|
||||
i32.load16_u offset=4
|
||||
set_local $17
|
||||
block $break|4
|
||||
loop $continue|4
|
||||
get_local $13
|
||||
@ -5755,10 +5817,10 @@
|
||||
end
|
||||
if
|
||||
block
|
||||
get_local $21
|
||||
get_local $17
|
||||
i32.const 1
|
||||
i32.sub
|
||||
set_local $21
|
||||
set_local $17
|
||||
get_local $13
|
||||
get_local $8
|
||||
i64.add
|
||||
@ -5768,8 +5830,8 @@
|
||||
end
|
||||
end
|
||||
end
|
||||
get_local $17
|
||||
get_local $21
|
||||
get_local $17
|
||||
i32.store16 offset=4
|
||||
get_local $15
|
||||
return
|
||||
@ -6138,7 +6200,7 @@
|
||||
(local $11 f64)
|
||||
(local $12 i32)
|
||||
(local $13 i32)
|
||||
(local $14 i64)
|
||||
(local $14 i32)
|
||||
(local $15 i64)
|
||||
(local $16 i64)
|
||||
(local $17 i64)
|
||||
@ -6148,7 +6210,8 @@
|
||||
(local $21 i64)
|
||||
(local $22 i64)
|
||||
(local $23 i64)
|
||||
(local $24 i32)
|
||||
(local $24 i64)
|
||||
(local $25 i32)
|
||||
get_local $1
|
||||
f64.const 0
|
||||
f64.lt
|
||||
@ -6290,21 +6353,29 @@
|
||||
end
|
||||
i32.load
|
||||
set_local $13
|
||||
block $~lib/internal/arraybuffer/loadUnsafe<u64,u64>|inlined.0 (result i64)
|
||||
block $~lib/internal/arraybuffer/LOAD<u64,u64>|inlined.0 (result i64)
|
||||
i32.const 0
|
||||
set_local $14
|
||||
get_local $12
|
||||
get_local $8
|
||||
i32.const 3
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $14
|
||||
i32.add
|
||||
i64.load offset=8
|
||||
end
|
||||
set_global $~lib/internal/number/_frc_pow
|
||||
block $~lib/internal/arraybuffer/loadUnsafe<i16,i32>|inlined.0 (result i32)
|
||||
block $~lib/internal/arraybuffer/LOAD<i16,i32>|inlined.0 (result i32)
|
||||
i32.const 0
|
||||
set_local $14
|
||||
get_local $13
|
||||
get_local $8
|
||||
i32.const 1
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $14
|
||||
i32.add
|
||||
i32.load16_s offset=8
|
||||
end
|
||||
set_global $~lib/internal/number/_exp_pow
|
||||
@ -6330,60 +6401,60 @@
|
||||
get_local $6
|
||||
i64.const 4294967295
|
||||
i64.and
|
||||
set_local $14
|
||||
set_local $15
|
||||
get_local $7
|
||||
i64.const 4294967295
|
||||
i64.and
|
||||
set_local $15
|
||||
set_local $16
|
||||
get_local $6
|
||||
i64.const 32
|
||||
i64.shr_u
|
||||
set_local $16
|
||||
set_local $17
|
||||
get_local $7
|
||||
i64.const 32
|
||||
i64.shr_u
|
||||
set_local $17
|
||||
get_local $14
|
||||
get_local $15
|
||||
i64.mul
|
||||
set_local $18
|
||||
get_local $16
|
||||
get_local $15
|
||||
get_local $16
|
||||
i64.mul
|
||||
get_local $18
|
||||
set_local $19
|
||||
get_local $17
|
||||
get_local $16
|
||||
i64.mul
|
||||
get_local $19
|
||||
i64.const 32
|
||||
i64.shr_u
|
||||
i64.add
|
||||
set_local $19
|
||||
get_local $14
|
||||
get_local $17
|
||||
set_local $20
|
||||
get_local $15
|
||||
get_local $18
|
||||
i64.mul
|
||||
get_local $19
|
||||
get_local $20
|
||||
i64.const 4294967295
|
||||
i64.and
|
||||
i64.add
|
||||
set_local $20
|
||||
get_local $20
|
||||
set_local $21
|
||||
get_local $21
|
||||
i64.const 2147483647
|
||||
i64.add
|
||||
set_local $20
|
||||
get_local $19
|
||||
i64.const 32
|
||||
i64.shr_u
|
||||
set_local $19
|
||||
set_local $21
|
||||
get_local $20
|
||||
i64.const 32
|
||||
i64.shr_u
|
||||
set_local $20
|
||||
get_local $16
|
||||
get_local $21
|
||||
i64.const 32
|
||||
i64.shr_u
|
||||
set_local $21
|
||||
get_local $17
|
||||
get_local $18
|
||||
i64.mul
|
||||
get_local $19
|
||||
i64.add
|
||||
get_local $20
|
||||
i64.add
|
||||
get_local $21
|
||||
i64.add
|
||||
end
|
||||
set_local $20
|
||||
set_local $21
|
||||
block $~lib/internal/number/umul64e|inlined.0 (result i32)
|
||||
get_local $4
|
||||
get_local $12
|
||||
@ -6394,66 +6465,66 @@
|
||||
set_local $8
|
||||
block $~lib/internal/number/umul64f|inlined.1 (result i64)
|
||||
get_global $~lib/internal/number/_frc_plus
|
||||
set_local $20
|
||||
get_local $20
|
||||
i64.const 4294967295
|
||||
i64.and
|
||||
set_local $19
|
||||
get_local $19
|
||||
get_local $7
|
||||
i64.const 4294967295
|
||||
i64.and
|
||||
set_local $18
|
||||
get_local $7
|
||||
i64.const 4294967295
|
||||
i64.and
|
||||
get_local $20
|
||||
i64.const 32
|
||||
i64.shr_u
|
||||
set_local $17
|
||||
get_local $19
|
||||
get_local $7
|
||||
i64.const 32
|
||||
i64.shr_u
|
||||
set_local $16
|
||||
get_local $7
|
||||
i64.const 32
|
||||
i64.shr_u
|
||||
set_local $15
|
||||
get_local $19
|
||||
get_local $18
|
||||
get_local $17
|
||||
i64.mul
|
||||
set_local $14
|
||||
get_local $16
|
||||
set_local $15
|
||||
get_local $17
|
||||
get_local $18
|
||||
i64.mul
|
||||
get_local $14
|
||||
get_local $15
|
||||
i64.const 32
|
||||
i64.shr_u
|
||||
i64.add
|
||||
set_local $21
|
||||
get_local $18
|
||||
get_local $15
|
||||
set_local $22
|
||||
get_local $19
|
||||
get_local $16
|
||||
i64.mul
|
||||
get_local $21
|
||||
get_local $22
|
||||
i64.const 4294967295
|
||||
i64.and
|
||||
i64.add
|
||||
set_local $22
|
||||
get_local $22
|
||||
set_local $23
|
||||
get_local $23
|
||||
i64.const 2147483647
|
||||
i64.add
|
||||
set_local $22
|
||||
get_local $21
|
||||
i64.const 32
|
||||
i64.shr_u
|
||||
set_local $21
|
||||
set_local $23
|
||||
get_local $22
|
||||
i64.const 32
|
||||
i64.shr_u
|
||||
set_local $22
|
||||
get_local $23
|
||||
i64.const 32
|
||||
i64.shr_u
|
||||
set_local $23
|
||||
get_local $17
|
||||
get_local $16
|
||||
get_local $15
|
||||
i64.mul
|
||||
get_local $21
|
||||
i64.add
|
||||
get_local $22
|
||||
i64.add
|
||||
get_local $23
|
||||
i64.add
|
||||
end
|
||||
i64.const 1
|
||||
i64.sub
|
||||
set_local $22
|
||||
set_local $23
|
||||
block $~lib/internal/number/umul64e|inlined.1 (result i32)
|
||||
get_global $~lib/internal/number/_exp
|
||||
set_local $9
|
||||
@ -6466,92 +6537,92 @@
|
||||
set_local $9
|
||||
block $~lib/internal/number/umul64f|inlined.2 (result i64)
|
||||
get_global $~lib/internal/number/_frc_minus
|
||||
set_local $21
|
||||
get_local $21
|
||||
i64.const 4294967295
|
||||
i64.and
|
||||
set_local $14
|
||||
get_local $7
|
||||
set_local $22
|
||||
get_local $22
|
||||
i64.const 4294967295
|
||||
i64.and
|
||||
set_local $15
|
||||
get_local $21
|
||||
i64.const 32
|
||||
i64.shr_u
|
||||
set_local $16
|
||||
get_local $7
|
||||
i64.const 4294967295
|
||||
i64.and
|
||||
set_local $16
|
||||
get_local $22
|
||||
i64.const 32
|
||||
i64.shr_u
|
||||
set_local $17
|
||||
get_local $14
|
||||
get_local $15
|
||||
i64.mul
|
||||
get_local $7
|
||||
i64.const 32
|
||||
i64.shr_u
|
||||
set_local $18
|
||||
get_local $16
|
||||
get_local $15
|
||||
get_local $16
|
||||
i64.mul
|
||||
get_local $18
|
||||
set_local $19
|
||||
get_local $17
|
||||
get_local $16
|
||||
i64.mul
|
||||
get_local $19
|
||||
i64.const 32
|
||||
i64.shr_u
|
||||
i64.add
|
||||
set_local $19
|
||||
get_local $14
|
||||
get_local $17
|
||||
set_local $20
|
||||
get_local $15
|
||||
get_local $18
|
||||
i64.mul
|
||||
get_local $19
|
||||
get_local $20
|
||||
i64.const 4294967295
|
||||
i64.and
|
||||
i64.add
|
||||
set_local $23
|
||||
get_local $23
|
||||
set_local $24
|
||||
get_local $24
|
||||
i64.const 2147483647
|
||||
i64.add
|
||||
set_local $23
|
||||
get_local $19
|
||||
set_local $24
|
||||
get_local $20
|
||||
i64.const 32
|
||||
i64.shr_u
|
||||
set_local $19
|
||||
get_local $23
|
||||
set_local $20
|
||||
get_local $24
|
||||
i64.const 32
|
||||
i64.shr_u
|
||||
set_local $23
|
||||
get_local $16
|
||||
set_local $24
|
||||
get_local $17
|
||||
get_local $18
|
||||
i64.mul
|
||||
get_local $19
|
||||
get_local $20
|
||||
i64.add
|
||||
get_local $23
|
||||
get_local $24
|
||||
i64.add
|
||||
end
|
||||
i64.const 1
|
||||
i64.add
|
||||
set_local $23
|
||||
get_local $22
|
||||
set_local $24
|
||||
get_local $23
|
||||
get_local $24
|
||||
i64.sub
|
||||
set_local $19
|
||||
set_local $20
|
||||
get_local $0
|
||||
get_local $20
|
||||
get_local $21
|
||||
get_local $8
|
||||
get_local $22
|
||||
get_local $23
|
||||
get_local $9
|
||||
get_local $19
|
||||
get_local $20
|
||||
get_local $2
|
||||
call $~lib/internal/number/genDigits
|
||||
end
|
||||
set_local $24
|
||||
set_local $25
|
||||
get_local $0
|
||||
get_local $2
|
||||
i32.const 1
|
||||
i32.shl
|
||||
i32.add
|
||||
get_local $24
|
||||
get_local $25
|
||||
get_local $2
|
||||
i32.sub
|
||||
get_global $~lib/internal/number/_K
|
||||
call $~lib/internal/number/prettify
|
||||
set_local $24
|
||||
get_local $24
|
||||
set_local $25
|
||||
get_local $25
|
||||
get_local $2
|
||||
i32.add
|
||||
)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -10,7 +10,6 @@ assert(Uint64Array.BYTES_PER_ELEMENT == 8);
|
||||
assert(Float32Array.BYTES_PER_ELEMENT == 4);
|
||||
assert(Float64Array.BYTES_PER_ELEMENT == 8);
|
||||
|
||||
|
||||
function isInt8ArrayEqual(a: Int8Array, b: Array<i8>): bool {
|
||||
if (a.length != b.length) return false;
|
||||
for (let i = 0, len = a.length; i < len; i++) {
|
||||
|
File diff suppressed because it is too large
Load Diff
3
tests/parser/index-declaration.ts
Normal file
3
tests/parser/index-declaration.ts
Normal file
@ -0,0 +1,3 @@
|
||||
class A {
|
||||
[key: i32]: f64;
|
||||
}
|
3
tests/parser/index-declaration.ts.fixture.ts
Normal file
3
tests/parser/index-declaration.ts.fixture.ts
Normal file
@ -0,0 +1,3 @@
|
||||
class A {
|
||||
[key: i32]: f64;
|
||||
}
|
3
tests/parser/optional-typeparameters.ts
Normal file
3
tests/parser/optional-typeparameters.ts
Normal file
@ -0,0 +1,3 @@
|
||||
function a<T=i32>(): T { return 0; }
|
||||
function a<T,U=i32>(): T { return 0; }
|
||||
function a<T,U=i32,V>(): T { return 0; } // ERROR 2706
|
10
tests/parser/optional-typeparameters.ts.fixture.ts
Normal file
10
tests/parser/optional-typeparameters.ts.fixture.ts
Normal file
@ -0,0 +1,10 @@
|
||||
function a<T=i32>(): T {
|
||||
return 0;
|
||||
}
|
||||
function a<T, U=i32>(): T {
|
||||
return 0;
|
||||
}
|
||||
function a<T, U=i32, V>(): T {
|
||||
return 0;
|
||||
}
|
||||
// ERROR 2706: "Required type parameters may not follow optional type parameters." in optional-typeparameters.ts:3:19
|
Loading…
x
Reference in New Issue
Block a user