DebuggerVariableJSObject.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. /*
  2. * Copyright (c) 2021, Matthew Olsson <matthewcolsson@gmail.com>
  3. * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include "DebuggerVariableJSObject.h"
  8. #include "Debugger.h"
  9. #include <LibJS/Runtime/Error.h>
  10. #include <LibJS/Runtime/GlobalObject.h>
  11. #include <LibJS/Runtime/PrimitiveString.h>
  12. #include <LibJS/Runtime/PropertyName.h>
  13. namespace HackStudio {
  14. DebuggerVariableJSObject* DebuggerVariableJSObject::create(DebuggerGlobalJSObject& global_object, const Debug::DebugInfo::VariableInfo& variable_info)
  15. {
  16. return global_object.heap().allocate<DebuggerVariableJSObject>(global_object, variable_info, *global_object.object_prototype());
  17. }
  18. DebuggerVariableJSObject::DebuggerVariableJSObject(const Debug::DebugInfo::VariableInfo& variable_info, JS::Object& prototype)
  19. : JS::Object(prototype)
  20. , m_variable_info(variable_info)
  21. {
  22. }
  23. DebuggerVariableJSObject::~DebuggerVariableJSObject()
  24. {
  25. }
  26. bool DebuggerVariableJSObject::internal_set(const JS::PropertyName& property_name, JS::Value value, JS::Value)
  27. {
  28. if (!property_name.is_string()) {
  29. vm().throw_exception<JS::TypeError>(global_object(), String::formatted("Invalid variable name {}", property_name.to_string()));
  30. return false;
  31. }
  32. auto name = property_name.as_string();
  33. auto it = m_variable_info.members.find_if([&](auto& variable) {
  34. return variable->name == name;
  35. });
  36. if (it.is_end()) {
  37. vm().throw_exception<JS::TypeError>(global_object(), String::formatted("Variable of type {} has no property {}", m_variable_info.type_name, property_name));
  38. return false;
  39. }
  40. auto& member = **it;
  41. auto new_value = debugger_object().js_to_debugger(value, member);
  42. if (!new_value.has_value()) {
  43. auto string_error = String::formatted("Cannot convert JS value {} to variable {} of type {}", value.to_string_without_side_effects(), name, member.type_name);
  44. vm().throw_exception<JS::TypeError>(global_object(), string_error);
  45. return false;
  46. }
  47. Debugger::the().session()->poke((u32*)member.location_data.address, new_value.value());
  48. return true;
  49. }
  50. DebuggerGlobalJSObject& DebuggerVariableJSObject::debugger_object() const
  51. {
  52. return static_cast<DebuggerGlobalJSObject&>(global_object());
  53. }
  54. }