mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-16 00:11:28 +00:00
Add a mechanism to enable additional (experimental) features and start with sign extension operations; Hashing experimentation
This commit is contained in:
@ -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];
|
||||
}
|
||||
|
Reference in New Issue
Block a user