Home | History | Annotate | Download | only in Expression
      1 //===-- ClangExpressionParser.cpp -------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "lldb/lldb-python.h"
     11 
     12 #include "lldb/Expression/ClangExpressionParser.h"
     13 
     14 #include "lldb/Core/ArchSpec.h"
     15 #include "lldb/Core/DataBufferHeap.h"
     16 #include "lldb/Core/Debugger.h"
     17 #include "lldb/Core/Disassembler.h"
     18 #include "lldb/Core/Stream.h"
     19 #include "lldb/Core/StreamString.h"
     20 #include "lldb/Expression/ClangASTSource.h"
     21 #include "lldb/Expression/ClangExpression.h"
     22 #include "lldb/Expression/ClangExpressionDeclMap.h"
     23 #include "lldb/Expression/IRExecutionUnit.h"
     24 #include "lldb/Expression/IRDynamicChecks.h"
     25 #include "lldb/Expression/IRInterpreter.h"
     26 #include "lldb/Target/ExecutionContext.h"
     27 #include "lldb/Target/ObjCLanguageRuntime.h"
     28 #include "lldb/Target/Process.h"
     29 #include "lldb/Target/Target.h"
     30 
     31 #include "clang/AST/ASTContext.h"
     32 #include "clang/AST/ExternalASTSource.h"
     33 #include "clang/Basic/FileManager.h"
     34 #include "clang/Basic/TargetInfo.h"
     35 #include "clang/Basic/Version.h"
     36 #include "clang/CodeGen/CodeGenAction.h"
     37 #include "clang/CodeGen/ModuleBuilder.h"
     38 #include "clang/Driver/CC1Options.h"
     39 #include "clang/Frontend/CompilerInstance.h"
     40 #include "clang/Frontend/CompilerInvocation.h"
     41 #include "clang/Frontend/FrontendActions.h"
     42 #include "clang/Frontend/FrontendDiagnostic.h"
     43 #include "clang/Frontend/FrontendPluginRegistry.h"
     44 #include "clang/Frontend/TextDiagnosticBuffer.h"
     45 #include "clang/Frontend/TextDiagnosticPrinter.h"
     46 #include "clang/Lex/Preprocessor.h"
     47 #include "clang/Parse/ParseAST.h"
     48 #include "clang/Rewrite/Frontend/FrontendActions.h"
     49 #include "clang/Sema/SemaConsumer.h"
     50 #include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
     51 
     52 #include "llvm/ADT/StringRef.h"
     53 #include "llvm/ExecutionEngine/ExecutionEngine.h"
     54 #include "llvm/Support/Debug.h"
     55 #include "llvm/Support/FileSystem.h"
     56 #include "llvm/Support/TargetSelect.h"
     57 
     58 #if defined(__FreeBSD__)
     59 #define USE_STANDARD_JIT
     60 #endif
     61 
     62 #if defined (USE_STANDARD_JIT)
     63 #include "llvm/ExecutionEngine/JIT.h"
     64 #else
     65 #include "llvm/ExecutionEngine/MCJIT.h"
     66 #endif
     67 #include "llvm/IR/LLVMContext.h"
     68 #include "llvm/IR/Module.h"
     69 #include "llvm/Support/ErrorHandling.h"
     70 #include "llvm/Support/MemoryBuffer.h"
     71 #include "llvm/Support/DynamicLibrary.h"
     72 #include "llvm/Support/Host.h"
     73 #include "llvm/Support/Signals.h"
     74 
     75 using namespace clang;
     76 using namespace llvm;
     77 using namespace lldb_private;
     78 
     79 //===----------------------------------------------------------------------===//
     80 // Utility Methods for Clang
     81 //===----------------------------------------------------------------------===//
     82 
     83 std::string GetBuiltinIncludePath(const char *Argv0) {
     84     SmallString<128> P(llvm::sys::fs::getMainExecutable(
     85         Argv0, (void *)(intptr_t) GetBuiltinIncludePath));
     86 
     87     if (!P.empty()) {
     88         llvm::sys::path::remove_filename(P); // Remove /clang from foo/bin/clang
     89         llvm::sys::path::remove_filename(P); // Remove /bin   from foo/bin
     90 
     91         // Get foo/lib/clang/<version>/include
     92         llvm::sys::path::append(P, "lib", "clang", CLANG_VERSION_STRING,
     93                                 "include");
     94     }
     95 
     96     return P.str();
     97 }
     98 
     99 
    100 //===----------------------------------------------------------------------===//
    101 // Main driver for Clang
    102 //===----------------------------------------------------------------------===//
    103 
    104 static void LLVMErrorHandler(void *UserData, const std::string &Message) {
    105     DiagnosticsEngine &Diags = *static_cast<DiagnosticsEngine*>(UserData);
    106 
    107     Diags.Report(diag::err_fe_error_backend) << Message;
    108 
    109     // We cannot recover from llvm errors.
    110     assert(0);
    111 }
    112 
    113 static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) {
    114     using namespace clang::frontend;
    115 
    116     switch (CI.getFrontendOpts().ProgramAction) {
    117         default:
    118             llvm_unreachable("Invalid program action!");
    119 
    120         case ASTDump:                return new ASTDumpAction();
    121         case ASTPrint:               return new ASTPrintAction();
    122         case ASTDumpXML:             return new ASTDumpXMLAction();
    123         case ASTView:                return new ASTViewAction();
    124         case DumpRawTokens:          return new DumpRawTokensAction();
    125         case DumpTokens:             return new DumpTokensAction();
    126         case EmitAssembly:           return new EmitAssemblyAction();
    127         case EmitBC:                 return new EmitBCAction();
    128         case EmitHTML:               return new HTMLPrintAction();
    129         case EmitLLVM:               return new EmitLLVMAction();
    130         case EmitLLVMOnly:           return new EmitLLVMOnlyAction();
    131         case EmitCodeGenOnly:        return new EmitCodeGenOnlyAction();
    132         case EmitObj:                return new EmitObjAction();
    133         case FixIt:                  return new FixItAction();
    134         case GeneratePCH:            return new GeneratePCHAction();
    135         case GeneratePTH:            return new GeneratePTHAction();
    136         case InitOnly:               return new InitOnlyAction();
    137         case ParseSyntaxOnly:        return new SyntaxOnlyAction();
    138 
    139         case PluginAction: {
    140             for (FrontendPluginRegistry::iterator it =
    141                  FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end();
    142                  it != ie; ++it) {
    143                 if (it->getName() == CI.getFrontendOpts().ActionName) {
    144                     llvm::OwningPtr<PluginASTAction> P(it->instantiate());
    145                     if (!P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs))
    146                         return 0;
    147                     return P.take();
    148                 }
    149             }
    150 
    151             CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name)
    152             << CI.getFrontendOpts().ActionName;
    153             return 0;
    154         }
    155 
    156         case PrintDeclContext:       return new DeclContextPrintAction();
    157         case PrintPreamble:          return new PrintPreambleAction();
    158         case PrintPreprocessedInput: return new PrintPreprocessedAction();
    159         case RewriteMacros:          return new RewriteMacrosAction();
    160         case RewriteObjC:            return new RewriteObjCAction();
    161         case RewriteTest:            return new RewriteTestAction();
    162         //case RunAnalysis:            return new AnalysisAction();
    163         case RunPreprocessorOnly:    return new PreprocessOnlyAction();
    164     }
    165 }
    166 
    167 static FrontendAction *CreateFrontendAction(CompilerInstance &CI) {
    168     // Create the underlying action.
    169     FrontendAction *Act = CreateFrontendBaseAction(CI);
    170     if (!Act)
    171         return 0;
    172 
    173     // If there are any AST files to merge, create a frontend action
    174     // adaptor to perform the merge.
    175     if (!CI.getFrontendOpts().ASTMergeFiles.empty())
    176         Act = new ASTMergeAction(Act, CI.getFrontendOpts().ASTMergeFiles);
    177 
    178     return Act;
    179 }
    180 
    181 //===----------------------------------------------------------------------===//
    182 // Implementation of ClangExpressionParser
    183 //===----------------------------------------------------------------------===//
    184 
    185 ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
    186                                               ClangExpression &expr) :
    187     m_expr (expr),
    188     m_compiler (),
    189     m_code_generator ()
    190 {
    191     // Initialize targets first, so that --version shows registered targets.
    192     static struct InitializeLLVM {
    193         InitializeLLVM() {
    194             llvm::InitializeAllTargets();
    195             llvm::InitializeAllAsmPrinters();
    196             llvm::InitializeAllTargetMCs();
    197             llvm::InitializeAllDisassemblers();
    198 
    199             llvm::DisablePrettyStackTrace = true;
    200         }
    201     } InitializeLLVM;
    202 
    203     // 1. Create a new compiler instance.
    204     m_compiler.reset(new CompilerInstance());
    205 
    206     // 2. Install the target.
    207 
    208     lldb::TargetSP target_sp;
    209     if (exe_scope)
    210         target_sp = exe_scope->CalculateTarget();
    211 
    212     // TODO: figure out what to really do when we don't have a valid target.
    213     // Sometimes this will be ok to just use the host target triple (when we
    214     // evaluate say "2+3", but other expressions like breakpoint conditions
    215     // and other things that _are_ target specific really shouldn't just be
    216     // using the host triple. This needs to be fixed in a better way.
    217     if (target_sp && target_sp->GetArchitecture().IsValid())
    218     {
    219         std::string triple = target_sp->GetArchitecture().GetTriple().str();
    220 
    221         int dash_count = 0;
    222         for (size_t i = 0; i < triple.size(); ++i)
    223         {
    224             if (triple[i] == '-')
    225                 dash_count++;
    226             if (dash_count == 3)
    227             {
    228                 triple.resize(i);
    229                 break;
    230             }
    231         }
    232 
    233         m_compiler->getTargetOpts().Triple = triple;
    234     }
    235     else
    236     {
    237         m_compiler->getTargetOpts().Triple = llvm::sys::getDefaultTargetTriple();
    238     }
    239 
    240     if (target_sp->GetArchitecture().GetMachine() == llvm::Triple::x86 ||
    241         target_sp->GetArchitecture().GetMachine() == llvm::Triple::x86_64)
    242     {
    243         m_compiler->getTargetOpts().Features.push_back("+sse");
    244         m_compiler->getTargetOpts().Features.push_back("+sse2");
    245     }
    246 
    247     if (m_compiler->getTargetOpts().Triple.find("ios") != std::string::npos)
    248         m_compiler->getTargetOpts().ABI = "apcs-gnu";
    249 
    250     m_compiler->createDiagnostics();
    251 
    252     // Create the target instance.
    253     m_compiler->setTarget(TargetInfo::CreateTargetInfo(m_compiler->getDiagnostics(),
    254                                                        &m_compiler->getTargetOpts()));
    255 
    256     assert (m_compiler->hasTarget());
    257 
    258     // 3. Set options.
    259 
    260     lldb::LanguageType language = expr.Language();
    261 
    262     switch (language)
    263     {
    264     case lldb::eLanguageTypeC:
    265         break;
    266     case lldb::eLanguageTypeObjC:
    267         m_compiler->getLangOpts().ObjC1 = true;
    268         m_compiler->getLangOpts().ObjC2 = true;
    269         break;
    270     case lldb::eLanguageTypeC_plus_plus:
    271         m_compiler->getLangOpts().CPlusPlus = true;
    272         m_compiler->getLangOpts().CPlusPlus11 = true;
    273         break;
    274     case lldb::eLanguageTypeObjC_plus_plus:
    275     default:
    276         m_compiler->getLangOpts().ObjC1 = true;
    277         m_compiler->getLangOpts().ObjC2 = true;
    278         m_compiler->getLangOpts().CPlusPlus = true;
    279         m_compiler->getLangOpts().CPlusPlus11 = true;
    280         break;
    281     }
    282 
    283     m_compiler->getLangOpts().Bool = true;
    284     m_compiler->getLangOpts().WChar = true;
    285     m_compiler->getLangOpts().Blocks = true;
    286     m_compiler->getLangOpts().DebuggerSupport = true; // Features specifically for debugger clients
    287     if (expr.DesiredResultType() == ClangExpression::eResultTypeId)
    288         m_compiler->getLangOpts().DebuggerCastResultToId = true;
    289 
    290     // Spell checking is a nice feature, but it ends up completing a
    291     // lot of types that we didn't strictly speaking need to complete.
    292     // As a result, we spend a long time parsing and importing debug
    293     // information.
    294     m_compiler->getLangOpts().SpellChecking = false;
    295 
    296     lldb::ProcessSP process_sp;
    297     if (exe_scope)
    298         process_sp = exe_scope->CalculateProcess();
    299 
    300     if (process_sp && m_compiler->getLangOpts().ObjC1)
    301     {
    302         if (process_sp->GetObjCLanguageRuntime())
    303         {
    304             if (process_sp->GetObjCLanguageRuntime()->GetRuntimeVersion() == eAppleObjC_V2)
    305                 m_compiler->getLangOpts().ObjCRuntime.set(ObjCRuntime::MacOSX, VersionTuple(10, 7));
    306             else
    307                 m_compiler->getLangOpts().ObjCRuntime.set(ObjCRuntime::FragileMacOSX, VersionTuple(10, 7));
    308 
    309             if (process_sp->GetObjCLanguageRuntime()->HasNewLiteralsAndIndexing())
    310                 m_compiler->getLangOpts().DebuggerObjCLiteral = true;
    311         }
    312     }
    313 
    314     m_compiler->getLangOpts().ThreadsafeStatics = false;
    315     m_compiler->getLangOpts().AccessControl = false; // Debuggers get universal access
    316     m_compiler->getLangOpts().DollarIdents = true; // $ indicates a persistent variable name
    317 
    318     // Set CodeGen options
    319     m_compiler->getCodeGenOpts().EmitDeclMetadata = true;
    320     m_compiler->getCodeGenOpts().InstrumentFunctions = false;
    321 
    322     // Disable some warnings.
    323     m_compiler->getDiagnostics().setDiagnosticGroupMapping("unused-value", clang::diag::MAP_IGNORE, SourceLocation());
    324     m_compiler->getDiagnostics().setDiagnosticGroupMapping("odr", clang::diag::MAP_IGNORE, SourceLocation());
    325 
    326     // Inform the target of the language options
    327     //
    328     // FIXME: We shouldn't need to do this, the target should be immutable once
    329     // created. This complexity should be lifted elsewhere.
    330     m_compiler->getTarget().setForcedLangOptions(m_compiler->getLangOpts());
    331 
    332     // 4. Set up the diagnostic buffer for reporting errors
    333 
    334     m_compiler->getDiagnostics().setClient(new clang::TextDiagnosticBuffer);
    335 
    336     // 5. Set up the source management objects inside the compiler
    337 
    338     clang::FileSystemOptions file_system_options;
    339     m_file_manager.reset(new clang::FileManager(file_system_options));
    340 
    341     if (!m_compiler->hasSourceManager())
    342         m_compiler->createSourceManager(*m_file_manager.get());
    343 
    344     m_compiler->createFileManager();
    345     m_compiler->createPreprocessor();
    346 
    347     // 6. Most of this we get from the CompilerInstance, but we
    348     // also want to give the context an ExternalASTSource.
    349     m_selector_table.reset(new SelectorTable());
    350     m_builtin_context.reset(new Builtin::Context());
    351 
    352     std::unique_ptr<clang::ASTContext> ast_context(new ASTContext(m_compiler->getLangOpts(),
    353                                                                  m_compiler->getSourceManager(),
    354                                                                  &m_compiler->getTarget(),
    355                                                                  m_compiler->getPreprocessor().getIdentifierTable(),
    356                                                                  *m_selector_table.get(),
    357                                                                  *m_builtin_context.get(),
    358                                                                  0));
    359 
    360     ClangExpressionDeclMap *decl_map = m_expr.DeclMap();
    361 
    362     if (decl_map)
    363     {
    364         llvm::OwningPtr<clang::ExternalASTSource> ast_source(decl_map->CreateProxy());
    365         decl_map->InstallASTContext(ast_context.get());
    366         ast_context->setExternalSource(ast_source);
    367     }
    368 
    369     m_compiler->setASTContext(ast_context.release());
    370 
    371     std::string module_name("$__lldb_module");
    372 
    373     m_llvm_context.reset(new LLVMContext());
    374     m_code_generator.reset(CreateLLVMCodeGen(m_compiler->getDiagnostics(),
    375                                              module_name,
    376                                              m_compiler->getCodeGenOpts(),
    377                                              m_compiler->getTargetOpts(),
    378                                              *m_llvm_context));
    379 }
    380 
    381 ClangExpressionParser::~ClangExpressionParser()
    382 {
    383 }
    384 
    385 unsigned
    386 ClangExpressionParser::Parse (Stream &stream)
    387 {
    388     TextDiagnosticBuffer *diag_buf = static_cast<TextDiagnosticBuffer*>(m_compiler->getDiagnostics().getClient());
    389 
    390     diag_buf->FlushDiagnostics (m_compiler->getDiagnostics());
    391 
    392     MemoryBuffer *memory_buffer = MemoryBuffer::getMemBufferCopy(m_expr.Text(), __FUNCTION__);
    393     m_compiler->getSourceManager().createMainFileIDForMemBuffer (memory_buffer);
    394 
    395     diag_buf->BeginSourceFile(m_compiler->getLangOpts(), &m_compiler->getPreprocessor());
    396 
    397     ASTConsumer *ast_transformer = m_expr.ASTTransformer(m_code_generator.get());
    398 
    399     if (ast_transformer)
    400         ParseAST(m_compiler->getPreprocessor(), ast_transformer, m_compiler->getASTContext());
    401     else
    402         ParseAST(m_compiler->getPreprocessor(), m_code_generator.get(), m_compiler->getASTContext());
    403 
    404     diag_buf->EndSourceFile();
    405 
    406     TextDiagnosticBuffer::const_iterator diag_iterator;
    407 
    408     int num_errors = 0;
    409 
    410     for (diag_iterator = diag_buf->warn_begin();
    411          diag_iterator != diag_buf->warn_end();
    412          ++diag_iterator)
    413         stream.Printf("warning: %s\n", (*diag_iterator).second.c_str());
    414 
    415     num_errors = 0;
    416 
    417     for (diag_iterator = diag_buf->err_begin();
    418          diag_iterator != diag_buf->err_end();
    419          ++diag_iterator)
    420     {
    421         num_errors++;
    422         stream.Printf("error: %s\n", (*diag_iterator).second.c_str());
    423     }
    424 
    425     for (diag_iterator = diag_buf->note_begin();
    426          diag_iterator != diag_buf->note_end();
    427          ++diag_iterator)
    428         stream.Printf("note: %s\n", (*diag_iterator).second.c_str());
    429 
    430     if (!num_errors)
    431     {
    432         if (m_expr.DeclMap() && !m_expr.DeclMap()->ResolveUnknownTypes())
    433         {
    434             stream.Printf("error: Couldn't infer the type of a variable\n");
    435             num_errors++;
    436         }
    437     }
    438 
    439     return num_errors;
    440 }
    441 
    442 static bool FindFunctionInModule (ConstString &mangled_name,
    443                                   llvm::Module *module,
    444                                   const char *orig_name)
    445 {
    446     for (llvm::Module::iterator fi = module->getFunctionList().begin(), fe = module->getFunctionList().end();
    447          fi != fe;
    448          ++fi)
    449     {
    450         if (fi->getName().str().find(orig_name) != std::string::npos)
    451         {
    452             mangled_name.SetCString(fi->getName().str().c_str());
    453             return true;
    454         }
    455     }
    456 
    457     return false;
    458 }
    459 
    460 Error
    461 ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
    462                                             lldb::addr_t &func_end,
    463                                             std::unique_ptr<IRExecutionUnit> &execution_unit_ap,
    464                                             ExecutionContext &exe_ctx,
    465                                             bool &can_interpret,
    466                                             ExecutionPolicy execution_policy)
    467 {
    468 	func_addr = LLDB_INVALID_ADDRESS;
    469 	func_end = LLDB_INVALID_ADDRESS;
    470     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
    471 
    472     std::unique_ptr<llvm::ExecutionEngine> execution_engine_ap;
    473 
    474     Error err;
    475 
    476     std::unique_ptr<llvm::Module> module_ap (m_code_generator->ReleaseModule());
    477 
    478     if (!module_ap.get())
    479     {
    480         err.SetErrorToGenericError();
    481         err.SetErrorString("IR doesn't contain a module");
    482         return err;
    483     }
    484 
    485     // Find the actual name of the function (it's often mangled somehow)
    486 
    487     ConstString function_name;
    488 
    489     if (!FindFunctionInModule(function_name, module_ap.get(), m_expr.FunctionName()))
    490     {
    491         err.SetErrorToGenericError();
    492         err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName());
    493         return err;
    494     }
    495     else
    496     {
    497         if (log)
    498             log->Printf("Found function %s for %s", function_name.AsCString(), m_expr.FunctionName());
    499     }
    500 
    501     m_execution_unit.reset(new IRExecutionUnit(m_llvm_context, // handed off here
    502                                                module_ap, // handed off here
    503                                                function_name,
    504                                                exe_ctx.GetTargetSP(),
    505                                                m_compiler->getTargetOpts().Features));
    506 
    507     ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); // result can be NULL
    508 
    509     if (decl_map)
    510     {
    511         Stream *error_stream = NULL;
    512         Target *target = exe_ctx.GetTargetPtr();
    513         if (target)
    514             error_stream = &target->GetDebugger().GetErrorStream();
    515 
    516         IRForTarget ir_for_target(decl_map,
    517                                   m_expr.NeedsVariableResolution(),
    518                                   *m_execution_unit,
    519                                   error_stream,
    520                                   function_name.AsCString());
    521 
    522         bool ir_can_run = ir_for_target.runOnModule(*m_execution_unit->GetModule());
    523 
    524         Error interpret_error;
    525 
    526         can_interpret = IRInterpreter::CanInterpret(*m_execution_unit->GetModule(), *m_execution_unit->GetFunction(), interpret_error);
    527 
    528         Process *process = exe_ctx.GetProcessPtr();
    529 
    530         if (!ir_can_run)
    531         {
    532             err.SetErrorString("The expression could not be prepared to run in the target");
    533             return err;
    534         }
    535 
    536         if (!can_interpret && execution_policy == eExecutionPolicyNever)
    537         {
    538             err.SetErrorStringWithFormat("Can't run the expression locally: %s", interpret_error.AsCString());
    539             return err;
    540         }
    541 
    542         if (!process && execution_policy == eExecutionPolicyAlways)
    543         {
    544             err.SetErrorString("Expression needed to run in the target, but the target can't be run");
    545             return err;
    546         }
    547 
    548         if (execution_policy == eExecutionPolicyAlways || !can_interpret)
    549         {
    550             if (m_expr.NeedsValidation() && process)
    551             {
    552                 if (!process->GetDynamicCheckers())
    553                 {
    554                     DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();
    555 
    556                     StreamString install_errors;
    557 
    558                     if (!dynamic_checkers->Install(install_errors, exe_ctx))
    559                     {
    560                         if (install_errors.GetString().empty())
    561                             err.SetErrorString ("couldn't install checkers, unknown error");
    562                         else
    563                             err.SetErrorString (install_errors.GetString().c_str());
    564 
    565                         return err;
    566                     }
    567 
    568                     process->SetDynamicCheckers(dynamic_checkers);
    569 
    570                     if (log)
    571                         log->Printf("== [ClangUserExpression::Evaluate] Finished installing dynamic checkers ==");
    572                 }
    573 
    574                 IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(), function_name.AsCString());
    575 
    576                 if (!ir_dynamic_checks.runOnModule(*m_execution_unit->GetModule()))
    577                 {
    578                     err.SetErrorToGenericError();
    579                     err.SetErrorString("Couldn't add dynamic checks to the expression");
    580                     return err;
    581                 }
    582             }
    583 
    584             m_execution_unit->GetRunnableInfo(err, func_addr, func_end);
    585         }
    586     }
    587     else
    588     {
    589         m_execution_unit->GetRunnableInfo(err, func_addr, func_end);
    590     }
    591 
    592     execution_unit_ap.reset (m_execution_unit.release());
    593 
    594     return err;
    595 }
    596