Skip to content

[Implement] nameof builtin #731

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions src/builtins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ export namespace BuiltinSymbols {
export const sizeof = "~lib/builtins/sizeof";
export const alignof = "~lib/builtins/alignof";
export const offsetof = "~lib/builtins/offsetof";
export const nameof = "~lib/builtins/nameof";
export const select = "~lib/builtins/select";
export const unreachable = "~lib/builtins/unreachable";
export const changetype = "~lib/builtins/changetype";
Expand Down Expand Up @@ -771,6 +772,51 @@ export function compileCall(
}
}
}
case BuiltinSymbols.nameof: {
// Check to make sure a parameter or a type was passed to the builtin
let resultType = evaluateConstantType(compiler, typeArguments, operands, reportNode);
if (resultType === null) {
compiler.currentType = compiler.program.stringInstance.type;
compiler.error(
DiagnosticCode.Operation_not_supported,
reportNode.typeArgumentsRange
);
return module.unreachable();
}

let value: string;
if (resultType.is(TypeFlags.REFERENCE)) {
if (resultType.classReference !== null) {
value = resultType.classReference.name;
} else {
assert(resultType.signatureReference);
value = "Function";
}
} else {
switch (resultType.kind) {
case TypeKind.BOOL: value = "bool"; break;
case TypeKind.I8: value = "i8"; break;
case TypeKind.U8: value = "u8"; break;
case TypeKind.I16: value = "i16"; break;
case TypeKind.U16: value = "u16"; break;
case TypeKind.I32: value = "i32"; break;
case TypeKind.U32: value = "u32"; break;
case TypeKind.F32: value = "f32"; break;
case TypeKind.I64: value = "i64"; break;
case TypeKind.U64: value = "u64"; break;
case TypeKind.F64: value = "f64"; break;
case TypeKind.ISIZE: value = "isize"; break;
case TypeKind.USIZE: value = "usize"; break;
case TypeKind.V128: value = "v128"; break;
// If the kind is not set properly, throw an error.
// The default case falls through to satisfy that value is always set, and never null.
default: assert(false);
case TypeKind.VOID: value = "void"; break;
}
}

return compiler.ensureStaticString(value);
}

// === Math ===================================================================================

Expand Down
4 changes: 4 additions & 0 deletions std/assembly/builtins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ export declare function offsetof<T>(fieldName?: string): usize; // | u32 / u64
@builtin
export declare function idof<T>(): u32;

// @ts-ignore
@builtin
export declare function nameof<T>(): string;

// @ts-ignore: decorator
@builtin
export declare function select<T>(ifTrue: T, ifFalse: T, condition: bool): T;
Expand Down
2 changes: 2 additions & 0 deletions std/assembly/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ declare function offsetof<T>(): usize;
declare function offsetof<T>(fieldName: keyof T | string): usize;
/** Determines the offset of the specified field within the given class type. Returns the class type's end offset if field name has been omitted. Compiles to a constant. */
declare function offsetof<T>(fieldName?: string): usize;
/** Determines the name of a given type. */
declare function nameof<T>(value?: T): string;
/** Determines the unique runtime id of a class type. Compiles to a constant. */
declare function idof<T>(): u32;
/** Changes the type of any value of `usize` kind to another one of `usize` kind. Useful for casting class instances to their pointer values and vice-versa. Beware that this is unsafe.*/
Expand Down
2 changes: 0 additions & 2 deletions tests/compiler/binary.optimized.wat
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
local.get $2
i32.wrap_i64
i32.const 0
i32.ne
i32.const 0
local.get $1
i32.const 2147483647
i32.and
Expand Down
Loading