[System] Suppress a few instances of CS0618 obsolete warnings
[mono.git] / mcs / class / Mono.CodeContracts / Mono.CodeContracts.Static.Analysis.StackAnalysis / StackDepthProvider.cs
1 // 
2 // StackDepthProvider.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 System.IO;
32 using Mono.CodeContracts.Static.AST;
33 using Mono.CodeContracts.Static.AST.Visitors;
34 using Mono.CodeContracts.Static.ControlFlow;
35 using Mono.CodeContracts.Static.DataStructures;
36 using Mono.CodeContracts.Static.Providers;
37
38 namespace Mono.CodeContracts.Static.Analysis.StackAnalysis {
39         class StackDepthProvider<TContext> : IILVisitor<APC, Dummy, Dummy, StackInfo, StackInfo>,
40                                                     IILDecoder<APC, int, int, IStackContextProvider, Dummy>,
41                                                     IStackContextProvider, IStackContext,
42                                                     IMethodContext,
43                                                     ICFG,
44                                                     IStackInfo where TContext : IMethodContextProvider {
45                 private readonly IILDecoder<APC, Dummy, Dummy, TContext, Dummy> il_decoder;
46                 private int cached_subroutine;
47                 private APCMap<int> local_stack_depth_cache;
48                 private APCMap<int> stack_depth_mirror_for_end_old;
49                 private bool recursion_guard;
50
51                 public StackDepthProvider (IILDecoder<APC, Dummy, Dummy, TContext, Dummy> ilDecoder,
52                                            IMetaDataProvider metaDataProvider)
53                 {
54                         this.il_decoder = ilDecoder;
55                         MetaDataProvider = metaDataProvider;
56                 }
57
58                 #region Implementation of IILDecoder<APC,Local,Parameter,Method,Field,Type,int,int,IStackContextProvider<Field,Method>,Dummy>
59                 public TResult ForwardDecode<TData, TResult, TVisitor> (APC pc, TVisitor visitor, TData data)
60                         where TVisitor : IILVisitor<APC, int, int, TData, TResult>
61                 {
62                         if (pc.Index != 0 || pc.SubroutineContext != null || pc.Block != pc.Block.Subroutine.Exit || !pc.Block.Subroutine.IsMethod)
63                                 return this.il_decoder.ForwardDecode<TData, TResult, StackDecoder<TContext, TData, TResult, TVisitor>> (pc, new StackDecoder<TContext, TData, TResult, TVisitor> (this, visitor), data);
64                         if (!pc.Block.Subroutine.HasReturnValue)
65                                 return visitor.Return (pc, -1, data);
66
67                         int source = GlobalStackDepth (pc) - 1;
68                         return visitor.Return (pc, source, data);
69                 }
70
71                 public bool IsUnreachable (APC pc)
72                 {
73                         return false;
74                 }
75
76                 public Dummy EdgeData (APC @from, APC to)
77                 {
78                         return Dummy.Value;
79                 }
80                 #endregion
81
82                 public IMetaDataProvider MetaDataProvider { get; private set; }
83
84                 private ICFG UnderlyingCFG
85                 {
86                         get { return this.il_decoder.ContextProvider.MethodContext.CFG; }
87                 }
88
89                 #region IILDecoder<APC,int,int,IStackContextProvider,Dummy> Members
90                 public IStackContextProvider ContextProvider
91                 {
92                         get { return this; }
93                 }
94                 #endregion
95
96                 #region IStackContextProvider Members
97                 public IStackContext StackContext
98                 {
99                         get { return this; }
100                 }
101
102                 public IMethodContext MethodContext
103                 {
104                         get { return this; }
105                 }
106                 #endregion
107
108                 public int GlobalStackDepth (APC pc)
109                 {
110                         int num = LocalStackDepth (pc);
111
112                         if (pc.SubroutineContext == null || !pc.Block.Subroutine.HasContextDependentStackDepth)
113                                 return num;
114
115                         CFGBlock block = pc.SubroutineContext.Head.From;
116                         return num + GlobalStackDepth (APC.ForEnd (block, pc.SubroutineContext.Tail));
117                 }
118
119                 public int LocalStackDepth (APC pc)
120                 {
121                         return LocalStackMap (pc.Block.Subroutine) [pc];
122                 }
123
124                 private int OldStartDepth (Subroutine subroutine)
125                 {
126                         Method method = ((IMethodInfo) subroutine).Method;
127                         int count = MetaDataProvider.Parameters (method).Count;
128                         if (!MetaDataProvider.IsConstructor (method) && !MetaDataProvider.IsStatic (method))
129                                 ++count;
130                         return count;
131                 }
132
133                 private APCMap<int> LocalStackMap (Subroutine subroutine)
134                 {
135                         if (this.local_stack_depth_cache == null || this.cached_subroutine != subroutine.Id) {
136                                 this.local_stack_depth_cache = GetStackDepthMap (subroutine);
137                                 this.cached_subroutine = subroutine.Id;
138                         }
139                         return this.local_stack_depth_cache;
140                 }
141
142                 private APCMap<int> GetStackDepthMap (Subroutine subroutine)
143                 {
144                         APCMap<int> result;
145                         var key = new TypedKey ("stackDepthKey");
146                         if (!subroutine.TryGetValue (key, out result)) {
147                                 result = ComputeStackDepthMap (subroutine);
148                                 subroutine.Add (key, result);
149                         }
150                         return result;
151                 }
152
153                 private APCMap<int> ComputeStackDepthMap (Subroutine subroutine)
154                 {
155                         var startDepths = new Dictionary<int, StackInfo> (subroutine.BlockCount);
156                         APCMap<int> apcMap = this.stack_depth_mirror_for_end_old = new APCMap<int> (subroutine);
157
158                         foreach (CFGBlock block in subroutine.Blocks) {
159                                 StackInfo stackInfo;
160                                 if (!startDepths.TryGetValue (block.Index, out stackInfo))
161                                         stackInfo = ComputeBlockStartDepth (block);
162                                 foreach (APC apc in block.APCs ()) {
163                                         apcMap.Add (apc, stackInfo.Depth);
164                                         stackInfo = this.il_decoder.ForwardDecode<StackInfo, StackInfo, IILVisitor<APC, Dummy, Dummy, StackInfo, StackInfo>> (apc, this, stackInfo);
165                                 }
166                                 if (!apcMap.ContainsKey (block.Last))
167                                         apcMap.Add (block.Last, stackInfo.Depth);
168                                 foreach (CFGBlock successor in subroutine.SuccessorBlocks (block)) {
169                                         bool oldRecursionGuard = this.recursion_guard;
170                                         this.recursion_guard = true;
171                                         try {
172                                                 bool isExceptionHandlerEdge;
173                                                 foreach (var info in subroutine.EdgeSubroutinesOuterToInner (block, successor, out isExceptionHandlerEdge, null).AsEnumerable ())
174                                                         stackInfo.Adjust (info.Value.StackDelta);
175                                         } finally {
176                                                 this.recursion_guard = oldRecursionGuard;
177                                         }
178                                         AddStartDepth (startDepths, successor, stackInfo);
179                                 }
180                         }
181                         return apcMap;
182                 }
183
184                 private StackInfo ComputeBlockStartDepth (CFGBlock block)
185                 {
186                         if (block.Subroutine.IsCatchFilterHeader (block))
187                                 return new StackInfo (1, 2);
188                         return new StackInfo (0, 4);
189                 }
190
191                 private void AddStartDepth (Dictionary<int, StackInfo> dict, CFGBlock block, StackInfo stackDepth)
192                 {
193                         StackInfo stackInfo;
194                         if (dict.TryGetValue (block.Index, out stackInfo))
195                                 return;
196                         dict.Add (block.Index, stackDepth.Clone ());
197                 }
198
199                 #region Implementation of ICFG
200                 APC ICFG.Entry
201                 {
202                         get { return UnderlyingCFG.Entry; }
203                 }
204
205                 APC ICFG.EntryAfterRequires
206                 {
207                         get { return UnderlyingCFG.EntryAfterRequires; }
208                 }
209
210                 APC ICFG.NormalExit
211                 {
212                         get { return UnderlyingCFG.NormalExit; }
213                 }
214
215                 APC ICFG.ExceptionExit
216                 {
217                         get { return UnderlyingCFG.ExceptionExit; }
218                 }
219
220                 Subroutine ICFG.Subroutine
221                 {
222                         get { return UnderlyingCFG.Subroutine; }
223                 }
224
225                 APC ICFG.Next (APC pc)
226                 {
227                         APC singleSuccessor;
228                         if (((ICFG) this).HasSingleSuccessor (pc, out singleSuccessor))
229                                 return singleSuccessor;
230                         return pc;
231                 }
232
233                 bool ICFG.HasSingleSuccessor (APC pc, out APC successor)
234                 {
235                         DecoratorHelper.Push (this);
236                         try {
237                                 return UnderlyingCFG.HasSingleSuccessor (pc, out successor);
238                         } finally {
239                                 DecoratorHelper.Pop ();
240                         }
241                 }
242
243                 bool ICFG.HasSinglePredecessor (APC pc, out APC predecessor)
244                 {
245                         DecoratorHelper.Push (this);
246                         try {
247                                 return UnderlyingCFG.HasSinglePredecessor (pc, out predecessor);
248                         } finally {
249                                 DecoratorHelper.Pop ();
250                         }
251                 }
252
253                 IEnumerable<APC> ICFG.Successors (APC pc)
254                 {
255                         DecoratorHelper.Push (this);
256                         try {
257                                 return UnderlyingCFG.Successors (pc);
258                         } finally {
259                                 DecoratorHelper.Pop ();
260                         }
261                 }
262
263                 IEnumerable<APC> ICFG.Predecessors (APC pc)
264                 {
265                         DecoratorHelper.Push (this);
266                         try {
267                                 return UnderlyingCFG.Predecessors (pc);
268                         } finally {
269                                 DecoratorHelper.Pop ();
270                         }
271                 }
272
273                 bool ICFG.IsJoinPoint (APC pc)
274                 {
275                         return UnderlyingCFG.IsJoinPoint (pc);
276                 }
277
278                 bool ICFG.IsSplitPoint (APC pc)
279                 {
280                         return UnderlyingCFG.IsSplitPoint (pc);
281                 }
282
283                 bool ICFG.IsBlockStart (APC pc)
284                 {
285                         return UnderlyingCFG.IsBlockStart (pc);
286                 }
287
288                 bool ICFG.IsBlockEnd (APC pc)
289                 {
290                         return UnderlyingCFG.IsBlockEnd (pc);
291                 }
292
293                 IILDecoder<APC, Dummy, Dummy, IMethodContextProvider, Dummy> ICFG.GetDecoder (IMetaDataProvider metaDataProvider)
294                 {
295                         return UnderlyingCFG.GetDecoder (metaDataProvider);
296                 }
297
298                 void ICFG.Print (TextWriter tw, ILPrinter<APC> printer, Func<CFGBlock, IEnumerable<Sequence<Edge<CFGBlock, EdgeTag>>>> contextLookup,
299                                  Sequence<Edge<CFGBlock, EdgeTag>> context)
300                 {
301                         DecoratorHelper.Push (this);
302                         try {
303                                 UnderlyingCFG.Print (tw, printer, contextLookup, context);
304                         } finally {
305                                 DecoratorHelper.Pop ();
306                         }
307                 }
308
309             public bool IsForwardBackEdge (APC @from, APC to)
310             {
311                 return this.UnderlyingCFG.IsForwardBackEdge (from, to);
312             }
313
314             public APC Post (APC pc)
315             {
316                     return UnderlyingCFG.Post (pc);
317             }
318
319                 #endregion
320
321                 #region Implementation of IStackInfo
322                 bool IStackInfo.IsCallOnThis (APC pc)
323                 {
324                         if (this.recursion_guard)
325                                 return false;
326                         return LocalStackMap (pc.Block.Subroutine).IsCallOnThis (pc);
327                 }
328                 #endregion
329
330                 #region Implementation of IStackContext<Field,Method>
331                 public int StackDepth (APC pc)
332                 {
333                         return GlobalStackDepth (pc);
334                 }
335                 #endregion
336
337                 #region Implementation of IMethodContext<Field,Method>
338                 Method IMethodContext.CurrentMethod
339                 {
340                         get { return this.il_decoder.ContextProvider.MethodContext.CurrentMethod; }
341                 }
342
343                 ICFG IMethodContext.CFG
344                 {
345                         get { return this; }
346                 }
347
348                 public IEnumerable<Field> Modifies (Method method)
349                 {
350                         return this.il_decoder.ContextProvider.MethodContext.Modifies (method);
351                 }
352
353                 public IEnumerable<Method> AffectedGetters (Field field)
354                 {
355                         return this.il_decoder.ContextProvider.MethodContext.AffectedGetters (field);
356                 }
357                 #endregion
358
359                 #region Implementation of IExpressionILVisitor<APC,Type,Dummy,Dummy,StackInfo,StackInfo>
360                 public StackInfo Binary (APC pc, BinaryOperator op, Dummy dest, Dummy operand1, Dummy operand2, StackInfo data)
361                 {
362                         return data.Pop (2).Push ();
363                 }
364
365                 public StackInfo Isinst (APC pc, TypeNode type, Dummy dest, Dummy obj, StackInfo data)
366                 {
367                         return data;
368                 }
369
370                 public StackInfo LoadNull (APC pc, Dummy dest, StackInfo polarity)
371                 {
372                         return polarity.Push ();
373                 }
374
375                 public StackInfo LoadConst (APC pc, TypeNode type, object constant, Dummy dest, StackInfo data)
376                 {
377                         return data.Push ();
378                 }
379
380                 public StackInfo Sizeof (APC pc, TypeNode type, Dummy dest, StackInfo data)
381                 {
382                         return data.Push ();
383                 }
384
385                 public StackInfo Unary (APC pc, UnaryOperator op, bool unsigned, Dummy dest, Dummy source, StackInfo data)
386                 {
387                         return data.Pop (1).Push ();
388                 }
389                 #endregion
390
391                 #region Implementation of ISyntheticILVisitor<APC,Method,Field,Type,Dummy,Dummy,StackInfo,StackInfo>
392                 public StackInfo Entry (APC pc, Method method, StackInfo data)
393                 {
394                         return data;
395                 }
396
397                 public StackInfo Assume (APC pc, EdgeTag tag, Dummy condition, StackInfo data)
398                 {
399                         return data.Pop (1);
400                 }
401
402                 public StackInfo Assert (APC pc, EdgeTag tag, Dummy condition, StackInfo data)
403                 {
404                         return data.Pop (1);
405                 }
406
407                 public StackInfo BeginOld (APC pc, APC matchingEnd, StackInfo data)
408                 {
409                         return new StackInfo (OldStartDepth (pc.Block.Subroutine), 4);
410                 }
411
412
413                 public StackInfo EndOld (APC pc, APC matchingBegin, TypeNode type, Dummy dest, Dummy source, StackInfo data)
414                 {
415                         return new StackInfo (this.stack_depth_mirror_for_end_old [matchingBegin] + 1, 4);
416                 }
417
418                 public StackInfo LoadStack (APC pc, int offset, Dummy dest, Dummy source, bool isOld, StackInfo data)
419                 {
420                         return data.Push (data [offset]);
421                 }
422
423                 public StackInfo LoadStackAddress (APC pc, int offset, Dummy dest, Dummy source, TypeNode type, bool isOld, StackInfo data)
424                 {
425                         return data.Push ();
426                 }
427
428                 public StackInfo LoadResult (APC pc, TypeNode type, Dummy dest, Dummy source, StackInfo data)
429                 {
430                         return data.Push ();
431                 }
432                 #endregion
433
434                 #region Implementation of IILVisitor<APC,Local,Parameter,Method,Field,Type,Dummy,Dummy,StackInfo,StackInfo>
435                 public StackInfo Arglist (APC pc, Dummy dest, StackInfo data)
436                 {
437                         return data.Push ();
438                 }
439
440                 public StackInfo Branch (APC pc, APC target, bool leavesExceptionBlock, StackInfo data)
441                 {
442                         return data;
443                 }
444
445                 public StackInfo BranchCond (APC pc, APC target, BranchOperator bop, Dummy value1, Dummy value2, StackInfo data)
446                 {
447                         return data.Pop (2);
448                 }
449
450                 public StackInfo BranchTrue (APC pc, APC target, Dummy cond, StackInfo data)
451                 {
452                         return data.Pop (1);
453                 }
454
455                 public StackInfo BranchFalse (APC pc, APC target, Dummy cond, StackInfo data)
456                 {
457                         return data.Pop (1);
458                 }
459
460                 public StackInfo Break (APC pc, StackInfo data)
461                 {
462                         return data;
463                 }
464
465                 public StackInfo Call<TypeList, ArgList> (APC pc, Method method, bool virt, TypeList extraVarargs, Dummy dest, ArgList args, StackInfo data)
466                         where TypeList : IIndexable<TypeNode>
467                         where ArgList : IIndexable<Dummy>
468                 {
469                         int count = MetaDataProvider.Parameters (method).Count + (extraVarargs == null ? 0 : extraVarargs.Count);
470                         if (!MetaDataProvider.IsStatic (method)) {
471                                 if (data.IsThis (count))
472                                         this.stack_depth_mirror_for_end_old.AddCallOnThis (pc);
473                                 ++count;
474                         }
475                         data = data.Pop (count);
476                         if (MetaDataProvider.IsVoidMethod (method))
477                                 return data;
478                         return data.Push ();
479                 }
480
481                 public StackInfo Calli<TypeList, ArgList> (APC pc, TypeNode returnType, TypeList argTypes, bool instance, Dummy dest, Dummy functionPointer, ArgList args, StackInfo data)
482                         where TypeList : IIndexable<TypeNode>
483                         where ArgList : IIndexable<Dummy>
484                 {
485                         int count = 1;
486                         if (instance)
487                                 ++count;
488                         int slots = count + (argTypes == null ? 0 : argTypes.Count);
489                         data.Pop (slots);
490                         if (MetaDataProvider.IsVoid (returnType))
491                                 return data;
492                         return data.Push ();
493                 }
494
495                 public StackInfo CheckFinite (APC pc, Dummy dest, Dummy source, StackInfo data)
496                 {
497                         return data;
498                 }
499
500                 public StackInfo CopyBlock (APC pc, Dummy destAddress, Dummy srcAddress, Dummy len, StackInfo data)
501                 {
502                         return data.Pop (3);
503                 }
504
505                 public StackInfo EndFilter (APC pc, Dummy decision, StackInfo data)
506                 {
507                         return data.Pop (1);
508                 }
509
510                 public StackInfo EndFinally (APC pc, StackInfo data)
511                 {
512                         return new StackInfo (0, 0);
513                 }
514
515                 public StackInfo Jmp (APC pc, Method method, StackInfo data)
516                 {
517                         return new StackInfo (0, 0);
518                 }
519
520                 public StackInfo LoadArg (APC pc, Parameter argument, bool isOld, Dummy dest, StackInfo data)
521                 {
522                         if (!MetaDataProvider.IsStatic (MetaDataProvider.DeclaringMethod (argument)) && MetaDataProvider.ParameterIndex (argument) == 0)
523                                 return data.PushThis ();
524
525                         return data.Push ();
526                 }
527
528                 public StackInfo LoadArgAddress (APC pc, Parameter argument, bool isOld, Dummy dest, StackInfo data)
529                 {
530                         return data.Push ();
531                 }
532
533                 public StackInfo LoadLocal (APC pc, Local local, Dummy dest, StackInfo data)
534                 {
535                         return data.Push ();
536                 }
537
538                 public StackInfo LoadLocalAddress (APC pc, Local local, Dummy dest, StackInfo data)
539                 {
540                         return data.Push ();
541                 }
542
543                 public StackInfo Nop (APC pc, StackInfo data)
544                 {
545                         return data;
546                 }
547
548                 public StackInfo Pop (APC pc, Dummy source, StackInfo data)
549                 {
550                         return data.Pop (1);
551                 }
552
553                 public StackInfo Return (APC pc, Dummy source, StackInfo data)
554                 {
555                         return data;
556                 }
557
558                 public StackInfo StoreArg (APC pc, Parameter argument, Dummy source, StackInfo data)
559                 {
560                         return data.Pop (1);
561                 }
562
563                 public StackInfo StoreLocal (APC pc, Local local, Dummy source, StackInfo data)
564                 {
565                         return data.Pop (1);
566                 }
567
568                 public StackInfo Switch (APC pc, TypeNode type, IEnumerable<Pair<object, APC>> cases, Dummy value, StackInfo data)
569                 {
570                         return data.Pop (1);
571                 }
572
573                 public StackInfo Box (APC pc, TypeNode type, Dummy dest, Dummy source, StackInfo data)
574                 {
575                         return data.Pop (1).Push ();
576                 }
577
578                 public StackInfo ConstrainedCallvirt<TypeList, ArgList> (APC pc, Method method, TypeNode constraint, TypeList extraVarargs, Dummy dest, ArgList args, StackInfo data)
579                         where TypeList : IIndexable<TypeNode>
580                         where ArgList : IIndexable<Dummy>
581                 {
582                         int paramsCount = MetaDataProvider.Parameters (method).Count + (extraVarargs == null ? 0 : extraVarargs.Count);
583                         if (!MetaDataProvider.IsStatic (method)) {
584                                 if (data.IsThis (paramsCount))
585                                         this.stack_depth_mirror_for_end_old.AddCallOnThis (pc);
586                                 ++paramsCount;
587                         }
588
589                         data = data.Pop (paramsCount);
590                         if (MetaDataProvider.IsVoid (MetaDataProvider.ReturnType (method)))
591                                 return data;
592
593                         return data.Push ();
594                 }
595
596                 public StackInfo CastClass (APC pc, TypeNode type, Dummy dest, Dummy obj, StackInfo data)
597                 {
598                         return data;
599                 }
600
601                 public StackInfo CopyObj (APC pc, TypeNode type, Dummy destPtr, Dummy sourcePtr, StackInfo data)
602                 {
603                         return data.Pop (2);
604                 }
605
606                 public StackInfo Initobj (APC pc, TypeNode type, Dummy ptr, StackInfo data)
607                 {
608                         return data.Pop (1);
609                 }
610
611                 public StackInfo LoadElement (APC pc, TypeNode type, Dummy dest, Dummy array, Dummy index, StackInfo data)
612                 {
613                         return data.Pop (2).Push ();
614                 }
615
616                 public StackInfo LoadField (APC pc, Field field, Dummy dest, Dummy obj, StackInfo data)
617                 {
618                         return data.Pop (1).Push ();
619                 }
620
621                 public StackInfo LoadFieldAddress (APC pc, Field field, Dummy dest, Dummy obj, StackInfo data)
622                 {
623                         return data.Pop (1).Push ();
624                 }
625
626                 public StackInfo LoadLength (APC pc, Dummy dest, Dummy array, StackInfo data)
627                 {
628                         return data.Pop (1).Push ();
629                 }
630
631                 public StackInfo LoadStaticField (APC pc, Field field, Dummy dest, StackInfo data)
632                 {
633                         return data.Push ();
634                 }
635
636                 public StackInfo LoadStaticFieldAddress (APC pc, Field field, Dummy dest, StackInfo data)
637                 {
638                         return data.Push ();
639                 }
640
641                 public StackInfo LoadTypeToken (APC pc, TypeNode type, Dummy dest, StackInfo data)
642                 {
643                         return data.Push ();
644                 }
645
646                 public StackInfo LoadFieldToken (APC pc, Field type, Dummy dest, StackInfo data)
647                 {
648                         return data.Push ();
649                 }
650
651                 public StackInfo LoadMethodToken (APC pc, Method type, Dummy dest, StackInfo data)
652                 {
653                         return data.Push ();
654                 }
655
656                 public StackInfo NewArray<ArgList> (APC pc, TypeNode type, Dummy dest, ArgList lengths, StackInfo data) where ArgList : IIndexable<Dummy>
657                 {
658                         return data.Pop (lengths.Count).Push ();
659                 }
660
661                 public StackInfo NewObj<ArgList> (APC pc, Method ctor, Dummy dest, ArgList args, StackInfo data) where ArgList : IIndexable<Dummy>
662                 {
663                         int paramsCount = MetaDataProvider.Parameters (ctor).Count;
664                         return data.Pop (paramsCount).Push ();
665                 }
666
667                 public StackInfo MkRefAny (APC pc, TypeNode type, Dummy dest, Dummy obj, StackInfo data)
668                 {
669                         return data;
670                 }
671
672                 public StackInfo RefAnyType (APC pc, Dummy dest, Dummy source, StackInfo data)
673                 {
674                         return data.Pop (1).Push ();
675                 }
676
677                 public StackInfo RefAnyVal (APC pc, TypeNode type, Dummy dest, Dummy source, StackInfo data)
678                 {
679                         return data.Pop (1).Push ();
680                 }
681
682                 public StackInfo Rethrow (APC pc, StackInfo data)
683                 {
684                         return new StackInfo (0, 0);
685                 }
686
687                 public StackInfo StoreElement (APC pc, TypeNode type, Dummy array, Dummy index, Dummy value, StackInfo data)
688                 {
689                         return data.Pop (3);
690                 }
691
692                 public StackInfo StoreField (APC pc, Field field, Dummy obj, Dummy value, StackInfo data)
693                 {
694                         return data.Pop (2);
695                 }
696
697                 public StackInfo StoreStaticField (APC pc, Field field, Dummy value, StackInfo data)
698                 {
699                         return data.Pop (1);
700                 }
701
702                 public StackInfo Throw (APC pc, Dummy exception, StackInfo data)
703                 {
704                         return new StackInfo (0, 0);
705                 }
706
707                 public StackInfo Unbox (APC pc, TypeNode type, Dummy dest, Dummy obj, StackInfo data)
708                 {
709                         return data.Pop (1).Push ();
710                 }
711
712                 public StackInfo UnboxAny (APC pc, TypeNode type, Dummy dest, Dummy obj, StackInfo data)
713                 {
714                         return data.Pop (1).Push ();
715                 }
716                 #endregion
717         }
718 }