// do switch from 1 .. count - 1 mapping 0 to the default case
switchStart = cfw.addTableSwitch(1, count - 1);
}
for (int i = 0; i != count; ++i) {
ScriptNode n = scriptOrFnNodes[i];
if (i == 0) {
if (count > 1) {
cfw.markTableSwitchDefault(switchStart);
switchStackTop = cfw.getStackTop();
}
} else {
cfw.markTableSwitchCase(switchStart, i - 1,
switchStackTop);
}
// Impelemnet method-specific switch code
switch (methodIndex) {
case Do_getFunctionName:
// Push function name
if (n.getType() == Token.SCRIPT) {
cfw.addPush("");
} else {
String name = ((FunctionNode)n).getName();
cfw.addPush(name);
}
cfw.add(ByteCode.ARETURN);
break;
case Do_getParamCount:
// Push number of defined parameters
cfw.addPush(n.getParamCount());
cfw.add(ByteCode.IRETURN);
break;
case Do_getParamAndVarCount:
// Push number of defined parameters and declared variables
cfw.addPush(n.getParamAndVarCount());
cfw.add(ByteCode.IRETURN);
break;
case Do_getParamOrVarName:
// Push name of parameter using another switch
// over paramAndVarCount
int paramAndVarCount = n.getParamAndVarCount();
if (paramAndVarCount == 0) {
// The runtime should never call the method in this
// case but to make bytecode verifier happy return null
// as throwing execption takes more code
cfw.add(ByteCode.ACONST_NULL);
cfw.add(ByteCode.ARETURN);
} else if (paramAndVarCount == 1) {
// As above do not check for valid index but always
// return the name of the first param
cfw.addPush(n.getParamOrVarName(0));
cfw.add(ByteCode.ARETURN);
} else {
// Do switch over getParamOrVarName
cfw.addILoad(1); // param or var index
// do switch from 1 .. paramAndVarCount - 1 mapping 0
// to the default case
int paramSwitchStart = cfw.addTableSwitch(
1, paramAndVarCount - 1);
for (int j = 0; j != paramAndVarCount; ++j) {
if (cfw.getStackTop() != 0) Kit.codeBug();
String s = n.getParamOrVarName(j);
if (j == 0) {
cfw.markTableSwitchDefault(paramSwitchStart);
} else {
cfw.markTableSwitchCase(paramSwitchStart, j - 1,
0);
}
cfw.addPush(s);
cfw.add(ByteCode.ARETURN);
}
}
break;
case Do_getParamOrVarConst:
// Push name of parameter using another switch
// over paramAndVarCount
paramAndVarCount = n.getParamAndVarCount();
boolean [] constness = n.getParamAndVarConst();
if (paramAndVarCount == 0) {
// The runtime should never call the method in this
// case but to make bytecode verifier happy return null
// as throwing execption takes more code
cfw.add(ByteCode.ICONST_0);
cfw.add(ByteCode.IRETURN);
} else if (paramAndVarCount == 1) {
// As above do not check for valid index but always
// return the name of the first param
cfw.addPush(constness[0]);
cfw.add(ByteCode.IRETURN);
} else {
// Do switch over getParamOrVarName
cfw.addILoad(1); // param or var index
// do switch from 1 .. paramAndVarCount - 1 mapping 0
// to the default case
int paramSwitchStart = cfw.addTableSwitch(
1, paramAndVarCount - 1);
for (int j = 0; j != paramAndVarCount; ++j) {
if (cfw.getStackTop() != 0) Kit.codeBug();
if (j == 0) {
cfw.markTableSwitchDefault(paramSwitchStart);
} else {
cfw.markTableSwitchCase(paramSwitchStart, j - 1,
0);
}
cfw.addPush(constness[j]);
cfw.add(ByteCode.IRETURN);
}
}
break;
case Do_getEncodedSource:
// Push number encoded source start and end
// to prepare for encodedSource.substring(start, end)
cfw.addPush(n.getEncodedSourceStart());
cfw.addPush(n.getEncodedSourceEnd());
cfw.addInvoke(ByteCode.INVOKEVIRTUAL,
"java/lang/String",
"substring",
"(II)Ljava/lang/String;");
cfw.add(ByteCode.ARETURN);