diff options
author | Ryan Brown <ribrdb@google.com> | 2015-11-02 19:30:40 +0000 |
---|---|---|
committer | Ryan Brown <ribrdb@google.com> | 2015-11-02 19:30:40 +0000 |
commit | 998c8a1c1c1cd0fa1cb1e1368abc52ba23caa987 (patch) | |
tree | e24424d6e8529b32b60550ecc4794f70ce8f6912 /lldb/source/Expression/UserExpression.cpp | |
parent | 7d564544eb73710e1a5769b9832890f620d0997d (diff) | |
download | bcm5719-llvm-998c8a1c1c1cd0fa1cb1e1368abc52ba23caa987.tar.gz bcm5719-llvm-998c8a1c1c1cd0fa1cb1e1368abc52ba23caa987.zip |
Create an expression parser for Go.
The Go interpreter doesn't JIT or use LLVM, so this also
moves all the JIT related code from UserExpression to a new class LLVMUserExpression.
Differential Revision: http://reviews.llvm.org/D13073
Fix merge
llvm-svn: 251820
Diffstat (limited to 'lldb/source/Expression/UserExpression.cpp')
-rw-r--r-- | lldb/source/Expression/UserExpression.cpp | 331 |
1 files changed, 9 insertions, 322 deletions
diff --git a/lldb/source/Expression/UserExpression.cpp b/lldb/source/Expression/UserExpression.cpp index 7bcb75306ab..23e93d34438 100644 --- a/lldb/source/Expression/UserExpression.cpp +++ b/lldb/source/Expression/UserExpression.cpp @@ -45,42 +45,18 @@ using namespace lldb_private; -UserExpression::UserExpression (ExecutionContextScope &exe_scope, - const char *expr, - const char *expr_prefix, - lldb::LanguageType language, - ResultType desired_type) : - Expression (exe_scope), - m_stack_frame_bottom (LLDB_INVALID_ADDRESS), - m_stack_frame_top (LLDB_INVALID_ADDRESS), - m_expr_text (expr), - m_expr_prefix (expr_prefix ? expr_prefix : ""), - m_language (language), - m_transformed_text (), - m_desired_type (desired_type), - m_execution_unit_sp(), - m_materializer_ap(), - m_jit_module_wp(), - m_enforce_valid_object (true), - m_in_cplusplus_method (false), - m_in_objectivec_method (false), - m_in_static_method(false), - m_needs_object_ptr (false), - m_const_object (false), - m_target (NULL), - m_can_interpret (false), - m_materialized_address (LLDB_INVALID_ADDRESS) +UserExpression::UserExpression(ExecutionContextScope &exe_scope, const char *expr, const char *expr_prefix, + lldb::LanguageType language, ResultType desired_type) + : Expression(exe_scope), + m_expr_text(expr), + m_expr_prefix(expr_prefix ? expr_prefix : ""), + m_language(language), + m_desired_type(desired_type) { } UserExpression::~UserExpression () { - if (m_target) - { - lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock()); - if (jit_module_sp) - m_target->GetImages().Remove(jit_module_sp); - } } void @@ -170,295 +146,6 @@ UserExpression::GetObjectPointer (lldb::StackFrameSP frame_sp, return ret; } -bool -UserExpression::PrepareToExecuteJITExpression (Stream &error_stream, - ExecutionContext &exe_ctx, - lldb::addr_t &struct_address) -{ - lldb::TargetSP target; - lldb::ProcessSP process; - lldb::StackFrameSP frame; - - if (!LockAndCheckContext(exe_ctx, - target, - process, - frame)) - { - error_stream.Printf("The context has changed before we could JIT the expression!\n"); - return false; - } - - if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret) - { - if (m_materialized_address == LLDB_INVALID_ADDRESS) - { - Error alloc_error; - - IRMemoryMap::AllocationPolicy policy = m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror; - - m_materialized_address = m_execution_unit_sp->Malloc(m_materializer_ap->GetStructByteSize(), - m_materializer_ap->GetStructAlignment(), - lldb::ePermissionsReadable | lldb::ePermissionsWritable, - policy, - alloc_error); - - if (!alloc_error.Success()) - { - error_stream.Printf("Couldn't allocate space for materialized struct: %s\n", alloc_error.AsCString()); - return false; - } - } - - struct_address = m_materialized_address; - - if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS) - { - Error alloc_error; - - const size_t stack_frame_size = 512 * 1024; - - m_stack_frame_bottom = m_execution_unit_sp->Malloc(stack_frame_size, - 8, - lldb::ePermissionsReadable | lldb::ePermissionsWritable, - IRMemoryMap::eAllocationPolicyHostOnly, - alloc_error); - - m_stack_frame_top = m_stack_frame_bottom + stack_frame_size; - - if (!alloc_error.Success()) - { - error_stream.Printf("Couldn't allocate space for the stack frame: %s\n", alloc_error.AsCString()); - return false; - } - } - - Error materialize_error; - - m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_sp, struct_address, materialize_error); - - if (!materialize_error.Success()) - { - error_stream.Printf("Couldn't materialize: %s\n", materialize_error.AsCString()); - return false; - } - } - return true; -} - -bool -UserExpression::FinalizeJITExecution (Stream &error_stream, - ExecutionContext &exe_ctx, - lldb::ExpressionVariableSP &result, - lldb::addr_t function_stack_bottom, - lldb::addr_t function_stack_top) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - - if (log) - log->Printf("-- [UserExpression::FinalizeJITExecution] Dematerializing after execution --"); - - if (!m_dematerializer_sp) - { - error_stream.Printf ("Couldn't apply expression side effects : no dematerializer is present"); - return false; - } - - Error dematerialize_error; - - m_dematerializer_sp->Dematerialize(dematerialize_error, function_stack_bottom, function_stack_top); - - if (!dematerialize_error.Success()) - { - error_stream.Printf ("Couldn't apply expression side effects : %s\n", dematerialize_error.AsCString("unknown error")); - return false; - } - - result = GetResultAfterDematerialization(exe_ctx.GetBestExecutionContextScope()); - - if (result) - result->TransferAddress(); - - m_dematerializer_sp.reset(); - - return true; -} - -lldb::ExpressionResults -UserExpression::Execute (Stream &error_stream, - ExecutionContext &exe_ctx, - const EvaluateExpressionOptions& options, - lldb::UserExpressionSP &shared_ptr_to_me, - lldb::ExpressionVariableSP &result) -{ - // The expression log is quite verbose, and if you're just tracking the execution of the - // expression, it's quite convenient to have these logs come out with the STEP log as well. - Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP)); - - if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret) - { - lldb::addr_t struct_address = LLDB_INVALID_ADDRESS; - - if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address)) - { - error_stream.Printf("Errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__); - return lldb::eExpressionSetupError; - } - - lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS; - lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS; - - if (m_can_interpret) - { - llvm::Module *module = m_execution_unit_sp->GetModule(); - llvm::Function *function = m_execution_unit_sp->GetFunction(); - - if (!module || !function) - { - error_stream.Printf("Supposed to interpret, but nothing is there"); - return lldb::eExpressionSetupError; - } - - Error interpreter_error; - - std::vector<lldb::addr_t> args; - - if (!AddInitialArguments(exe_ctx, args, error_stream)) - { - error_stream.Printf ("Errored out in %s, couldn't AddInitialArguments", __FUNCTION__); - return lldb::eExpressionSetupError; - } - - args.push_back(struct_address); - - function_stack_bottom = m_stack_frame_bottom; - function_stack_top = m_stack_frame_top; - - IRInterpreter::Interpret (*module, - *function, - args, - *m_execution_unit_sp.get(), - interpreter_error, - function_stack_bottom, - function_stack_top, - exe_ctx); - - if (!interpreter_error.Success()) - { - error_stream.Printf("Supposed to interpret, but failed: %s", interpreter_error.AsCString()); - return lldb::eExpressionDiscarded; - } - } - else - { - if (!exe_ctx.HasThreadScope()) - { - error_stream.Printf("UserExpression::Execute called with no thread selected."); - return lldb::eExpressionSetupError; - } - - Address wrapper_address (m_jit_start_addr); - - std::vector<lldb::addr_t> args; - - if (!AddInitialArguments(exe_ctx, args, error_stream)) - { - error_stream.Printf ("Errored out in %s, couldn't AddInitialArguments", __FUNCTION__); - return lldb::eExpressionSetupError; - } - - args.push_back(struct_address); - - lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(), - wrapper_address, - args, - options, - shared_ptr_to_me)); - - if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream)) - return lldb::eExpressionSetupError; - - ThreadPlanCallUserExpression *user_expression_plan = static_cast<ThreadPlanCallUserExpression *>(call_plan_sp.get()); - - lldb::addr_t function_stack_pointer = user_expression_plan->GetFunctionStackPointer(); - - function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize(); - function_stack_top = function_stack_pointer; - - if (log) - log->Printf("-- [UserExpression::Execute] Execution of expression begins --"); - - if (exe_ctx.GetProcessPtr()) - exe_ctx.GetProcessPtr()->SetRunningUserExpression(true); - - lldb::ExpressionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx, - call_plan_sp, - options, - error_stream); - - if (exe_ctx.GetProcessPtr()) - exe_ctx.GetProcessPtr()->SetRunningUserExpression(false); - - if (log) - log->Printf("-- [UserExpression::Execute] Execution of expression completed --"); - - if (execution_result == lldb::eExpressionInterrupted || execution_result == lldb::eExpressionHitBreakpoint) - { - const char *error_desc = NULL; - - if (call_plan_sp) - { - lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo(); - if (real_stop_info_sp) - error_desc = real_stop_info_sp->GetDescription(); - } - if (error_desc) - error_stream.Printf ("Execution was interrupted, reason: %s.", error_desc); - else - error_stream.PutCString ("Execution was interrupted."); - - if ((execution_result == lldb::eExpressionInterrupted && options.DoesUnwindOnError()) - || (execution_result == lldb::eExpressionHitBreakpoint && options.DoesIgnoreBreakpoints())) - error_stream.PutCString ("\nThe process has been returned to the state before expression evaluation."); - else - { - if (execution_result == lldb::eExpressionHitBreakpoint) - user_expression_plan->TransferExpressionOwnership(); - error_stream.PutCString ("\nThe process has been left at the point where it was interrupted, " - "use \"thread return -x\" to return to the state before expression evaluation."); - } - - return execution_result; - } - else if (execution_result == lldb::eExpressionStoppedForDebug) - { - error_stream.PutCString ("Execution was halted at the first instruction of the expression " - "function because \"debug\" was requested.\n" - "Use \"thread return -x\" to return to the state before expression evaluation."); - return execution_result; - } - else if (execution_result != lldb::eExpressionCompleted) - { - error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result)); - return execution_result; - } - } - - if (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_bottom, function_stack_top)) - { - return lldb::eExpressionCompleted; - } - else - { - return lldb::eExpressionResultUnavailable; - } - } - else - { - error_stream.Printf("Expression can't be run, because there is no JIT compiled function"); - return lldb::eExpressionSetupError; - } -} - lldb::ExpressionResults UserExpression::Evaluate (ExecutionContext &exe_ctx, const EvaluateExpressionOptions& options, @@ -570,8 +257,8 @@ UserExpression::Evaluate (ExecutionContext &exe_ctx, else { // If a pointer to a lldb::ModuleSP was passed in, return the JIT'ed module if one was created - if (jit_module_sp_ptr && user_expression_sp->m_execution_unit_sp) - *jit_module_sp_ptr = user_expression_sp->m_execution_unit_sp->GetJITModule(); + if (jit_module_sp_ptr) + *jit_module_sp_ptr = user_expression_sp->GetJITModule(); lldb::ExpressionVariableSP expr_result; |