Add isFunction and isNullable builtins (#504)

This commit is contained in:
Daniel Wirtz 2019-02-22 01:11:05 +01:00 committed by GitHub
parent 3b5b96f496
commit f318d68383
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 321 additions and 208 deletions

View File

@ -76,6 +76,8 @@ export namespace BuiltinSymbols {
export const isReference = "~lib/builtins/isReference";
export const isString = "~lib/builtins/isString";
export const isArray = "~lib/builtins/isArray";
export const isFunction = "~lib/builtins/isFunction";
export const isNullable = "~lib/builtins/isNullable";
export const isDefined = "~lib/builtins/isDefined";
export const isConstant = "~lib/builtins/isConstant";
export const isManaged = "~lib/builtins/isManaged";
@ -348,6 +350,18 @@ export function compileCall(
: 0
);
}
case BuiltinSymbols.isFunction: { // isFunction<T!> / isFunction<T?>(value: T) -> bool
let type = evaluateConstantType(compiler, typeArguments, operands, reportNode);
compiler.currentType = Type.bool;
if (!type) return module.createUnreachable();
return module.createI32(type.signatureReference ? 1 : 0);
}
case BuiltinSymbols.isNullable: { // isNullable<T!> / isNullable<T?>(value: T) -> bool
let type = evaluateConstantType(compiler, typeArguments, operands, reportNode);
compiler.currentType = Type.bool;
if (!type) return module.createUnreachable();
return module.createI32(type.is(TypeFlags.NULLABLE) ? 1 : 0);
}
case BuiltinSymbols.isDefined: { // isDefined(expression) -> bool
compiler.currentType = Type.bool;
if (typeArguments) {

View File

@ -9,6 +9,8 @@
@builtin export declare function isReference<T>(value?: T): bool;
@builtin export declare function isString<T>(value?: T): bool;
@builtin export declare function isArray<T>(value?: T): bool;
@builtin export declare function isFunction<T>(value?: T): bool;
@builtin export declare function isNullable<T>(value?: T): bool;
@builtin export declare function isDefined(expression: void): bool;
@builtin export declare function isConstant(expression: void): bool;
@builtin export declare function isManaged<T>(value?: T): bool;

View File

@ -128,6 +128,10 @@ declare function isReference<T>(value?: any): value is object | string;
declare function isString<T>(value?: any): value is string | String;
/** Tests if the specified type *or* expression can be used as an array. Compiles to a constant. */
declare function isArray<T>(value?: any): value is Array<any>;
/** Tests if the specified type *or* expression is of a function type. Compiles to a constant. */
declare function isFunction<T>(value?: any): value is Array<any>;
/** Tests if the specified type *or* expression is of a nullable reference type. Compiles to a constant. */
declare function isNullable<T>(value?: any): value is Array<any>;
/** Tests if the specified expression resolves to a defined element. Compiles to a constant. */
declare function isDefined(expression: any): bool;
/** Tests if the specified expression evaluates to a constant value. Compiles to a constant. */

View File

@ -43,7 +43,7 @@
if
i32.const 0
i32.const 8
i32.const 50
i32.const 59
i32.const 19
call $~lib/env/abort
unreachable
@ -56,7 +56,7 @@
if
i32.const 0
i32.const 8
i32.const 51
i32.const 60
i32.const 20
call $~lib/env/abort
unreachable
@ -69,7 +69,7 @@
if
i32.const 0
i32.const 8
i32.const 52
i32.const 61
i32.const 20
call $~lib/env/abort
unreachable
@ -92,7 +92,7 @@
if
i32.const 0
i32.const 8
i32.const 68
i32.const 77
i32.const 19
call $~lib/env/abort
unreachable
@ -105,7 +105,7 @@
if
i32.const 0
i32.const 8
i32.const 69
i32.const 78
i32.const 20
call $~lib/env/abort
unreachable
@ -118,7 +118,7 @@
if
i32.const 0
i32.const 8
i32.const 70
i32.const 79
i32.const 20
call $~lib/env/abort
unreachable

View File

@ -1,4 +1,5 @@
var b: bool;
class C {}
// type checks
@ -10,6 +11,10 @@ assert(isReference<string>());
assert(!isReference<usize>());
assert(isArray<i32[]>());
assert(!isArray<usize>());
assert(isFunction<() => void>());
assert(!isFunction<u32>());
assert(isNullable<C | null>());
assert(!isNullable<C>());
assert(isInteger(<i32>1));
assert(!isInteger(<f32>1));
@ -21,6 +26,10 @@ assert(isString("1"));
assert(!isString(1));
assert(isArray(changetype<i32[]>(null)));
assert(!isArray(changetype<usize>(null)));
assert(isFunction(changetype<() => void>(null)));
assert(!isFunction(changetype<u32>(null)));
assert(isNullable(changetype<C | null>(null)));
assert(!isNullable(changetype<C>(null)));
// evaluation

View File

@ -65,17 +65,6 @@
(local $5 f64)
i32.const 1
i32.eqz
if
i32.const 0
i32.const 8
i32.const 5
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 0
i32.eqz
i32.eqz
if
i32.const 0
i32.const 8
@ -84,7 +73,8 @@
call $~lib/env/abort
unreachable
end
i32.const 1
i32.const 0
i32.eqz
i32.eqz
if
i32.const 0
@ -94,8 +84,7 @@
call $~lib/env/abort
unreachable
end
i32.const 0
i32.eqz
i32.const 1
i32.eqz
if
i32.const 0
@ -105,7 +94,8 @@
call $~lib/env/abort
unreachable
end
i32.const 1
i32.const 0
i32.eqz
i32.eqz
if
i32.const 0
@ -115,8 +105,7 @@
call $~lib/env/abort
unreachable
end
i32.const 0
i32.eqz
i32.const 1
i32.eqz
if
i32.const 0
@ -126,7 +115,8 @@
call $~lib/env/abort
unreachable
end
i32.const 1
i32.const 0
i32.eqz
i32.eqz
if
i32.const 0
@ -136,13 +126,23 @@
call $~lib/env/abort
unreachable
end
i32.const 1
i32.eqz
if
i32.const 0
i32.const 8
i32.const 12
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 0
i32.eqz
i32.eqz
if
i32.const 0
i32.const 8
i32.const 12
i32.const 13
i32.const 0
call $~lib/env/abort
unreachable
@ -191,17 +191,6 @@
end
i32.const 1
i32.eqz
if
i32.const 0
i32.const 8
i32.const 18
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 0
i32.eqz
i32.eqz
if
i32.const 0
i32.const 8
@ -210,7 +199,8 @@
call $~lib/env/abort
unreachable
end
i32.const 1
i32.const 0
i32.eqz
i32.eqz
if
i32.const 0
@ -220,8 +210,7 @@
call $~lib/env/abort
unreachable
end
i32.const 0
i32.eqz
i32.const 1
i32.eqz
if
i32.const 0
@ -231,7 +220,8 @@
call $~lib/env/abort
unreachable
end
i32.const 1
i32.const 0
i32.eqz
i32.eqz
if
i32.const 0
@ -241,13 +231,44 @@
call $~lib/env/abort
unreachable
end
i32.const 1
i32.eqz
if
i32.const 0
i32.const 8
i32.const 23
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 0
i32.eqz
i32.eqz
if
i32.const 0
i32.const 8
i32.const 23
i32.const 24
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 1
i32.eqz
if
i32.const 0
i32.const 8
i32.const 25
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 0
i32.eqz
i32.eqz
if
i32.const 0
i32.const 8
i32.const 26
i32.const 0
call $~lib/env/abort
unreachable
@ -295,6 +316,69 @@
unreachable
end
i32.const 1
i32.eqz
if
i32.const 0
i32.const 8
i32.const 31
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 0
i32.eqz
i32.eqz
if
i32.const 0
i32.const 8
i32.const 32
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 1
i32.eqz
if
i32.const 0
i32.const 8
i32.const 36
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 0
i32.eqz
i32.eqz
if
i32.const 0
i32.const 8
i32.const 37
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 1
i32.eqz
if
i32.const 0
i32.const 8
i32.const 38
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 0
i32.eqz
i32.eqz
if
i32.const 0
i32.const 8
i32.const 39
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 1
i32.clz
drop
i32.const 1
@ -373,7 +457,7 @@
if
i32.const 0
i32.const 8
i32.const 50
i32.const 59
i32.const 19
call $~lib/env/abort
unreachable
@ -394,7 +478,7 @@
if
i32.const 0
i32.const 8
i32.const 51
i32.const 60
i32.const 20
call $~lib/env/abort
unreachable
@ -415,7 +499,7 @@
if
i32.const 0
i32.const 8
i32.const 52
i32.const 61
i32.const 20
call $~lib/env/abort
unreachable
@ -481,7 +565,7 @@
if
i32.const 0
i32.const 8
i32.const 68
i32.const 77
i32.const 19
call $~lib/env/abort
unreachable
@ -502,7 +586,7 @@
if
i32.const 0
i32.const 8
i32.const 69
i32.const 78
i32.const 20
call $~lib/env/abort
unreachable
@ -523,7 +607,7 @@
if
i32.const 0
i32.const 8
i32.const 70
i32.const 79
i32.const 20
call $~lib/env/abort
unreachable
@ -577,7 +661,7 @@
if
i32.const 0
i32.const 8
i32.const 87
i32.const 96
i32.const 0
call $~lib/env/abort
unreachable
@ -597,7 +681,7 @@
if
i32.const 0
i32.const 8
i32.const 88
i32.const 97
i32.const 0
call $~lib/env/abort
unreachable
@ -619,7 +703,7 @@
if
i32.const 0
i32.const 8
i32.const 89
i32.const 98
i32.const 0
call $~lib/env/abort
unreachable
@ -641,7 +725,7 @@
if
i32.const 0
i32.const 8
i32.const 90
i32.const 99
i32.const 0
call $~lib/env/abort
unreachable
@ -664,7 +748,7 @@
if
i32.const 0
i32.const 8
i32.const 91
i32.const 100
i32.const 0
call $~lib/env/abort
unreachable
@ -686,7 +770,7 @@
if
i32.const 0
i32.const 8
i32.const 92
i32.const 101
i32.const 0
call $~lib/env/abort
unreachable
@ -800,7 +884,7 @@
if
i32.const 0
i32.const 8
i32.const 123
i32.const 132
i32.const 0
call $~lib/env/abort
unreachable
@ -820,7 +904,7 @@
if
i32.const 0
i32.const 8
i32.const 124
i32.const 133
i32.const 0
call $~lib/env/abort
unreachable
@ -842,7 +926,7 @@
if
i32.const 0
i32.const 8
i32.const 125
i32.const 134
i32.const 0
call $~lib/env/abort
unreachable
@ -864,7 +948,7 @@
if
i32.const 0
i32.const 8
i32.const 126
i32.const 135
i32.const 0
call $~lib/env/abort
unreachable
@ -887,7 +971,7 @@
if
i32.const 0
i32.const 8
i32.const 127
i32.const 136
i32.const 0
call $~lib/env/abort
unreachable
@ -909,7 +993,7 @@
if
i32.const 0
i32.const 8
i32.const 128
i32.const 137
i32.const 0
call $~lib/env/abort
unreachable
@ -1222,104 +1306,6 @@
i32.const 1
i32.eq
i32.eqz
if
i32.const 0
i32.const 8
i32.const 247
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 2
i32.const 2
i32.eq
i32.eqz
if
i32.const 0
i32.const 8
i32.const 248
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 4
i32.const 4
i32.eq
i32.eqz
if
i32.const 0
i32.const 8
i32.const 249
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 8
i32.const 8
i32.eq
i32.eqz
if
i32.const 0
i32.const 8
i32.const 250
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 4
drop
i32.const 1
i32.const 1
i32.eq
i32.eqz
if
i32.const 0
i32.const 8
i32.const 252
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 1
i32.const 1
i32.eq
i32.eqz
if
i32.const 0
i32.const 8
i32.const 253
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 2
i32.const 2
i32.eq
i32.eqz
if
i32.const 0
i32.const 8
i32.const 254
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 4
i32.const 4
i32.eq
i32.eqz
if
i32.const 0
i32.const 8
i32.const 255
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 8
i32.const 8
i32.eq
i32.eqz
if
i32.const 0
i32.const 8
@ -1328,8 +1314,18 @@
call $~lib/env/abort
unreachable
end
i32.const 4
drop
i32.const 2
i32.const 2
i32.eq
i32.eqz
if
i32.const 0
i32.const 8
i32.const 257
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 4
i32.const 4
i32.eq
@ -1354,8 +1350,22 @@
call $~lib/env/abort
unreachable
end
i32.const 4
drop
i32.const 1
i32.const 1
i32.eq
i32.eqz
if
i32.const 0
i32.const 8
i32.const 261
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 1
i32.const 1
i32.eq
i32.eqz
if
@ -1366,8 +1376,8 @@
call $~lib/env/abort
unreachable
end
i32.const 4
i32.const 4
i32.const 2
i32.const 2
i32.eq
i32.eqz
if
@ -1378,8 +1388,8 @@
call $~lib/env/abort
unreachable
end
i32.const 0
i32.const 0
i32.const 4
i32.const 4
i32.eq
i32.eqz
if
@ -1390,8 +1400,8 @@
call $~lib/env/abort
unreachable
end
i32.const 2
i32.const 2
i32.const 8
i32.const 8
i32.eq
i32.eqz
if
@ -1402,8 +1412,10 @@
call $~lib/env/abort
unreachable
end
i32.const 0
i32.const 0
i32.const 4
drop
i32.const 4
i32.const 4
i32.eq
i32.eqz
if
@ -1426,6 +1438,78 @@
call $~lib/env/abort
unreachable
end
i32.const 0
i32.const 0
i32.eq
i32.eqz
if
i32.const 0
i32.const 8
i32.const 271
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 4
i32.const 4
i32.eq
i32.eqz
if
i32.const 0
i32.const 8
i32.const 272
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 0
i32.const 0
i32.eq
i32.eqz
if
i32.const 0
i32.const 8
i32.const 273
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 2
i32.const 2
i32.eq
i32.eqz
if
i32.const 0
i32.const 8
i32.const 274
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 0
i32.const 0
i32.eq
i32.eqz
if
i32.const 0
i32.const 8
i32.const 276
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 8
i32.const 8
i32.eq
i32.eqz
if
i32.const 0
i32.const 8
i32.const 277
i32.const 0
call $~lib/env/abort
unreachable
end
f64.const nan:0x8000000000000
f64.const nan:0x8000000000000
f64.ne
@ -1433,7 +1517,7 @@
if
i32.const 0
i32.const 8
i32.const 270
i32.const 279
i32.const 0
call $~lib/env/abort
unreachable
@ -1451,7 +1535,7 @@
if
i32.const 0
i32.const 8
i32.const 271
i32.const 280
i32.const 0
call $~lib/env/abort
unreachable
@ -1469,7 +1553,7 @@
if
i32.const 0
i32.const 8
i32.const 272
i32.const 281
i32.const 0
call $~lib/env/abort
unreachable
@ -1490,7 +1574,7 @@
if
i32.const 0
i32.const 8
i32.const 273
i32.const 282
i32.const 0
call $~lib/env/abort
unreachable
@ -1511,7 +1595,7 @@
if
i32.const 0
i32.const 8
i32.const 274
i32.const 283
i32.const 0
call $~lib/env/abort
unreachable
@ -1532,7 +1616,7 @@
if
i32.const 0
i32.const 8
i32.const 275
i32.const 284
i32.const 0
call $~lib/env/abort
unreachable
@ -1553,7 +1637,7 @@
if
i32.const 0
i32.const 8
i32.const 276
i32.const 285
i32.const 0
call $~lib/env/abort
unreachable
@ -1573,7 +1657,7 @@
if
i32.const 0
i32.const 8
i32.const 277
i32.const 286
i32.const 0
call $~lib/env/abort
unreachable
@ -1593,7 +1677,7 @@
if
i32.const 0
i32.const 8
i32.const 278
i32.const 287
i32.const 0
call $~lib/env/abort
unreachable
@ -1609,7 +1693,7 @@
if
i32.const 0
i32.const 8
i32.const 291
i32.const 300
i32.const 0
call $~lib/env/abort
unreachable
@ -1621,7 +1705,7 @@
if
i32.const 0
i32.const 8
i32.const 292
i32.const 301
i32.const 0
call $~lib/env/abort
unreachable
@ -1637,7 +1721,7 @@
if
i32.const 0
i32.const 8
i32.const 293
i32.const 302
i32.const 0
call $~lib/env/abort
unreachable
@ -1649,7 +1733,7 @@
if
i32.const 0
i32.const 8
i32.const 294
i32.const 303
i32.const 0
call $~lib/env/abort
unreachable
@ -1661,7 +1745,7 @@
if
i32.const 0
i32.const 8
i32.const 295
i32.const 304
i32.const 0
call $~lib/env/abort
unreachable
@ -1673,7 +1757,7 @@
if
i32.const 0
i32.const 8
i32.const 296
i32.const 305
i32.const 0
call $~lib/env/abort
unreachable
@ -1685,7 +1769,7 @@
if
i32.const 0
i32.const 8
i32.const 297
i32.const 306
i32.const 0
call $~lib/env/abort
unreachable
@ -1697,7 +1781,7 @@
if
i32.const 0
i32.const 8
i32.const 298
i32.const 307
i32.const 0
call $~lib/env/abort
unreachable
@ -1709,7 +1793,7 @@
if
i32.const 0
i32.const 8
i32.const 300
i32.const 309
i32.const 0
call $~lib/env/abort
unreachable
@ -1721,7 +1805,7 @@
if
i32.const 0
i32.const 8
i32.const 301
i32.const 310
i32.const 0
call $~lib/env/abort
unreachable
@ -1733,7 +1817,7 @@
if
i32.const 0
i32.const 8
i32.const 302
i32.const 311
i32.const 0
call $~lib/env/abort
unreachable
@ -1745,7 +1829,7 @@
if
i32.const 0
i32.const 8
i32.const 303
i32.const 312
i32.const 0
call $~lib/env/abort
unreachable
@ -1757,7 +1841,7 @@
if
i32.const 0
i32.const 8
i32.const 304
i32.const 313
i32.const 0
call $~lib/env/abort
unreachable
@ -1769,7 +1853,7 @@
if
i32.const 0
i32.const 8
i32.const 305
i32.const 314
i32.const 0
call $~lib/env/abort
unreachable
@ -1781,7 +1865,7 @@
if
i32.const 0
i32.const 8
i32.const 306
i32.const 315
i32.const 0
call $~lib/env/abort
unreachable
@ -1793,7 +1877,7 @@
if
i32.const 0
i32.const 8
i32.const 307
i32.const 316
i32.const 0
call $~lib/env/abort
unreachable
@ -1805,7 +1889,7 @@
if
i32.const 0
i32.const 8
i32.const 308
i32.const 317
i32.const 0
call $~lib/env/abort
unreachable
@ -1817,7 +1901,7 @@
if
i32.const 0
i32.const 8
i32.const 308
i32.const 317
i32.const 29
call $~lib/env/abort
unreachable
@ -1829,7 +1913,7 @@
if
i32.const 0
i32.const 8
i32.const 309
i32.const 318
i32.const 0
call $~lib/env/abort
unreachable
@ -1841,7 +1925,7 @@
if
i32.const 0
i32.const 8
i32.const 309
i32.const 318
i32.const 29
call $~lib/env/abort
unreachable
@ -1853,7 +1937,7 @@
if
i32.const 0
i32.const 8
i32.const 311
i32.const 320
i32.const 0
call $~lib/env/abort
unreachable
@ -1865,7 +1949,7 @@
if
i32.const 0
i32.const 8
i32.const 312
i32.const 321
i32.const 0
call $~lib/env/abort
unreachable
@ -1877,7 +1961,7 @@
if
i32.const 0
i32.const 8
i32.const 313
i32.const 322
i32.const 0
call $~lib/env/abort
unreachable
@ -1889,7 +1973,7 @@
if
i32.const 0
i32.const 8
i32.const 314
i32.const 323
i32.const 0
call $~lib/env/abort
unreachable
@ -1901,7 +1985,7 @@
if
i32.const 0
i32.const 8
i32.const 315
i32.const 324
i32.const 0
call $~lib/env/abort
unreachable
@ -1913,7 +1997,7 @@
if
i32.const 0
i32.const 8
i32.const 316
i32.const 325
i32.const 0
call $~lib/env/abort
unreachable
@ -1925,7 +2009,7 @@
if
i32.const 0
i32.const 8
i32.const 318
i32.const 327
i32.const 0
call $~lib/env/abort
unreachable
@ -1937,7 +2021,7 @@
if
i32.const 0
i32.const 8
i32.const 319
i32.const 328
i32.const 0
call $~lib/env/abort
unreachable
@ -1949,7 +2033,7 @@
if
i32.const 0
i32.const 8
i32.const 320
i32.const 329
i32.const 0
call $~lib/env/abort
unreachable
@ -1961,7 +2045,7 @@
if
i32.const 0
i32.const 8
i32.const 321
i32.const 330
i32.const 0
call $~lib/env/abort
unreachable
@ -1973,7 +2057,7 @@
if
i32.const 0
i32.const 8
i32.const 322
i32.const 331
i32.const 0
call $~lib/env/abort
unreachable
@ -1985,7 +2069,7 @@
if
i32.const 0
i32.const 8
i32.const 323
i32.const 332
i32.const 0
call $~lib/env/abort
unreachable