mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 07:02:13 +00:00
Add a mechanism to enable additional (experimental) features and start with sign extension operations; Hashing experimentation
This commit is contained in:
parent
00fee73022
commit
1bf0ca6525
12
bin/asc.js
12
bin/asc.js
@ -373,6 +373,18 @@ exports.main = function main(argv, options, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
// Enable additional features if specified
|
||||
var features = args.feature;
|
||||
if (features != null) {
|
||||
if (typeof features === "string") features = features.split(",");
|
||||
for (let i = 0, k = features.length; i < k; ++i) {
|
||||
let name = features[i].trim();
|
||||
let flag = assemblyscript["FEATURE_" + name.toUpperCase()];
|
||||
if (!flag) return callback(Error("Feature '" + name + "' is invalid."));
|
||||
assemblyscript.enableFeature(compilerOptions, flag);
|
||||
}
|
||||
}
|
||||
|
||||
var module;
|
||||
stats.compileCount++;
|
||||
(() => {
|
||||
|
@ -149,6 +149,10 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"feature": {
|
||||
"desc": "Enables additional (experimental) WebAssembly features.",
|
||||
"type": "string"
|
||||
},
|
||||
"measure": {
|
||||
"desc": "Prints measuring information on I/O and compile times.",
|
||||
"type": "boolean"
|
||||
|
2
dist/asc.js
vendored
2
dist/asc.js
vendored
File diff suppressed because one or more lines are too long
2
dist/asc.js.map
vendored
2
dist/asc.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/assemblyscript.js
vendored
2
dist/assemblyscript.js
vendored
File diff suppressed because one or more lines are too long
2
dist/assemblyscript.js.map
vendored
2
dist/assemblyscript.js.map
vendored
File diff suppressed because one or more lines are too long
3247
package-lock.json
generated
3247
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -12,7 +12,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@protobufjs/utf8": "^1.1.0",
|
||||
"binaryen": "47.0.0-nightly.20180503",
|
||||
"binaryen": "47.0.0-nightly.20180507",
|
||||
"glob": "^7.1.2",
|
||||
"long": "^4.0.0",
|
||||
"minimist": "^1.2.0",
|
||||
|
@ -173,6 +173,8 @@ export class Options {
|
||||
sourceMap: bool = false;
|
||||
/** Global aliases. */
|
||||
globalAliases: Map<string,string> | null = null;
|
||||
/** Additional features to activate. */
|
||||
features: Feature = Feature.NONE;
|
||||
|
||||
/** Tests if the target is WASM64 or, otherwise, WASM32. */
|
||||
get isWasm64(): bool {
|
||||
@ -193,6 +195,19 @@ export class Options {
|
||||
get nativeSizeType(): NativeType {
|
||||
return this.target == Target.WASM64 ? NativeType.I64 : NativeType.I32;
|
||||
}
|
||||
|
||||
/** Tests if a specific feature is activated. */
|
||||
hasFeature(feature: Feature): bool {
|
||||
return (this.features & feature) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** Indicates specific features to activate. */
|
||||
export const enum Feature {
|
||||
/** No additional features. */
|
||||
NONE = 0,
|
||||
/** Sign extension operations. */
|
||||
SIGNEXT = 1 << 0 // see: https://github.com/WebAssembly/sign-extension-ops
|
||||
}
|
||||
|
||||
/** Indicates the desired kind of a conversion. */
|
||||
@ -237,11 +252,11 @@ export class Compiler extends DiagnosticEmitter {
|
||||
/** Counting memory offset. */
|
||||
memoryOffset: I64;
|
||||
/** Memory segments being compiled. */
|
||||
memorySegments: MemorySegment[] = new Array();
|
||||
memorySegments: MemorySegment[] = [];
|
||||
/** Map of already compiled static string segments. */
|
||||
stringSegments: Map<string,MemorySegment> = new Map();
|
||||
/** Function table being compiled. */
|
||||
functionTable: Function[] = new Array();
|
||||
functionTable: Function[] = [];
|
||||
/** Argument count helper global. */
|
||||
argcVar: GlobalRef = 0;
|
||||
/** Argument count helper setter. */
|
||||
@ -802,7 +817,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
);
|
||||
if (!instance) return null;
|
||||
instance.outerScope = outerScope;
|
||||
if (!this.compileFunction(instance)) return null;
|
||||
if (!this.compileFunction(instance)) return null; // reports
|
||||
return instance;
|
||||
}
|
||||
|
||||
@ -868,7 +883,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
var module = this.module;
|
||||
if (body) {
|
||||
let isConstructor = instance.is(CommonFlags.CONSTRUCTOR);
|
||||
let returnType: Type = instance.signature.returnType;
|
||||
let returnType = instance.signature.returnType;
|
||||
|
||||
// compile body
|
||||
let previousFunction = this.currentFunction;
|
||||
@ -886,6 +901,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
);
|
||||
flow.set(FlowFlags.RETURNS);
|
||||
if (!flow.canOverflow(stmt, returnType)) flow.set(FlowFlags.RETURNS_WRAPPED);
|
||||
flow.finalize();
|
||||
} else {
|
||||
assert(body.kind == NodeKind.BLOCK);
|
||||
stmt = this.compileStatement(body);
|
||||
@ -1179,6 +1195,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
compileClass(instance: Class): bool {
|
||||
if (instance.is(CommonFlags.COMPILED)) return true;
|
||||
instance.set(CommonFlags.COMPILED);
|
||||
|
||||
var staticMembers = instance.prototype.members;
|
||||
if (staticMembers) {
|
||||
for (let element of staticMembers.values()) {
|
||||
@ -6792,27 +6809,31 @@ export class Compiler extends DiagnosticEmitter {
|
||||
var module = this.module;
|
||||
var flow = this.currentFunction.flow;
|
||||
switch (type.kind) {
|
||||
case TypeKind.I8: { // TODO: Use 'i32.extend8_s' once sign-extension-ops lands
|
||||
case TypeKind.I8: {
|
||||
if (flow.canOverflow(expr, type)) {
|
||||
expr = module.createBinary(BinaryOp.ShrI32,
|
||||
module.createBinary(BinaryOp.ShlI32,
|
||||
expr,
|
||||
module.createI32(24)
|
||||
),
|
||||
module.createI32(24)
|
||||
);
|
||||
expr = this.options.hasFeature(Feature.SIGNEXT)
|
||||
? module.createUnary(UnaryOp.ExtendI8ToI32, expr)
|
||||
: module.createBinary(BinaryOp.ShrI32,
|
||||
module.createBinary(BinaryOp.ShlI32,
|
||||
expr,
|
||||
module.createI32(24)
|
||||
),
|
||||
module.createI32(24)
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TypeKind.I16: { // TODO: Use 'i32.extend16_s' once sign-extension-ops lands
|
||||
case TypeKind.I16: {
|
||||
if (flow.canOverflow(expr, type)) {
|
||||
expr = module.createBinary(BinaryOp.ShrI32,
|
||||
module.createBinary(BinaryOp.ShlI32,
|
||||
expr,
|
||||
module.createI32(16)
|
||||
),
|
||||
module.createI32(16)
|
||||
);
|
||||
expr = this.options.hasFeature(Feature.SIGNEXT)
|
||||
? module.createUnary(UnaryOp.ExtendI16ToI32, expr)
|
||||
: module.createBinary(BinaryOp.ShrI32,
|
||||
module.createBinary(BinaryOp.ShlI32,
|
||||
expr,
|
||||
module.createI32(16)
|
||||
),
|
||||
module.createI32(16)
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
5
src/glue/binaryen.d.ts
vendored
5
src/glue/binaryen.d.ts
vendored
@ -115,6 +115,11 @@ declare function _BinaryenPromoteFloat32(): BinaryenOp;
|
||||
declare function _BinaryenDemoteFloat64(): BinaryenOp;
|
||||
declare function _BinaryenReinterpretInt32(): BinaryenOp;
|
||||
declare function _BinaryenReinterpretInt64(): BinaryenOp;
|
||||
declare function _BinaryenExtendS8Int32(): BinaryenOp;
|
||||
declare function _BinaryenExtendS16Int32(): BinaryenOp;
|
||||
declare function _BinaryenExtendS8Int64(): BinaryenOp;
|
||||
declare function _BinaryenExtendS16Int64(): BinaryenOp;
|
||||
declare function _BinaryenExtendS32Int64(): BinaryenOp;
|
||||
declare function _BinaryenAddInt32(): BinaryenOp;
|
||||
declare function _BinaryenSubInt32(): BinaryenOp;
|
||||
declare function _BinaryenMulInt32(): BinaryenOp;
|
||||
|
11
src/index.ts
11
src/index.ts
@ -6,7 +6,8 @@
|
||||
import {
|
||||
Compiler,
|
||||
Options,
|
||||
Target
|
||||
Target,
|
||||
Feature
|
||||
} from "./compiler";
|
||||
|
||||
import {
|
||||
@ -129,6 +130,14 @@ export function setGlobalAlias(options: Options, name: string, alias: string): v
|
||||
globalAliases.set(name, alias);
|
||||
}
|
||||
|
||||
/** Sign extension operations. */
|
||||
export const FEATURE_SIGNEXT = Feature.SIGNEXT;
|
||||
|
||||
/** Enables a specific feature. */
|
||||
export function enableFeature(options: Options, feature: Feature): void {
|
||||
options.features |= feature;
|
||||
}
|
||||
|
||||
/** Finishes parsing. */
|
||||
export function finishParsing(parser: Parser): Program {
|
||||
return parser.finish();
|
||||
|
@ -104,14 +104,14 @@ export enum UnaryOp {
|
||||
PromoteF32 = _BinaryenPromoteFloat32(),
|
||||
DemoteF64 = _BinaryenDemoteFloat64(),
|
||||
ReinterpretI32 = _BinaryenReinterpretInt32(),
|
||||
ReinterpretI64 = _BinaryenReinterpretInt64()
|
||||
ReinterpretI64 = _BinaryenReinterpretInt64(),
|
||||
|
||||
// see: https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md#new-sign-extending-operators
|
||||
// ExtendI8ToI32 =_BinaryenExtendS8Int32()
|
||||
// ExtendI16ToI32 = _BinaryenExtendS16Int32()
|
||||
// ExtendI8ToI64 = _BinaryenExtendS8Int64() // operand is I64
|
||||
// ExtendI16ToI64 = _BinaryenExtendS16Int64()
|
||||
// ExtendI32ToI64 = _BinaryenExtendS32Int64()
|
||||
// see: https://github.com/WebAssembly/sign-extension-ops
|
||||
ExtendI8ToI32 = _BinaryenExtendS8Int32(),
|
||||
ExtendI16ToI32 = _BinaryenExtendS16Int32(),
|
||||
ExtendI8ToI64 = _BinaryenExtendS8Int64(),
|
||||
ExtendI16ToI64 = _BinaryenExtendS16Int64(),
|
||||
ExtendI32ToI64 = _BinaryenExtendS32Int64()
|
||||
|
||||
// see: https://github.com/WebAssembly/nontrapping-float-to-int-conversions
|
||||
// TruncF32ToI32Sat
|
||||
|
20
src/types.ts
20
src/types.ts
@ -505,7 +505,7 @@ export class Signature {
|
||||
var parameterNames = this.parameterNames;
|
||||
return parameterNames && parameterNames.length > index
|
||||
? parameterNames[index]
|
||||
: getGenericParameterName(index);
|
||||
: getDefaultParameterName(index);
|
||||
}
|
||||
|
||||
/** Tests if a value of this function type is assignable to a target of the specified function type. */
|
||||
@ -581,7 +581,7 @@ export class Signature {
|
||||
if (index) sb.push(", ");
|
||||
if (i == restIndex) sb.push("...");
|
||||
if (i < numNames) sb.push((<string[]>names)[i]);
|
||||
else sb.push(getGenericParameterName(i));
|
||||
else sb.push(getDefaultParameterName(i));
|
||||
if (i >= optionalStart && i != restIndex) sb.push("?: ");
|
||||
else sb.push(": ");
|
||||
sb.push(parameters[i].toString());
|
||||
@ -595,14 +595,14 @@ export class Signature {
|
||||
|
||||
// helpers
|
||||
|
||||
// Cached generic parameter names used where names are unknown.
|
||||
var cachedGenericParameterNames: string[] | null = null;
|
||||
// Cached default parameter names used where names are unknown.
|
||||
var cachedDefaultParameterNames: string[] | null = null;
|
||||
|
||||
/** Gets the cached generic parameter name for the specified index. */
|
||||
export function getGenericParameterName(index: i32): string {
|
||||
if (!cachedGenericParameterNames) cachedGenericParameterNames = [];
|
||||
for (let i = cachedGenericParameterNames.length; i <= index; ++i) {
|
||||
cachedGenericParameterNames.push("arg$" + i.toString(10));
|
||||
/** Gets the cached default parameter name for the specified index. */
|
||||
export function getDefaultParameterName(index: i32): string {
|
||||
if (!cachedDefaultParameterNames) cachedDefaultParameterNames = [];
|
||||
for (let i = cachedDefaultParameterNames.length; i <= index; ++i) {
|
||||
cachedDefaultParameterNames.push("arg$" + i.toString(10));
|
||||
}
|
||||
return cachedGenericParameterNames[index - 1];
|
||||
return cachedDefaultParameterNames[index - 1];
|
||||
}
|
||||
|
61
std/assembly/internal/hash.ts
Normal file
61
std/assembly/internal/hash.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import {
|
||||
HEADER_SIZE as HEADER_SIZE_STR
|
||||
} from "./string";
|
||||
|
||||
// FNV-1a 32-bit as a starting point, see: http://isthe.com/chongo/tech/comp/fnv/
|
||||
|
||||
const FNV_OFFSET: u32 = 2166136261;
|
||||
const FNV_PRIME: u32 = 16777619;
|
||||
|
||||
export function hash<T>(key: T): u32 {
|
||||
var hash: u32 = FNV_OFFSET;
|
||||
if (isString(key)) {
|
||||
for (let i: usize = 0, k: usize = key.length << 1; i < k; ++i) {
|
||||
hash = (hash ^ <u32>load<u8>(changetype<usize>(key) + i, HEADER_SIZE_STR)) * FNV_PRIME;
|
||||
}
|
||||
} else if (isFloat(key)) {
|
||||
if (sizeof<T>() == 4) { // f32
|
||||
let u = reinterpret<u32>(key);
|
||||
hash = (hash ^ ( u & 0xff)) * FNV_PRIME;
|
||||
hash = (hash ^ ((u >>> 8) & 0xff)) * FNV_PRIME;
|
||||
hash = (hash ^ ((u >>> 16) & 0xff)) * FNV_PRIME;
|
||||
hash = (hash ^ ( u >>> 24 )) * FNV_PRIME;
|
||||
} else if (sizeof<T>() == 8) { // f64
|
||||
let u = reinterpret<u64>(key);
|
||||
let l = <u32> u;
|
||||
let h = <u32>(u >>> 32);
|
||||
hash = (hash ^ ( l & 0xff)) * FNV_PRIME;
|
||||
hash = (hash ^ ((l >>> 8) & 0xff)) * FNV_PRIME;
|
||||
hash = (hash ^ ((l >>> 16) & 0xff)) * FNV_PRIME;
|
||||
hash = (hash ^ ( l >>> 24 )) * FNV_PRIME;
|
||||
hash = (hash ^ ( h & 0xff)) * FNV_PRIME;
|
||||
hash = (hash ^ ((h >>> 8) & 0xff)) * FNV_PRIME;
|
||||
hash = (hash ^ ((h >>> 16) & 0xff)) * FNV_PRIME;
|
||||
hash = (hash ^ ( h >>> 24 )) * FNV_PRIME;
|
||||
} else unreachable();
|
||||
} else if (sizeof<T>() == 1) { // bool, i8, u8
|
||||
hash = (hash ^ (<u32>key & 0xff)) * FNV_PRIME;
|
||||
} else if (sizeof<T>() == 2) { // i16, u16
|
||||
let u = <u32>key;
|
||||
hash = (hash ^ ( u & 0xff)) * FNV_PRIME;
|
||||
hash = (hash ^ ( u >>> 8 )) * FNV_PRIME;
|
||||
} else if (sizeof<T>() == 4) { // i32, u32
|
||||
let u = <u32>key;
|
||||
hash = (hash ^ ( u & 0xff)) * FNV_PRIME;
|
||||
hash = (hash ^ ((u >>> 8) & 0xff)) * FNV_PRIME;
|
||||
hash = (hash ^ ((u >>> 16) & 0xff)) * FNV_PRIME;
|
||||
hash = (hash ^ ( u >>> 24 )) * FNV_PRIME;
|
||||
} else if (sizeof<T>() == 8) { // i64, u64
|
||||
let l = <u32> <u64>key;
|
||||
let h = <u32>(<u64>key >>> 32);
|
||||
hash = (hash ^ ( l & 0xff)) * FNV_PRIME;
|
||||
hash = (hash ^ ((l >>> 8) & 0xff)) * FNV_PRIME;
|
||||
hash = (hash ^ ((l >>> 16) & 0xff)) * FNV_PRIME;
|
||||
hash = (hash ^ ( l >>> 24 )) * FNV_PRIME;
|
||||
hash = (hash ^ ( h & 0xff)) * FNV_PRIME;
|
||||
hash = (hash ^ ((h >>> 8) & 0xff)) * FNV_PRIME;
|
||||
hash = (hash ^ ((h >>> 16) & 0xff)) * FNV_PRIME;
|
||||
hash = (hash ^ ( h >>> 24 )) * FNV_PRIME;
|
||||
} else unreachable();
|
||||
return hash;
|
||||
}
|
351
tests/compiler/std/hash.optimized.wat
Normal file
351
tests/compiler/std/hash.optimized.wat
Normal file
@ -0,0 +1,351 @@
|
||||
(module
|
||||
(type $ii (func (param i32) (result i32)))
|
||||
(type $iv (func (param i32)))
|
||||
(type $fi (func (param f32) (result i32)))
|
||||
(type $Fi (func (param f64) (result i32)))
|
||||
(type $v (func))
|
||||
(import "env" "logi" (func $std/hash/logi (param i32)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\01\00\00\00a")
|
||||
(data (i32.const 16) "\02\00\00\00a\00b")
|
||||
(data (i32.const 24) "\03\00\00\00a\00b\00c")
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
(func $~lib/internal/hash/hash<usize> (; 1 ;) (type $ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(i32.and
|
||||
(tee_local $1
|
||||
(get_local $0)
|
||||
)
|
||||
(i32.const 255)
|
||||
)
|
||||
(i32.const -2128831035)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
(i32.and
|
||||
(i32.shr_u
|
||||
(get_local $1)
|
||||
(i32.const 8)
|
||||
)
|
||||
(i32.const 255)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
(i32.and
|
||||
(i32.shr_u
|
||||
(get_local $1)
|
||||
(i32.const 16)
|
||||
)
|
||||
(i32.const 255)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
(i32.shr_u
|
||||
(get_local $1)
|
||||
(i32.const 24)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
)
|
||||
(func $~lib/internal/hash/hash<String> (; 2 ;) (type $ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(set_local $2
|
||||
(i32.const -2128831035)
|
||||
)
|
||||
(set_local $3
|
||||
(i32.shl
|
||||
(i32.load
|
||||
(get_local $0)
|
||||
)
|
||||
(i32.const 1)
|
||||
)
|
||||
)
|
||||
(loop $continue|0
|
||||
(if
|
||||
(i32.lt_u
|
||||
(get_local $1)
|
||||
(get_local $3)
|
||||
)
|
||||
(block
|
||||
(set_local $2
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(get_local $2)
|
||||
(i32.load8_u offset=4
|
||||
(i32.add
|
||||
(get_local $0)
|
||||
(get_local $1)
|
||||
)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
)
|
||||
(set_local $1
|
||||
(i32.add
|
||||
(get_local $1)
|
||||
(i32.const 1)
|
||||
)
|
||||
)
|
||||
(br $continue|0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(get_local $2)
|
||||
)
|
||||
(func $~lib/internal/hash/hash<f32> (; 3 ;) (type $fi) (param $0 f32) (result i32)
|
||||
(local $1 i32)
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(i32.and
|
||||
(tee_local $1
|
||||
(i32.reinterpret/f32
|
||||
(get_local $0)
|
||||
)
|
||||
)
|
||||
(i32.const 255)
|
||||
)
|
||||
(i32.const -2128831035)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
(i32.and
|
||||
(i32.shr_u
|
||||
(get_local $1)
|
||||
(i32.const 8)
|
||||
)
|
||||
(i32.const 255)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
(i32.and
|
||||
(i32.shr_u
|
||||
(get_local $1)
|
||||
(i32.const 16)
|
||||
)
|
||||
(i32.const 255)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
(i32.shr_u
|
||||
(get_local $1)
|
||||
(i32.const 24)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
)
|
||||
(func $~lib/internal/hash/hash<f64> (; 4 ;) (type $Fi) (param $0 f64) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i64)
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(i32.and
|
||||
(tee_local $1
|
||||
(i32.wrap/i64
|
||||
(tee_local $2
|
||||
(i64.reinterpret/f64
|
||||
(get_local $0)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(i32.const 255)
|
||||
)
|
||||
(i32.const -2128831035)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
(i32.and
|
||||
(i32.shr_u
|
||||
(get_local $1)
|
||||
(i32.const 8)
|
||||
)
|
||||
(i32.const 255)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
(i32.and
|
||||
(i32.shr_u
|
||||
(get_local $1)
|
||||
(i32.const 16)
|
||||
)
|
||||
(i32.const 255)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
(i32.shr_u
|
||||
(get_local $1)
|
||||
(i32.const 24)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
(i32.and
|
||||
(tee_local $1
|
||||
(i32.wrap/i64
|
||||
(i64.shr_u
|
||||
(get_local $2)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
(i32.const 255)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
(i32.and
|
||||
(i32.shr_u
|
||||
(get_local $1)
|
||||
(i32.const 8)
|
||||
)
|
||||
(i32.const 255)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
(i32.and
|
||||
(i32.shr_u
|
||||
(get_local $1)
|
||||
(i32.const 16)
|
||||
)
|
||||
(i32.const 255)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
(i32.shr_u
|
||||
(get_local $1)
|
||||
(i32.const 24)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
)
|
||||
(func $start (; 5 ;) (type $v)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<usize>
|
||||
(i32.const 0)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<String>
|
||||
(i32.const 4)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<String>
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<String>
|
||||
(i32.const 16)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<String>
|
||||
(i32.const 24)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f32>
|
||||
(f32.const 0)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f32>
|
||||
(f32.const 1)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f32>
|
||||
(f32.const 1.100000023841858)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f32>
|
||||
(f32.const 0)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f32>
|
||||
(f32.const inf)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f32>
|
||||
(f32.const nan:0x400000)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f64>
|
||||
(f64.const 0)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f64>
|
||||
(f64.const 1)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f64>
|
||||
(f64.const 1.1)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f64>
|
||||
(f64.const 0)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f64>
|
||||
(f64.const inf)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f64>
|
||||
(f64.const nan:0x8000000000000)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
23
tests/compiler/std/hash.ts
Normal file
23
tests/compiler/std/hash.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { hash } from "internal/hash";
|
||||
|
||||
declare function logi(i: i32): void;
|
||||
|
||||
logi(hash(null));
|
||||
logi(hash(""));
|
||||
logi(hash("a"));
|
||||
logi(hash("ab"));
|
||||
logi(hash("abc"));
|
||||
|
||||
logi(hash(<f32>0.0));
|
||||
logi(hash(<f32>1.0));
|
||||
logi(hash(<f32>1.1));
|
||||
logi(hash(<f32>-0));
|
||||
logi(hash(<f32>Infinity));
|
||||
logi(hash(<f32>NaN));
|
||||
|
||||
logi(hash(<f64>0.0));
|
||||
logi(hash(<f64>1.0));
|
||||
logi(hash(<f64>1.1));
|
||||
logi(hash(<f64>-0));
|
||||
logi(hash(<f64>Infinity));
|
||||
logi(hash(<f64>NaN));
|
453
tests/compiler/std/hash.untouched.wat
Normal file
453
tests/compiler/std/hash.untouched.wat
Normal file
@ -0,0 +1,453 @@
|
||||
(module
|
||||
(type $i (func (result i32)))
|
||||
(type $ii (func (param i32) (result i32)))
|
||||
(type $iv (func (param i32)))
|
||||
(type $fi (func (param f32) (result i32)))
|
||||
(type $F (func (result f64)))
|
||||
(type $Fi (func (param f64) (result i32)))
|
||||
(type $v (func))
|
||||
(import "env" "logi" (func $std/hash/logi (param i32)))
|
||||
(global $~lib/internal/allocator/AL_BITS i32 (i32.const 3))
|
||||
(global $~lib/internal/allocator/AL_SIZE i32 (i32.const 8))
|
||||
(global $~lib/internal/allocator/AL_MASK i32 (i32.const 7))
|
||||
(global $~lib/internal/allocator/MAX_SIZE_32 i32 (i32.const 1073741824))
|
||||
(global $~lib/internal/string/HEADER_SIZE i32 (i32.const 4))
|
||||
(global $~lib/internal/string/MAX_LENGTH i32 (i32.const 536870910))
|
||||
(global $~lib/internal/string/EMPTY i32 (i32.const 4))
|
||||
(global $~lib/internal/hash/FNV_OFFSET i32 (i32.const -2128831035))
|
||||
(global $~lib/internal/hash/FNV_PRIME i32 (i32.const 16777619))
|
||||
(global $Infinity f64 (f64.const inf))
|
||||
(global $NaN f64 (f64.const nan:0x8000000000000))
|
||||
(global $HEAP_BASE i32 (i32.const 36))
|
||||
(memory $0 1)
|
||||
(data (i32.const 4) "\00\00\00\00")
|
||||
(data (i32.const 8) "\01\00\00\00a\00")
|
||||
(data (i32.const 16) "\02\00\00\00a\00b\00")
|
||||
(data (i32.const 24) "\03\00\00\00a\00b\00c\00")
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
(func $~lib/internal/hash/hash<usize> (; 1 ;) (type $ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(set_local $1
|
||||
(i32.const -2128831035)
|
||||
)
|
||||
(block
|
||||
(set_local $2
|
||||
(get_local $0)
|
||||
)
|
||||
(set_local $1
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(get_local $1)
|
||||
(i32.and
|
||||
(get_local $2)
|
||||
(i32.const 255)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
)
|
||||
(set_local $1
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(get_local $1)
|
||||
(i32.and
|
||||
(i32.shr_u
|
||||
(get_local $2)
|
||||
(i32.const 8)
|
||||
)
|
||||
(i32.const 255)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
)
|
||||
(set_local $1
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(get_local $1)
|
||||
(i32.and
|
||||
(i32.shr_u
|
||||
(get_local $2)
|
||||
(i32.const 16)
|
||||
)
|
||||
(i32.const 255)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
)
|
||||
(set_local $1
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(get_local $1)
|
||||
(i32.shr_u
|
||||
(get_local $2)
|
||||
(i32.const 24)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
)
|
||||
)
|
||||
(return
|
||||
(get_local $1)
|
||||
)
|
||||
)
|
||||
(func $~lib/internal/hash/hash<String> (; 2 ;) (type $ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(set_local $1
|
||||
(i32.const -2128831035)
|
||||
)
|
||||
(block $break|0
|
||||
(block
|
||||
(set_local $2
|
||||
(i32.const 0)
|
||||
)
|
||||
(set_local $3
|
||||
(i32.shl
|
||||
(i32.load
|
||||
(get_local $0)
|
||||
)
|
||||
(i32.const 1)
|
||||
)
|
||||
)
|
||||
)
|
||||
(loop $continue|0
|
||||
(if
|
||||
(i32.lt_u
|
||||
(get_local $2)
|
||||
(get_local $3)
|
||||
)
|
||||
(block
|
||||
(set_local $1
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(get_local $1)
|
||||
(i32.load8_u offset=4
|
||||
(i32.add
|
||||
(get_local $0)
|
||||
(get_local $2)
|
||||
)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
)
|
||||
(set_local $2
|
||||
(i32.add
|
||||
(get_local $2)
|
||||
(i32.const 1)
|
||||
)
|
||||
)
|
||||
(br $continue|0)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(return
|
||||
(get_local $1)
|
||||
)
|
||||
)
|
||||
(func $~lib/internal/hash/hash<f32> (; 3 ;) (type $fi) (param $0 f32) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(set_local $1
|
||||
(i32.const -2128831035)
|
||||
)
|
||||
(block
|
||||
(set_local $2
|
||||
(i32.reinterpret/f32
|
||||
(get_local $0)
|
||||
)
|
||||
)
|
||||
(set_local $1
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(get_local $1)
|
||||
(i32.and
|
||||
(get_local $2)
|
||||
(i32.const 255)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
)
|
||||
(set_local $1
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(get_local $1)
|
||||
(i32.and
|
||||
(i32.shr_u
|
||||
(get_local $2)
|
||||
(i32.const 8)
|
||||
)
|
||||
(i32.const 255)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
)
|
||||
(set_local $1
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(get_local $1)
|
||||
(i32.and
|
||||
(i32.shr_u
|
||||
(get_local $2)
|
||||
(i32.const 16)
|
||||
)
|
||||
(i32.const 255)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
)
|
||||
(set_local $1
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(get_local $1)
|
||||
(i32.shr_u
|
||||
(get_local $2)
|
||||
(i32.const 24)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
)
|
||||
)
|
||||
(return
|
||||
(get_local $1)
|
||||
)
|
||||
)
|
||||
(func $~lib/internal/hash/hash<f64> (; 4 ;) (type $Fi) (param $0 f64) (result i32)
|
||||
(local $1 i32)
|
||||
(local $2 i64)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(set_local $1
|
||||
(i32.const -2128831035)
|
||||
)
|
||||
(block
|
||||
(set_local $2
|
||||
(i64.reinterpret/f64
|
||||
(get_local $0)
|
||||
)
|
||||
)
|
||||
(set_local $3
|
||||
(i32.wrap/i64
|
||||
(get_local $2)
|
||||
)
|
||||
)
|
||||
(set_local $4
|
||||
(i32.wrap/i64
|
||||
(i64.shr_u
|
||||
(get_local $2)
|
||||
(i64.const 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set_local $1
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(get_local $1)
|
||||
(i32.and
|
||||
(get_local $3)
|
||||
(i32.const 255)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
)
|
||||
(set_local $1
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(get_local $1)
|
||||
(i32.and
|
||||
(i32.shr_u
|
||||
(get_local $3)
|
||||
(i32.const 8)
|
||||
)
|
||||
(i32.const 255)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
)
|
||||
(set_local $1
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(get_local $1)
|
||||
(i32.and
|
||||
(i32.shr_u
|
||||
(get_local $3)
|
||||
(i32.const 16)
|
||||
)
|
||||
(i32.const 255)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
)
|
||||
(set_local $1
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(get_local $1)
|
||||
(i32.shr_u
|
||||
(get_local $3)
|
||||
(i32.const 24)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
)
|
||||
(set_local $1
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(get_local $1)
|
||||
(i32.and
|
||||
(get_local $4)
|
||||
(i32.const 255)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
)
|
||||
(set_local $1
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(get_local $1)
|
||||
(i32.and
|
||||
(i32.shr_u
|
||||
(get_local $4)
|
||||
(i32.const 8)
|
||||
)
|
||||
(i32.const 255)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
)
|
||||
(set_local $1
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(get_local $1)
|
||||
(i32.and
|
||||
(i32.shr_u
|
||||
(get_local $4)
|
||||
(i32.const 16)
|
||||
)
|
||||
(i32.const 255)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
)
|
||||
(set_local $1
|
||||
(i32.mul
|
||||
(i32.xor
|
||||
(get_local $1)
|
||||
(i32.shr_u
|
||||
(get_local $4)
|
||||
(i32.const 24)
|
||||
)
|
||||
)
|
||||
(i32.const 16777619)
|
||||
)
|
||||
)
|
||||
)
|
||||
(return
|
||||
(get_local $1)
|
||||
)
|
||||
)
|
||||
(func $start (; 5 ;) (type $v)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<usize>
|
||||
(i32.const 0)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<String>
|
||||
(i32.const 4)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<String>
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<String>
|
||||
(i32.const 16)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<String>
|
||||
(i32.const 24)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f32>
|
||||
(f32.const 0)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f32>
|
||||
(f32.const 1)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f32>
|
||||
(f32.const 1.100000023841858)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f32>
|
||||
(f32.const 0)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f32>
|
||||
(f32.const inf)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f32>
|
||||
(f32.const nan:0x400000)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f64>
|
||||
(f64.const 0)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f64>
|
||||
(f64.const 1)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f64>
|
||||
(f64.const 1.1)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f64>
|
||||
(f64.const 0)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f64>
|
||||
(f64.const inf)
|
||||
)
|
||||
)
|
||||
(call $std/hash/logi
|
||||
(call $~lib/internal/hash/hash<f64>
|
||||
(f64.const nan:0x8000000000000)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user