Skip to content

Commit f551bc7

Browse files
authored
Implement bulk memory operations (AssemblyScript#467)
1 parent 831054d commit f551bc7

23 files changed

+331
-263
lines changed

cli/asc.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@
161161
"",
162162
" sign-extension Enables sign-extension operations",
163163
" mutable-global Enables mutable global imports and exports",
164+
" bulk-memory Enables bulk memory operations",
164165
""
165166
],
166167
"type": "s"

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
},
1313
"dependencies": {
1414
"@protobufjs/utf8": "^1.1.0",
15-
"binaryen": "67.0.0-nightly.20190203",
15+
"binaryen": "67.0.0-nightly.20190207",
1616
"glob": "^7.1.3",
1717
"long": "^4.0.0"
1818
},

src/builtins.ts

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
import {
77
Compiler,
88
ConversionKind,
9-
WrapMode
9+
WrapMode,
10+
Feature
1011
} from "./compiler";
1112

1213
import {
@@ -1958,6 +1959,12 @@ export function compileCall(
19581959
}
19591960
// see: https://github.com/WebAssembly/bulk-memory-operations
19601961
case "memory.copy": { // memory.copy(dest: usize, src: usize: n: usize) -> void
1962+
if (!compiler.options.hasFeature(Feature.BULK_MEMORY)) {
1963+
let instance = compiler.resolver.resolveFunction(prototype, null); // reports
1964+
compiler.currentType = Type.void;
1965+
if (!instance) return module.createUnreachable();
1966+
return compiler.compileCallDirect(instance, operands, reportNode);
1967+
}
19611968
if (typeArguments) {
19621969
compiler.error(
19631970
DiagnosticCode.Type_0_is_not_generic,
@@ -1972,29 +1979,35 @@ export function compileCall(
19721979
compiler.currentType = Type.void;
19731980
return module.createUnreachable();
19741981
}
1982+
let usizeType = compiler.options.usizeType;
19751983
arg0 = compiler.compileExpression(
19761984
operands[0],
1977-
compiler.options.usizeType,
1985+
usizeType,
19781986
ConversionKind.IMPLICIT,
19791987
WrapMode.NONE
19801988
);
19811989
arg1 = compiler.compileExpression(
19821990
operands[1],
1983-
compiler.options.usizeType,
1991+
usizeType,
19841992
ConversionKind.IMPLICIT,
19851993
WrapMode.NONE
19861994
);
19871995
arg2 = compiler.compileExpression(
19881996
operands[2],
1989-
compiler.options.usizeType,
1997+
usizeType,
19901998
ConversionKind.IMPLICIT,
19911999
WrapMode.NONE
19922000
);
19932001
compiler.currentType = Type.void;
1994-
throw new Error("not implemented");
1995-
// return module.createHost(HostOp.MoveMemory, null, [ arg0, arg1, arg2 ]);
2002+
return module.createMemoryCopy(arg0, arg1, arg2);
19962003
}
19972004
case "memory.fill": { // memory.fill(dest: usize, value: u8, n: usize) -> void
2005+
if (!compiler.options.hasFeature(Feature.BULK_MEMORY)) {
2006+
let instance = compiler.resolver.resolveFunction(prototype, null); // reports
2007+
compiler.currentType = Type.void;
2008+
if (!instance) return module.createUnreachable();
2009+
return compiler.compileCallDirect(instance, operands, reportNode);
2010+
}
19982011
if (typeArguments) {
19992012
compiler.error(
20002013
DiagnosticCode.Type_0_is_not_generic,
@@ -2009,9 +2022,10 @@ export function compileCall(
20092022
compiler.currentType = Type.void;
20102023
return module.createUnreachable();
20112024
}
2025+
let usizeType = compiler.options.usizeType;
20122026
arg0 = compiler.compileExpression(
20132027
operands[0],
2014-
compiler.options.usizeType,
2028+
usizeType,
20152029
ConversionKind.IMPLICIT,
20162030
WrapMode.NONE
20172031
);
@@ -2023,13 +2037,12 @@ export function compileCall(
20232037
);
20242038
arg2 = compiler.compileExpression(
20252039
operands[2],
2026-
compiler.options.usizeType,
2040+
usizeType,
20272041
ConversionKind.IMPLICIT,
20282042
WrapMode.NONE
20292043
);
20302044
compiler.currentType = Type.void;
2031-
throw new Error("not implemented");
2032-
// return module.createHost(HostOp.SetMemory, null, [ arg0, arg1, arg2 ]);
2045+
return module.createMemoryFill(arg0, arg1, arg2);
20332046
}
20342047

20352048
// other

src/compiler.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,9 @@ export const enum Feature {
233233
/** Sign extension operations. */
234234
SIGN_EXTENSION = 1 << 0, // see: https://github.com/WebAssembly/sign-extension-ops
235235
/** Mutable global imports and exports. */
236-
MUTABLE_GLOBAL = 1 << 1 // see: https://github.com/WebAssembly/mutable-global
236+
MUTABLE_GLOBAL = 1 << 1, // see: https://github.com/WebAssembly/mutable-global
237+
/** Bulk memory operations. */
238+
BULK_MEMORY = 1 << 2 // see: https://github.com/WebAssembly/bulk-memory-operations
237239
}
238240

239241
/** Indicates the desired kind of a conversion. */

src/glue/binaryen.d.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ declare function _BinaryenSIMDReplaceId(): BinaryenExpressionId;
5555
declare function _BinaryenSIMDShuffleId(): BinaryenExpressionId;
5656
declare function _BinaryenSIMDBitselectId(): BinaryenExpressionId;
5757
declare function _BinaryenSIMDShiftId(): BinaryenExpressionId;
58+
declare function _BinaryenMemoryInitId(): BinaryenExpressionId;
59+
declare function _BinaryenDataDropId(): BinaryenExpressionId;
60+
declare function _BinaryenMemoryCopyId(): BinaryenExpressionId;
61+
declare function _BinaryenMemoryFillId(): BinaryenExpressionId;
5862

5963
declare type BinaryenModuleRef = usize;
6064
declare type v128ptr = usize; // TODO: LLVM C-abi for const uint8_t[16]?
@@ -63,7 +67,8 @@ declare function _BinaryenModuleCreate(): BinaryenModuleRef;
6367
declare function _BinaryenModuleDispose(module: BinaryenModuleRef): void;
6468

6569
// LLVM C ABI with `out` being a large enough buffer receiving the
66-
// BinaryenLiteral struct.
70+
// BinaryenLiteral struct of size `_BinaryenSizeofLiteral()`.
71+
declare function _BinaryenSizeofLiteral(): usize;
6772
declare function _BinaryenLiteralInt32(out: usize, x: i32): void;
6873
declare function _BinaryenLiteralInt64(out: usize, x: i32, y: i32): void;
6974
declare function _BinaryenLiteralFloat32(out: usize, x: f32): void;
@@ -394,6 +399,11 @@ declare function _BinaryenSIMDShuffle(module: BinaryenModuleRef, left: BinaryenE
394399
declare function _BinaryenSIMDBitselect(module: BinaryenModuleRef, left: BinaryenExpressionRef, right: BinaryenExpressionRef, cond: BinaryenExpressionRef): BinaryenExpressionRef;
395400
declare function _BinaryenSIMDShift(module: BinaryenModuleRef, op: BinaryenSIMDOp, vec: BinaryenExpressionRef, shift: BinaryenExpressionRef): BinaryenExpressionRef;
396401

402+
declare function _BinaryenMemoryInit(module: BinaryenModuleRef, segment: u32, dest: BinaryenExpressionRef, offset: BinaryenExpressionRef, size: BinaryenExpressionRef): BinaryenExpressionRef;
403+
declare function _BinaryenDataDrop(module: BinaryenModuleRef, segment: u32): BinaryenExpressionRef;
404+
declare function _BinaryenMemoryCopy(module: BinaryenModuleRef, dest: BinaryenExpressionRef, source: BinaryenExpressionRef, size: BinaryenExpressionRef): BinaryenExpressionRef;
405+
declare function _BinaryenMemoryFill(module: BinaryenModuleRef, dest: BinaryenExpressionRef, value: BinaryenExpressionRef, size: BinaryenExpressionRef): BinaryenExpressionRef;
406+
397407
declare function _BinaryenExpressionGetId(expr: BinaryenExpressionRef): BinaryenExpressionId;
398408
declare function _BinaryenExpressionGetType(expr: BinaryenExpressionRef): BinaryenType;
399409
declare function _BinaryenExpressionPrint(expr: BinaryenExpressionRef): void;
@@ -519,6 +529,21 @@ declare function _BinaryenSIMDShiftGetOp(expr: BinaryenExpressionRef): BinaryenS
519529
declare function _BinaryenSIMDShiftGetVec(expr: BinaryenExpressionRef): BinaryenExpressionRef;
520530
declare function _BinaryenSIMDShiftGetShift(expr: BinaryenExpressionRef): BinaryenExpressionRef;
521531

532+
declare function _BinaryenMemoryInitGetSegment(expr: BinaryenExpressionRef): u32;
533+
declare function _BinaryenMemoryInitGetDest(expr: BinaryenExpressionRef): BinaryenExpressionRef;
534+
declare function _BinaryenMemoryInitGetOffset(expr: BinaryenExpressionRef): BinaryenExpressionRef;
535+
declare function _BinaryenMemoryInitGetSize(expr: BinaryenExpressionRef): BinaryenExpressionRef;
536+
537+
declare function _BinaryenDataDropGetSegment(expr: BinaryenExpressionRef): u32;
538+
539+
declare function _BinaryenMemoryCopyGetDest(expr: BinaryenExpressionRef): BinaryenExpressionRef;
540+
declare function _BinaryenMemoryCopyGetSource(expr: BinaryenExpressionRef): BinaryenExpressionRef;
541+
declare function _BinaryenMemoryCopyGetSize(expr: BinaryenExpressionRef): BinaryenExpressionRef;
542+
543+
declare function _BinaryenMemoryFillGetDest(expr: BinaryenExpressionRef): BinaryenExpressionRef;
544+
declare function _BinaryenMemoryFillGetValue(expr: BinaryenExpressionRef): BinaryenExpressionRef;
545+
declare function _BinaryenMemoryFillGetSize(expr: BinaryenExpressionRef): BinaryenExpressionRef;
546+
522547
declare type BinaryenFunctionTypeRef = usize;
523548

524549
declare function _BinaryenAddFunctionType(module: BinaryenModuleRef, name: usize, result: BinaryenType, paramTypes: usize, numParams: BinaryenIndex): BinaryenFunctionTypeRef;

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ export function setGlobalAlias(options: Options, name: string, alias: string): v
128128
export const FEATURE_SIGN_EXTENSION = Feature.SIGN_EXTENSION;
129129
/** Mutable global imports and exports. */
130130
export const FEATURE_MUTABLE_GLOBAL = Feature.MUTABLE_GLOBAL;
131+
/** Bulk memory operations. */
132+
export const FEATURE_BULK_MEMORY = Feature.BULK_MEMORY;
131133

132134
/** Enables a specific feature. */
133135
export function enableFeature(options: Options, feature: Feature): void {

0 commit comments

Comments
 (0)