Skip to content

Commit 1c00382

Browse files
authored
[jak3] Decompile gcommon (#3321)
Decompile `gcommon`. I adjusted the spacing of docstring comments, and removed some spammy decompiler warning prints. I also added some random notes I had on VU programs from jak1/jak2. They are not polished, but I think it's still worth including since we'll have to go through them again for jak 3.
1 parent 9a4929a commit 1c00382

File tree

27 files changed

+4101
-650
lines changed

27 files changed

+4101
-650
lines changed

decompiler/analysis/cfg_builder.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1428,7 +1428,9 @@ Form* try_sc_as_type_of_jak2(FormPool& pool, Function& f, const ShortCircuit* vt
14281428
f.ir2.env.disable_def(b2_delay_op.dst(), f.warnings);
14291429
f.ir2.env.disable_use(shift_left->expr().get_arg(0).var());
14301430

1431-
f.warnings.warning("Using new Jak 2 rtype-of");
1431+
if (f.ir2.env.version != GameVersion::Jak3) {
1432+
f.warnings.warning("Using new Jak 2 rtype-of");
1433+
}
14321434
return b0_ptr;
14331435
}
14341436

decompiler/analysis/final_output.cpp

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,27 @@ goos::Object get_arg_list_for_function(const Function& func, const Env& env) {
2323
}
2424

2525
namespace {
26+
27+
std::string fix_docstring_indent(const std::string& input) {
28+
std::string result;
29+
for (auto c : input) {
30+
if (c == '\n') {
31+
result += '\n';
32+
for (int i = 0; i < 3; i++) {
33+
result += ' ';
34+
}
35+
} else {
36+
result += c;
37+
}
38+
}
39+
return result;
40+
}
41+
2642
void append_body_to_function_definition(goos::Object* top_form,
2743
const std::vector<goos::Object>& inline_body,
2844
const FunctionVariableDefinitions& var_dec,
29-
const TypeSpec& ts) {
45+
const TypeSpec& ts,
46+
GameVersion version) {
3047
// Some forms like docstrings and local-vars we _always_ want to be at the top level and first (in
3148
// the order added)
3249
std::vector<goos::Object> initial_top_level_forms;
@@ -35,7 +52,12 @@ void append_body_to_function_definition(goos::Object* top_form,
3552
body_elements.insert(body_elements.end(), inline_body.begin(), inline_body.end());
3653
// If the first element in the body is a docstring, add it first
3754
if (body_elements.size() > 0 && body_elements.at(0).is_string()) {
38-
initial_top_level_forms.push_back(inline_body.at(0));
55+
if (version > GameVersion::Jak2) {
56+
initial_top_level_forms.push_back(
57+
goos::StringObject::make_new(fix_docstring_indent(inline_body.at(0).as_string()->data)));
58+
} else {
59+
initial_top_level_forms.push_back(inline_body.at(0));
60+
}
3961
body_elements.erase(body_elements.begin());
4062
}
4163

@@ -65,7 +87,7 @@ void append_body_to_function_definition(goos::Object* top_form,
6587
}
6688
} // namespace
6789

68-
goos::Object final_output_lambda(const Function& func) {
90+
goos::Object final_output_lambda(const Function& func, GameVersion version) {
6991
std::vector<goos::Object> inline_body;
7092
func.ir2.top_form->inline_forms(inline_body, func.ir2.env);
7193
auto var_dec = func.ir2.env.local_var_type_list(func.ir2.top_form, func.type.arg_count() - 1);
@@ -74,11 +96,11 @@ goos::Object final_output_lambda(const Function& func) {
7496
if (behavior) {
7597
auto result = pretty_print::build_list(fmt::format("lambda :behavior {}", *behavior),
7698
get_arg_list_for_function(func, func.ir2.env));
77-
append_body_to_function_definition(&result, inline_body, var_dec, func.type);
99+
append_body_to_function_definition(&result, inline_body, var_dec, func.type, version);
78100
return result;
79101
} else {
80102
auto result = pretty_print::build_list("lambda", get_arg_list_for_function(func, func.ir2.env));
81-
append_body_to_function_definition(&result, inline_body, var_dec, func.type);
103+
append_body_to_function_definition(&result, inline_body, var_dec, func.type, version);
82104
return result;
83105
}
84106
}
@@ -115,7 +137,7 @@ goos::Object final_output_defstate_anonymous_behavior(const Function& func,
115137
auto var_dec = func.ir2.env.local_var_type_list(func.ir2.top_form, func.type.arg_count() - 1);
116138

117139
auto result = pretty_print::build_list("behavior", get_arg_list_for_function(func, func.ir2.env));
118-
append_body_to_function_definition(&result, inline_body, var_dec, func.type);
140+
append_body_to_function_definition(&result, inline_body, var_dec, func.type, dts.version());
119141
return result;
120142
}
121143

@@ -167,7 +189,7 @@ std::string final_defun_out(const Function& func,
167189
}
168190
}
169191

170-
append_body_to_function_definition(&top_form, inline_body, var_dec, func.type);
192+
append_body_to_function_definition(&top_form, inline_body, var_dec, func.type, dts.version());
171193
return pretty_print::to_string(top_form);
172194
}
173195

@@ -188,7 +210,8 @@ std::string final_defun_out(const Function& func,
188210
inline_body.insert(inline_body.begin(),
189211
pretty_print::new_string(method_info.docstring.value()));
190212
}
191-
append_body_to_function_definition(&top_form, inline_body, var_dec, method_info.type);
213+
append_body_to_function_definition(&top_form, inline_body, var_dec, method_info.type,
214+
dts.version());
192215
return pretty_print::to_string(top_form);
193216
}
194217

@@ -199,7 +222,7 @@ std::string final_defun_out(const Function& func,
199222
top.push_back(arguments);
200223
auto top_form = pretty_print::build_list(top);
201224

202-
append_body_to_function_definition(&top_form, inline_body, var_dec, func.type);
225+
append_body_to_function_definition(&top_form, inline_body, var_dec, func.type, dts.version());
203226
return pretty_print::to_string(top_form);
204227
}
205228

@@ -212,7 +235,7 @@ std::string final_defun_out(const Function& func,
212235
top.push_back(arguments);
213236
auto top_form = pretty_print::build_list(top);
214237

215-
append_body_to_function_definition(&top_form, inline_body, var_dec, func.type);
238+
append_body_to_function_definition(&top_form, inline_body, var_dec, func.type, dts.version());
216239
return pretty_print::to_string(top_form);
217240
}
218241

@@ -226,7 +249,7 @@ std::string final_defun_out(const Function& func,
226249
top.push_back(arguments);
227250
auto top_form = pretty_print::build_list(top);
228251

229-
append_body_to_function_definition(&top_form, inline_body, var_dec, func.type);
252+
append_body_to_function_definition(&top_form, inline_body, var_dec, func.type, dts.version());
230253
return pretty_print::to_string(top_form);
231254
}
232255

decompiler/analysis/final_output.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ std::string write_from_top_level(const Function& top_level,
1818
const std::unordered_set<std::string>& skip_functions);
1919

2020
goos::Object get_arg_list_for_function(const Function& func, const Env& env);
21-
goos::Object final_output_lambda(const Function& function);
21+
goos::Object final_output_lambda(const Function& function, GameVersion version);
2222
goos::Object final_output_defstate_anonymous_behavior(const Function& func,
2323
const DecompilerTypeSystem& dts);
2424
} // namespace decompiler

decompiler/analysis/static_refs.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ bool try_convert_lambda(const Function& parent_function,
4646
if (defstate_behavior) {
4747
result = final_output_defstate_anonymous_behavior(*other_func, dts);
4848
} else {
49-
result = final_output_lambda(*other_func);
49+
result = final_output_lambda(*other_func, dts.version());
5050
}
5151

5252
f->clear();

0 commit comments

Comments
 (0)