private object InvokeTarget(Scope scope) {
if (scope == _optimizedContext.GlobalScope && !_optimizedContext.LanguageContext.EnableTracing) {
EnsureCompiled();
Exception e = PythonOps.SaveCurrentException();
var funcCode = EnsureFunctionCode(_optimizedTarget, false, true);
PushFrame(_optimizedContext, funcCode);
try {
if (Ast.CompilerContext.SourceUnit.Kind == SourceCodeKind.Expression) {
return OptimizedEvalWrapper(funcCode);
}
return _optimizedTarget(funcCode);
} finally {
PythonOps.RestoreCurrentException(e);
PopFrame();
}
}
// if we're running against a different scope or we need tracing then re-compile the code.
if (_unoptimizedCode == null) {
// TODO: Copy instead of mutate
((PythonCompilerOptions)Ast.CompilerContext.Options).Optimized = false;
Interlocked.CompareExchange(
ref _unoptimizedCode,
Ast.MakeLookupCode().ToScriptCode(),
null
);
}
// This is a brand new ScriptCode which also handles all appropriate ScriptCode
// things such as pushing a function code or updating the stack trace for
// exec/eval code. Therefore we don't need to do any of that here.
return _unoptimizedCode.Run(scope);
}