diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 49597efacf..42d8715922 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -115,8 +115,7 @@ jobs: - uses: dcodeIO/setup-node-nvm@master with: node-mirror: https://nodejs.org/download/v8-canary/ - # FIXME: newer node-v8 builds are currently broken - node-version: "14.0.0-v8-canary201911242015a12d82" + node-version: "15.0.0-v8-canary202007077c53168ead" - name: Install dependencies run: npm ci --no-audit - name: Clean distribution files diff --git a/package-lock.json b/package-lock.json index 2dba409769..7b4f7202af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1260,9 +1260,9 @@ "dev": true }, "binaryen": { - "version": "93.0.0-nightly.20200609", - "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-93.0.0-nightly.20200609.tgz", - "integrity": "sha512-CIaeav05u+fWRN2h1ecwIoSaOF/Mk6U85M/G6eg1nOHAXYYmOuh9TztF9Fu8krRWnl98J3W+VfDClApMV5zCtw==" + "version": "93.0.0-nightly.20200611", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-93.0.0-nightly.20200611.tgz", + "integrity": "sha512-1s/kDzzIeWT++PdhRJ551/fle6NzqObITXO2y7QLDNnLi1mOFQYqPMskHTnq2qxgWe7dxuU0h9VyVrrfk2PxfA==" }, "bindings": { "version": "1.5.0", diff --git a/package.json b/package.json index fbc5f3b32e..77bb6aa2b4 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "url": "https://github.com/AssemblyScript/assemblyscript/issues" }, "dependencies": { - "binaryen": "93.0.0-nightly.20200609", + "binaryen": "93.0.0-nightly.20200611", "long": "^4.0.0", "source-map-support": "^0.5.19", "ts-node": "^6.2.0" diff --git a/src/builtins.ts b/src/builtins.ts index 6b874ebc37..475f0e2830 100644 --- a/src/builtins.ts +++ b/src/builtins.ts @@ -971,7 +971,7 @@ function builtin_nameof(ctx: BuiltinContext): ExpressionRef { if (signatureReference) { value = "Function"; } else { - value = "Anyref"; + value = "Externref"; } } } else { @@ -990,7 +990,7 @@ function builtin_nameof(ctx: BuiltinContext): ExpressionRef { case TypeKind.ISIZE: { value = "isize"; break; } case TypeKind.USIZE: { value = "usize"; break; } case TypeKind.V128: { value = "v128"; break; } - case TypeKind.ANYREF: { value = "anyref"; break; } + case TypeKind.EXTERNREF: { value = "externref"; break; } default: assert(false); case TypeKind.VOID: { value = "void"; break; } } @@ -2440,7 +2440,8 @@ function builtin_select(ctx: BuiltinContext): ExpressionRef { var arg1 = compiler.compileExpression(operands[1], type, Constraints.CONV_IMPLICIT); var arg2 = compiler.makeIsTrueish( compiler.compileExpression(operands[2], Type.bool), - compiler.currentType // ^ + compiler.currentType, // ^ + operands[2] ); compiler.currentType = type; return module.select(arg0, arg1, arg2); @@ -2577,9 +2578,9 @@ function builtin_memory_data(ctx: BuiltinContext): ExpressionRef { let exprs = new Array(numElements); let isStatic = true; for (let i = 0; i < numElements; ++i) { - let expression = expressions[i]; - if (expression) { - let expr = compiler.compileExpression(expression, elementType, + let elementExpression = expressions[i]; + if (elementExpression) { + let expr = compiler.compileExpression(elementExpression, elementType, Constraints.CONV_IMPLICIT | Constraints.WILL_RETAIN ); let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects); @@ -2590,7 +2591,7 @@ function builtin_memory_data(ctx: BuiltinContext): ExpressionRef { } exprs[i] = expr; } else { - exprs[i] = compiler.makeZero(elementType); + exprs[i] = compiler.makeZero(elementType, valuesOperand); } } if (!isStatic) { diff --git a/src/common.ts b/src/common.ts index 20dae5d0a3..5e286f1462 100644 --- a/src/common.ts +++ b/src/common.ts @@ -123,7 +123,7 @@ export namespace CommonNames { export const f32 = "f32"; export const f64 = "f64"; export const v128 = "v128"; - export const anyref = "anyref"; + export const externref = "externref"; export const i8x16 = "i8x16"; export const u8x16 = "u8x16"; export const i16x8 = "i16x8"; @@ -185,7 +185,7 @@ export namespace CommonNames { export const F32 = "F32"; export const F64 = "F64"; export const V128 = "V128"; - export const Anyref = "Anyref"; + export const Externref = "Externref"; export const String = "String"; export const Array = "Array"; export const StaticArray = "StaticArray"; diff --git a/src/compiler.ts b/src/compiler.ts index 3113f4468c..7bcc8cf1a8 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -1201,7 +1201,7 @@ export class Compiler extends DiagnosticEmitter { if (global.is(CommonFlags.INLINED)) { initExpr = this.compileInlineConstant(global, global.type, Constraints.PREFER_STATIC | Constraints.WILL_RETAIN); } else { - initExpr = this.makeZero(type); + initExpr = this.makeZero(type, global.declaration); } } @@ -1214,7 +1214,7 @@ export class Compiler extends DiagnosticEmitter { findDecorator(DecoratorKind.INLINE, global.decoratorNodes)!.range, "inline" ); } - module.addGlobal(internalName, nativeType, true, this.makeZero(type)); + module.addGlobal(internalName, nativeType, true, this.makeZero(type, global.declaration)); if (type.isManaged && !this.skippedAutoreleases.has(initExpr)) initExpr = this.makeRetain(initExpr, type); this.currentBody.push( module.global_set(internalName, initExpr) @@ -2361,7 +2361,8 @@ export class Compiler extends DiagnosticEmitter { this.currentFlow = condFlow; let condExpr = this.makeIsTrueish( this.compileExpression(statement.condition, Type.i32), - this.currentType + this.currentType, + statement.condition ); let condKind = this.evaluateCondition(condExpr); @@ -2505,7 +2506,8 @@ export class Compiler extends DiagnosticEmitter { if (condition) { condExpr = this.makeIsTrueish( this.compileExpression(condition, Type.bool), - this.currentType + this.currentType, + condition ); condKind = this.evaluateCondition(condExpr); @@ -2665,7 +2667,8 @@ export class Compiler extends DiagnosticEmitter { // Precompute the condition (always executes) var condExpr = this.makeIsTrueish( this.compileExpression(statement.condition, Type.bool), - this.currentType + this.currentType, + statement.condition ); var condKind = this.evaluateCondition(condExpr); @@ -3186,7 +3189,7 @@ export class Compiler extends DiagnosticEmitter { // TODO: Detect this condition inside of a loop instead? initializers.push( module.local_set(local.index, - this.makeZero(type) + this.makeZero(type, declaration) ) ); flow.setLocalFlag(local.index, LocalFlags.CONDITIONALLY_RETAINED); @@ -3255,7 +3258,8 @@ export class Compiler extends DiagnosticEmitter { this.currentFlow = condFlow; var condExpr = this.makeIsTrueish( this.compileExpression(statement.condition, Type.bool), - this.currentType + this.currentType, + statement.condition ); var condKind = this.evaluateCondition(condExpr); @@ -4375,7 +4379,7 @@ export class Compiler extends DiagnosticEmitter { ); break; } - case TypeKind.ANYREF: { + case TypeKind.EXTERNREF: { // TODO: ref.eq this.error( DiagnosticCode.Not_implemented_0, @@ -4476,7 +4480,7 @@ export class Compiler extends DiagnosticEmitter { ); break; } - case TypeKind.ANYREF: { + case TypeKind.EXTERNREF: { // TODO: !ref.eq this.error( DiagnosticCode.Not_implemented_0, @@ -5798,8 +5802,8 @@ export class Compiler extends DiagnosticEmitter { rightFlow.freeScopedLocals(); this.currentFlow = flow; expr = module.if( - this.makeIsTrueish(leftExpr, leftType), - this.makeIsTrueish(rightExpr, rightType), + this.makeIsTrueish(leftExpr, leftType, left), + this.makeIsTrueish(rightExpr, rightType, right), module.i32(0) ); this.currentType = Type.bool; @@ -5843,7 +5847,7 @@ export class Compiler extends DiagnosticEmitter { this.currentFlow = flow; expr = module.if( - this.makeIsTrueish(leftExpr, leftType), + this.makeIsTrueish(leftExpr, leftType, left), rightExpr, retainLeftInElse ? this.makeRetain( @@ -5864,7 +5868,7 @@ export class Compiler extends DiagnosticEmitter { // simplify if cloning left without side effects is possible if (expr = module.cloneExpression(leftExpr, true, 0)) { expr = module.if( - this.makeIsTrueish(leftExpr, this.currentType), + this.makeIsTrueish(leftExpr, this.currentType, left), rightExpr, expr ); @@ -5875,7 +5879,7 @@ export class Compiler extends DiagnosticEmitter { if (!flow.canOverflow(leftExpr, leftType)) flow.setLocalFlag(tempLocal.index, LocalFlags.WRAPPED); if (flow.isNonnull(leftExpr, leftType)) flow.setLocalFlag(tempLocal.index, LocalFlags.NONNULL); expr = module.if( - this.makeIsTrueish(module.local_tee(tempLocal.index, leftExpr), leftType), + this.makeIsTrueish(module.local_tee(tempLocal.index, leftExpr), leftType, left), rightExpr, module.local_get(tempLocal.index, leftType.toNativeType()) ); @@ -5904,9 +5908,9 @@ export class Compiler extends DiagnosticEmitter { rightFlow.freeScopedLocals(); this.currentFlow = flow; expr = module.if( - this.makeIsTrueish(leftExpr, leftType), + this.makeIsTrueish(leftExpr, leftType, left), module.i32(1), - this.makeIsTrueish(rightExpr, rightType) + this.makeIsTrueish(rightExpr, rightType, right) ); this.currentType = Type.bool; @@ -5951,7 +5955,7 @@ export class Compiler extends DiagnosticEmitter { this.currentFlow = flow; expr = module.if( - this.makeIsTrueish(leftExpr, leftType), + this.makeIsTrueish(leftExpr, leftType, left), retainLeftInThen ? this.makeRetain( module.local_get(temp.index, leftType.toNativeType()), @@ -5972,7 +5976,7 @@ export class Compiler extends DiagnosticEmitter { // simplify if cloning left without side effects is possible if (expr = module.cloneExpression(leftExpr, true, 0)) { expr = module.if( - this.makeIsTrueish(leftExpr, leftType), + this.makeIsTrueish(leftExpr, leftType, left), expr, rightExpr ); @@ -5983,7 +5987,7 @@ export class Compiler extends DiagnosticEmitter { if (!flow.canOverflow(leftExpr, leftType)) flow.setLocalFlag(temp.index, LocalFlags.WRAPPED); if (flow.isNonnull(leftExpr, leftType)) flow.setLocalFlag(temp.index, LocalFlags.NONNULL); expr = module.if( - this.makeIsTrueish(module.local_tee(temp.index, leftExpr), leftType), + this.makeIsTrueish(module.local_tee(temp.index, leftExpr), leftType, left), module.local_get(temp.index, leftType.toNativeType()), rightExpr ); @@ -7389,7 +7393,7 @@ export class Compiler extends DiagnosticEmitter { let needsVarargsStub = false; for (let n = numParameters; n < overloadNumParameters; ++n) { // TODO: inline constant initializers and skip varargs stub - paramExprs[1 + n] = this.makeZero(overloadParameterTypes[n]); + paramExprs[1 + n] = this.makeZero(overloadParameterTypes[n], overloadInstance.declaration); needsVarargsStub = true; } let calledName = needsVarargsStub @@ -7874,7 +7878,7 @@ export class Compiler extends DiagnosticEmitter { } } } - operands.push(this.makeZero(parameterTypes[i])); + operands.push(this.makeZero(parameterTypes[i], instance.declaration)); allOptionalsAreConstant = false; } if (!allOptionalsAreConstant) { @@ -7966,15 +7970,16 @@ export class Compiler extends DiagnosticEmitter { ); } assert(index == numArgumentsInclThis); - return this.makeCallIndirect(signature, indexArg, operands, immediatelyDropped); + return this.makeCallIndirect(signature, indexArg, reportNode, operands, immediatelyDropped); } /** Creates an indirect call to the function at `indexArg` in the function table. */ makeCallIndirect( signature: Signature, indexArg: ExpressionRef, + reportNode: Node, operands: ExpressionRef[] | null = null, - immediatelyDropped: bool = false + immediatelyDropped: bool = false, ): ExpressionRef { var module = this.module; var numOperands = operands ? operands.length : 0; @@ -8000,7 +8005,7 @@ export class Compiler extends DiagnosticEmitter { } let parameterTypes = signature.parameterTypes; for (let i = numArguments; i < maxArguments; ++i) { - operands.push(this.makeZero(parameterTypes[i])); + operands.push(this.makeZero(parameterTypes[i], reportNode)); } } @@ -8271,7 +8276,13 @@ export class Compiler extends DiagnosticEmitter { this.currentType = signatureReference.type.asNullable(); return module.i32(0); } - return module.ref_null(); + // TODO: return null ref for externref or funcref + this.error( + DiagnosticCode.Not_implemented_0, + expression.range, + "ref.null" + ); + return module.unreachable(); } this.currentType = options.usizeType; this.warning( @@ -8464,7 +8475,7 @@ export class Compiler extends DiagnosticEmitter { ); if (!functionInstance || !this.compileFunction(functionInstance)) return module.unreachable(); if (contextualType.is(TypeFlags.HOST | TypeFlags.REFERENCE)) { - this.currentType = Type.anyref; + this.currentType = Type.externref; return module.ref_func(functionInstance.internalName); } let index = this.ensureFunctionTableEntry(functionInstance); @@ -8541,7 +8552,7 @@ export class Compiler extends DiagnosticEmitter { ? BinaryOp.NeI64 : BinaryOp.NeI32, expr, - this.makeZero(actualType) + this.makeZero(actualType, expression.expression) ); } @@ -8648,7 +8659,7 @@ export class Compiler extends DiagnosticEmitter { ? BinaryOp.NeI64 : BinaryOp.NeI32, expr, - this.makeZero(actualType) + this.makeZero(actualType, expression.expression) ); // is just `true` @@ -8787,9 +8798,9 @@ export class Compiler extends DiagnosticEmitter { var isStatic = true; var nativeElementType = elementType.toNativeType(); for (let i = 0; i < length; ++i) { - let expression = expressions[i]; - if (expression) { - let expr = this.compileExpression(expression, elementType, + let elementExpression = expressions[i]; + if (elementExpression) { + let expr = this.compileExpression(elementExpression, elementType, Constraints.CONV_IMPLICIT | Constraints.WILL_RETAIN ); let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects); @@ -8800,7 +8811,7 @@ export class Compiler extends DiagnosticEmitter { } values[i] = expr; } else { - values[i] = this.makeZero(elementType); + values[i] = this.makeZero(elementType, expression); } } @@ -8957,9 +8968,9 @@ export class Compiler extends DiagnosticEmitter { var nativeElementType = elementType.toNativeType(); var isStatic = true; for (let i = 0; i < length; ++i) { - let expression = expressions[i]; - if (expression) { - let expr = this.compileExpression(expression, elementType, + let elementExpression = expressions[i]; + if (elementExpression) { + let expr = this.compileExpression(elementExpression, elementType, Constraints.CONV_IMPLICIT | Constraints.WILL_RETAIN ); let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects); @@ -8970,7 +8981,7 @@ export class Compiler extends DiagnosticEmitter { } values[i] = expr; } else { - values[i] = this.makeZero(elementType); + values[i] = this.makeZero(elementType, expression); } } @@ -9242,7 +9253,7 @@ export class Compiler extends DiagnosticEmitter { module.store( // TODO: handle setters as well fieldType.byteSize, module.local_get(tempLocal.index, nativeClassType), - this.makeZero(fieldType), + this.makeZero(fieldType, expression), fieldType.toNativeType(), fieldInstance.memoryOffset ) @@ -9531,7 +9542,7 @@ export class Compiler extends DiagnosticEmitter { ctorInstance, argumentExpressions, reportNode, - this.makeZero(this.options.usizeType), + this.makeZero(this.options.usizeType, reportNode), constraints ); if (getExpressionType(expr) != NativeType.None) { // possibly WILL_DROP @@ -9697,7 +9708,8 @@ export class Compiler extends DiagnosticEmitter { var condExpr = this.makeIsTrueish( this.compileExpression(expression.condition, Type.bool), - this.currentType + this.currentType, + expression.condition ); // Try to eliminate unnecesssary branches if the condition is constant // FIXME: skips common denominator, inconsistently picking branch type @@ -10124,7 +10136,7 @@ export class Compiler extends DiagnosticEmitter { this.options.isWasm64 ? BinaryOp.SubI64 : BinaryOp.SubI32, - this.makeZero(this.currentType), + this.makeZero(this.currentType, expression.operand), expr ); break; @@ -10311,7 +10323,7 @@ export class Compiler extends DiagnosticEmitter { // allow '!' for references even without an overload } - expr = module.unary(UnaryOp.EqzI32, this.makeIsTrueish(expr, this.currentType)); + expr = module.unary(UnaryOp.EqzI32, this.makeIsTrueish(expr, this.currentType, expression.operand)); this.currentType = Type.bool; break; } @@ -10469,7 +10481,7 @@ export class Compiler extends DiagnosticEmitter { typeString = "object"; } } else { - typeString = "anyref"; // TODO? + typeString = "externref"; // TODO? } } } else if (type == Type.bool) { @@ -10580,7 +10592,7 @@ export class Compiler extends DiagnosticEmitter { checkTypeSupported(type: Type, reportNode: Node): bool { switch (type.kind) { case TypeKind.V128: return this.checkFeatureEnabled(Feature.SIMD, reportNode); - case TypeKind.ANYREF: return this.checkFeatureEnabled(Feature.REFERENCE_TYPES, reportNode); + case TypeKind.EXTERNREF: return this.checkFeatureEnabled(Feature.REFERENCE_TYPES, reportNode); } if (type.is(TypeFlags.REFERENCE)) { let classReference = type.classReference; @@ -10635,7 +10647,7 @@ export class Compiler extends DiagnosticEmitter { // === Specialized code generation ============================================================== /** Makes a constant zero of the specified type. */ - makeZero(type: Type): ExpressionRef { + makeZero(type: Type, reportNode: Node): ExpressionRef { var module = this.module; switch (type.kind) { default: assert(false); @@ -10653,7 +10665,14 @@ export class Compiler extends DiagnosticEmitter { case TypeKind.F32: return module.f32(0); case TypeKind.F64: return module.f64(0); case TypeKind.V128: return module.v128(v128_zero); - case TypeKind.ANYREF: return module.ref_null(); + case TypeKind.EXTERNREF: + // TODO: return null ref for both externref as well as funcref + this.error( + DiagnosticCode.Not_implemented_0, + reportNode.range, + "ref.null" + ); + return module.unreachable(); } } @@ -10699,7 +10718,7 @@ export class Compiler extends DiagnosticEmitter { } /** Creates a comparison whether an expression is 'true' in a broader sense. */ - makeIsTrueish(expr: ExpressionRef, type: Type): ExpressionRef { + makeIsTrueish(expr: ExpressionRef, type: Type, reportNode: Node): ExpressionRef { var module = this.module; switch (type.kind) { case TypeKind.I8: @@ -10752,10 +10771,16 @@ export class Compiler extends DiagnosticEmitter { flow.freeTempLocal(temp); return ret; } - case TypeKind.ANYREF: { + case TypeKind.EXTERNREF: { // TODO: non-null object might still be considered falseish // i.e. a ref to Boolean(false), Number(0), String("") etc. - return module.unary(UnaryOp.EqzI32, module.ref_is_null(expr)); + // TODO: return module.unary(UnaryOp.EqzI32, module.ref_is_null(expr)); + this.error( + DiagnosticCode.Not_implemented_0, + reportNode.range, + "ref.is_null" + ); + return module.unreachable(); } default: { assert(false); @@ -10846,7 +10871,7 @@ export class Compiler extends DiagnosticEmitter { // otherwise initialize with zero } else { - initExpr = this.makeZero(fieldType); + initExpr = this.makeZero(fieldType, fieldPrototype.declaration); } stmts.push( @@ -10881,7 +10906,7 @@ export class Compiler extends DiagnosticEmitter { // essentially ignoring the message GC-wise. Doesn't matter anyway on a crash. messageArg = this.compileExpression(message, stringInstance.type, Constraints.CONV_IMPLICIT | Constraints.WILL_RETAIN); } else { - messageArg = this.makeZero(stringInstance.type); + messageArg = this.makeZero(stringInstance.type, codeLocation); } return this.makeStaticAbort(messageArg, codeLocation); diff --git a/src/flow.ts b/src/flow.ts index 7ca0890a31..aa29b46e38 100644 --- a/src/flow.ts +++ b/src/flow.ts @@ -311,7 +311,7 @@ export class Flow { case NativeType.F32: { temps = parentFunction.tempF32s; break; } case NativeType.F64: { temps = parentFunction.tempF64s; break; } case NativeType.V128: { temps = parentFunction.tempV128s; break; } - case NativeType.Anyref: { temps = parentFunction.tempAnyrefs; break; } + case NativeType.Externref: { temps = parentFunction.tempExternrefs; break; } case NativeType.Exnref: { temps = parentFunction.tempExnrefs; break; } default: throw new Error("concrete type expected"); } @@ -395,10 +395,10 @@ export class Flow { else parentFunction.tempV128s = temps = []; break; } - case NativeType.Anyref: { - let tempAnyrefs = parentFunction.tempAnyrefs; - if (tempAnyrefs) temps = tempAnyrefs; - else parentFunction.tempAnyrefs = temps = []; + case NativeType.Externref: { + let tempExternrefs = parentFunction.tempExternrefs; + if (tempExternrefs) temps = tempExternrefs; + else parentFunction.tempExternrefs = temps = []; break; } case NativeType.Exnref: { diff --git a/src/glue/binaryen.d.ts b/src/glue/binaryen.d.ts index 7e04e7b7f9..2c95e61339 100644 --- a/src/glue/binaryen.d.ts +++ b/src/glue/binaryen.d.ts @@ -1,6 +1,6 @@ /** * @fileoverview Portable definitions for Binaryen's C-API. - * + * * tsc uses the .js file next to it, while asc makes it a Wasm import. * * See: https://github.com/WebAssembly/binaryen/blob/master/src/binaryen-c.h @@ -34,7 +34,7 @@ export declare function _BinaryenTypeFloat32(): BinaryenType; export declare function _BinaryenTypeFloat64(): BinaryenType; export declare function _BinaryenTypeVec128(): BinaryenType; export declare function _BinaryenTypeFuncref(): BinaryenType; -export declare function _BinaryenTypeAnyref(): BinaryenType; +export declare function _BinaryenTypeExternref(): BinaryenType; export declare function _BinaryenTypeNullref(): BinaryenType; export declare function _BinaryenTypeExnref(): BinaryenType; export declare function _BinaryenTypeUnreachable(): BinaryenType; diff --git a/src/module.ts b/src/module.ts index 2408137baa..ebfbd43fe1 100644 --- a/src/module.ts +++ b/src/module.ts @@ -38,7 +38,7 @@ export namespace NativeType { export const F64: NativeType = 5 /* _BinaryenTypeFloat64 */; export const V128: NativeType = 6 /* _BinaryenTypeVec128 */; export const Funcref: NativeType = 7 /* _BinaryenTypeFuncref */; - export const Anyref: NativeType = 8 /* _BinaryenTypeAnyref */; + export const Externref: NativeType = 8 /* _BinaryenTypeExternref */; export const Nullref: NativeType = 9 /* _BinaryenTypeNullref */; export const Exnref: NativeType = 10 /* _BinaryenTypeExnref */; export const Auto: NativeType = -1 /* _BinaryenTypeAuto */; @@ -1759,8 +1759,8 @@ export class Module { // TODO return 0; } - // Not possible to clone an anyref as it is opaque - case NativeType.Anyref: { + // Not possible to clone an externref as it is opaque + case NativeType.Externref: { return 0; } default: { diff --git a/src/program.ts b/src/program.ts index 44b08ee489..5af1b39ff1 100644 --- a/src/program.ts +++ b/src/program.ts @@ -905,7 +905,7 @@ export class Program extends DiagnosticEmitter { // compiler needs to check this condition whenever such a value is created // respectively stored or loaded. this.registerNativeType(CommonNames.v128, Type.v128); - this.registerNativeType(CommonNames.anyref, Type.anyref); + this.registerNativeType(CommonNames.externref, Type.externref); // register compiler hints this.registerConstantInteger(CommonNames.ASC_TARGET, Type.i32, @@ -1136,7 +1136,7 @@ export class Program extends DiagnosticEmitter { this.registerWrapperClass(Type.f32, CommonNames.F32); this.registerWrapperClass(Type.f64, CommonNames.F64); if (options.hasFeature(Feature.SIMD)) this.registerWrapperClass(Type.v128, CommonNames.V128); - if (options.hasFeature(Feature.REFERENCE_TYPES)) this.registerWrapperClass(Type.anyref, CommonNames.Anyref); + if (options.hasFeature(Feature.REFERENCE_TYPES)) this.registerWrapperClass(Type.externref, CommonNames.Externref); // resolve prototypes of extended classes or interfaces var resolver = this.resolver; @@ -3565,7 +3565,7 @@ export class Function extends TypedElement { tempF32s: Local[] | null = null; tempF64s: Local[] | null = null; tempV128s: Local[] | null = null; - tempAnyrefs: Local[] | null = null; + tempExternrefs: Local[] | null = null; tempExnrefs: Local[] | null = null; // used by flows to keep track of break labels diff --git a/src/resolver.ts b/src/resolver.ts index 9ab9b80d9c..330ba50d08 100644 --- a/src/resolver.ts +++ b/src/resolver.ts @@ -1222,7 +1222,7 @@ export class Resolver extends DiagnosticEmitter { let classReference = ctxType.classReference; return ctxType.is(TypeFlags.REFERENCE) && classReference !== null ? classReference.type.asNullable() - : this.program.options.usizeType; // TODO: anyref context? + : this.program.options.usizeType; // TODO: externref context? } } var element = this.lookupIdentifierExpression(node, ctxFlow, ctxElement, reportMode); @@ -2301,7 +2301,7 @@ export class Resolver extends DiagnosticEmitter { if ( numNullLiterals > 0 && elementType.is(TypeFlags.REFERENCE) && - !elementType.is(TypeFlags.HOST) // TODO: anyref isn't nullable as-is + !elementType.is(TypeFlags.HOST) // TODO: externref isn't nullable as-is ) { elementType = elementType.asNullable(); } diff --git a/src/types.ts b/src/types.ts index fad02f6c24..aedd5bcf4b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -61,7 +61,7 @@ export const enum TypeKind { // references /** Any host reference. */ - ANYREF, + EXTERNREF, // other @@ -267,7 +267,7 @@ export class Type { if (targetFunction = target.signatureReference) { return currentFunction.isAssignableTo(targetFunction); } - } else if (this.kind == TypeKind.ANYREF && target.kind == TypeKind.ANYREF) { + } else if (this.kind == TypeKind.EXTERNREF && target.kind == TypeKind.EXTERNREF) { return true; } } @@ -344,8 +344,8 @@ export class Type { : signatureReference.toString(); } // TODO: Reflect.apply(value, "toString", []) ? - assert(this.kind == TypeKind.ANYREF); - return "anyref"; + assert(this.kind == TypeKind.EXTERNREF); + return "externref"; } switch (this.kind) { case TypeKind.I8: return "i8"; @@ -362,7 +362,7 @@ export class Type { case TypeKind.F32: return "f32"; case TypeKind.F64: return "f64"; case TypeKind.V128: return "v128"; - case TypeKind.ANYREF: return "anyref"; + case TypeKind.EXTERNREF: return "externref"; default: assert(false); case TypeKind.VOID: return "void"; } @@ -388,7 +388,7 @@ export class Type { case TypeKind.F32: return NativeType.F32; case TypeKind.F64: return NativeType.F64; case TypeKind.V128: return NativeType.V128; - case TypeKind.ANYREF: return NativeType.Anyref; + case TypeKind.EXTERNREF: return NativeType.Externref; case TypeKind.VOID: return NativeType.None; } } @@ -521,7 +521,7 @@ export class Type { ); /** Any host reference. */ - static readonly anyref: Type = new Type(TypeKind.ANYREF, + static readonly externref: Type = new Type(TypeKind.EXTERNREF, TypeFlags.HOST | TypeFlags.REFERENCE, 0 ); diff --git a/std/assembly/bindings/Reflect.ts b/std/assembly/bindings/Reflect.ts index ed08e7cd2b..411833bf23 100644 --- a/std/assembly/bindings/Reflect.ts +++ b/std/assembly/bindings/Reflect.ts @@ -1,4 +1,4 @@ -export declare function get(target: anyref, propertyKey: anyref/* , receiver: anyref */): anyref; -export declare function has(target: anyref, propertyKey: anyref): bool; -export declare function set(target: anyref, propertyKey: anyref, value: anyref/* , receiver: anyref */): anyref; -export declare function apply(target: anyref, thisArgument: anyref, argumentsList: anyref): anyref; +export declare function get(target: externref, propertyKey: externref/* , receiver: externref */): externref; +export declare function has(target: externref, propertyKey: externref): bool; +export declare function set(target: externref, propertyKey: externref, value: externref/* , receiver: externref */): externref; +export declare function apply(target: externref, thisArgument: externref, argumentsList: externref): externref; diff --git a/std/assembly/bindings/console.ts b/std/assembly/bindings/console.ts index c9fe14275b..8dea45426d 100644 --- a/std/assembly/bindings/console.ts +++ b/std/assembly/bindings/console.ts @@ -1,10 +1,10 @@ -export declare function assert(value: anyref): void; +export declare function assert(value: externref): void; export declare function clear(): void; -export declare function error(value: anyref): void; -export declare function info(value: anyref): void; -export declare function log(value: anyref): void; -export declare function time(label: anyref): anyref; -export declare function timeEnd(label: anyref): void; -export declare function timeLog(label: anyref): void; +export declare function error(value: externref): void; +export declare function info(value: externref): void; +export declare function log(value: externref): void; +export declare function time(label: externref): externref; +export declare function timeEnd(label: externref): void; +export declare function timeLog(label: externref): void; export declare function trace(): void; -export declare function warn(value: anyref): void; +export declare function warn(value: externref): void; diff --git a/std/assembly/index.d.ts b/std/assembly/index.d.ts index 2253ea2ec0..03af3ac0b7 100644 --- a/std/assembly/index.d.ts +++ b/std/assembly/index.d.ts @@ -36,7 +36,7 @@ declare type f64 = number; /** A 128-bit vector. */ declare type v128 = object; /** A host reference. */ -declare type anyref = object; +declare type externref = object; // Compiler hints diff --git a/std/assembly/reference.ts b/std/assembly/reference.ts index b344f1addf..b45db14403 100644 --- a/std/assembly/reference.ts +++ b/std/assembly/reference.ts @@ -1,4 +1,4 @@ /** Host reference abstraction. */ @final @unmanaged -export abstract class Anyref { +export abstract class Externref { } diff --git a/tests/compiler/features/reference-types.optimized.wat b/tests/compiler/features/reference-types.optimized.wat index 6917b9154d..8f9e7c11e3 100644 --- a/tests/compiler/features/reference-types.optimized.wat +++ b/tests/compiler/features/reference-types.optimized.wat @@ -1,25 +1,24 @@ (module - (type $anyref_=>_anyref (func (param anyref) (result anyref))) + (type $externref_=>_externref (func (param externref) (result externref))) (type $none_=>_none (func)) (type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32))) - (type $anyref_=>_none (func (param anyref))) - (type $anyref_anyref_=>_i32 (func (param anyref anyref) (result i32))) - (type $anyref_anyref_=>_anyref (func (param anyref anyref) (result anyref))) - (import "reference-types" "someObject" (global $features/reference-types/someObject anyref)) - (import "reference-types" "someKey" (global $features/reference-types/someKey anyref)) - (import "Reflect" "has" (func $~lib/bindings/Reflect/has (param anyref anyref) (result i32))) + (type $externref_=>_none (func (param externref))) + (type $externref_externref_=>_i32 (func (param externref externref) (result i32))) + (type $externref_externref_=>_externref (func (param externref externref) (result externref))) + (import "reference-types" "someObject" (global $features/reference-types/someObject externref)) + (import "reference-types" "someKey" (global $features/reference-types/someKey externref)) + (import "Reflect" "has" (func $~lib/bindings/Reflect/has (param externref externref) (result i32))) (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) - (import "console" "log" (func $~lib/bindings/console/log (param anyref))) - (import "Reflect" "get" (func $~lib/bindings/Reflect/get (param anyref anyref) (result anyref))) - (import "reference-types" "external" (func $features/reference-types/external (param anyref) (result anyref))) + (import "console" "log" (func $~lib/bindings/console/log (param externref))) + (import "Reflect" "get" (func $~lib/bindings/Reflect/get (param externref externref) (result externref))) + (import "reference-types" "external" (func $features/reference-types/external (param externref) (result externref))) (memory $0 1) (data (i32.const 1024) "6\00\00\00\01\00\00\00\01\00\00\006\00\00\00f\00e\00a\00t\00u\00r\00e\00s\00/\00r\00e\00f\00e\00r\00e\00n\00c\00e\00-\00t\00y\00p\00e\00s\00.\00t\00s") - (global $features/reference-types/nullGlobal (mut anyref) (ref.null)) (export "memory" (memory $0)) (export "external" (func $features/reference-types/external)) (export "internal" (func $features/reference-types/internal)) (start $~start) - (func $features/reference-types/internal (param $0 anyref) (result anyref) + (func $features/reference-types/internal (param $0 externref) (result externref) local.get $0 call $features/reference-types/external call $features/reference-types/external @@ -46,18 +45,4 @@ global.get $features/reference-types/someKey call $~lib/bindings/Reflect/get call $~lib/bindings/console/log - global.get $features/reference-types/nullGlobal - ref.is_null - i32.eqz - if - i32.const 0 - i32.const 1040 - i32.const 32 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - ref.null - global.set $features/reference-types/nullGlobal - ) ) diff --git a/tests/compiler/features/reference-types.ts b/tests/compiler/features/reference-types.ts index 3a2cf0e7e0..fa2fa17d89 100644 --- a/tests/compiler/features/reference-types.ts +++ b/tests/compiler/features/reference-types.ts @@ -1,24 +1,24 @@ -// can use anyref as a parameter or return type +// can use externref as a parameter or return type -export declare function external(a: anyref): anyref; +export declare function external(a: externref): externref; -export function internal(a: anyref): anyref { +export function internal(a: externref): externref { const b = external(a); let c = external(b); var d = external(c); return d; } -// can use reflection to work with anyref values +// can use reflection to work with externref values import * as Reflect from "bindings/Reflect"; -declare const someObject: anyref; -declare const someKey: anyref; +declare const someObject: externref; +declare const someKey: externref; assert(Reflect.has(someObject, someKey)); -// can call JS bindings with anyref values +// can call JS bindings with externref values import * as console from "bindings/console"; @@ -26,27 +26,27 @@ console.log(someObject); console.log(someKey); console.log(Reflect.get(someObject, someKey)); -// can represent and recognize 'null' - -var nullGlobal: anyref; +// TODO: can represent and recognize 'null' for both externref and funcref +/* var nullGlobal: externref; assert(!nullGlobal); nullGlobal = null; assert(!nullGlobal); -var nullGlobalInit: anyref = null; +var nullGlobalInit: externref = null; assert(!nullGlobalInit); { - let nullLocal: anyref; + let nullLocal: externref; assert(!nullLocal); nullLocal = null; assert(!nullLocal); - let nullLocalInit: anyref = null; + let nullLocalInit: externref = null; assert(!nullLocalInit); } -// can represent function references +// funcref can represent function references function someFunc(): void {} -var funcGlobal: anyref = someFunc; +var funcGlobal: externref = someFunc; { - let funcLocal: anyref = someFunc; + let funcLocal: externref = someFunc; } +*/ \ No newline at end of file diff --git a/tests/compiler/features/reference-types.untouched.wat b/tests/compiler/features/reference-types.untouched.wat index 34afe5fdff..0f9a373a7c 100644 --- a/tests/compiler/features/reference-types.untouched.wat +++ b/tests/compiler/features/reference-types.untouched.wat @@ -1,33 +1,25 @@ (module (type $none_=>_none (func)) - (type $anyref_=>_anyref (func (param anyref) (result anyref))) + (type $externref_=>_externref (func (param externref) (result externref))) (type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32))) - (type $anyref_=>_none (func (param anyref))) - (type $anyref_anyref_=>_i32 (func (param anyref anyref) (result i32))) - (type $anyref_anyref_=>_anyref (func (param anyref anyref) (result anyref))) - (import "reference-types" "someObject" (global $features/reference-types/someObject anyref)) - (import "reference-types" "someKey" (global $features/reference-types/someKey anyref)) - (import "Reflect" "has" (func $~lib/bindings/Reflect/has (param anyref anyref) (result i32))) + (type $externref_=>_none (func (param externref))) + (type $externref_externref_=>_i32 (func (param externref externref) (result i32))) + (type $externref_externref_=>_externref (func (param externref externref) (result externref))) + (import "reference-types" "someObject" (global $features/reference-types/someObject externref)) + (import "reference-types" "someKey" (global $features/reference-types/someKey externref)) + (import "Reflect" "has" (func $~lib/bindings/Reflect/has (param externref externref) (result i32))) (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) - (import "console" "log" (func $~lib/bindings/console/log (param anyref))) - (import "Reflect" "get" (func $~lib/bindings/Reflect/get (param anyref anyref) (result anyref))) - (import "reference-types" "external" (func $features/reference-types/external (param anyref) (result anyref))) + (import "console" "log" (func $~lib/bindings/console/log (param externref))) + (import "Reflect" "get" (func $~lib/bindings/Reflect/get (param externref externref) (result externref))) + (import "reference-types" "external" (func $features/reference-types/external (param externref) (result externref))) (memory $0 1) (data (i32.const 16) "6\00\00\00\01\00\00\00\01\00\00\006\00\00\00f\00e\00a\00t\00u\00r\00e\00s\00/\00r\00e\00f\00e\00r\00e\00n\00c\00e\00-\00t\00y\00p\00e\00s\00.\00t\00s\00") (table $0 1 funcref) - (global $features/reference-types/nullGlobal (mut anyref) (ref.null)) - (global $features/reference-types/nullGlobalInit (mut anyref) (ref.null)) - (global $features/reference-types/funcGlobal (mut anyref) (ref.null)) (export "memory" (memory $0)) (export "external" (func $features/reference-types/external)) (export "internal" (func $features/reference-types/internal)) (start $~start) - (func $features/reference-types/someFunc - nop - ) (func $start:features/reference-types - (local $0 anyref) - (local $1 anyref) global.get $features/reference-types/someObject global.get $features/reference-types/someKey call $~lib/bindings/Reflect/has @@ -50,101 +42,11 @@ global.get $features/reference-types/someKey call $~lib/bindings/Reflect/get call $~lib/bindings/console/log - global.get $features/reference-types/nullGlobal - ref.is_null - i32.eqz - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 32 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - ref.null - global.set $features/reference-types/nullGlobal - global.get $features/reference-types/nullGlobal - ref.is_null - i32.eqz - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 34 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - ref.null - global.set $features/reference-types/nullGlobalInit - global.get $features/reference-types/nullGlobalInit - ref.is_null - i32.eqz - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 36 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - local.get $0 - ref.is_null - i32.eqz - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 39 - i32.const 3 - call $~lib/builtins/abort - unreachable - end - ref.null - local.set $0 - local.get $0 - ref.is_null - i32.eqz - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 41 - i32.const 3 - call $~lib/builtins/abort - unreachable - end - ref.null - local.set $1 - local.get $1 - ref.is_null - i32.eqz - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 43 - i32.const 3 - call $~lib/builtins/abort - unreachable - end - ref.func $features/reference-types/someFunc - global.set $features/reference-types/funcGlobal - ref.func $features/reference-types/someFunc - local.set $1 ) - (func $features/reference-types/internal (param $0 anyref) (result anyref) - (local $1 anyref) - (local $2 anyref) - (local $3 anyref) + (func $features/reference-types/internal (param $0 externref) (result externref) + (local $1 externref) + (local $2 externref) + (local $3 externref) local.get $0 call $features/reference-types/external local.set $1 diff --git a/tests/features.json b/tests/features.json index fc4884d8c5..aa20113fe6 100644 --- a/tests/features.json +++ b/tests/features.json @@ -22,7 +22,7 @@ "--enable reference-types" ], "v8_flags": [ - "--experimental-wasm-anyref" + "--experimental-wasm-reftypes" ] }, "bigint-integration": {