private void GenerateFunctionConstructor(ClassFileWriter cfw)
{
int SCOPE_ARG = 1;
int CONTEXT_ARG = 2;
int ID_ARG = 3;
cfw.StartMethod("<init>", FUNCTION_CONSTRUCTOR_SIGNATURE, ClassFileWriter.ACC_PUBLIC);
cfw.AddALoad(0);
cfw.AddInvoke(ByteCode.INVOKESPECIAL, SUPER_CLASS_NAME, "<init>", "()V");
cfw.AddLoadThis();
cfw.AddILoad(ID_ARG);
cfw.Add(ByteCode.PUTFIELD, cfw.GetClassName(), ID_FIELD_NAME, "I");
cfw.AddLoadThis();
cfw.AddALoad(CONTEXT_ARG);
cfw.AddALoad(SCOPE_ARG);
int start = (scriptOrFnNodes[0].GetType() == Token.SCRIPT) ? 1 : 0;
int end = scriptOrFnNodes.Length;
if (start == end)
{
throw BadTree();
}
bool generateSwitch = (2 <= end - start);
int switchStart = 0;
int switchStackTop = 0;
if (generateSwitch)
{
cfw.AddILoad(ID_ARG);
// do switch from (start + 1, end - 1) mapping start to
// the default case
switchStart = cfw.AddTableSwitch(start + 1, end - 1);
}
for (int i = start; i != end; ++i)
{
if (generateSwitch)
{
if (i == start)
{
cfw.MarkTableSwitchDefault(switchStart);
switchStackTop = cfw.GetStackTop();
}
else
{
cfw.MarkTableSwitchCase(switchStart, i - 1 - start, switchStackTop);
}
}
OptFunctionNode ofn = OptFunctionNode.Get(scriptOrFnNodes[i]);
cfw.AddInvoke(ByteCode.INVOKESPECIAL, mainClassName, GetFunctionInitMethodName(ofn), FUNCTION_INIT_SIGNATURE);
cfw.Add(ByteCode.RETURN);
}
// 4 = this + scope + context + id
cfw.StopMethod((short)4);
}