DebuggerVariableJSObject.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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::put(const JS::PropertyName& name, JS::Value value, JS::Value receiver)
  27. {
  28. if (m_is_writing_properties)
  29. return JS::Object::put(name, value, receiver);
  30. if (!name.is_string()) {
  31. vm().throw_exception<JS::TypeError>(global_object(), String::formatted("Invalid variable name {}", name.to_string()));
  32. return false;
  33. }
  34. auto property_name = name.as_string();
  35. auto it = m_variable_info.members.find_if([&](auto& variable) {
  36. return variable->name == property_name;
  37. });
  38. if (it.is_end()) {
  39. vm().throw_exception<JS::TypeError>(global_object(), String::formatted("Variable of type {} has no property {}", m_variable_info.type_name, property_name));
  40. return false;
  41. }
  42. auto& member = **it;
  43. auto new_value = debugger_object().js_to_debugger(value, member);
  44. if (!new_value.has_value()) {
  45. auto string_error = String::formatted("Cannot convert JS value {} to variable {} of type {}", value.to_string_without_side_effects(), name.as_string(), member.type_name);
  46. vm().throw_exception<JS::TypeError>(global_object(), string_error);
  47. return false;
  48. }
  49. Debugger::the().session()->poke((u32*)member.location_data.address, new_value.value());
  50. return true;
  51. }
  52. DebuggerGlobalJSObject& DebuggerVariableJSObject::debugger_object() const
  53. {
  54. return static_cast<DebuggerGlobalJSObject&>(global_object());
  55. }
  56. }