-
1. Re: about sun jvm can't use local var
adinn Oct 27, 2011 5:16 AM (in response to swimablefish)Hi swimable,
swimablefish wrote:
hi , I've read about this problem, https://issues.jboss.org/browse/BYTEMAN-28 . We use sun's jvm, that means we can't use this function.
Is it possible that byteman provide a array which contain's local var, then we can according to the order of the local var showed in method to
get the local var. So we can get rid of the dependence on the jvm. I don't know whether this solutions is feasible.
Yes, it would be possible to provide some sort of anonymous indexed syntax for accessing local variables in the same way as for parameter variables. So, for example, given a method like this
class MapUtils
{
. . .
public long cityBlockMetric(Point p1, Point p2)
{
int x1 = p1.x;
int x2 = p2.x;
int y1 = p1.y;
int y2 = p2.y;
long result = 0;
if (x1 < x2) {int xDiff = (x2 - x1);
result += xDiff;
} else {
int xDiff = (x1 - x2);
result += xDiff;
}
if (y1 < y2) {
int yDiff = (y2 - y1);
result += yDiff;
} else {
int yDiff = (y1 - y2);
result += yDiff;
}
}
return result;
}
You could use a trace rule like this to trace each fo the asisgnments to result
RULE trace metric
CLASS MapUtils
METHOD cityBlockMetric
AFTER WRITE $local5 ALL
IF TRUE
DO traceln("added " + $local6 + " to result " $local5)
ENDRULE
This rule would match the four assignments inside the if/else clauses because there are 6 local variables present at those points so the references to $local5 and $local6 clearly make sense. However, it would fail to match the initial assignment of result because the reference to $local6 would not be able to be resolved. At each of the four matching trigger locations $local5 can be clearly identified as the local variable result of type long and $local6 as an int local variable -- either xDiff or yDiff.
If instead you were to use an array $locals[] then and you wodl have to refer to the locals vars as follows.
RULE trace metric
CLASS MapUtils
METHOD cityBlockMetric
AFTER WRITE $locals[5] ALL
IF TRUE
DO traceln("added " + $locals[6] + " to result " $locals[5])
ENDRULE
Two problems occur here. First you could only safely typecheck the array as an Object[]. This means $locals[5] would have to be typed as an Object. That would not matter much in this rule because the value is only used in the call to traceln but it would matter if you actually wanted to use $locals[5] as a long or $locals[6] as an int. For that to work you would need some way of casting it to a long (I am thinking about a solution to hwo to cast values in rules but that's another rather long story)
The second problem is that this rule would match the initial assignment where locals only has length 5. So the reference to $locals[6] in the action will result in an array bounds exception. To make this work correctly you woudl need to add a condition which would stop the rule firing at the first trigger location
RULE trace metric
CLASS MapUtils
METHOD cityBlockMetric
AFTER WRITE $locals[5] ALL
IF $locals.length <= 5
DO traceln("added " + $locals[6] + " to result " $locals[5])
ENDRULE
So if anything were to be implemented then I think the first version is preferable.
I don't see this as being very difficult to add. I need to think more about how to refer to the local vars. Using $local1 etc is an option but it means references to local variables whose name really is local1, etc will then be misinterpreted. But thta's a small detail. My only real concern is that this feature is perhaps difficult to use. In order to write your rule you need to be able to keep track of how many local variables are in scope at each injection point. This is hard enough when you have a single injection point but when you use an ALL count for the location you may find that $local4 has a different type at different matching locatons.The result will be that you get typecheck errors for some locations while the rule is happily injected at others. That outcome is also posisbel but far less less likely when using actual local variable names because values with different types usually have different names, meanign that the rule wil fail to match rather than fail to typecheck.
Anyway, I think it is defiitely worth considering further the idea of providing this feature. So, thank you very much for the suggestion. I will raise a feature request JIRA for htis and add a link to this thread.