Showing the changes to src/vm/thread.cpp (1 of 9 files). Show all
Unified · Split
| @@ -111,6 +111,7 @@ vm_thread_t::vm_thread_t( · 110 unmodified lines | |||
| 111 | vm_module_ref_t &entry, | 111 | vm_module_ref_t &entry, |
| 112 | uint32_t parent_thread_id) | 112 | uint32_t parent_thread_id) |
| 113 | : vm_alloc_t(vm_thread_t::type_desc()) | 113 | : vm_alloc_t(vm_thread_t::type_desc()) |
| 114 | , _error_message{ nullptr } | ||
| 114 | , _parent_thread_id{ parent_thread_id } | 115 | , _parent_thread_id{ parent_thread_id } |
| 115 | , _registers{ *this, entry } | 116 | , _registers{ *this, entry } |
| 116 | , _thread_id{ get_unique_thread_id() } | 117 | , _thread_id{ get_unique_thread_id() } |
| @@ -135,6 +136,7 @@ vm_thread_t::vm_thread_t( · 18 unmodified lines | |||
| 135 | const vm_frame_t &initial_frame, | 136 | const vm_frame_t &initial_frame, |
| 136 | vm_pc_t start_pc) | 137 | vm_pc_t start_pc) |
| 137 | : vm_alloc_t(vm_thread_t::type_desc()) | 138 | : vm_alloc_t(vm_thread_t::type_desc()) |
| 139 | , _error_message{ nullptr } | ||
| 138 | , _parent_thread_id{ parent_thread_id } | 140 | , _parent_thread_id{ parent_thread_id } |
| 139 | , _registers{ *this, entry } | 141 | , _registers{ *this, entry } |
| 140 | , _thread_id{ get_unique_thread_id() } | 142 | , _thread_id{ get_unique_thread_id() } |
| @@ -162,6 +164,9 @@ vm_thread_t::~vm_thread_t() · 21 unmodified lines | |||
| 162 | { | 164 | { |
| 163 | if (debug::is_component_tracing_enabled<debug::component_trace_t::thread>()) | 165 | if (debug::is_component_tracing_enabled<debug::component_trace_t::thread>()) |
| 164 | debug::log_msg(debug::component_trace_t::thread, debug::log_level_t::debug, "destroy: vm thread: %d %d\n", _thread_id, _parent_thread_id); | 166 | debug::log_msg(debug::component_trace_t::thread, debug::log_level_t::debug, "destroy: vm thread: %d %d\n", _thread_id, _parent_thread_id); |
| 167 | |||
| 168 | free_memory(_error_message); | ||
| 169 | debug::assign_debug_pointer(&_error_message); | ||
| 165 | } | 170 | } |
| 166 | 171 | ||
| 167 | namespace | 172 | namespace |
| @@ -214,6 +219,7 @@ namespace · 46 unmodified lines | |||
| 214 | 219 | ||
| 215 | vm_thread_state_t vm_thread_t::execute(vm_t &vm, const uint32_t quanta) | 220 | vm_thread_state_t vm_thread_t::execute(vm_t &vm, const uint32_t quanta) |
| 216 | { | 221 | { |
| 222 | const auto max_error_message = std::size_t{ 1024 }; | ||
| 217 | _registers.current_thread_state = vm_thread_state_t::running; | 223 | _registers.current_thread_state = vm_thread_state_t::running; |
| 218 | _registers.current_thread_quanta = quanta; | 224 | _registers.current_thread_quanta = quanta; |
| 219 | assert(_registers.pc != runtime_constants::invalid_program_counter); | 225 | assert(_registers.pc != runtime_constants::invalid_program_counter); |
| @@ -226,27 +232,27 @@ vm_thread_state_t vm_thread_t::execute(vm_t &vm, const uint32_t quanta) · 6 unmodified lines | |||
| 226 | else | 232 | else |
| 227 | execute_impl<execute_with_tool_t>(_registers, vm); | 233 | execute_impl<execute_with_tool_t>(_registers, vm); |
| 228 | } | 234 | } |
| 235 | catch (const vm_term_request &) | ||
| 236 | { | ||
| 237 | throw; | ||
| 238 | } | ||
| 229 | catch (const unhandled_user_exception &uue) | 239 | catch (const unhandled_user_exception &uue) |
| 230 | { | 240 | { |
| 231 | // [TODO] Store the exception | 241 | _error_message = calloc_memory<char>(max_error_message); |
| 232 | std::fprintf(stderr, "%s - '%s' in %s at instruction %d\n", uue.what(), uue.exception_id, uue.module_name, uue.program_counter); | 242 | std::snprintf(_error_message, max_error_message, "%s - '%s' in %s at instruction %d", uue.what(), uue.exception_id, uue.module_name, uue.program_counter); |
| 233 | _registers.current_thread_state = vm_thread_state_t::broken; | 243 | _registers.current_thread_state = vm_thread_state_t::broken; |
| 234 | if (tool_dispatch != nullptr) | ||
| 235 | tool_dispatch->on_thread_broken(*this); | ||
| 236 | } | 244 | } |
| 237 | catch (const index_out_of_range_memory &ioor) | 245 | catch (const index_out_of_range_memory &ioor) |
| 238 | { | 246 | { |
| 239 | std::fprintf(stderr, "%s - %d [%d,%d]\n", ioor.what(), ioor.invalid_value, ioor.valid_min, ioor.valid_max); | 247 | _error_message = calloc_memory<char>(max_error_message); |
| 248 | std::snprintf(_error_message, max_error_message, "%s - %d [%d,%d]", ioor.what(), ioor.invalid_value, ioor.valid_min, ioor.valid_max); | ||
| 240 | _registers.current_thread_state = vm_thread_state_t::broken; | 249 | _registers.current_thread_state = vm_thread_state_t::broken; |
| 241 | if (tool_dispatch != nullptr) | ||
| 242 | tool_dispatch->on_thread_broken(*this); | ||
| 243 | } | 250 | } |
| 244 | catch (const vm_user_exception &ue) | 251 | catch (const vm_user_exception &ue) |
| 245 | { | 252 | { |
| 246 | std::fprintf(stderr, "%s\n", ue.what()); | 253 | _error_message = calloc_memory<char>(max_error_message); |
| 254 | std::snprintf(_error_message, max_error_message, "%s", ue.what()); | ||
| 247 | _registers.current_thread_state = vm_thread_state_t::broken; | 255 | _registers.current_thread_state = vm_thread_state_t::broken; |
| 248 | if (tool_dispatch != nullptr) | ||
| 249 | tool_dispatch->on_thread_broken(*this); | ||
| 250 | } | 256 | } |
| 251 | 257 | ||
| 252 | // Log the execution result | 258 | // Log the execution result |
| @@ -262,16 +268,22 @@ vm_thread_state_t vm_thread_t::execute(vm_t &vm, const uint32_t quanta) · 9 unmodified lines | |||
| 262 | _registers.current_thread_state); | 268 | _registers.current_thread_state); |
| 263 | } | 269 | } |
| 264 | 270 | ||
| 265 | // If the thread is still in the running state transition it back to its entry state. | 271 | switch (_registers.current_thread_state) |
| 266 | if (_registers.current_thread_state == vm_thread_state_t::running) | ||
| 267 | { | 272 | { |
| 273 | case vm_thread_state_t::running: | ||
| 268 | _registers.current_thread_state = (tool_dispatch == nullptr) ? vm_thread_state_t::ready : vm_thread_state_t::debug; | 274 | _registers.current_thread_state = (tool_dispatch == nullptr) ? vm_thread_state_t::ready : vm_thread_state_t::debug; |
| 269 | } | 275 | break; |
| 270 | else if (vm_thread_state_t::exiting == _registers.current_thread_state | 276 | |
| 271 | || vm_thread_state_t::empty_stack == _registers.current_thread_state) | 277 | case vm_thread_state_t::empty_stack: |
| 272 | { | 278 | case vm_thread_state_t::exiting: |
| 273 | if (tool_dispatch != nullptr) | 279 | if (tool_dispatch != nullptr) |
| 274 | tool_dispatch->on_thread_end(*this); | 280 | tool_dispatch->on_thread_end(*this); |
| 281 | break; | ||
| 282 | |||
| 283 | case vm_thread_state_t::broken: | ||
| 284 | if (tool_dispatch != nullptr) | ||
| 285 | tool_dispatch->on_thread_broken(*this); | ||
| 286 | break; | ||
| 275 | } | 287 | } |
| 276 | 288 | ||
| 277 | return _registers.current_thread_state; | 289 | return _registers.current_thread_state; |
| @@ -288,6 +300,11 @@ vm_thread_state_t vm_thread_t::get_state() const · 10 unmodified lines | |||
| 288 | return _registers.current_thread_state; | 300 | return _registers.current_thread_state; |
| 289 | } | 301 | } |
| 290 | 302 | ||
| 303 | const char *vm_thread_t::get_error_message() const | ||
| 304 | { | ||
| 305 | return _error_message; | ||
| 306 | } | ||
| 307 | |||
| 291 | uint32_t vm_thread_t::get_thread_id() const | 308 | uint32_t vm_thread_t::get_thread_id() const |
| 292 | { | 309 | { |
| 293 | return _thread_id; | 310 | return _thread_id; |