mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-07-18 15:52:07 +00:00
Rename memory instructions; Rework constant handling
This commit is contained in:
examples
i64-polyfill
mandelbrot
build
n-body
ugc
assembly
lib/loader/tests/assembly
package-lock.jsonpackage.jsonsnap
src
binary.tsbuiltins.tscompiler.tsdecompiler.tsdefinitions.tsdiagnosticMessages.generated.tsdiagnosticMessages.json
glue
module.tsprogram.tsstd
assembly
portable
tests
allocators
binaryen
compiler
abi.optimized.watabi.untouched.watasc-constants.untouched.watbuiltins.optimized.watbuiltins.tsbuiltins.untouched.watcall-optional.optimized.watcall-optional.untouched.watclass-extends.optimized.watclass-extends.untouched.watclass-overloading.optimized.watclass-overloading.untouched.watclass-with-boolean-field.optimized.watclass-with-boolean-field.untouched.watclass.optimized.watclass.untouched.watenum.optimized.watenum.tsenum.untouched.watexport.optimized.watexport.untouched.watexports.optimized.watexports.tsexports.untouched.watexternal.optimized.watexternal.untouched.watfunction-types.optimized.watfunction-types.untouched.wati64-polyfill.optimized.wati64-polyfill.untouched.watif.optimized.watif.untouched.watimport.untouched.watinfer-type.untouched.watinlining-recursive.optimized.watinlining-recursive.untouched.watinlining.optimized.watinlining.untouched.watlimits.untouched.watmain.optimized.watmain.untouched.watmandelbrot.optimized.watmandelbrot.untouched.watmany-locals.optimized.watmany-locals.untouched.watmemcpy.optimized.watmemcpy.untouched.watmemmove.untouched.watmemset.optimized.watnamed-export-default.optimized.watnamed-export-default.untouched.watnamed-import-default.optimized.watnamed-import-default.untouched.watnamespace.tsnamespace.untouched.watnew-without-allocator.optimized.watnew-without-allocator.tsnew-without-allocator.untouched.watobject-literal.optimized.watobject-literal.untouched.watrecursive.optimized.watrecursive.untouched.watreexport.optimized.watreexport.untouched.watretain-i32.untouched.wat
std
allocator_arena.optimized.watallocator_arena.tsallocator_arena.untouched.watarray-access.optimized.watarray-access.untouched.watarray-literal.optimized.watarray-literal.untouched.watarray.optimized.watarray.untouched.watarraybuffer.optimized.watarraybuffer.untouched.watconstructor.optimized.watconstructor.tsconstructor.untouched.watgc-integration.optimized.watgc-integration.tsgc-integration.untouched.watgc.optimized.watgc.tsgc.untouched.wathash.untouched.watlibm.optimized.watlibm.untouched.watmap.optimized.watmap.untouched.watmath.untouched.watmod.untouched.watnew.optimized.watnew.untouched.watoperator-overloading.optimized.watoperator-overloading.untouched.watpointer.optimized.watpointer.untouched.watset.optimized.watset.untouched.watstatic-array.optimized.watstatic-array.untouched.watstring-utf8.optimized.watstring-utf8.tsstring-utf8.untouched.watstring.optimized.watstring.untouched.watsymbol.optimized.watsymbol.untouched.wattypedarray.optimized.wattypedarray.untouched.wat
typealias.optimized.wattypealias.untouched.wat
189
src/builtins.ts
189
src/builtins.ts
@@ -48,13 +48,19 @@ import {
|
||||
Class,
|
||||
Field,
|
||||
OperatorKind,
|
||||
FlowFlags
|
||||
FlowFlags,
|
||||
Global,
|
||||
DecoratorFlags
|
||||
} from "./program";
|
||||
|
||||
import {
|
||||
ReportMode
|
||||
} from "./resolver";
|
||||
|
||||
import {
|
||||
CommonFlags
|
||||
} from "./common";
|
||||
|
||||
/** Compiles a call to a built-in function. */
|
||||
export function compileCall(
|
||||
compiler: Compiler,
|
||||
@@ -134,24 +140,17 @@ export function compileCall(
|
||||
}
|
||||
case "isDefined": { // isDefined(expression) -> bool
|
||||
compiler.currentType = Type.bool;
|
||||
if (operands.length != 1) {
|
||||
if (typeArguments) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Type_0_is_not_generic,
|
||||
reportNode.range, prototype.internalName
|
||||
);
|
||||
}
|
||||
compiler.error(
|
||||
DiagnosticCode.Expected_0_arguments_but_got_1,
|
||||
reportNode.range, "1", operands.length.toString(10)
|
||||
);
|
||||
return module.createUnreachable();
|
||||
}
|
||||
if (typeArguments) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Type_0_is_not_generic,
|
||||
reportNode.range, prototype.internalName
|
||||
);
|
||||
}
|
||||
if (operands.length != 1) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Expected_0_arguments_but_got_1,
|
||||
reportNode.range, "1", operands.length.toString(10)
|
||||
);
|
||||
return module.createUnreachable();
|
||||
}
|
||||
let element = compiler.resolver.resolveExpression(operands[0], compiler.currentFunction, ReportMode.SWALLOW);
|
||||
@@ -159,24 +158,17 @@ export function compileCall(
|
||||
}
|
||||
case "isConstant": { // isConstant(expression) -> bool
|
||||
compiler.currentType = Type.bool;
|
||||
if (operands.length != 1) {
|
||||
if (typeArguments) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Type_0_is_not_generic,
|
||||
reportNode.range, prototype.internalName
|
||||
);
|
||||
}
|
||||
compiler.error(
|
||||
DiagnosticCode.Expected_0_arguments_but_got_1,
|
||||
reportNode.range, "1", operands.length.toString(10)
|
||||
);
|
||||
return module.createUnreachable();
|
||||
}
|
||||
if (typeArguments) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Type_0_is_not_generic,
|
||||
reportNode.range, prototype.internalName
|
||||
);
|
||||
}
|
||||
if (operands.length != 1) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Expected_0_arguments_but_got_1,
|
||||
reportNode.range, "1", operands.length.toString(10)
|
||||
);
|
||||
return module.createUnreachable();
|
||||
}
|
||||
let expr = compiler.compileExpressionRetainType(operands[0], Type.i32, WrapMode.NONE);
|
||||
@@ -1879,7 +1871,7 @@ export function compileCall(
|
||||
|
||||
// host operations
|
||||
|
||||
case "current_memory": { // current_memory() -> i32
|
||||
case "__memory_size": { // __memory_size() -> i32
|
||||
compiler.currentType = Type.i32;
|
||||
if (operands.length != 0) {
|
||||
compiler.error(
|
||||
@@ -1895,7 +1887,7 @@ export function compileCall(
|
||||
}
|
||||
return module.createHost(HostOp.CurrentMemory);
|
||||
}
|
||||
case "grow_memory": { // grow_memory(pages: i32) -> i32
|
||||
case "__memory_grow": { // __memory_grow(pages: i32) -> i32
|
||||
compiler.currentType = Type.i32;
|
||||
if (operands.length != 1) {
|
||||
compiler.error(
|
||||
@@ -1915,7 +1907,7 @@ export function compileCall(
|
||||
return module.createHost(HostOp.GrowMemory, null, [ arg0 ]);
|
||||
}
|
||||
// see: https://github.com/WebAssembly/bulk-memory-operations
|
||||
case "move_memory": { // move_memory(dest: usize, src: usize: n: usize) -> void
|
||||
case "__memory_copy": { // __memory_copy(dest: usize, src: usize: n: usize) -> void
|
||||
if (typeArguments) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Type_0_is_not_generic,
|
||||
@@ -1952,7 +1944,7 @@ export function compileCall(
|
||||
throw new Error("not implemented");
|
||||
// return module.createHost(HostOp.MoveMemory, null, [ arg0, arg1, arg2 ]);
|
||||
}
|
||||
case "set_memory": { // set_memory(dest: usize, value: u8, n: usize) -> void
|
||||
case "__memory_fill": { // __memory_fill(dest: usize, value: u8, n: usize) -> void
|
||||
if (typeArguments) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Type_0_is_not_generic,
|
||||
@@ -2318,6 +2310,30 @@ export function compileCall(
|
||||
return module.createCallIndirect(arg0, operandExprs, typeName);
|
||||
}
|
||||
|
||||
// user-defined diagnostic macros
|
||||
|
||||
case "ERROR": {
|
||||
compiler.error(
|
||||
DiagnosticCode.User_defined_0,
|
||||
reportNode.range, (operands.length ? operands[0] : reportNode).range.toString()
|
||||
);
|
||||
return module.createUnreachable();
|
||||
}
|
||||
case "WARNING": {
|
||||
compiler.warning(
|
||||
DiagnosticCode.User_defined_0,
|
||||
reportNode.range, (operands.length ? operands[0] : reportNode).range.toString()
|
||||
);
|
||||
return module.createNop();
|
||||
}
|
||||
case "INFO": {
|
||||
compiler.info(
|
||||
DiagnosticCode.User_defined_0,
|
||||
reportNode.range, (operands.length ? operands[0] : reportNode).range.toString()
|
||||
);
|
||||
return module.createNop();
|
||||
}
|
||||
|
||||
// conversions
|
||||
|
||||
case "i8": {
|
||||
@@ -2610,6 +2626,84 @@ export function compileCall(
|
||||
WrapMode.NONE
|
||||
);
|
||||
}
|
||||
|
||||
// gc
|
||||
|
||||
case "__gc_iterate_roots": {
|
||||
// TOOD: make it so that this can only be called from a library file?
|
||||
if (typeArguments) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Type_0_is_not_generic,
|
||||
reportNode.range, prototype.internalName
|
||||
);
|
||||
}
|
||||
if (operands.length != 1) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Expected_0_arguments_but_got_1,
|
||||
reportNode.range, "1", operands.length.toString(10)
|
||||
);
|
||||
compiler.currentType = Type.void;
|
||||
return module.createUnreachable();
|
||||
}
|
||||
let expr = compiler.compileExpressionRetainType(operands[0], Type.u32, WrapMode.NONE);
|
||||
let type = compiler.currentType;
|
||||
let signatureReference = type.signatureReference;
|
||||
compiler.currentType = Type.void;
|
||||
if (
|
||||
!type.is(TypeFlags.REFERENCE) ||
|
||||
!signatureReference ||
|
||||
signatureReference.parameterTypes.length != 1 ||
|
||||
signatureReference.parameterTypes[0] != compiler.options.usizeType
|
||||
) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Type_0_is_not_assignable_to_type_1,
|
||||
reportNode.range, type.toString(), "(ref: usize) => void"
|
||||
);
|
||||
return module.createUnreachable();
|
||||
}
|
||||
let exprs = new Array<ExpressionRef>();
|
||||
for (let element of compiler.program.elementsLookup.values()) {
|
||||
if (element.kind != ElementKind.GLOBAL) continue;
|
||||
let global = <Global>element;
|
||||
let classReference = global.type.classReference;
|
||||
if (
|
||||
global.is(CommonFlags.COMPILED) &&
|
||||
classReference !== null &&
|
||||
!classReference.hasDecorator(DecoratorFlags.UNMANAGED)
|
||||
) {
|
||||
if (global.is(CommonFlags.INLINED)) {
|
||||
let value = global.constantIntegerValue;
|
||||
exprs.push(
|
||||
module.createCallIndirect(
|
||||
expr,
|
||||
[
|
||||
compiler.options.isWasm64
|
||||
? module.createI64(i64_low(value), i64_high(value))
|
||||
: module.createI32(i64_low(value))
|
||||
],
|
||||
signatureReference.toSignatureString()
|
||||
)
|
||||
);
|
||||
} else {
|
||||
exprs.push(
|
||||
module.createCallIndirect(
|
||||
expr,
|
||||
[
|
||||
module.createGetGlobal(
|
||||
global.internalName,
|
||||
compiler.options.nativeSizeType
|
||||
)
|
||||
],
|
||||
signatureReference.toSignatureString()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return exprs.length
|
||||
? module.createBlock(null, exprs)
|
||||
: module.createNop();
|
||||
}
|
||||
}
|
||||
var expr = deferASMCall(compiler, prototype, operands, contextualType, reportNode);
|
||||
if (expr) {
|
||||
@@ -2816,8 +2910,6 @@ function evaluateConstantOffset(compiler: Compiler, expression: Expression): i32
|
||||
return value;
|
||||
}
|
||||
|
||||
const allocateInternalName = "allocate_memory";
|
||||
|
||||
/** Compiles a memory allocation for an instance of the specified class. */
|
||||
export function compileAllocate(
|
||||
compiler: Compiler,
|
||||
@@ -2828,29 +2920,15 @@ export function compileAllocate(
|
||||
assert(classInstance.program == program);
|
||||
var module = compiler.module;
|
||||
var options = compiler.options;
|
||||
|
||||
var allocatePrototype = program.elementsLookup.get(allocateInternalName);
|
||||
if (!allocatePrototype) {
|
||||
var allocateInstance = program.memoryAllocateInstance;
|
||||
if (!allocateInstance) {
|
||||
program.error(
|
||||
DiagnosticCode.Cannot_find_name_0,
|
||||
reportNode.range, allocateInternalName
|
||||
);
|
||||
program.info(
|
||||
DiagnosticCode.An_allocator_must_be_declared_to_allocate_memory_Try_importing_allocator_arena_or_allocator_tlsf,
|
||||
reportNode.range
|
||||
reportNode.range, "memory.allocate"
|
||||
);
|
||||
return module.createUnreachable();
|
||||
}
|
||||
if (allocatePrototype.kind != ElementKind.FUNCTION_PROTOTYPE) {
|
||||
program.error(
|
||||
DiagnosticCode.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures,
|
||||
reportNode.range, allocatePrototype.internalName
|
||||
);
|
||||
return module.createUnreachable();
|
||||
}
|
||||
|
||||
var allocateInstance = compiler.resolver.resolveFunction(<FunctionPrototype>allocatePrototype, null);
|
||||
if (!(allocateInstance && compiler.compileFunction(allocateInstance))) return module.createUnreachable();
|
||||
if (!compiler.compileFunction(allocateInstance)) return module.createUnreachable();
|
||||
|
||||
compiler.currentType = classInstance.type;
|
||||
return module.createCall(
|
||||
@@ -2863,8 +2941,6 @@ export function compileAllocate(
|
||||
);
|
||||
}
|
||||
|
||||
const abortInternalName = "abort";
|
||||
|
||||
/** Compiles an abort wired to the conditionally imported 'abort' function. */
|
||||
export function compileAbort(
|
||||
compiler: Compiler,
|
||||
@@ -2874,13 +2950,10 @@ export function compileAbort(
|
||||
var program = compiler.program;
|
||||
var module = compiler.module;
|
||||
|
||||
var stringType = program.typesLookup.get("string"); // might be intended
|
||||
var stringType = program.typesLookup.get("string");
|
||||
if (!stringType) return module.createUnreachable();
|
||||
|
||||
var abortPrototype = program.elementsLookup.get(abortInternalName); // might be intended
|
||||
if (!abortPrototype || abortPrototype.kind != ElementKind.FUNCTION_PROTOTYPE) return module.createUnreachable();
|
||||
|
||||
var abortInstance = compiler.resolver.resolveFunction(<FunctionPrototype>abortPrototype, null);
|
||||
var abortInstance = program.abortInstance;
|
||||
if (!(abortInstance && compiler.compileFunction(abortInstance))) return module.createUnreachable();
|
||||
|
||||
var messageArg = message != null
|
||||
|
Reference in New Issue
Block a user