Skip to content

Commit

Permalink
fix: compiler error when comparing any with number (#121)
Browse files Browse the repository at this point in the history
Signed-off-by: ganjing <[email protected]>
  • Loading branch information
Shanks0224 authored Dec 21, 2023
1 parent d497214 commit 51980ac
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 38 deletions.
103 changes: 80 additions & 23 deletions src/backend/binaryen/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1928,6 +1928,7 @@ export namespace FunctionalFuncs {
export function operatorAnyStatic(
module: binaryen.Module,
leftValueRef: binaryen.ExpressionRef,
leftValueType: ValueType,
rightValueRef: binaryen.ExpressionRef,
rightValueType: ValueType,
opKind: ts.SyntaxKind,
Expand All @@ -1942,30 +1943,60 @@ export namespace FunctionalFuncs {
case ts.SyntaxKind.EqualsEqualsEqualsToken:
case ts.SyntaxKind.ExclamationEqualsToken:
case ts.SyntaxKind.ExclamationEqualsEqualsToken: {
if (rightValueType.kind === ValueTypeKind.NULL) {
if (
leftValueType.kind === ValueTypeKind.NULL ||
rightValueType.kind === ValueTypeKind.NULL
) {
const anyValueRef =
leftValueType.kind === ValueTypeKind.NULL
? rightValueRef
: leftValueRef;
res = module.call(
dyntype.dyntype_is_null,
[dynCtx, leftValueRef],
[dynCtx, anyValueRef],
binaryen.i32,
);
// TODO: ref.null need table.get support in native API
} else if (rightValueType.kind === ValueTypeKind.UNDEFINED) {
res = isDynUndefined(module, leftValueRef);
} else if (rightValueType.kind === ValueTypeKind.NUMBER) {
} else if (
leftValueType.kind === ValueTypeKind.UNDEFINED ||
rightValueType.kind === ValueTypeKind.UNDEFINED
) {
const anyValueRef =
leftValueType.kind === ValueTypeKind.UNDEFINED
? rightValueRef
: leftValueRef;
res = isDynUndefined(module, anyValueRef);
} else if (
leftValueType.kind === ValueTypeKind.NUMBER ||
rightValueType.kind === ValueTypeKind.NUMBER
) {
const isLeftStatic =
leftValueType.kind === ValueTypeKind.NUMBER
? true
: false;
res = operateF64F64ToDyn(
module,
leftValueRef,
rightValueRef,
opKind,
true,
isLeftStatic,
!isLeftStatic,
);
} else if (rightValueType.kind === ValueTypeKind.STRING) {
} else if (
leftValueType.kind === ValueTypeKind.STRING ||
rightValueType.kind === ValueTypeKind.STRING
) {
const isLeftStatic =
leftValueType.kind === ValueTypeKind.STRING
? true
: false;
res = operateStrStrToDyn(
module,
leftValueRef,
rightValueRef,
opKind,
true,
isLeftStatic,
!isLeftStatic,
);
} else {
throw new UnimplementError(
Expand All @@ -1981,21 +2012,41 @@ export namespace FunctionalFuncs {
break;
}
default:
if (rightValueType.kind === ValueTypeKind.NUMBER) {
if (
leftValueType.kind === ValueTypeKind.NUMBER ||
rightValueType.kind === ValueTypeKind.NUMBER
) {
const isLeftStatic =
leftValueType.kind === ValueTypeKind.NUMBER
? true
: false;
res = operateF64F64ToDyn(
module,
leftValueRef,
rightValueRef,
opKind,
true,
isLeftStatic,
!isLeftStatic,
);
} else if (rightValueType.kind === ValueTypeKind.STRING) {
} else if (
leftValueType.kind === ValueTypeKind.STRING ||
rightValueType.kind === ValueTypeKind.STRING
) {
if (!UtilFuncs.isSupportedStringOP(opKind))
throw new UnimplementError(
`operator doesn't support on any string operation, ${opKind}`,
);
const isLeftStatic =
leftValueType.kind === ValueTypeKind.STRING
? true
: false;
res = operateStrStrToDyn(
module,
leftValueRef,
rightValueRef,
opKind,
true,
isLeftStatic,
!isLeftStatic,
);
} else {
throw new UnimplementError(
Expand Down Expand Up @@ -2068,13 +2119,16 @@ export namespace FunctionalFuncs {
leftValueRef: binaryen.ExpressionRef,
rightValueRef: binaryen.ExpressionRef,
opKind: ts.SyntaxKind,
isLeftStatic = false,
isRightStatic = false,
) {
const tmpLeftNumberRef = module.call(
dyntype.dyntype_to_number,
[getDynContextRef(module), leftValueRef],
binaryen.f64,
);
const tmpLeftNumberRef = isLeftStatic
? leftValueRef
: module.call(
dyntype.dyntype_to_number,
[getDynContextRef(module), leftValueRef],
binaryen.f64,
);
const tmpRightNumberRef = isRightStatic
? rightValueRef
: module.call(
Expand All @@ -2088,21 +2142,24 @@ export namespace FunctionalFuncs {
tmpRightNumberRef,
opKind,
);
return generateDynNumber(module, operateNumber);
if (binaryen.getExpressionType(operateNumber) === binaryen.i32) {
return operateNumber;
} else {
return generateDynNumber(module, operateNumber);
}
}

export function operateStrStrToDyn(
module: binaryen.Module,
leftValueRef: binaryen.ExpressionRef,
rightValueRef: binaryen.ExpressionRef,
opKind: ts.SyntaxKind,
isLeftStatic = false,
isRightStatic = false,
) {
const tmpLeftStrRef = unboxAnyToBase(
module,
leftValueRef,
ValueTypeKind.STRING,
);
const tmpLeftStrRef = isLeftStatic
? leftValueRef
: unboxAnyToBase(module, leftValueRef, ValueTypeKind.STRING);
const tmpRightStrRef = isRightStatic
? rightValueRef
: unboxAnyToBase(module, rightValueRef, ValueTypeKind.STRING);
Expand Down
20 changes: 5 additions & 15 deletions src/backend/binaryen/wasm_expr_gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -757,30 +757,20 @@ export class WASMExpressionGen {
}
/** static any*/
if (
FunctionalFuncs.treatAsAny(leftValueType.kind) &&
!FunctionalFuncs.treatAsAny(rightValueType.kind)
(FunctionalFuncs.treatAsAny(leftValueType.kind) &&
!FunctionalFuncs.treatAsAny(rightValueType.kind)) ||
(!FunctionalFuncs.treatAsAny(leftValueType.kind) &&
FunctionalFuncs.treatAsAny(rightValueType.kind))
) {
return FunctionalFuncs.operatorAnyStatic(
this.module,
leftValueRef,
leftValueType,
rightValueRef,
rightValueType,
opKind,
);
}
/** static any*/
if (
!FunctionalFuncs.treatAsAny(leftValueType.kind) &&
FunctionalFuncs.treatAsAny(rightValueType.kind)
) {
return FunctionalFuncs.operatorAnyStatic(
this.module,
rightValueRef,
leftValueRef,
leftValueType,
opKind,
);
}
// iff array, class or interface
if (
(leftValueType.kind === ValueTypeKind.ARRAY &&
Expand Down
15 changes: 15 additions & 0 deletions tests/samples/any_binary_operation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,18 @@ export function addAnyInBinaryExpr() {
str2 = str1 + 'a' + str3;
console.log(str2);
}

export function anyCmpNum() {
let a: any = 10;
if (a > 9) {
console.log('Greater than 9');
} else {
console.log('Less than 9');
}

if(11 > a) {
console.log('Less than 11');
} else {
console.log('Greater than 11');
}
}
5 changes: 5 additions & 0 deletions tools/validate/wamr/validation.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@
"name": "addAnyInBinaryExpr",
"args": [],
"result": "str11astr33"
},
{
"name": "anyCmpNum",
"args": [],
"result": "Greater than 9\nLess than 11"
}
]
},
Expand Down

0 comments on commit 51980ac

Please sign in to comment.