// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. module internal FSharp.Compiler.AbstractIL.Internal.AsciiConstants open Internal.Utilities.Collections open FSharp.Compiler.AbstractIL.Internal.Library open FSharp.Compiler.AbstractIL.IL // set to the proper value at CompileOps.fs (BuildFrameworkTcImports) // Only reelvant when compiling FSharp.Core.dll let parseILGlobals = ref EcmaMscorlibILGlobals /// Table of parsing and pretty printing data for instructions. let noArgInstrs = lazy [ ["ldc";"i4";"0"], mkLdcInt32 0 ["ldc";"i4";"1"], mkLdcInt32 1 ["ldc";"i4";"2"], mkLdcInt32 2 ["ldc";"i4";"3"], mkLdcInt32 3 ["ldc";"i4";"4"], mkLdcInt32 4 ["ldc";"i4";"5"], mkLdcInt32 5 ["ldc";"i4";"6"], mkLdcInt32 6 ["ldc";"i4";"7"], mkLdcInt32 7 ["ldc";"i4";"8"], mkLdcInt32 8 ["ldc";"i4";"M1"], mkLdcInt32 -1 ["ldc";"i4";"m1"], mkLdcInt32 -1 ["stloc";"0"], mkStloc (uint16 0) ["stloc";"1"], mkStloc (uint16 1) ["stloc";"2"], mkStloc (uint16 2) ["stloc";"3"], mkStloc (uint16 3) ["ldloc";"0"], mkLdloc (uint16 0) ["ldloc";"1"], mkLdloc (uint16 1) ["ldloc";"2"], mkLdloc (uint16 2) ["ldloc";"3"], mkLdloc (uint16 3) ["ldarg";"0"], mkLdarg (uint16 0) ["ldarg";"1"], mkLdarg (uint16 1) ["ldarg";"2"], mkLdarg (uint16 2) ["ldarg";"3"], mkLdarg (uint16 3) ["ret"], I_ret ["add"], AI_add ["add";"ovf"], AI_add_ovf ["add";"ovf";"un"], AI_add_ovf_un ["and"], AI_and ["div"], AI_div ["div";"un"], AI_div_un ["ceq"], AI_ceq ["cgt"], AI_cgt ["cgt";"un"], AI_cgt_un ["clt"], AI_clt ["clt";"un"], AI_clt_un ["conv";"i1"], AI_conv DT_I1 ["conv";"i2"], AI_conv DT_I2 ["conv";"i4"], AI_conv DT_I4 ["conv";"i8"], AI_conv DT_I8 ["conv";"i"], AI_conv DT_I ["conv";"r4"], AI_conv DT_R4 ["conv";"r8"], AI_conv DT_R8 ["conv";"u1"], AI_conv DT_U1 ["conv";"u2"], AI_conv DT_U2 ["conv";"u4"], AI_conv DT_U4 ["conv";"u8"], AI_conv DT_U8 ["conv";"u"], AI_conv DT_U ["conv";"r"; "un"], AI_conv DT_R ["conv";"ovf";"i1"], AI_conv_ovf DT_I1 ["conv";"ovf";"i2"], AI_conv_ovf DT_I2 ["conv";"ovf";"i4"], AI_conv_ovf DT_I4 ["conv";"ovf";"i8"], AI_conv_ovf DT_I8 ["conv";"ovf";"i"], AI_conv_ovf DT_I ["conv";"ovf";"u1"], AI_conv_ovf DT_U1 ["conv";"ovf";"u2"], AI_conv_ovf DT_U2 ["conv";"ovf";"u4"], AI_conv_ovf DT_U4 ["conv";"ovf";"u8"], AI_conv_ovf DT_U8 ["conv";"ovf";"u"], AI_conv_ovf DT_U ["conv";"ovf";"i1"; "un"], AI_conv_ovf_un DT_I1 ["conv";"ovf";"i2"; "un"], AI_conv_ovf_un DT_I2 ["conv";"ovf";"i4"; "un"], AI_conv_ovf_un DT_I4 ["conv";"ovf";"i8"; "un"], AI_conv_ovf_un DT_I8 ["conv";"ovf";"i"; "un"], AI_conv_ovf_un DT_I ["conv";"ovf";"u1"; "un"], AI_conv_ovf_un DT_U1 ["conv";"ovf";"u2"; "un"], AI_conv_ovf_un DT_U2 ["conv";"ovf";"u4"; "un"], AI_conv_ovf_un DT_U4 ["conv";"ovf";"u8"; "un"], AI_conv_ovf_un DT_U8 ["conv";"ovf";"u"; "un"], AI_conv_ovf_un DT_U ["stelem";"i1"], I_stelem DT_I1 ["stelem";"i2"], I_stelem DT_I2 ["stelem";"i4"], I_stelem DT_I4 ["stelem";"i8"], I_stelem DT_I8 ["stelem";"r4"], I_stelem DT_R4 ["stelem";"r8"], I_stelem DT_R8 ["stelem";"i"], I_stelem DT_I ["stelem";"u"], I_stelem DT_I ["stelem";"u8"], I_stelem DT_I8 ["stelem";"ref"], I_stelem DT_REF ["ldelem";"i1"], I_ldelem DT_I1 ["ldelem";"i2"], I_ldelem DT_I2 ["ldelem";"i4"], I_ldelem DT_I4 ["ldelem";"i8"], I_ldelem DT_I8 ["ldelem";"u8"], I_ldelem DT_I8 ["ldelem";"u1"], I_ldelem DT_U1 ["ldelem";"u2"], I_ldelem DT_U2 ["ldelem";"u4"], I_ldelem DT_U4 ["ldelem";"r4"], I_ldelem DT_R4 ["ldelem";"r8"], I_ldelem DT_R8 ["ldelem";"u"], I_ldelem DT_I // EQUIV ["ldelem";"i"], I_ldelem DT_I ["ldelem";"ref"], I_ldelem DT_REF ["mul"], AI_mul ["mul";"ovf"], AI_mul_ovf ["mul";"ovf";"un"], AI_mul_ovf_un ["rem"], AI_rem ["rem";"un"], AI_rem_un ["shl"], AI_shl ["shr"], AI_shr ["shr";"un"], AI_shr_un ["sub"], AI_sub ["sub";"ovf"], AI_sub_ovf ["sub";"ovf";"un"], AI_sub_ovf_un ["xor"], AI_xor ["or"], AI_or ["neg"], AI_neg ["not"], AI_not ["ldnull"], AI_ldnull ["dup"], AI_dup ["pop"], AI_pop ["ckfinite"], AI_ckfinite ["nop"], AI_nop ["break"], I_break ["arglist"], I_arglist ["endfilter"], I_endfilter ["endfinally"], I_endfinally ["refanytype"], I_refanytype ["localloc"], I_localloc ["throw"], I_throw ["ldlen"], I_ldlen ["rethrow"], I_rethrow ] #if DEBUG let wordsOfNoArgInstr, isNoArgInstr = let t = lazy (let t = HashMultiMap(300, HashIdentity.Structural) noArgInstrs |> Lazy.force |> List.iter (fun (x, mk) -> t.Add(mk, x)) t) (fun s -> (Lazy.force t).[s]), (fun s -> (Lazy.force t).ContainsKey s) #endif let mk_stind (nm, dt) = (nm, (fun () -> I_stind(Aligned, Nonvolatile, dt))) let mk_ldind (nm, dt) = (nm, (fun () -> I_ldind(Aligned, Nonvolatile, dt))) type NoArgInstr = (unit -> ILInstr) type Int32Instr = (int32 -> ILInstr) type Int32Int32Instr = (int32 * int32 -> ILInstr) type Int64Instr = (int64 -> ILInstr) type DoubleInstr = (ILConst -> ILInstr) type MethodSpecInstr = (ILMethodSpec * ILVarArgs -> ILInstr) type TypeInstr = (ILType -> ILInstr) type IntTypeInstr = (int * ILType -> ILInstr) type ValueTypeInstr = (ILType -> ILInstr) (* nb. diff. interp of types to TypeInstr *) type StringInstr = (string -> ILInstr) type TokenInstr = (ILToken -> ILInstr) type SwitchInstr = (ILCodeLabel list * ILCodeLabel -> ILInstr) type InstrTable<'T> = (string list * 'T) list type LazyInstrTable<'T> = Lazy> /// Table of parsing and pretty printing data for instructions. let NoArgInstrs : Lazy> = lazy [ for (nm, i) in noArgInstrs.Force() do yield (nm, (fun () -> i)) yield mk_stind (["stind";"u"], DT_I) yield mk_stind (["stind";"i"], DT_I) yield mk_stind (["stind";"u1"], DT_I1) yield mk_stind (["stind";"i1"], DT_I1) yield mk_stind (["stind";"u2"], DT_I2) yield mk_stind (["stind";"i2"], DT_I2) yield mk_stind (["stind";"u4"], DT_I4) yield mk_stind (["stind";"i4"], DT_I4) yield mk_stind (["stind";"u8"], DT_I8) yield mk_stind (["stind";"i8"], DT_I8) yield mk_stind (["stind";"r4"], DT_R4) yield mk_stind (["stind";"r8"], DT_R8) yield mk_stind (["stind";"ref"], DT_REF) yield mk_ldind (["ldind";"i"], DT_I) yield mk_ldind (["ldind";"i1"], DT_I1) yield mk_ldind (["ldind";"i2"], DT_I2) yield mk_ldind (["ldind";"i4"], DT_I4) yield mk_ldind (["ldind";"i8"], DT_I8) yield mk_ldind (["ldind";"u1"], DT_U1) yield mk_ldind (["ldind";"u2"], DT_U2) yield mk_ldind (["ldind";"u4"], DT_U4) yield mk_ldind (["ldind";"u8"], DT_I8) yield mk_ldind (["ldind";"r4"], DT_R4) yield mk_ldind (["ldind";"r8"], DT_R8) yield mk_ldind (["ldind";"ref"], DT_REF) yield ["cpblk"], (fun () -> I_cpblk(Aligned, Nonvolatile)) yield ["initblk"], (fun () -> I_initblk(Aligned, Nonvolatile)) ] /// Table of parsing and pretty printing data for instructions. let Int64Instrs : Lazy> = lazy [ ["ldc";"i8"], (fun x -> AI_ldc (DT_I8, ILConst.I8 x)) ] /// Table of parsing and pretty printing data for instructions. let Int32Instrs : Lazy> = lazy [ ["ldc";"i4"], mkLdcInt32 ["ldc";"i4";"s"], mkLdcInt32 ] /// Table of parsing and pretty printing data for instructions. let Int32Int32Instrs : Lazy> = lazy [ ["ldlen";"multi"], EI_ldlen_multi ] /// Table of parsing and pretty printing data for instructions. let DoubleInstrs : Lazy> = lazy [ ["ldc";"r4"], (fun x -> (AI_ldc (DT_R4, x))) ["ldc";"r8"], (fun x -> (AI_ldc (DT_R8, x))) ] /// Table of parsing and pretty printing data for instructions. let MethodSpecInstrs : Lazy> = lazy [ ["call"], (fun (mspec, y) -> I_call (Normalcall, mspec, y)) ] /// Table of parsing and pretty printing data for instructions. let StringInstrs : Lazy> = lazy [ ["ldstr"], I_ldstr ] /// Table of parsing and pretty printing data for instructions. let TokenInstrs : Lazy> = lazy [ ["ldtoken"], I_ldtoken ] /// Table of parsing and pretty printing data for instructions. let TypeInstrs : Lazy> = lazy [ ["ldelema"], (fun x -> I_ldelema (NormalAddress, false, ILArrayShape.SingleDimensional, x)) ["ldelem";"any"], (fun x -> I_ldelem_any (ILArrayShape.SingleDimensional, x)) ["stelem";"any"], (fun x -> I_stelem_any (ILArrayShape.SingleDimensional, x)) ["newarr"], (fun x -> I_newarr (ILArrayShape.SingleDimensional, x)) ["castclass"], I_castclass ["ilzero"], EI_ilzero ["isinst"], I_isinst ["initobj";"any"], I_initobj ["unbox";"any"], I_unbox_any ] /// Table of parsing and pretty printing data for instructions. let IntTypeInstrs : Lazy> = lazy [ ["ldelem";"multi"], (fun (x, y) -> (I_ldelem_any (ILArrayShape.FromRank x, y))) ["stelem";"multi"], (fun (x, y) -> (I_stelem_any (ILArrayShape.FromRank x, y))) ["newarr";"multi"], (fun (x, y) -> (I_newarr (ILArrayShape.FromRank x, y))) ["ldelema";"multi"], (fun (x, y) -> (I_ldelema (NormalAddress, false, ILArrayShape.FromRank x, y))) ] /// Table of parsing and pretty printing data for instructions. let ValueTypeInstrs : Lazy> = lazy [ ["cpobj"], I_cpobj ["initobj"], I_initobj ["ldobj"], (fun z -> I_ldobj (Aligned, Nonvolatile, z)) ["stobj"], (fun z -> I_stobj (Aligned, Nonvolatile, z)) ["sizeof"], I_sizeof ["box"], I_box ["unbox"], I_unbox ]