add declare-file debug (#1004)

This commit is contained in:
water111 2021-12-12 12:52:23 -05:00 committed by GitHub
parent a10f9da8b8
commit f6b40637a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 113 additions and 64 deletions

View File

@ -4,7 +4,7 @@
// if you want to filter to only some object names.
// it will make the decompiler much faster.
"allowed_objects": [],
"banned_objects": [],
"banned_objects": ["collide-mesh"],
////////////////////////////
// CODE ANALYSIS OPTIONS

View File

@ -206,4 +206,5 @@
- Using `->` on a plain `pointer` or `inline-array` now generates an error instead of crashing the compiler
- It is now possible to use a macro to provide a static inline array element definition
- It is now possible to have symbol names that have a `#` in the middle of them
- `go-hook` now returns the return value of the `enter-state` function it calls
- `go-hook` now returns the return value of the `enter-state` function it calls
- Added a `(declare-file (debug))` to put things in the debug segment by default. This only changes _static_ objects. Dynamic allocation with forms like `cons` will continue to use the main segment like before.

View File

@ -5,6 +5,8 @@
;; name in dgo: cam-layout
;; dgos: GAME, ENGINE
(declare-file (debug))
;; DECOMP BEGINS
;; this file is debug only

View File

@ -8,6 +8,8 @@
;; NOTES - removed one of the 2 inspects
;; - also fixed up a basic file-stream constructor on the stack
(declare-file (debug))
(declare-type list-control structure)
(define-extern anim-test-anim-list-handler (function int list-control symbol))
(define-extern anim-test-edit-sequence-list-handler (function int list-control symbol))

View File

@ -5,6 +5,8 @@
;; name in dgo: default-menu
;; dgos: GAME, ENGINE
(declare-file (debug))
;; Forward declarations for stuff we haven't written yet:
(define-extern *edit-instance* string)

View File

@ -125,7 +125,7 @@ class Compiler {
Val* compile_float(float value, Env* env, int seg);
Val* compile_symbol(const goos::Object& form, Env* env);
Val* compile_string(const goos::Object& form, Env* env);
Val* compile_string(const std::string& str, Env* env, int seg = MAIN_SEGMENT);
Val* compile_string(const std::string& str, Env* env, int seg);
Val* compile_get_symbol_value(const goos::Object& form, const std::string& name, Env* env);
Val* compile_function_or_method_call(const goos::Object& form, Env* env);
@ -233,15 +233,20 @@ class Compiler {
Env* env,
bool call_constructor);
StaticResult fill_static_array(const goos::Object& form, const goos::Object& rest, Env* env);
StaticResult fill_static_array(const goos::Object& form,
const goos::Object& rest,
Env* env,
int seg);
StaticResult fill_static_boxed_array(const goos::Object& form,
const goos::Object& rest,
Env* env);
Env* env,
int seg);
StaticResult fill_static_inline_array(const goos::Object& form,
const goos::Object& rest,
Env* env);
Env* env,
int seg);
void fill_static_inline_array_inline(const goos::Object& form,
const TypeSpec& content_type,
@ -330,10 +335,11 @@ class Compiler {
Val* compile_new_static_structure_or_basic(const goos::Object& form,
const TypeSpec& type,
const goos::Object& field_defs,
Env* env);
Val* compile_static_pair(const goos::Object& form, Env* env);
Env* env,
int seg);
Val* compile_static_pair(const goos::Object& form, Env* env, int seg);
StaticResult compile_static(const goos::Object& form, Env* env);
StaticResult compile_static_no_eval_for_pairs(const goos::Object& form, Env* env);
StaticResult compile_static_no_eval_for_pairs(const goos::Object& form, Env* env, int seg);
Val* compile_bitfield_definition(const goos::Object& form,
const TypeSpec& type,
@ -343,7 +349,8 @@ class Compiler {
StaticResult compile_new_static_structure(const goos::Object& form,
const TypeSpec& type,
const goos::Object& _field_defs,
Env* env);
Env* env,
int seg);
void compile_static_structure_inline(const goos::Object& form,
const TypeSpec& type,
@ -606,6 +613,7 @@ class Compiler {
Val* compile_inline(const goos::Object& form, const goos::Object& rest, Env* env);
Val* compile_declare(const goos::Object& form, const goos::Object& rest, Env* env);
Val* compile_local_vars(const goos::Object& form, const goos::Object& rest, Env* env);
Val* compile_declare_file(const goos::Object& form, const goos::Object& rest, Env* env);
// Type
Val* compile_deftype(const goos::Object& form, const goos::Object& rest, Env* env);

View File

@ -118,12 +118,16 @@ class FileEnv : public Env {
return (T*)m_vals.back().get();
}
int default_segment() const { return m_default_segment; }
void set_debug_file() { m_default_segment = DEBUG_SEGMENT; }
protected:
std::string m_name;
std::vector<std::shared_ptr<FunctionEnv>> m_functions;
std::vector<std::unique_ptr<StaticObject>> m_statics;
int m_anon_func_counter = 0;
std::vector<std::unique_ptr<Val>> m_vals;
int m_default_segment = MAIN_SEGMENT;
// statics
FunctionEnv* m_top_level_func = nullptr;
@ -192,6 +196,14 @@ class FunctionEnv : public DeclareEnv {
int align_bytes);
int stack_slots_used_for_stack_vars() const { return m_stack_var_slots_used; }
int segment_for_static_data() {
if (segment == TOP_LEVEL_SEGMENT) {
return file_env()->default_segment();
} else {
return segment;
}
}
int idx_in_file = -1;
template <typename T, class... Args>

View File

@ -208,6 +208,7 @@ const std::unordered_map<
{"declare", &Compiler::compile_declare},
{"inline", &Compiler::compile_inline},
{"local-vars", &Compiler::compile_local_vars},
{"declare-file", &Compiler::compile_declare_file},
// {"with-inline", &Compiler::compile_with_inline},
// {"get-ra-ptr", &Compiler::compile_get_ra_ptr},
@ -428,14 +429,12 @@ Val* Compiler::compile_symbol(const goos::Object& form, Env* env) {
}
/*!
* Compile a string constant. The constant is placed in the same segment as the parent function.
* Compile a string constant. The constant is placed in the same segment as the parent function. For
* top-level functions, the string is placed in the file's default segment.
*/
Val* Compiler::compile_string(const goos::Object& form, Env* env) {
auto segment = env->function_env()->segment;
if (segment == TOP_LEVEL_SEGMENT) {
segment = MAIN_SEGMENT;
}
return compile_string(form.as_string()->data, env, segment);
return compile_string(form.as_string()->data, env,
env->function_env()->segment_for_static_data());
}
/*!
@ -456,12 +455,10 @@ Val* Compiler::compile_string(const std::string& str, Env* env, int seg) {
* of the code, at least in Jak 1.
*/
Val* Compiler::compile_float(const goos::Object& code, Env* env) {
auto segment = env->function_env()->segment;
if (segment == TOP_LEVEL_SEGMENT) {
segment = MAIN_SEGMENT;
}
assert(code.is_float());
return compile_float(code.float_obj.value, env, segment);
// TODO: this will put top-level only floats in main. Which is conservative because I
// don't think we can take the address of a float constant.
return compile_float(code.float_obj.value, env, env->function_env()->segment_for_static_data());
}
/*!

View File

@ -149,11 +149,7 @@ Val* Compiler::compile_lambda(const goos::Object& form, const goos::Object& rest
args.has_named("inline-only") && symbol_string(args.get_named("inline-only")) != "#f";
// pick default segment to store function in.
int segment = MAIN_SEGMENT;
if (fe->segment == DEBUG_SEGMENT) {
// make anonymous lambdas in debug functions also go to debug
segment = DEBUG_SEGMENT;
}
int segment = fe->segment_for_static_data();
// override default segment.
if (args.has_named("segment")) {
@ -714,3 +710,34 @@ Val* Compiler::compile_declare(const goos::Object& form, const goos::Object& res
});
return get_none();
}
Val* Compiler::compile_declare_file(const goos::Object& /*form*/,
const goos::Object& rest,
Env* env) {
for_each_in_list(rest, [&](const goos::Object& o) {
if (!o.is_pair()) {
throw_compiler_error(o, "Invalid declare-file specification.");
}
auto first = o.as_pair()->car;
auto rrest = &o.as_pair()->cdr;
if (!first.is_symbol()) {
throw_compiler_error(
first, "Invalid declare option specification, expected a symbol, but got {} instead.",
first.print());
}
if (first.as_symbol()->name == "debug") {
if (!rrest->is_empty_list()) {
throw_compiler_error(first, "Invalid debug declare");
}
env->file_env()->set_debug_file();
} else {
throw_compiler_error(first, "Unrecognized declare-file option {}.", first.print());
}
});
return get_none();
}

View File

@ -146,7 +146,7 @@ Val* Compiler::compile_quote(const goos::Object& form, const goos::Object& rest,
return empty_pair;
}
case goos::ObjectType::PAIR:
return compile_static_pair(thing, env);
return compile_static_pair(thing, env, env->function_env()->segment_for_static_data());
default:
throw_compiler_error(form, "Quote is not yet implemented for {}.", thing.print());
}

View File

@ -264,14 +264,15 @@ void Compiler::compile_static_structure_inline(const goos::Object& form,
StaticResult Compiler::compile_new_static_structure(const goos::Object& form,
const TypeSpec& type,
const goos::Object& _field_defs,
Env* env) {
Env* env,
int seg) {
std::unique_ptr<StaticStructure> obj;
if (is_basic(type)) {
obj = std::make_unique<StaticBasic>(MAIN_SEGMENT, type.base_type());
obj = std::make_unique<StaticBasic>(seg, type.base_type());
} else {
// if we ever find this type of static data outside of MAIN_SEGMENT, we can create an option
// in the new form to pick the segment.
obj = std::make_unique<StaticStructure>(MAIN_SEGMENT);
obj = std::make_unique<StaticStructure>(seg);
}
auto type_info = dynamic_cast<StructureType*>(m_ts.lookup_type(type));
@ -554,22 +555,19 @@ Val* Compiler::compile_bitfield_definition(const goos::Object& form,
* - Integers
* - Strings
*/
StaticResult Compiler::compile_static_no_eval_for_pairs(const goos::Object& form, Env* env) {
StaticResult Compiler::compile_static_no_eval_for_pairs(const goos::Object& form,
Env* env,
int seg) {
auto fie = env->file_env();
auto fe = env->function_env();
auto segment = fe->segment;
if (segment == TOP_LEVEL_SEGMENT) {
segment = MAIN_SEGMENT;
}
if (form.is_pair()) {
if (form.as_pair()->car.is_symbol() && (form.as_pair()->car.as_symbol()->name == "new" ||
form.as_pair()->car.as_symbol()->name == "the" ||
form.as_pair()->car.as_symbol()->name == "lambda")) {
return compile_static(form, env);
}
auto car = compile_static_no_eval_for_pairs(form.as_pair()->car, env);
auto cdr = compile_static_no_eval_for_pairs(form.as_pair()->cdr, env);
auto pair_structure = std::make_unique<StaticPair>(car, cdr, segment);
auto car = compile_static_no_eval_for_pairs(form.as_pair()->car, env, seg);
auto cdr = compile_static_no_eval_for_pairs(form.as_pair()->cdr, env, seg);
auto pair_structure = std::make_unique<StaticPair>(car, cdr, seg);
auto result =
StaticResult::make_structure_reference(pair_structure.get(), m_ts.make_typespec("pair"));
fie->add_static(std::move(pair_structure));
@ -588,7 +586,7 @@ StaticResult Compiler::compile_static_no_eval_for_pairs(const goos::Object& form
return StaticResult::make_symbol("_empty_");
} else if (form.is_string()) {
// todo - this should eventually work with a string pool
auto obj = std::make_unique<StaticString>(form.as_string()->data, segment);
auto obj = std::make_unique<StaticString>(form.as_string()->data, seg);
auto result = StaticResult::make_structure_reference(obj.get(), m_ts.make_typespec("string"));
fie->add_static(std::move(obj));
return result;
@ -599,7 +597,7 @@ StaticResult Compiler::compile_static_no_eval_for_pairs(const goos::Object& form
}
/*!
* Generic copmilation function to handle:
* Generic compilation function to handle:
* - (new 'static <structure-or-basic>), a reference
*
* - (new 'static '<bitfield>), an integer constant
@ -616,10 +614,7 @@ StaticResult Compiler::compile_static(const goos::Object& form_before_macro, Env
auto form = expand_macro_completely(form_before_macro, env);
auto fie = env->file_env();
auto fe = env->function_env();
auto segment = fe->segment;
if (segment == TOP_LEVEL_SEGMENT) {
segment = MAIN_SEGMENT;
}
auto segment = fe->segment_for_static_data();
if (form.is_symbol()) {
// constant, #t, or #f
@ -660,7 +655,7 @@ StaticResult Compiler::compile_static(const goos::Object& form_before_macro, Env
throw_compiler_error(form, "The form {} is an invalid quoted form.", form.print());
}
if (second.is_pair() || second.is_empty_list()) {
return compile_static_no_eval_for_pairs(second, env);
return compile_static_no_eval_for_pairs(second, env, segment);
} else {
throw_compiler_error(form, "Could not evaluate the quoted form {} at compile time.",
second.print());
@ -685,11 +680,11 @@ StaticResult Compiler::compile_static(const goos::Object& form_before_macro, Env
}
if (unquote(args.at(1)).as_symbol()->name == "boxed-array") {
return fill_static_boxed_array(form, rest, env);
return fill_static_boxed_array(form, rest, env, segment);
} else if (unquote(args.at(1)).as_symbol()->name == "array") {
return fill_static_array(form, rest, env);
return fill_static_array(form, rest, env, segment);
} else if (unquote(args.at(1)).as_symbol()->name == "inline-array") {
return fill_static_inline_array(form, rest, env);
return fill_static_inline_array(form, rest, env, segment);
} else {
auto ts = parse_typespec(unquote(args.at(1)));
if (ts == TypeSpec("string")) {
@ -710,7 +705,7 @@ StaticResult Compiler::compile_static(const goos::Object& form_before_macro, Env
compile_bitfield_definition(form, ts, constructor_args, false, env));
return StaticResult::make_constant_data(val->value(), val->type());
} else if (is_structure(ts)) {
return compile_new_static_structure(form, ts, constructor_args, env);
return compile_new_static_structure(form, ts, constructor_args, env, segment);
} else {
throw_compiler_error(form, "Cannot construct a static {}.", ts.print());
}
@ -831,7 +826,8 @@ void Compiler::fill_static_array_inline(const goos::Object& form,
StaticResult Compiler::fill_static_array(const goos::Object& form,
const goos::Object& rest,
Env* env) {
Env* env,
int seg) {
auto fie = env->file_env();
// (new 'static 'boxed-array ...)
// get all arguments now
@ -851,10 +847,9 @@ StaticResult Compiler::fill_static_array(const goos::Object& form,
assert(deref_info.can_deref);
assert(deref_info.mem_deref);
auto array_data_size_bytes = length * deref_info.stride;
// todo, segments
std::unique_ptr<StaticStructure> obj;
obj = std::make_unique<StaticStructure>(MAIN_SEGMENT);
obj = std::make_unique<StaticStructure>(seg);
obj->data.resize(array_data_size_bytes);
@ -870,7 +865,8 @@ StaticResult Compiler::fill_static_array(const goos::Object& form,
StaticResult Compiler::fill_static_boxed_array(const goos::Object& form,
const goos::Object& rest,
Env* env) {
Env* env,
int seg) {
auto fie = env->file_env();
// (new 'static 'boxed-array ...)
// get all arguments now
@ -923,7 +919,7 @@ StaticResult Compiler::fill_static_boxed_array(const goos::Object& form,
auto array_data_size_bytes = allocated_length * deref_info.stride;
// todo, segments
std::unique_ptr<StaticStructure> obj;
obj = std::make_unique<StaticBasic>(MAIN_SEGMENT, "array");
obj = std::make_unique<StaticBasic>(seg, "array");
int array_header_size = 16;
obj->data.resize(array_header_size + array_data_size_bytes);
@ -1002,7 +998,8 @@ void Compiler::fill_static_inline_array_inline(const goos::Object& form,
StaticResult Compiler::fill_static_inline_array(const goos::Object& form,
const goos::Object& rest,
Env* env) {
Env* env,
int seg) {
auto fie = env->file_env();
// (new 'static 'inline-array ...)
// get all arguments now
@ -1021,8 +1018,7 @@ StaticResult Compiler::fill_static_inline_array(const goos::Object& form,
auto deref_info = m_ts.get_deref_info(inline_array_type);
assert(deref_info.can_deref);
assert(!deref_info.mem_deref);
// todo
auto obj = std::make_unique<StaticStructure>(MAIN_SEGMENT);
auto obj = std::make_unique<StaticStructure>(seg);
obj->set_offset(is_basic(content_type) ? 4 : 0);
obj->data.resize(length * deref_info.stride);
@ -1035,9 +1031,9 @@ StaticResult Compiler::fill_static_inline_array(const goos::Object& form,
return result;
}
Val* Compiler::compile_static_pair(const goos::Object& form, Env* env) {
Val* Compiler::compile_static_pair(const goos::Object& form, Env* env, int seg) {
assert(form.is_pair()); // (quote PAIR)
auto result = compile_static_no_eval_for_pairs(form, env);
auto result = compile_static_no_eval_for_pairs(form, env, seg);
assert(result.is_reference());
auto fe = env->function_env();
auto static_result = fe->alloc_val<StaticVal>(result.reference(), result.typespec());
@ -1047,9 +1043,10 @@ Val* Compiler::compile_static_pair(const goos::Object& form, Env* env) {
Val* Compiler::compile_new_static_structure_or_basic(const goos::Object& form,
const TypeSpec& type,
const goos::Object& field_defs,
Env* env) {
Env* env,
int seg) {
auto fe = env->function_env();
auto sr = compile_new_static_structure(form, type, field_defs, env);
auto sr = compile_new_static_structure(form, type, field_defs, env, seg);
auto result = fe->alloc_val<StaticVal>(sr.reference(), type);
return result;
}

View File

@ -485,7 +485,7 @@ Val* Compiler::compile_defmethod(const goos::Object& form, const goos::Object& _
place->func = nullptr;
auto new_func_env = std::make_unique<FunctionEnv>(env, lambda.debug_name, &m_goos.reader);
new_func_env->set_segment(MAIN_SEGMENT); // todo, how do we set debug?
new_func_env->set_segment(env->function_env()->segment_for_static_data());
new_func_env->method_of_type_name = symbol_string(type_name);
// set up arguments
@ -1060,7 +1060,8 @@ Val* Compiler::compile_static_new(const goos::Object& form,
} else {
auto type_of_object = parse_typespec(unquote(type));
if (is_structure(type_of_object)) {
return compile_new_static_structure_or_basic(form, type_of_object, *rest, env);
return compile_new_static_structure_or_basic(form, type_of_object, *rest, env,
env->function_env()->segment_for_static_data());
}
if (is_bitfield(type_of_object)) {