Update mcs/class/Commons.Xml.Relaxng/Commons.Xml.Relaxng/RelaxngPattern.cs
[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<LispList<Edge<CFGBlock, EdgeTag>>>> contextLookup,
299                                  LispList<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                 #endregion
309
310                 #region Implementation of IStackInfo
311                 bool IStackInfo.IsCallOnThis (APC pc)
312                 {
313                         if (this.recursion_guard)
314                                 return false;
315                         return LocalStackMap (pc.Block.Subroutine).IsCallOnThis (pc);
316                 }
317                 #endregion
318
319                 #region Implementation of IStackContext<Field,Method>
320                 public int StackDepth (APC pc)
321                 {
322                         return GlobalStackDepth (pc);
323                 }
324                 #endregion
325
326                 #region Implementation of IMethodContext<Field,Method>
327                 Method IMethodContext.CurrentMethod
328                 {
329                         get { return this.il_decoder.ContextProvider.MethodContext.CurrentMethod; }
330                 }
331
332                 ICFG IMethodContext.CFG
333                 {
334                         get { return this; }
335                 }
336
337                 public IEnumerable<Field> Modifies (Method method)
338                 {
339                         return this.il_decoder.ContextProvider.MethodContext.Modifies (method);
340                 }
341
342                 public IEnumerable<Method> AffectedGetters (Field field)
343                 {
344                         return this.il_decoder.ContextProvider.MethodContext.AffectedGetters (field);
345                 }
346                 #endregion
347
348                 #region Implementation of IExpressionILVisitor<APC,Type,Dummy,Dummy,StackInfo,StackInfo>
349                 public StackInfo Binary (APC pc, BinaryOperator op, Dummy dest, Dummy operand1, Dummy operand2, StackInfo data)
350                 {
351                         return data.Pop (2).Push ();
352                 }
353
354                 public StackInfo Isinst (APC pc, TypeNode type, Dummy dest, Dummy obj, StackInfo data)
355                 {
356                         return data;
357                 }
358
359                 public StackInfo LoadNull (APC pc, Dummy dest, StackInfo polarity)
360                 {
361                         return polarity.Push ();
362                 }
363
364                 public StackInfo LoadConst (APC pc, TypeNode type, object constant, Dummy dest, StackInfo data)
365                 {
366                         return data.Push ();
367                 }
368
369                 public StackInfo Sizeof (APC pc, TypeNode type, Dummy dest, StackInfo data)
370                 {
371                         return data.Push ();
372                 }
373
374                 public StackInfo Unary (APC pc, UnaryOperator op, bool unsigned, Dummy dest, Dummy source, StackInfo data)
375                 {
376                         return data.Pop (1).Push ();
377                 }
378                 #endregion
379
380                 #region Implementation of ISyntheticILVisitor<APC,Method,Field,Type,Dummy,Dummy,StackInfo,StackInfo>
381                 public StackInfo Entry (APC pc, Method method, StackInfo data)
382                 {
383                         return data;
384                 }
385
386                 public StackInfo Assume (APC pc, EdgeTag tag, Dummy condition, StackInfo data)
387                 {
388                         return data.Pop (1);
389                 }
390
391                 public StackInfo Assert (APC pc, EdgeTag tag, Dummy condition, StackInfo data)
392                 {
393                         return data.Pop (1);
394                 }
395
396                 public StackInfo BeginOld (APC pc, APC matchingEnd, StackInfo data)
397                 {
398                         return new StackInfo (OldStartDepth (pc.Block.Subroutine), 4);
399                 }
400
401
402                 public StackInfo EndOld (APC pc, APC matchingBegin, TypeNode type, Dummy dest, Dummy source, StackInfo data)
403                 {
404                         return new StackInfo (this.stack_depth_mirror_for_end_old [matchingBegin] + 1, 4);
405                 }
406
407                 public StackInfo LoadStack (APC pc, int offset, Dummy dest, Dummy source, bool isOld, StackInfo data)
408                 {
409                         return data.Push (data [offset]);
410                 }
411
412                 public StackInfo LoadStackAddress (APC pc, int offset, Dummy dest, Dummy source, TypeNode type, bool isOld, StackInfo data)
413                 {
414                         return data.Push ();
415                 }
416
417                 public StackInfo LoadResult (APC pc, TypeNode type, Dummy dest, Dummy source, StackInfo data)
418                 {
419                         return data.Push ();
420                 }
421                 #endregion
422
423                 #region Implementation of IILVisitor<APC,Local,Parameter,Method,Field,Type,Dummy,Dummy,StackInfo,StackInfo>
424                 public StackInfo Arglist (APC pc, Dummy dest, StackInfo data)
425                 {
426                         return data.Push ();
427                 }
428
429                 public StackInfo Branch (APC pc, APC target, bool leavesExceptionBlock, StackInfo data)
430                 {
431                         return data;
432                 }
433
434                 public StackInfo BranchCond (APC pc, APC target, BranchOperator bop, Dummy value1, Dummy value2, StackInfo data)
435                 {
436                         return data.Pop (2);
437                 }
438
439                 public StackInfo BranchTrue (APC pc, APC target, Dummy cond, StackInfo data)
440                 {
441                         return data.Pop (1);
442                 }
443
444                 public StackInfo BranchFalse (APC pc, APC target, Dummy cond, StackInfo data)
445                 {
446                         return data.Pop (1);
447                 }
448
449                 public StackInfo Break (APC pc, StackInfo data)
450                 {
451                         return data;
452                 }
453
454                 public StackInfo Call<TypeList, ArgList> (APC pc, Method method, bool virt, TypeList extraVarargs, Dummy dest, ArgList args, StackInfo data)
455                         where TypeList : IIndexable<TypeNode>
456                         where ArgList : IIndexable<Dummy>
457                 {
458                         int count = MetaDataProvider.Parameters (method).Count + (extraVarargs == null ? 0 : extraVarargs.Count);
459                         if (!MetaDataProvider.IsStatic (method)) {
460                                 if (data.IsThis (count))
461                                         this.stack_depth_mirror_for_end_old.AddCallOnThis (pc);
462                                 ++count;
463                         }
464                         data = data.Pop (count);
465                         if (MetaDataProvider.IsVoidMethod (method))
466                                 return data;
467                         return data.Push ();
468                 }
469
470                 public StackInfo Calli<TypeList, ArgList> (APC pc, TypeNode returnType, TypeList argTypes, bool instance, Dummy dest, Dummy functionPointer, ArgList args, StackInfo data)
471                         where TypeList : IIndexable<TypeNode>
472                         where ArgList : IIndexable<Dummy>
473                 {
474                         int count = 1;
475                         if (instance)
476                                 ++count;
477                         int slots = count + (argTypes == null ? 0 : argTypes.Count);
478                         data.Pop (slots);
479                         if (MetaDataProvider.IsVoid (returnType))
480                                 return data;
481                         return data.Push ();
482                 }
483
484                 public StackInfo CheckFinite (APC pc, Dummy dest, Dummy source, StackInfo data)
485                 {
486                         return data;
487                 }
488
489                 public StackInfo CopyBlock (APC pc, Dummy destAddress, Dummy srcAddress, Dummy len, StackInfo data)
490                 {
491                         return data.Pop (3);
492                 }
493
494                 public StackInfo EndFilter (APC pc, Dummy decision, StackInfo data)
495                 {
496                         return data.Pop (1);
497                 }
498
499                 public StackInfo EndFinally (APC pc, StackInfo data)
500                 {
501                         return new StackInfo (0, 0);
502                 }
503
504                 public StackInfo Jmp (APC pc, Method method, StackInfo data)
505                 {
506                         return new StackInfo (0, 0);
507                 }
508
509                 public StackInfo LoadArg (APC pc, Parameter argument, bool isOld, Dummy dest, StackInfo data)
510                 {
511                         if (!MetaDataProvider.IsStatic (MetaDataProvider.DeclaringMethod (argument)) && MetaDataProvider.ParameterIndex (argument) == 0)
512                                 return data.PushThis ();
513
514                         return data.Push ();
515                 }
516
517                 public StackInfo LoadArgAddress (APC pc, Parameter argument, bool isOld, Dummy dest, StackInfo data)
518                 {
519                         return data.Push ();
520                 }
521
522                 public StackInfo LoadLocal (APC pc, Local local, Dummy dest, StackInfo data)
523                 {
524                         return data.Push ();
525                 }
526
527                 public StackInfo LoadLocalAddress (APC pc, Local local, Dummy dest, StackInfo data)
528                 {
529                         return data.Push ();
530                 }
531
532                 public StackInfo Nop (APC pc, StackInfo data)
533                 {
534                         return data;
535                 }
536
537                 public StackInfo Pop (APC pc, Dummy source, StackInfo data)
538                 {
539                         return data.Pop (1);
540                 }
541
542                 public StackInfo Return (APC pc, Dummy source, StackInfo data)
543                 {
544                         return data;
545                 }
546
547                 public StackInfo StoreArg (APC pc, Parameter argument, Dummy source, StackInfo data)
548                 {
549                         return data.Pop (1);
550                 }
551
552                 public StackInfo StoreLocal (APC pc, Local local, Dummy source, StackInfo data)
553                 {
554                         return data.Pop (1);
555                 }
556
557                 public StackInfo Switch (APC pc, TypeNode type, IEnumerable<Pair<object, APC>> cases, Dummy value, StackInfo data)
558                 {
559                         return data.Pop (1);
560                 }
561
562                 public StackInfo Box (APC pc, TypeNode type, Dummy dest, Dummy source, StackInfo data)
563                 {
564                         return data.Pop (1).Push ();
565                 }
566
567                 public StackInfo ConstrainedCallvirt<TypeList, ArgList> (APC pc, Method method, TypeNode constraint, TypeList extraVarargs, Dummy dest, ArgList args, StackInfo data)
568                         where TypeList : IIndexable<TypeNode>
569                         where ArgList : IIndexable<Dummy>
570                 {
571                         int paramsCount = MetaDataProvider.Parameters (method).Count + (extraVarargs == null ? 0 : extraVarargs.Count);
572                         if (!MetaDataProvider.IsStatic (method)) {
573                                 if (data.IsThis (paramsCount))
574                                         this.stack_depth_mirror_for_end_old.AddCallOnThis (pc);
575                                 ++paramsCount;
576                         }
577
578                         data = data.Pop (paramsCount);
579                         if (MetaDataProvider.IsVoid (MetaDataProvider.ReturnType (method)))
580                                 return data;
581
582                         return data.Push ();
583                 }
584
585                 public StackInfo CastClass (APC pc, TypeNode type, Dummy dest, Dummy obj, StackInfo data)
586                 {
587                         return data;
588                 }
589
590                 public StackInfo CopyObj (APC pc, TypeNode type, Dummy destPtr, Dummy sourcePtr, StackInfo data)
591                 {
592                         return data.Pop (2);
593                 }
594
595                 public StackInfo Initobj (APC pc, TypeNode type, Dummy ptr, StackInfo data)
596                 {
597                         return data.Pop (1);
598                 }
599
600                 public StackInfo LoadElement (APC pc, TypeNode type, Dummy dest, Dummy array, Dummy index, StackInfo data)
601                 {
602                         return data.Pop (2).Push ();
603                 }
604
605                 public StackInfo LoadField (APC pc, Field field, Dummy dest, Dummy obj, StackInfo data)
606                 {
607                         return data.Pop (1).Push ();
608                 }
609
610                 public StackInfo LoadFieldAddress (APC pc, Field field, Dummy dest, Dummy obj, StackInfo data)
611                 {
612                         return data.Pop (1).Push ();
613                 }
614
615                 public StackInfo LoadLength (APC pc, Dummy dest, Dummy array, StackInfo data)
616                 {
617                         return data.Pop (1).Push ();
618                 }
619
620                 public StackInfo LoadStaticField (APC pc, Field field, Dummy dest, StackInfo data)
621                 {
622                         return data.Push ();
623                 }
624
625                 public StackInfo LoadStaticFieldAddress (APC pc, Field field, Dummy dest, StackInfo data)
626                 {
627                         return data.Push ();
628                 }
629
630                 public StackInfo LoadTypeToken (APC pc, TypeNode type, Dummy dest, StackInfo data)
631                 {
632                         return data.Push ();
633                 }
634
635                 public StackInfo LoadFieldToken (APC pc, Field type, Dummy dest, StackInfo data)
636                 {
637                         return data.Push ();
638                 }
639
640                 public StackInfo LoadMethodToken (APC pc, Method type, Dummy dest, StackInfo data)
641                 {
642                         return data.Push ();
643                 }
644
645                 public StackInfo NewArray<ArgList> (APC pc, TypeNode type, Dummy dest, ArgList lengths, StackInfo data) where ArgList : IIndexable<Dummy>
646                 {
647                         return data.Pop (lengths.Count).Push ();
648                 }
649
650                 public StackInfo NewObj<ArgList> (APC pc, Method ctor, Dummy dest, ArgList args, StackInfo data) where ArgList : IIndexable<Dummy>
651                 {
652                         int paramsCount = MetaDataProvider.Parameters (ctor).Count;
653                         return data.Pop (paramsCount).Push ();
654                 }
655
656                 public StackInfo MkRefAny (APC pc, TypeNode type, Dummy dest, Dummy obj, StackInfo data)
657                 {
658                         return data;
659                 }
660
661                 public StackInfo RefAnyType (APC pc, Dummy dest, Dummy source, StackInfo data)
662                 {
663                         return data.Pop (1).Push ();
664                 }
665
666                 public StackInfo RefAnyVal (APC pc, TypeNode type, Dummy dest, Dummy source, StackInfo data)
667                 {
668                         return data.Pop (1).Push ();
669                 }
670
671                 public StackInfo Rethrow (APC pc, StackInfo data)
672                 {
673                         return new StackInfo (0, 0);
674                 }
675
676                 public StackInfo StoreElement (APC pc, TypeNode type, Dummy array, Dummy index, Dummy value, StackInfo data)
677                 {
678                         return data.Pop (3);
679                 }
680
681                 public StackInfo StoreField (APC pc, Field field, Dummy obj, Dummy value, StackInfo data)
682                 {
683                         return data.Pop (2);
684                 }
685
686                 public StackInfo StoreStaticField (APC pc, Field field, Dummy value, StackInfo data)
687                 {
688                         return data.Pop (1);
689                 }
690
691                 public StackInfo Throw (APC pc, Dummy exception, StackInfo data)
692                 {
693                         return new StackInfo (0, 0);
694                 }
695
696                 public StackInfo Unbox (APC pc, TypeNode type, Dummy dest, Dummy obj, StackInfo data)
697                 {
698                         return data.Pop (1).Push ();
699                 }
700
701                 public StackInfo UnboxAny (APC pc, TypeNode type, Dummy dest, Dummy obj, StackInfo data)
702                 {
703                         return data.Pop (1).Push ();
704                 }
705                 #endregion
706         }
707 }