The Hidden Parameter

time to read 3 min | 423 words

I have a problem doing AST manipulation at run time, sometimes the code work, and sometimes it doesn't. I know what cause the error, and I can fix it for one scenario, but then the other scenario is borken. I'm pretty sure that I'm doing something nasty, but I don't know what. I'm trying to build a method and reference its arguments, but I keep getting errors when I try to test this.

I'm actually reading raw IL (at least it's better than ASMx86), trying to figure out some things that aren't going well. The problem I've have is with parameter indexing. I've a piece of code that generate other code, and it works if I'm passing it a method with 3 parameters, but not if I pass a method with 4 parameters. Actually, that is not a good explanation, I generate a method (at compile time, using the Boo Compiler AST) based on another method. I add two parameters to this method. The problem is what to do when I'm referencing those parameters. Since the IL reference them by index (ldarg.1, ldarg.s, etc) and not by name (that is for us humans), I'm getting problems about null reference methods on some cases (but only some). The logic I'm using is

Found it!

I started to write this question when I suddenly saw the difference between the two cases, there is something in the asking that makes me suddenly view the problem in a different light. As you can see above, I first thought that this is a problem with the number of the parameters a method has, but the issue was different altogther. One of the methods was static, the other an instance method.

First, some background, what is the difference between an instance and a static method? A static method can't use this, can't access non static resources, etc. It took me so long to figure this out because I didn't notice that one method was static and the other wasn't. An instance method actually get this as a hidden parameter. The practical meaning of this is that for instance methods parameter indexing starts with 1, while parameter indexing for static methods starts with 0. That was the reason for the problem, and after adding three lines, the code is working for both conditions.

Thinking about it, the second I realized that the difference between the method wasn't the number of parameters but the static/instance issue, it was obvious what was causing the problem. (Reading a lot of the IL code didn't hurt, either :-).) I guess I should be thankful that I've experiance in C++, otherwise I would likely still be scratching my head.