Skip to content
Merged
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
273 changes: 265 additions & 8 deletions src/tools/ilasm/src/ILAssembler/CIL.g4
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ The .NET Foundation licenses this file to you under the MIT license.

grammar CIL;

import Instructions;

tokens { IncludedFileEof, SyntheticIncludedFileEof }

INT32: '-'? ('0x' [0-9A-Fa-f]+ | [0-9]+);
Expand Down Expand Up @@ -122,6 +120,258 @@ PP_ENDIF: '#endif';
PP_INCLUDE: '#include';
MRESOURCE: '.mresource';

// Instruction tokens MUST be defined before DOTTEDNAME and ID to ensure they take precedence
// For example, "ldc.r8" must be recognized as INSTR_R token, not as DOTTEDNAME
INSTR_NONE:
'nop'
| 'break'
| 'ldarg.0'
| 'ldarg.1'
| 'ldarg.2'
| 'ldarg.3'
| 'ldloc.0'
| 'ldloc.1'
| 'ldloc.2'
| 'ldloc.3'
| 'stloc.0'
| 'stloc.1'
| 'stloc.2'
| 'stloc.3'
| 'ldnull'
| 'ldc.i4.m1'
| 'ldc.i4.0'
| 'ldc.i4.1'
| 'ldc.i4.2'
| 'ldc.i4.3'
| 'ldc.i4.4'
| 'ldc.i4.5'
| 'ldc.i4.6'
| 'ldc.i4.7'
| 'ldc.i4.8'
| 'dup'
| 'pop'
| 'ret'
| 'ldind.i1'
| 'ldind.u1'
| 'ldind.i2'
| 'ldind.u2'
| 'ldind.i4'
| 'ldind.u4'
| 'ldind.i8'
| 'ldind.i'
| 'ldind.r4'
| 'ldind.r8'
| 'ldind.ref'
| 'stind.ref'
| 'stind.i1'
| 'stind.i2'
| 'stind.i4'
| 'stind.i8'
| 'stind.r4'
| 'stind.r8'
| 'add'
| 'sub'
| 'mul'
| 'div'
| 'div.un'
| 'rem'
| 'rem.un'
| 'and'
| 'or'
| 'xor'
| 'shl'
| 'shr'
| 'shr.un'
| 'neg'
| 'not'
| 'conv.i1'
| 'conv.i2'
| 'conv.i4'
| 'conv.i8'
| 'conv.r4'
| 'conv.r8'
| 'conv.u4'
| 'conv.u8'
| 'conv.r.un'
| 'throw'
| 'conv.ovf.i1.un'
| 'conv.ovf.i2.un'
| 'conv.ovf.i4.un'
| 'conv.ovf.i8.un'
| 'conv.ovf.u1.un'
| 'conv.ovf.u2.un'
| 'conv.ovf.u4.un'
| 'conv.ovf.u8.un'
| 'conv.ovf.i.un'
| 'conv.ovf.u.un'
| 'ldlen'
| 'ldelem.i1'
| 'ldelem.u1'
| 'ldelem.i2'
| 'ldelem.u2'
| 'ldelem.i4'
| 'ldelem.u4'
| 'ldelem.i8'
| 'ldelem.i'
| 'ldelem.r4'
| 'ldelem.r8'
| 'ldelem.ref'
| 'stelem.i'
| 'stelem.i1'
| 'stelem.i2'
| 'stelem.i4'
| 'stelem.i8'
| 'stelem.r4'
| 'stelem.r8'
| 'stelem.ref'
| 'conv.ovf.i1'
| 'conv.ovf.u1'
| 'conv.ovf.i2'
| 'conv.ovf.u2'
| 'conv.ovf.i4'
| 'conv.ovf.u4'
| 'conv.ovf.i8'
| 'conv.ovf.u8'
| 'ckfinite'
| 'conv.u2'
| 'conv.u1'
| 'conv.i'
| 'conv.ovf.i'
| 'conv.ovf.u'
| 'add.ovf'
| 'add.ovf.un'
| 'mul.ovf'
| 'mul.ovf.un'
| 'sub.ovf'
| 'sub.ovf.un'
| 'endfinally'
| 'stind.i'
| 'conv.u'
| 'prefix7'
| 'prefix6'
| 'prefix5'
| 'prefix4'
| 'prefix3'
| 'prefix2'
| 'prefix1'
| 'prefixref'
| 'arglist'
| 'ceq'
| 'cgt'
| 'cgt.un'
| 'clt'
| 'clt.un'
| 'localloc'
| 'endfilter'
| 'volatile.'
| 'tail.'
| 'cpblk'
| 'initblk'
| 'rethrow'
| 'refanytype'
| 'readonly.'
| 'illegal'
| 'endmac';

INSTR_VAR:
'ldarg.s'
| 'ldarga.s'
| 'starg.s'
| 'ldloc.s'
| 'ldloca.s'
| 'stloc.s'
| 'ldarg'
| 'ldarga'
| 'starg'
| 'ldloc'
| 'ldloca'
| 'stloc';

INSTR_I:
'ldc.i4.s'
| 'ldc.i4'
| 'unaligned.'
| 'no.';

INSTR_I8: 'ldc.i8';

INSTR_R:
'ldc.r4'
| 'ldc.r8';

INSTR_METHOD:
'jmp'
| 'call'
| 'callvirt'
| 'newobj'
| 'ldftn'
| 'ldvirtftn';

