1/**************************************************************************/
2/* debugger_marshalls.cpp */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#include "debugger_marshalls.h"
32
33#include "core/io/marshalls.h"
34
35#define CHECK_SIZE(arr, expected, what) ERR_FAIL_COND_V_MSG((uint32_t)arr.size() < (uint32_t)(expected), false, String("Malformed ") + what + " message from script debugger, message too short. Expected size: " + itos(expected) + ", actual size: " + itos(arr.size()))
36#define CHECK_END(arr, expected, what) ERR_FAIL_COND_V_MSG((uint32_t)arr.size() > (uint32_t)expected, false, String("Malformed ") + what + " message from script debugger, message too long. Expected size: " + itos(expected) + ", actual size: " + itos(arr.size()))
37
38Array DebuggerMarshalls::ScriptStackDump::serialize() {
39 Array arr;
40 arr.push_back(frames.size() * 3);
41 for (int i = 0; i < frames.size(); i++) {
42 arr.push_back(frames[i].file);
43 arr.push_back(frames[i].line);
44 arr.push_back(frames[i].func);
45 }
46 return arr;
47}
48
49bool DebuggerMarshalls::ScriptStackDump::deserialize(const Array &p_arr) {
50 CHECK_SIZE(p_arr, 1, "ScriptStackDump");
51 uint32_t size = p_arr[0];
52 CHECK_SIZE(p_arr, size, "ScriptStackDump");
53 int idx = 1;
54 for (uint32_t i = 0; i < size / 3; i++) {
55 ScriptLanguage::StackInfo sf;
56 sf.file = p_arr[idx];
57 sf.line = p_arr[idx + 1];
58 sf.func = p_arr[idx + 2];
59 frames.push_back(sf);
60 idx += 3;
61 }
62 CHECK_END(p_arr, idx, "ScriptStackDump");
63 return true;
64}
65
66Array DebuggerMarshalls::ScriptStackVariable::serialize(int max_size) {
67 Array arr;
68 arr.push_back(name);
69 arr.push_back(type);
70 arr.push_back(value.get_type());
71
72 Variant var = value;
73 if (value.get_type() == Variant::OBJECT && value.get_validated_object() == nullptr) {
74 var = Variant();
75 }
76
77 int len = 0;
78 Error err = encode_variant(var, nullptr, len, false);
79 if (err != OK) {
80 ERR_PRINT("Failed to encode variant.");
81 }
82
83 if (len > max_size) {
84 arr.push_back(Variant());
85 } else {
86 arr.push_back(var);
87 }
88 return arr;
89}
90
91bool DebuggerMarshalls::ScriptStackVariable::deserialize(const Array &p_arr) {
92 CHECK_SIZE(p_arr, 4, "ScriptStackVariable");
93 name = p_arr[0];
94 type = p_arr[1];
95 var_type = p_arr[2];
96 value = p_arr[3];
97 CHECK_END(p_arr, 4, "ScriptStackVariable");
98 return true;
99}
100
101Array DebuggerMarshalls::OutputError::serialize() {
102 Array arr;
103 arr.push_back(hr);
104 arr.push_back(min);
105 arr.push_back(sec);
106 arr.push_back(msec);
107 arr.push_back(source_file);
108 arr.push_back(source_func);
109 arr.push_back(source_line);
110 arr.push_back(error);
111 arr.push_back(error_descr);
112 arr.push_back(warning);
113 unsigned int size = callstack.size();
114 const ScriptLanguage::StackInfo *r = callstack.ptr();
115 arr.push_back(size * 3);
116 for (int i = 0; i < callstack.size(); i++) {
117 arr.push_back(r[i].file);
118 arr.push_back(r[i].func);
119 arr.push_back(r[i].line);
120 }
121 return arr;
122}
123
124bool DebuggerMarshalls::OutputError::deserialize(const Array &p_arr) {
125 CHECK_SIZE(p_arr, 11, "OutputError");
126 hr = p_arr[0];
127 min = p_arr[1];
128 sec = p_arr[2];
129 msec = p_arr[3];
130 source_file = p_arr[4];
131 source_func = p_arr[5];
132 source_line = p_arr[6];
133 error = p_arr[7];
134 error_descr = p_arr[8];
135 warning = p_arr[9];
136 unsigned int stack_size = p_arr[10];
137 CHECK_SIZE(p_arr, stack_size, "OutputError");
138 int idx = 11;
139 callstack.resize(stack_size / 3);
140 ScriptLanguage::StackInfo *w = callstack.ptrw();
141 for (unsigned int i = 0; i < stack_size / 3; i++) {
142 w[i].file = p_arr[idx];
143 w[i].func = p_arr[idx + 1];
144 w[i].line = p_arr[idx + 2];
145 idx += 3;
146 }
147 CHECK_END(p_arr, idx, "OutputError");
148 return true;
149}
150