1 // 2 // StackDecoder.cs 3 // 4 // Authors: 5 // Alexander Chebaturkin (chebaturkin@gmail.com) 6 // 7 // Copyright (C) 2011 Alexander Chebaturkin 8 // 9 // Permission is hereby granted, free of charge, to any person obtaining 10 // a copy of this software and associated documentation files (the 11 // "Software"), to deal in the Software without restriction, including 12 // without limitation the rights to use, copy, modify, merge, publish, 13 // distribute, sublicense, and/or sell copies of the Software, and to 14 // permit persons to whom the Software is furnished to do so, subject to 15 // the following conditions: 16 // 17 // The above copyright notice and this permission notice shall be 18 // included in all copies or substantial portions of the Software. 19 // 20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 // 28 29 using System; 30 using System.Collections.Generic; 31 using Mono.CodeContracts.Static.AST; 32 using Mono.CodeContracts.Static.AST.Visitors; 33 using Mono.CodeContracts.Static.ControlFlow; 34 using Mono.CodeContracts.Static.DataStructures; 35 36 namespace Mono.CodeContracts.Static.Analysis.StackAnalysis { 37 struct StackDecoder<TContext, TData, TResult, TVisitor> : IILVisitor<APC, Dummy, Dummy, TData, TResult> 38 where TContext : IMethodContextProvider 39 where TVisitor : IILVisitor<APC, int, int, TData, TResult> 40 { 41 private readonly StackDepthProvider<TContext> parent; 42 private readonly TVisitor visitor; 43 StackDecoderMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder44 public StackDecoder(StackDepthProvider<TContext> parent, 45 TVisitor visitor) 46 { 47 this.parent = parent; 48 this.visitor = visitor; 49 } 50 PopMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder51 private int Pop(APC label, int count) 52 { 53 return this.parent.GlobalStackDepth (label) - 1 - count; 54 } 55 PopSequenceMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder56 private SequenceGenerator PopSequence(APC pc, int args, int offset) 57 { 58 return new SequenceGenerator (this.parent.GlobalStackDepth (pc) - args - offset, args); 59 } 60 PushMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder61 private int Push(APC label, int count) 62 { 63 return this.parent.GlobalStackDepth (label) - count; 64 } 65 PushMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder66 private int Push(APC label, int args, TypeNode returnType) 67 { 68 if (this.parent.MetaDataProvider.IsVoid (returnType)) 69 return -1; 70 71 return Push (label, args); 72 } 73 GetParametersCountMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder74 private int GetParametersCount(Method ctor, int extraVarargs) 75 { 76 int result = extraVarargs + this.parent.MetaDataProvider.Parameters (ctor).Count; 77 if (!this.parent.MetaDataProvider.IsStatic (ctor)) 78 ++result; 79 return result; 80 } 81 RemapParameterToLoadStackMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder82 private bool RemapParameterToLoadStack(APC pc, ref Parameter param, out bool isLoadResult, out int loadStackOffset, out bool isOld, out APC lookupPC) 83 { 84 if (pc.SubroutineContext == null) { 85 isLoadResult = false; 86 loadStackOffset = 0; 87 isOld = false; 88 lookupPC = pc; 89 return false; 90 } 91 92 if (pc.Block.Subroutine.IsRequires) { 93 isLoadResult = false; 94 isOld = false; 95 lookupPC = pc; 96 for (Sequence<Edge<CFGBlock, EdgeTag>> list = pc.SubroutineContext; list != null; list = list.Tail) { 97 EdgeTag edgeTag = list.Head.Tag; 98 if (edgeTag == EdgeTag.Entry) { 99 param = RemapParameter (param, list.Head.From, pc.Block); 100 loadStackOffset = 0; 101 return false; 102 } 103 if (edgeTag.Is (EdgeTag.BeforeMask)) { 104 int stackDepth = this.parent.LocalStackDepth (pc); 105 loadStackOffset = this.parent.MetaDataProvider.ParameterStackIndex (param) + stackDepth; 106 return true; 107 } 108 } 109 throw new InvalidOperationException (); 110 } 111 112 if (pc.Block.Subroutine.IsEnsuresOrOldValue) { 113 isOld = true; 114 for (Sequence<Edge<CFGBlock, EdgeTag>> ctx = pc.SubroutineContext; ctx != null; ctx = ctx.Tail) { 115 EdgeTag tag = ctx.Head.Tag; 116 if (tag == EdgeTag.Exit) { 117 param = RemapParameter (param, ctx.Head.From, pc.Block); 118 isLoadResult = false; 119 loadStackOffset = 0; 120 lookupPC = pc; 121 return false; 122 } 123 124 if (tag == EdgeTag.AfterCall) { 125 loadStackOffset = this.parent.MetaDataProvider.ParameterStackIndex (param); 126 isLoadResult = false; 127 lookupPC = new APC (ctx.Head.From, 0, ctx.Tail); 128 return true; 129 } 130 131 if (tag == EdgeTag.AfterNewObj) { 132 if (this.parent.MetaDataProvider.ParameterIndex (param) == 0) { 133 loadStackOffset = this.parent.LocalStackDepth (pc); 134 isLoadResult = true; 135 lookupPC = pc; 136 isOld = false; 137 return false; 138 } 139 140 loadStackOffset = this.parent.MetaDataProvider.ParameterIndex (param); 141 isLoadResult = false; 142 lookupPC = new APC (ctx.Head.From, 0, ctx.Tail); 143 return true; 144 } 145 if (tag == EdgeTag.OldManifest) { 146 param = RemapParameter (param, ctx.Tail.Head.From, pc.Block); 147 isOld = false; 148 isLoadResult = false; 149 loadStackOffset = 0; 150 lookupPC = pc; 151 return false; 152 } 153 } 154 throw new InvalidOperationException (); 155 } 156 157 if (pc.Block.Subroutine.IsInvariant) { 158 for (Sequence<Edge<CFGBlock, EdgeTag>> list = pc.SubroutineContext; list != null; list = list.Tail) { 159 EdgeTag tag = list.Head.Tag; 160 if (tag == EdgeTag.Entry || tag == EdgeTag.Exit) { 161 Method method; 162 if (pc.TryGetContainingMethod (out method)) { 163 param = this.parent.MetaDataProvider.This (method); 164 isLoadResult = false; 165 loadStackOffset = 0; 166 isOld = tag == EdgeTag.Exit; 167 lookupPC = pc; 168 return false; 169 } 170 isLoadResult = false; 171 loadStackOffset = 0; 172 isOld = false; 173 lookupPC = pc; 174 return false; 175 } 176 if (tag == EdgeTag.AfterCall) { 177 Method calledMethod; 178 bool isNewObj; 179 bool isVirtual; 180 list.Head.From.IsMethodCallBlock (out calledMethod, out isNewObj, out isVirtual); 181 int count = this.parent.MetaDataProvider.Parameters (calledMethod).Count; 182 loadStackOffset = count; 183 isLoadResult = false; 184 isOld = true; 185 lookupPC = new APC (list.Head.From, 0, list.Tail); 186 return true; 187 } 188 if (tag == EdgeTag.AfterNewObj) { 189 isLoadResult = true; 190 loadStackOffset = this.parent.LocalStackDepth (pc); 191 isOld = false; 192 lookupPC = pc; 193 return false; 194 } 195 if (tag.Is (EdgeTag.BeforeMask)) 196 throw new InvalidOperationException ("this should never happen"); 197 } 198 throw new InvalidOperationException ("this should never happen"); 199 } 200 201 isLoadResult = false; 202 loadStackOffset = 0; 203 isOld = false; 204 lookupPC = pc; 205 return false; 206 } 207 RemapParameterMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder208 private Parameter RemapParameter(Parameter p, CFGBlock parentMethodBlock, CFGBlock subroutineBlock) 209 { 210 Method parentMethod = ((IMethodInfo) parentMethodBlock.Subroutine).Method; 211 Method method = ((IMethodInfo) subroutineBlock.Subroutine).Method; 212 213 if (this.parent.MetaDataProvider.Equal (method, parentMethod)) 214 return p; 215 216 int index = this.parent.MetaDataProvider.ParameterIndex (p); 217 if (this.parent.MetaDataProvider.IsStatic (parentMethod) || index != 0) 218 return this.parent.MetaDataProvider.Parameters (parentMethod)[index]; 219 220 return this.parent.MetaDataProvider.This (parentMethod); 221 } 222 IsReferenceTypeMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder223 private bool IsReferenceType(APC pc, TypeNode type) 224 { 225 return this.parent.MetaDataProvider.IsReferenceType (type); 226 } 227 GetSpecializedTypeMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder228 private TypeNode GetSpecializedType(APC pc, TypeNode type) 229 { 230 var methodInfo = pc.Block.Subroutine as IMethodInfo; 231 if (methodInfo == null) 232 return type; 233 234 throw new NotImplementedException (); 235 } 236 237 #region Implementation of IExpressionILVisitor<APC,Type,Dummy,Dummy,Data,Result> BinaryMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder238 public TResult Binary(APC pc, BinaryOperator op, Dummy dest, Dummy operand1, Dummy operand2, TData data) 239 { 240 return this.visitor.Binary (pc, op, Push (pc, 2), Pop (pc, 1), Pop (pc, 0), data); 241 } 242 IsinstMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder243 public TResult Isinst(APC pc, TypeNode type, Dummy dest, Dummy obj, TData data) 244 { 245 return this.visitor.Isinst (pc, type, Push (pc, 1), Pop (pc, 0), data); 246 } 247 LoadNullMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder248 public TResult LoadNull(APC pc, Dummy dest, TData polarity) 249 { 250 return this.visitor.LoadNull (pc, Push (pc, 0), polarity); 251 } 252 LoadConstMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder253 public TResult LoadConst(APC pc, TypeNode type, object constant, Dummy dest, TData data) 254 { 255 return this.visitor.LoadConst (pc, type, constant, Push (pc, 0), data); 256 } 257 SizeofMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder258 public TResult Sizeof(APC pc, TypeNode type, Dummy dest, TData data) 259 { 260 return this.visitor.Sizeof (pc, type, Push (pc, 0), data); 261 } 262 UnaryMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder263 public TResult Unary(APC pc, UnaryOperator op, bool unsigned, Dummy dest, Dummy source, TData data) 264 { 265 return this.visitor.Unary (pc, op, unsigned, Push (pc, 1), Pop (pc, 0), data); 266 } 267 #endregion 268 269 #region Implementation of ISyntheticILVisitor<APC,Method,Field,Type,Dummy,Dummy,Data,Result> EntryMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder270 public TResult Entry(APC pc, Method method, TData data) 271 { 272 return this.visitor.Entry (pc, method, data); 273 } 274 AssumeMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder275 public TResult Assume(APC pc, EdgeTag tag, Dummy condition, TData data) 276 { 277 return this.visitor.Assume (pc, tag, Pop (pc, 0), data); 278 } 279 AssertMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder280 public TResult Assert(APC pc, EdgeTag tag, Dummy condition, TData data) 281 { 282 return this.visitor.Assert (pc, tag, Pop (pc, 0), data); 283 } 284 BeginOldMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder285 public TResult BeginOld(APC pc, APC matchingEnd, TData data) 286 { 287 return this.visitor.BeginOld (pc, matchingEnd, data); 288 } 289 EndOldMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder290 public TResult EndOld(APC pc, APC matchingBegin, TypeNode type, Dummy dest, Dummy source, TData data) 291 { 292 if (pc.InsideOldManifestation) 293 return this.visitor.LoadStack (pc, 1, Push (matchingBegin, 0), Pop (pc, 0), false, data); 294 295 return this.visitor.EndOld (pc, matchingBegin, type, Push (matchingBegin, 0), Pop (pc, 0), data); 296 } 297 LoadStackMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder298 public TResult LoadStack(APC pc, int offset, Dummy dest, Dummy source, bool isOld, TData data) 299 { 300 return this.visitor.LoadStack (pc, offset, Push (pc, 0), Pop (pc, offset), isOld, data); 301 } 302 LoadStackAddressMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder303 public TResult LoadStackAddress(APC pc, int offset, Dummy dest, Dummy source, TypeNode type, bool isOld, TData data) 304 { 305 return this.visitor.LoadStackAddress (pc, offset, Push (pc, 0), Pop (pc, offset), type, isOld, data); 306 } 307 LoadResultMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder308 public TResult LoadResult(APC pc, TypeNode type, Dummy dest, Dummy source, TData data) 309 { 310 int offset = this.parent.LocalStackDepth (pc); 311 return this.visitor.LoadResult (pc, type, Push (pc, 0), Pop (pc, offset), data); 312 } 313 #endregion 314 315 #region Implementation of IILVisitor<APC,Local,Parameter,Method,Field,Type,Dummy,Dummy,Data,Result> ArglistMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder316 public TResult Arglist(APC pc, Dummy dest, TData data) 317 { 318 return this.visitor.Arglist (pc, Push (pc, 0), data); 319 } 320 BranchMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder321 public TResult Branch(APC pc, APC target, bool leavesExceptionBlock, TData data) 322 { 323 return this.visitor.Branch (pc, target, leavesExceptionBlock, data); 324 } 325 BranchCondMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder326 public TResult BranchCond(APC pc, APC target, BranchOperator bop, Dummy value1, Dummy value2, TData data) 327 { 328 return this.visitor.BranchCond (pc, target, bop, Pop (pc, 1), Pop (pc, 0), data); 329 } 330 BranchTrueMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder331 public TResult BranchTrue(APC pc, APC target, Dummy cond, TData data) 332 { 333 return this.visitor.BranchTrue (pc, target, Pop (pc, 0), data); 334 } 335 BranchFalseMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder336 public TResult BranchFalse(APC pc, APC target, Dummy cond, TData data) 337 { 338 return this.visitor.BranchFalse (pc, target, Pop (pc, 0), data); 339 } 340 BreakMono.CodeContracts.Static.Analysis.StackAnalysis.StackDecoder341 public TResult Break(APC pc, TData data) 342 { 343 return this.visitor.Break (pc, data); 344 } 345 346 public TResult Call<TypeList, ArgList>(APC pc, Method method, bool virt, TypeList extraVarargs, Dummy dest, ArgList args, TData data) 347 where TypeList : IIndexable<TypeNode> 348 where ArgList : IIndexable<Dummy> 349 { 350 int argsCount = GetParametersCount (method, extraVarargs == null ? 0 : extraVarargs.Count); 351 return this.visitor.Call (pc, method, virt, extraVarargs, Push (pc, argsCount, this.parent.MetaDataProvider.ReturnType (method)), PopSequence (pc, argsCount, 0), data); 352 } 353 354 public TResult Calli<TypeList, ArgList>(APC pc, TypeNode returnType, TypeList argTypes, bool instance, Dummy dest, Dummy functionPointer, ArgList args, TData data) 355 where TypeList : IIndexable<TypeNode> 356 where ArgList : IIndexable<Dummy> 357 { 358 int argsCount = argTypes.Count + (instance ? 1 : 0); 359 return this.visitor.Calli (pc, returnType, argTypes, instance, Push (pc, argsCount + 1, returnType), Pop (pc, 0), PopSequence (pc, argsCount, 1), data); 360 } 361 CheckFinite(APC pc, Dummy dest, Dummy source, TData data)362 public TResult CheckFinite(APC pc, Dummy dest, Dummy source, TData data) 363 { 364 return this.visitor.CheckFinite (pc, Push (pc, 1), Pop (pc, 0), data); 365 } 366 CopyBlock(APC pc, Dummy destAddress, Dummy srcAddress, Dummy len, TData data)367 public TResult CopyBlock(APC pc, Dummy destAddress, Dummy srcAddress, Dummy len, TData data) 368 { 369 return this.visitor.CopyBlock (pc, Pop (pc, 2), Pop (pc, 1), Pop (pc, 0), data); 370 } 371 EndFilter(APC pc, Dummy decision, TData data)372 public TResult EndFilter(APC pc, Dummy decision, TData data) 373 { 374 return this.visitor.EndFilter (pc, Pop (pc, 0), data); 375 } 376 EndFinally(APC pc, TData data)377 public TResult EndFinally(APC pc, TData data) 378 { 379 return this.visitor.EndFinally (pc, data); 380 } 381 Jmp(APC pc, Method method, TData data)382 public TResult Jmp(APC pc, Method method, TData data) 383 { 384 return this.visitor.Jmp (pc, method, data); 385 } 386 LoadArg(APC pc, Parameter argument, bool dummyOld, Dummy dest, TData data)387 public TResult LoadArg(APC pc, Parameter argument, bool dummyOld, Dummy dest, TData data) 388 { 389 Parameter p = argument; 390 bool isLdResult; 391 int loadStackOffset; 392 bool isOld; 393 APC lookupPC; 394 if (RemapParameterToLoadStack (pc, ref argument, out isLdResult, out loadStackOffset, out isOld, out lookupPC)) 395 return this.visitor.LoadStack (pc, loadStackOffset, Push (pc, 0), Pop (lookupPC, loadStackOffset), isOld, data); 396 397 if (argument == null) 398 argument = p; 399 400 if (isLdResult) { 401 if (this.parent.MetaDataProvider.IsStruct (this.parent.MetaDataProvider.DeclaringType (this.parent.MetaDataProvider.DeclaringMethod (argument)))) 402 return this.visitor.LoadStackAddress (pc, loadStackOffset, Push (pc, 0), Pop (pc, loadStackOffset), this.parent.MetaDataProvider.ParameterType (argument), isOld, data); 403 404 return this.visitor.LoadResult (pc, this.parent.MetaDataProvider.ParameterType (argument), Push (pc, 0), Pop (pc, loadStackOffset), data); 405 } 406 407 return this.visitor.LoadArg (pc, argument, isOld, Push (pc, 0), data); 408 } 409 LoadArgAddress(APC pc, Parameter argument, bool dummyOld, Dummy dest, TData data)410 public TResult LoadArgAddress(APC pc, Parameter argument, bool dummyOld, Dummy dest, TData data) 411 { 412 bool isLoadResult; 413 int loadStackOffset; 414 bool isOld; 415 APC lookupPC; 416 if (RemapParameterToLoadStack (pc, ref argument, out isLoadResult, out loadStackOffset, out isOld, out lookupPC)) 417 return this.visitor.LoadStackAddress (pc, loadStackOffset, Push (pc, 0), Pop (lookupPC, loadStackOffset), this.parent.MetaDataProvider.ParameterType (argument), isOld, data); 418 419 if (isLoadResult) 420 throw new InvalidOperationException (); 421 422 return this.visitor.LoadArgAddress (pc, argument, isOld, Push (pc, 0), data); 423 } 424 LoadLocal(APC pc, Local local, Dummy dest, TData data)425 public TResult LoadLocal(APC pc, Local local, Dummy dest, TData data) 426 { 427 return this.visitor.LoadLocal (pc, local, Push (pc, 0), data); 428 } 429 LoadLocalAddress(APC pc, Local local, Dummy dest, TData data)430 public TResult LoadLocalAddress(APC pc, Local local, Dummy dest, TData data) 431 { 432 return this.visitor.LoadLocalAddress (pc, local, Push (pc, 0), data); 433 } 434 Nop(APC pc, TData data)435 public TResult Nop(APC pc, TData data) 436 { 437 return this.visitor.Nop (pc, data); 438 } 439 Pop(APC pc, Dummy source, TData data)440 public TResult Pop(APC pc, Dummy source, TData data) 441 { 442 return this.visitor.Pop (pc, Pop (pc, 0), data); 443 } 444 Return(APC pc, Dummy source, TData data)445 public TResult Return(APC pc, Dummy source, TData data) 446 { 447 return this.visitor.Nop (pc, data); 448 } 449 StoreArg(APC pc, Parameter argument, Dummy source, TData data)450 public TResult StoreArg(APC pc, Parameter argument, Dummy source, TData data) 451 { 452 return this.visitor.StoreArg (pc, argument, Pop (pc, 0), data); 453 } 454 StoreLocal(APC pc, Local local, Dummy source, TData data)455 public TResult StoreLocal(APC pc, Local local, Dummy source, TData data) 456 { 457 return this.visitor.StoreLocal (pc, local, Pop (pc, 0), data); 458 } 459 Switch(APC pc, TypeNode type, IEnumerable<Pair<object, APC>> cases, Dummy value, TData data)460 public TResult Switch(APC pc, TypeNode type, IEnumerable<Pair<object, APC>> cases, Dummy value, TData data) 461 { 462 return this.visitor.Switch (pc, type, cases, Pop (pc, 0), data); 463 } 464 Box(APC pc, TypeNode type, Dummy dest, Dummy source, TData data)465 public TResult Box(APC pc, TypeNode type, Dummy dest, Dummy source, TData data) 466 { 467 type = GetSpecializedType (pc, type); 468 if (IsReferenceType (pc, type)) 469 return this.visitor.Nop (pc, data); 470 471 return this.visitor.Box (pc, type, Push (pc, 1), Pop (pc, 0), data); 472 } 473 474 public TResult ConstrainedCallvirt<TypeList, ArgList>(APC pc, Method method, TypeNode constraint, TypeList extraVarargs, Dummy dest, ArgList args, TData data) 475 where TypeList : IIndexable<TypeNode> 476 where ArgList : IIndexable<Dummy> 477 { 478 int argsCount = GetParametersCount (method, extraVarargs == null ? 0 : extraVarargs.Count); 479 return this.visitor.ConstrainedCallvirt (pc, method, constraint, extraVarargs, Push (pc, argsCount, this.parent.MetaDataProvider.ReturnType (method)), PopSequence (pc, argsCount, 0), data); 480 } 481 CastClass(APC pc, TypeNode type, Dummy dest, Dummy obj, TData data)482 public TResult CastClass(APC pc, TypeNode type, Dummy dest, Dummy obj, TData data) 483 { 484 return this.visitor.CastClass (pc, type, Push (pc, 1), Pop (pc, 0), data); 485 } 486 CopyObj(APC pc, TypeNode type, Dummy destPtr, Dummy sourcePtr, TData data)487 public TResult CopyObj(APC pc, TypeNode type, Dummy destPtr, Dummy sourcePtr, TData data) 488 { 489 return this.visitor.CopyObj (pc, type, Pop (pc, 1), Pop (pc, 0), data); 490 } 491 Initobj(APC pc, TypeNode type, Dummy ptr, TData data)492 public TResult Initobj(APC pc, TypeNode type, Dummy ptr, TData data) 493 { 494 return this.visitor.Initobj (pc, type, Pop (pc, 0), data); 495 } 496 LoadElement(APC pc, TypeNode type, Dummy dest, Dummy array, Dummy index, TData data)497 public TResult LoadElement(APC pc, TypeNode type, Dummy dest, Dummy array, Dummy index, TData data) 498 { 499 return this.visitor.LoadElement (pc, type, Push (pc, 2), Pop (pc, 1), Pop (pc, 0), data); 500 } 501 LoadField(APC pc, Field field, Dummy dest, Dummy obj, TData data)502 public TResult LoadField(APC pc, Field field, Dummy dest, Dummy obj, TData data) 503 { 504 return this.visitor.LoadField (pc, field, Push (pc, 1), Pop (pc, 0), data); 505 } 506 LoadFieldAddress(APC pc, Field field, Dummy dest, Dummy obj, TData data)507 public TResult LoadFieldAddress(APC pc, Field field, Dummy dest, Dummy obj, TData data) 508 { 509 return this.visitor.LoadFieldAddress (pc, field, Push (pc, 1), Pop (pc, 0), data); 510 } 511 LoadLength(APC pc, Dummy dest, Dummy array, TData data)512 public TResult LoadLength(APC pc, Dummy dest, Dummy array, TData data) 513 { 514 return this.visitor.LoadLength (pc, Push (pc, 1), Pop (pc, 0), data); 515 } 516 LoadStaticField(APC pc, Field field, Dummy dest, TData data)517 public TResult LoadStaticField(APC pc, Field field, Dummy dest, TData data) 518 { 519 return this.visitor.LoadStaticField (pc, field, Push (pc, 0), data); 520 } 521 LoadStaticFieldAddress(APC pc, Field field, Dummy dest, TData data)522 public TResult LoadStaticFieldAddress(APC pc, Field field, Dummy dest, TData data) 523 { 524 return this.visitor.LoadStaticFieldAddress (pc, field, Push (pc, 0), data); 525 } 526 LoadTypeToken(APC pc, TypeNode type, Dummy dest, TData data)527 public TResult LoadTypeToken(APC pc, TypeNode type, Dummy dest, TData data) 528 { 529 return this.visitor.LoadTypeToken (pc, type, Push (pc, 0), data); 530 } 531 LoadFieldToken(APC pc, Field field, Dummy dest, TData data)532 public TResult LoadFieldToken(APC pc, Field field, Dummy dest, TData data) 533 { 534 return this.visitor.LoadFieldToken (pc, field, Push (pc, 0), data); 535 } 536 LoadMethodToken(APC pc, Method method, Dummy dest, TData data)537 public TResult LoadMethodToken(APC pc, Method method, Dummy dest, TData data) 538 { 539 return this.visitor.LoadMethodToken (pc, method, Push (pc, 0), data); 540 } 541 542 public TResult NewArray<ArgList>(APC pc, TypeNode type, Dummy dest, ArgList lengths, TData data) 543 where ArgList : IIndexable<Dummy> 544 { 545 return this.visitor.NewArray (pc, type, Push (pc, 1), PopSequence (pc, lengths.Count, 0), data); 546 } 547 548 public TResult NewObj<ArgList>(APC pc, Method ctor, Dummy dest, ArgList args, TData data) 549 where ArgList : IIndexable<Dummy> 550 { 551 int argsCount = GetParametersCount (ctor, 0) - 1; 552 return this.visitor.NewObj (pc, ctor, Push (pc, argsCount), PopSequence (pc, argsCount, 0), data); 553 } 554 MkRefAny(APC pc, TypeNode type, Dummy dest, Dummy obj, TData data)555 public TResult MkRefAny(APC pc, TypeNode type, Dummy dest, Dummy obj, TData data) 556 { 557 return this.visitor.MkRefAny (pc, type, Push (pc, 1), Pop (pc, 0), data); 558 } 559 RefAnyType(APC pc, Dummy dest, Dummy source, TData data)560 public TResult RefAnyType(APC pc, Dummy dest, Dummy source, TData data) 561 { 562 return this.visitor.RefAnyType (pc, Push (pc, 1), Pop (pc, 0), data); 563 } 564 RefAnyVal(APC pc, TypeNode type, Dummy dest, Dummy source, TData data)565 public TResult RefAnyVal(APC pc, TypeNode type, Dummy dest, Dummy source, TData data) 566 { 567 return this.visitor.RefAnyVal (pc, type, Push (pc, 1), Pop (pc, 0), data); 568 } 569 Rethrow(APC pc, TData data)570 public TResult Rethrow(APC pc, TData data) 571 { 572 return this.visitor.Rethrow (pc, data); 573 } 574 StoreElement(APC pc, TypeNode type, Dummy array, Dummy index, Dummy value, TData data)575 public TResult StoreElement(APC pc, TypeNode type, Dummy array, Dummy index, Dummy value, TData data) 576 { 577 return this.visitor.StoreElement (pc, type, Pop (pc, 2), Pop (pc, 1), Pop (pc, 0), data); 578 } 579 StoreField(APC pc, Field field, Dummy obj, Dummy value, TData data)580 public TResult StoreField(APC pc, Field field, Dummy obj, Dummy value, TData data) 581 { 582 return this.visitor.StoreField (pc, field, Pop (pc, 1), Pop (pc, 0), data); 583 } 584 StoreStaticField(APC pc, Field field, Dummy value, TData data)585 public TResult StoreStaticField(APC pc, Field field, Dummy value, TData data) 586 { 587 return this.visitor.StoreStaticField (pc, field, Pop (pc, 0), data); 588 } 589 Throw(APC pc, Dummy exception, TData data)590 public TResult Throw(APC pc, Dummy exception, TData data) 591 { 592 return this.visitor.Throw (pc, Pop (pc, 0), data); 593 } 594 Unbox(APC pc, TypeNode type, Dummy dest, Dummy obj, TData data)595 public TResult Unbox(APC pc, TypeNode type, Dummy dest, Dummy obj, TData data) 596 { 597 return this.visitor.Unbox (pc, type, Push (pc, 1), Pop (pc, 0), data); 598 } 599 UnboxAny(APC pc, TypeNode type, Dummy dest, Dummy obj, TData data)600 public TResult UnboxAny(APC pc, TypeNode type, Dummy dest, Dummy obj, TData data) 601 { 602 return this.visitor.UnboxAny (pc, type, Push (pc, 1), Pop (pc, 0), data); 603 } 604 #endregion 605 } 606 }