INSTR_SIG: 'calli';

INSTR_BRTARGET:
'br.s'
| 'brfalse.s'
| 'brtrue.s'
| 'beq.s'
| 'bge.s'
| 'bgt.s'
| 'ble.s'
| 'blt.s'
| 'bne.un.s'
| 'bge.un.s'
| 'bgt.un.s'
| 'ble.un.s'
| 'blt.un.s'
| 'br'
| 'brfalse'
| 'brtrue'
| 'beq'
| 'bge'
| 'bgt'
| 'ble'
| 'blt'
| 'bne.un'
| 'bge.un'
| 'bgt.un'
| 'ble.un'
| 'blt.un'
| 'leave'
| 'leave.s';

INSTR_SWITCH: 'switch';

INSTR_TYPE:
'cpobj'
| 'ldobj'
| 'castclass'
| 'isinst'
| 'unbox'
| 'stobj'
| 'box'
| 'newarr'
| 'ldelema'
| 'ldelem'
| 'stelem'
| 'unbox.any'
| 'refanyval'
| 'mkrefany'
| 'initobj'
| 'constrained.'
| 'sizeof';

INSTR_STRING: 'ldstr';

INSTR_FIELD:
'ldfld'
| 'ldflda'
| 'stfld'
| 'ldsfld'
| 'ldsflda'
| 'stsfld';

INSTR_TOK: 'ldtoken';

// ID needs to be last to ensure it doesn't take priority over other token types
fragment IDSTART: [A-Za-z_#$@];
fragment IDCONT: [A-Za-z0-9_#?$@`];
Expand Down Expand Up @@ -414,6 +664,7 @@ instr:
| instr_r float64
| instr_r int64
| instr_r '(' bytes ')'
| instr_r 'bytearray' '(' bytes ')' // Support bytearray syntax for floating point instructions
| instr_brtarget int32
| instr_brtarget id
| instr_method methodRef
Expand Down Expand Up @@ -922,20 +1173,20 @@ VTENTRY: '.vtentry';
methodDecls: methodDecl*;

methodDecl:
EMITBYTE int32
instr // MOVED TO TOP - instructions must be matched first!
| EMITBYTE int32
| sehBlock
| MAXSTACK int32
| LOCALS sigArgs
| LOCALS 'init' sigArgs
| ENTRYPOINT
| ZEROINIT
| dataDecl
| instr
| id ':'
| labelDecl
| secDecl
| extSourceSpec // Leave for later when I get to generating symbols.
| languageDecl // Leave for later when I get to generating symbols.
| customAttrDecl
| extSourceSpec
| languageDecl
| customDescrInMethodBody // Only customDescr and customDescrWithOwner, NOT bare typedefs
| compControl
| EXPORT '[' int32 ']'
| EXPORT '[' int32 ']' 'as' id
Expand All @@ -949,6 +1200,12 @@ methodDecl:
| PARAM CONSTRAINT dottedName ',' typeSpec customAttrDecl*
| PARAM '[' int32 ']' initOpt customAttrDecl*;

labelDecl: id ':';

customDescrInMethodBody:
customDescr
| customDescrWithOwner;

scopeBlock: '{' methodDecls '}';

/* Structured exception handling directives */
Expand Down
20 changes: 20 additions & 0 deletions src/tools/ilasm/src/ILAssembler/Diagnostic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ public static class DiagnosticIds
public const string ArgumentNotFound = "ILA0018";
public const string LocalNotFound = "ILA0019";
public const string TypedefNotFound = "ILA0020";
public const string AbstractMethodNotInAbstractType = "ILA0021";
public const string InvalidPInvokeSignature = "ILA0022";
public const string MissingInstanceCallConv = "ILA0023";
public const string DeprecatedNativeType = "ILA0024";
public const string DeprecatedCustomMarshaller = "ILA0025";
public const string UnsupportedSecurityDeclaration = "ILA0026";
public const string GenericParameterIndexOutOfRange = "ILA0027";
public const string UnknownGenericParameter = "ILA0028";
public const string ParameterIndexOutOfRange = "ILA0029";
public const string DuplicateMethod = "ILA0030";
}

internal static class DiagnosticMessageTemplates
Expand All @@ -64,4 +74,14 @@ internal static class DiagnosticMessageTemplates
public const string ArgumentNotFound = "Argument '{0}' not found";
public const string LocalNotFound = "Local variable '{0}' not found";
public const string TypedefNotFound = "Typedef '{0}' not found";
public const string AbstractMethodNotInAbstractType = "Abstract method '{0}' cannot be declared in a non-abstract type";
public const string InvalidPInvokeSignature = "Invalid P/Invoke signature: module name is required";
public const string MissingInstanceCallConv = "Instance call convention required for method reference";
public const string DeprecatedNativeType = "Native type '{0}' is deprecated";
public const string DeprecatedCustomMarshaller = "The 4-string form of custom marshaller is deprecated";
public const string UnsupportedSecurityDeclaration = "Individual SecurityAttribute permissions are not supported; use PermissionSet instead";
public const string GenericParameterIndexOutOfRange = "Generic parameter index {0} is out of range";
public const string UnknownGenericParameter = "Unknown generic parameter '{0}'";
public const string ParameterIndexOutOfRange = "Parameter index {0} is out of range";
public const string DuplicateMethod = "Duplicate method definition";
}
Loading
Loading