internal void TranslateToIL(CompilerGlobals compilerGlobals){
if (this.suppressIL) return;
globals.ScopeStack.Push(this.own_scope);
try{
if (this.mb == null && this.cb == null)
this.GetMethodBase(compilerGlobals);
int offset = (this.attributes&MethodAttributes.Static) == MethodAttributes.Static ? 0 : 1;
int extras = 3;
if (this.isMethod)
extras = 0;
else if (!this.hasArgumentsObject)
extras = 2;
ILGenerator il = this.mb != null ? this.mb.GetILGenerator() : this.cb.GetILGenerator();
this.returnLabel = il.DefineLabel();
// Emit all the namespaces used by this function
if (this.body.Engine.GenerateDebugInfo){
ScriptObject ns = this.enclosing_scope.GetParent();
while (ns != null){
if (ns is PackageScope)
il.UsingNamespace(((PackageScope)ns).name);
else if (ns is WrappedNamespace && !((WrappedNamespace)ns).name.Equals(""))
il.UsingNamespace(((WrappedNamespace)ns).name);
ns = ns.GetParent();
}
}
if (!this.isImplicitCtor && this.body != null){
int startLine = this.body.context.StartLine;
int startCol = this.body.context.StartColumn;
this.body.context.document.EmitLineInfo(il, startLine, startCol, startLine, startCol + 1);
if (this.body.context.document.debugOn)
il.Emit(OpCodes.Nop);
}
//set up the compiler to emit direct accesses to the locals and pars.
int n = this.fields.Length;
for (int i = 0; i < n; i++){
// Use indexed lookup for the parameters. We must check to make sure the field
// is not a nested function as they might have the same name as a parameter.
int j = this.IsNestedFunctionField(this.fields[i]) ? -1 : System.Array.IndexOf(this.formal_parameters, this.fields[i].Name);
if (j >= 0)
this.fields[i].metaData = (short)(j+extras+offset);
else if (this.hasArgumentsObject && this.fields[i].Name.Equals("arguments"))
this.fields[i].metaData = (short)(2+offset);
else if (!this.fields[i].IsLiteral || this.fields[i].value is FunctionObject){
Type t = this.fields[i].FieldType;
LocalBuilder tok = il.DeclareLocal(t);
if (this.fields[i].debugOn)
tok.SetLocalSymInfo(this.fields[i].debuggerName);
this.fields[i].metaData = tok;
}else if (this.own_scope.mustSaveStackLocals){ //Need to emit a field. FunctionDeclaration will initialize it with a closure
LocalBuilder tok = il.DeclareLocal(this.fields[i].FieldType);
this.fields[i].metaData = tok;
}
}
if (this.isConstructor){
int pn = formal_parameters.Length+1;
ClassScope cscope = (ClassScope)this.enclosing_scope;
//Call the default super constructor followed by the field initializers
if (this.superConstructor == null)
cscope.owner.EmitInitialCalls(il, null, null, null, 0);
else{
ParameterInfo[] pars = this.superConstructor.GetParameters();
if (this.superConstructorCall != null)
cscope.owner.EmitInitialCalls(il, this.superConstructor, pars, this.superConstructorCall.arguments, pn);
else
cscope.owner.EmitInitialCalls(il, this.superConstructor, pars, null, pn);
}
}
if ((this.isMethod || this.isConstructor) && this.must_save_stack_locals){
this.TranslateToMethodWithStackFrame(il, compilerGlobals, false);
return;
}
this.TranslateToILToCopyOuterScopeLocals(il, true, null);
bool savedInsideProtectedRegion = compilerGlobals.InsideProtectedRegion;
compilerGlobals.InsideProtectedRegion = false;
bool savedInsideFinally = compilerGlobals.InsideFinally;
int savedFinallyStackTop = compilerGlobals.FinallyStackTop;
compilerGlobals.InsideFinally = false;
this.body.TranslateToILInitializer(il);
this.body.TranslateToIL(il, Typeob.Void);
compilerGlobals.InsideProtectedRegion = savedInsideProtectedRegion;
compilerGlobals.InsideFinally = savedInsideFinally;
compilerGlobals.FinallyStackTop = savedFinallyStackTop;
il.MarkLabel(this.returnLabel);
if (this.body.context.document.debugOn){
this.EmitLastLineInfo(il);
il.Emit(OpCodes.Nop);
}
this.TranslateToILToSaveLocals(il); //put locals on heap so that nested functions can get to them
if (this.own_scope.returnVar != null)
il.Emit(OpCodes.Ldloc, (LocalBuilder)this.own_scope.returnVar.GetMetaData());
il.Emit(OpCodes.Ret);
}finally{
globals.ScopeStack.Pop();
}
}