mirror of
https://github.com/open-goal/jak-project
synced 2026-07-09 06:53:45 -04:00
[decompiler] Better support for non-virtual methods (#543)
* fix up nonvirtual method calls and stack new method calls * look at final in compiler too
This commit is contained in:
@@ -630,6 +630,23 @@ int BasicType::get_inline_array_start_alignment() const {
|
||||
}
|
||||
}
|
||||
|
||||
bool BasicType::operator==(const Type& other) const {
|
||||
if (typeid(*this) != typeid(other)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* p_other = dynamic_cast<const BasicType*>(&other);
|
||||
// clang-format off
|
||||
return other.is_equal(*this) &&
|
||||
m_fields == p_other->m_fields &&
|
||||
m_dynamic == p_other->m_dynamic &&
|
||||
m_size_in_mem == p_other->m_size_in_mem &&
|
||||
m_pack == p_other->m_pack &&
|
||||
m_allow_misalign == p_other->m_allow_misalign &&
|
||||
m_final == p_other->m_final;
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Bitfield
|
||||
/////////////////
|
||||
|
||||
@@ -107,7 +107,6 @@ class Type {
|
||||
bool m_allow_in_runtime = true;
|
||||
std::string m_runtime_name;
|
||||
bool m_is_boxed = false; // does this have runtime type information?
|
||||
|
||||
int m_heap_base = 0;
|
||||
};
|
||||
|
||||
@@ -286,7 +285,13 @@ class BasicType : public StructureType {
|
||||
int get_offset() const override;
|
||||
int get_inline_array_start_alignment() const override;
|
||||
std::string print() const override;
|
||||
bool final() const { return m_final; }
|
||||
void set_final() { m_final = true; }
|
||||
~BasicType() = default;
|
||||
bool operator==(const Type& other) const override;
|
||||
|
||||
protected:
|
||||
bool m_final = false;
|
||||
};
|
||||
|
||||
class BitField {
|
||||
|
||||
@@ -724,6 +724,7 @@ void TypeSystem::add_builtin_types() {
|
||||
auto symbol_type = add_builtin_basic("basic", "symbol");
|
||||
auto type_type = add_builtin_basic("basic", "type");
|
||||
auto string_type = add_builtin_basic("basic", "string");
|
||||
string_type->set_final(); // no virtual calls used on string.
|
||||
auto function_type = add_builtin_basic("basic", "function");
|
||||
auto vu_function_type = add_builtin_structure("structure", "vu-function");
|
||||
auto link_block_type = add_builtin_basic("basic", "link-block");
|
||||
@@ -1539,3 +1540,16 @@ std::string TypeSystem::generate_deftype(const Type* type) const {
|
||||
";; cannot generate deftype for {}, it is not a structure, basic, or bitfield (parent {})\n",
|
||||
type->get_name(), type->get_parent());
|
||||
}
|
||||
|
||||
bool TypeSystem::should_use_virtual_methods(const Type* type) const {
|
||||
auto as_basic = dynamic_cast<const BasicType*>(type);
|
||||
if (as_basic && !as_basic->final()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool TypeSystem::should_use_virtual_methods(const TypeSpec& type) const {
|
||||
return should_use_virtual_methods(lookup_type(type));
|
||||
}
|
||||
@@ -174,6 +174,9 @@ class TypeSystem {
|
||||
int offset,
|
||||
int field_size);
|
||||
|
||||
bool should_use_virtual_methods(const Type* type) const;
|
||||
bool should_use_virtual_methods(const TypeSpec& type) const;
|
||||
|
||||
/*!
|
||||
* Get a type by name and cast to a child class of Type*. Must succeed.
|
||||
*/
|
||||
|
||||
@@ -208,6 +208,7 @@ struct StructureDefResult {
|
||||
bool generate_runtime_type = true;
|
||||
bool pack_me = false;
|
||||
bool allow_misaligned = false;
|
||||
bool final = false;
|
||||
};
|
||||
|
||||
StructureDefResult parse_structure_def(StructureType* type,
|
||||
@@ -271,6 +272,8 @@ StructureDefResult parse_structure_def(StructureType* type,
|
||||
flags.heap_base = hb;
|
||||
} else if (opt_name == ":allow-misaligned") {
|
||||
result.allow_misaligned = true;
|
||||
} else if (opt_name == ":final") {
|
||||
result.final = true;
|
||||
} else {
|
||||
throw std::runtime_error("Invalid option in field specification: " + opt_name);
|
||||
}
|
||||
@@ -436,6 +439,11 @@ DeftypeResult parse_deftype(const goos::Object& deftype, TypeSystem* ts) {
|
||||
auto new_type = std::make_unique<BasicType>(parent_type_name, name, false, 0);
|
||||
auto pto = dynamic_cast<BasicType*>(ts->lookup_type(parent_type));
|
||||
assert(pto);
|
||||
if (pto->final()) {
|
||||
throw std::runtime_error(
|
||||
fmt::format("[TypeSystem] Cannot make a child type {} of final basic type {}", name,
|
||||
parent_type_name));
|
||||
}
|
||||
new_type->inherit(pto);
|
||||
ts->forward_declare_type_as_basic(name);
|
||||
auto sr = parse_structure_def(new_type.get(), ts, field_list_obj, options_obj);
|
||||
@@ -452,6 +460,9 @@ DeftypeResult parse_deftype(const goos::Object& deftype, TypeSystem* ts) {
|
||||
throw std::runtime_error("invalid pack option on basic");
|
||||
}
|
||||
new_type->set_heap_base(result.flags.heap_base);
|
||||
if (sr.final) {
|
||||
new_type->set_final();
|
||||
}
|
||||
ts->add_type(name, std::move(new_type));
|
||||
} else if (is_type("structure", parent_type, ts)) {
|
||||
auto new_type = std::make_unique<StructureType>(parent_type_name, name, false, false, false, 0);
|
||||
@@ -468,6 +479,10 @@ DeftypeResult parse_deftype(const goos::Object& deftype, TypeSystem* ts) {
|
||||
if (sr.allow_misaligned) {
|
||||
new_type->set_allow_misalign(true);
|
||||
}
|
||||
if (sr.final) {
|
||||
throw std::runtime_error(
|
||||
fmt::format("[TypeSystem] :final option cannot be used on structure type {}", name));
|
||||
}
|
||||
new_type->set_heap_base(result.flags.heap_base);
|
||||
ts->add_type(name, std::move(new_type));
|
||||
} else if (is_type("integer", parent_type, ts)) {
|
||||
|
||||
@@ -726,9 +726,9 @@ TP_Type LoadVarOp::get_src_type(const TypeState& input,
|
||||
if (method_id == GOAL_NEW_METHOD) {
|
||||
return TP_Type::make_from_ts(method_type);
|
||||
} else if (input_type.kind == TP_Type::Kind::TYPE_OF_TYPE_NO_VIRTUAL) {
|
||||
return TP_Type::make_non_virtual_method(method_type);
|
||||
return TP_Type::make_non_virtual_method(method_type, TypeSpec(type_name));
|
||||
} else {
|
||||
return TP_Type::make_virtual_method(method_type);
|
||||
return TP_Type::make_virtual_method(method_type, TypeSpec(type_name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -740,7 +740,7 @@ TP_Type LoadVarOp::get_src_type(const TypeState& input,
|
||||
if (method_id != GOAL_NEW_METHOD && method_id != GOAL_RELOC_METHOD) {
|
||||
// this can get us the wrong thing for `new` methods. And maybe relocate?
|
||||
return TP_Type::make_non_virtual_method(
|
||||
method_info.type.substitute_for_method_call("object"));
|
||||
method_info.type.substitute_for_method_call("object"), TypeSpec("object"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1329,6 +1329,7 @@ class StackVarDefElement : public FormElement {
|
||||
FormStack& stack,
|
||||
std::vector<FormElement*>* result,
|
||||
bool allow_side_effects) override;
|
||||
const TypeSpec& type() const { return m_entry.ref_type; }
|
||||
|
||||
private:
|
||||
StackVarEntry m_entry;
|
||||
|
||||
@@ -1796,12 +1796,23 @@ void FunctionCallElement::update_from_stack(const Env& env,
|
||||
}
|
||||
|
||||
std::vector<Form*> arg_forms;
|
||||
bool has_good_types = env.has_type_analysis() && function_type.arg_count() == nargs + 1;
|
||||
TypeSpec first_arg_type;
|
||||
|
||||
for (size_t arg_id = 0; arg_id < nargs; arg_id++) {
|
||||
auto val = unstacked.at(arg_id + 1); // first is the function itself.
|
||||
auto& var = all_pop_vars.at(arg_id + 1);
|
||||
if (env.has_type_analysis() && function_type.arg_count() == nargs + 1) {
|
||||
if (has_good_types) {
|
||||
auto actual_arg_type = env.get_types_before_op(var.idx()).get(var.reg()).typespec();
|
||||
auto val_atom = form_as_atom(val);
|
||||
if (val_atom && val_atom->is_var()) {
|
||||
actual_arg_type = env.get_variable_type(val_atom->var(), true);
|
||||
}
|
||||
|
||||
if (arg_id == 0) {
|
||||
first_arg_type = actual_arg_type;
|
||||
}
|
||||
|
||||
auto desired_arg_type = function_type.get_arg(arg_id);
|
||||
if (!env.dts->ts.tc(desired_arg_type, actual_arg_type)) {
|
||||
arg_forms.push_back(cast_form(val, desired_arg_type, pool, env));
|
||||
@@ -1826,6 +1837,17 @@ void FunctionCallElement::update_from_stack(const Env& env,
|
||||
auto vtable_var_name = env.get_variable_name(*vtable_reg);
|
||||
auto arg0_mr = match(Matcher::any_reg(0), unstacked.at(1));
|
||||
if (arg0_mr.matched && env.get_variable_name(*arg0_mr.maps.regs.at(0)) == vtable_var_name) {
|
||||
if (tp_type.kind != TP_Type::Kind::VIRTUAL_METHOD) {
|
||||
throw std::runtime_error(
|
||||
"Method internal mismatch. METHOD_OF_OBJECT operator didn't get a VIRTUAL_METHOD "
|
||||
"type.");
|
||||
}
|
||||
|
||||
if (!env.dts->ts.should_use_virtual_methods(tp_type.method_from_type())) {
|
||||
throw std::runtime_error(
|
||||
fmt::format("Method call on {} used a virtual call unexpectedly.",
|
||||
tp_type.method_from_type().print()));
|
||||
}
|
||||
// fmt::print("STACK\n{}\n\n", stack.print(env));
|
||||
auto pop =
|
||||
pop_to_forms({*arg0_mr.maps.regs.at(0)}, env, pool, stack, allow_side_effects, {}, {2})
|
||||
@@ -1944,7 +1966,7 @@ void FunctionCallElement::update_from_stack(const Env& env,
|
||||
|
||||
{
|
||||
// detect method calls:
|
||||
// ex: ((method-of-type x new) (quote global) pair gp-0 a3-0)
|
||||
// ex: ((method-of-type x blah) arg...)
|
||||
constexpr int method_name = 0;
|
||||
constexpr int type_source = 1;
|
||||
|
||||
@@ -1957,7 +1979,73 @@ void FunctionCallElement::update_from_stack(const Env& env,
|
||||
auto match_result = match(matcher, temp_form);
|
||||
if (match_result.matched) {
|
||||
auto name = match_result.maps.strings.at(method_name);
|
||||
if (name != "new") {
|
||||
// only do these checks on non-new methods. New methods are treated as functions because
|
||||
// they are never virtual and are never called like a method.
|
||||
if (tp_type.kind != TP_Type::Kind::NON_VIRTUAL_METHOD) {
|
||||
throw std::runtime_error(fmt::format(
|
||||
"Method internal mismatch. METHOD_OF_TYPE operator didn't get a NON_VIRTUAL_METHOD "
|
||||
"type. Got {} instead.",
|
||||
tp_type.print()));
|
||||
}
|
||||
|
||||
if (env.dts->ts.should_use_virtual_methods(tp_type.method_from_type())) {
|
||||
throw std::runtime_error(
|
||||
fmt::format("Expected type {} to use virtual methods, but it didn't. Set option "
|
||||
":final in the deftype to disable virtual method calls",
|
||||
tp_type.method_from_type().print()));
|
||||
}
|
||||
}
|
||||
|
||||
auto type_source_form = match_result.maps.forms.at(type_source);
|
||||
|
||||
// if the type is the exact type of the argument, we want to build it into a method call
|
||||
if (type_source_form->to_string(env) == first_arg_type.base_type() && name != "new") {
|
||||
auto method_op = pool.alloc_single_element_form<ConstantTokenElement>(nullptr, name);
|
||||
auto gop = GenericOperator::make_function(method_op);
|
||||
|
||||
result->push_back(pool.alloc_element<GenericElement>(gop, arg_forms));
|
||||
return;
|
||||
}
|
||||
|
||||
if (name == "new" && arg_forms.size() >= 2) {
|
||||
bool got_stack_new = true;
|
||||
// method
|
||||
// (the-as symbol (new 'stack-no-clear 'draw-context))
|
||||
// draw-context
|
||||
auto first_cast = arg_forms.at(0)->try_as_element<CastElement>();
|
||||
if (!first_cast || first_cast->type() != TypeSpec("symbol")) {
|
||||
got_stack_new = false;
|
||||
}
|
||||
|
||||
if (got_stack_new) {
|
||||
auto new_op = first_cast->source()->try_as_element<StackVarDefElement>();
|
||||
if (!new_op || new_op->type().base_type() != type_source_form->to_string(env)) {
|
||||
got_stack_new = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (got_stack_new) {
|
||||
if (arg_forms.at(1)->to_string(env) != type_source_form->to_string(env)) {
|
||||
got_stack_new = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (got_stack_new) {
|
||||
std::vector<Form*> stack_new_args;
|
||||
stack_new_args.push_back(
|
||||
pool.alloc_single_element_form<ConstantTokenElement>(nullptr, "'stack"));
|
||||
stack_new_args.push_back(pool.alloc_single_element_form<ConstantTokenElement>(
|
||||
nullptr, fmt::format("'{}", type_source_form->to_string(env))));
|
||||
for (size_t i = 2; i < arg_forms.size(); i++) {
|
||||
stack_new_args.push_back(arg_forms.at(i));
|
||||
}
|
||||
result->push_back(pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::NEW), stack_new_args));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto method_op =
|
||||
pool.alloc_single_element_form<GetMethodElement>(nullptr, type_source_form, name, false);
|
||||
auto gop = GenericOperator::make_function(method_op);
|
||||
|
||||
@@ -111,16 +111,18 @@ class TP_Type {
|
||||
|
||||
static TP_Type make_from_ts(const std::string& ts) { return make_from_ts(TypeSpec(ts)); }
|
||||
|
||||
static TP_Type make_virtual_method(const TypeSpec& method_type) {
|
||||
static TP_Type make_virtual_method(const TypeSpec& method_type, const TypeSpec& obj_type) {
|
||||
TP_Type result;
|
||||
result.kind = Kind::VIRTUAL_METHOD;
|
||||
result.m_ts = method_type;
|
||||
result.m_method_from_type = obj_type;
|
||||
return result;
|
||||
}
|
||||
|
||||
static TP_Type make_non_virtual_method(const TypeSpec& method_type) {
|
||||
static TP_Type make_non_virtual_method(const TypeSpec& method_type, const TypeSpec& obj_type) {
|
||||
TP_Type result;
|
||||
result.kind = Kind::NON_VIRTUAL_METHOD;
|
||||
result.m_method_from_type = obj_type;
|
||||
result.m_ts = method_type;
|
||||
return result;
|
||||
}
|
||||
@@ -288,8 +290,14 @@ class TP_Type {
|
||||
return false;
|
||||
}
|
||||
|
||||
const TypeSpec& method_from_type() const {
|
||||
assert(kind == Kind::VIRTUAL_METHOD || kind == Kind::NON_VIRTUAL_METHOD);
|
||||
return m_method_from_type;
|
||||
}
|
||||
|
||||
private:
|
||||
TypeSpec m_ts;
|
||||
TypeSpec m_method_from_type;
|
||||
std::string m_str;
|
||||
int64_t m_int = 0;
|
||||
bool m_pcpyud = false; // have we extracted the top doubleword of a bitfield?
|
||||
|
||||
@@ -72,7 +72,7 @@ RegVal* Compiler::compile_get_method_of_object(const goos::Object& form,
|
||||
auto fe = get_parent_env_of_type<FunctionEnv>(env);
|
||||
|
||||
RegVal* runtime_type = nullptr;
|
||||
if (is_basic(compile_time_type)) {
|
||||
if (m_ts.should_use_virtual_methods(compile_time_type)) {
|
||||
runtime_type = fe->make_gpr(m_ts.make_typespec("type"));
|
||||
MemLoadInfo info;
|
||||
info.size = 4;
|
||||
|
||||
@@ -666,24 +666,11 @@
|
||||
(set! (-> s5-0 vector 1 quad) (the-as uint128 0))
|
||||
(set! (-> s5-0 vector 2 quad) (the-as uint128 0))
|
||||
(set! (-> s5-0 vector 3 quad) (the-as uint128 0))
|
||||
(let
|
||||
((s4-0
|
||||
((method-of-type vector4s-3 new)
|
||||
(the-as symbol (new 'stack-no-clear 'vector4s-3))
|
||||
vector4s-3
|
||||
)
|
||||
)
|
||||
(s3-0 (new 'stack-no-clear 'vector))
|
||||
)
|
||||
(let ((s4-0 (new 'stack 'vector4s-3))
|
||||
(s3-0 (new 'stack-no-clear 'vector))
|
||||
)
|
||||
(set! (-> s3-0 quad) (the-as uint128 0))
|
||||
(let
|
||||
((s2-0
|
||||
((method-of-type vector4s-3 new)
|
||||
(the-as symbol (new 'stack-no-clear 'vector4s-3))
|
||||
vector4s-3
|
||||
)
|
||||
)
|
||||
)
|
||||
(let ((s2-0 (new 'stack 'vector4s-3)))
|
||||
(matrix*! s5-0 arg0 (-> *math-camera* camera-temp))
|
||||
(matrix-3x3-inverse-transpose! gp-0 arg0)
|
||||
(let ((v1-3 s3-0))
|
||||
@@ -757,7 +744,3 @@
|
||||
(none)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
|
||||
;; definition for method 12 of type connection
|
||||
(defmethod belongs-to-process? connection ((obj connection) (arg0 process))
|
||||
(= arg0 ((method-of-type connection get-process) obj))
|
||||
(= arg0 (get-process obj))
|
||||
)
|
||||
|
||||
;; definition for method 2 of type connection
|
||||
@@ -253,25 +253,25 @@
|
||||
(format #t "~Talive-list:~%")
|
||||
(let ((s5-0 *print-column*))
|
||||
(set! *print-column* (+ *print-column* (the-as uint 64)))
|
||||
((method-of-type connectable inspect) (-> obj alive-list))
|
||||
(inspect (-> obj alive-list))
|
||||
(set! *print-column* s5-0)
|
||||
)
|
||||
(format #t "~Talive-list-end:~%")
|
||||
(let ((s5-1 *print-column*))
|
||||
(set! *print-column* (+ *print-column* (the-as uint 64)))
|
||||
((method-of-type connectable inspect) (-> obj alive-list-end))
|
||||
(inspect (-> obj alive-list-end))
|
||||
(set! *print-column* s5-1)
|
||||
)
|
||||
(format #t "~Tdead-list:~%")
|
||||
(let ((s5-2 *print-column*))
|
||||
(set! *print-column* (+ *print-column* (the-as uint 64)))
|
||||
((method-of-type connectable inspect) (-> obj dead-list))
|
||||
(inspect (-> obj dead-list))
|
||||
(set! *print-column* s5-2)
|
||||
)
|
||||
(format #t "~Tdead-list-end:~%")
|
||||
(let ((s5-3 *print-column*))
|
||||
(set! *print-column* (+ *print-column* (the-as uint 64)))
|
||||
((method-of-type connectable inspect) (-> obj dead-list-end))
|
||||
(inspect (-> obj dead-list-end))
|
||||
(set! *print-column* s5-3)
|
||||
)
|
||||
(format #t "~Tdata[~D]: @ #x~X~%" (-> obj allocated-length) (-> obj data))
|
||||
@@ -427,7 +427,7 @@
|
||||
|
||||
;; definition for method 13 of type connection
|
||||
(defmethod move-to-dead connection ((obj connection))
|
||||
(let ((v1-1 ((method-of-type connection get-engine) obj)))
|
||||
(let ((v1-1 (get-engine obj)))
|
||||
(set! (-> obj prev0 next0) (-> obj next0))
|
||||
(set! (-> obj next0 prev0) (-> obj prev0))
|
||||
(set! (-> obj prev1 next1) (-> obj next1))
|
||||
|
||||
@@ -506,32 +506,21 @@
|
||||
(defun
|
||||
draw-sprite2d-xy
|
||||
((buf dma-buffer) (x int) (y int) (w int) (h int) (color rgba))
|
||||
(let*
|
||||
((context
|
||||
((method-of-type draw-context new)
|
||||
(the-as symbol (new 'stack-no-clear 'draw-context))
|
||||
draw-context
|
||||
x
|
||||
y
|
||||
w
|
||||
h
|
||||
color
|
||||
)
|
||||
)
|
||||
(draw-x (max 1792 (min 2304 (+ (-> context orgx) 1792))))
|
||||
(draw-y
|
||||
(max
|
||||
(min
|
||||
(+ (-> context orgy) (-> *video-parms* screen-miny))
|
||||
(-> *video-parms* screen-maxy)
|
||||
)
|
||||
(-> *video-parms* screen-miny)
|
||||
)
|
||||
)
|
||||
(draw-w (-> context width))
|
||||
(draw-h (-> context height))
|
||||
(end-dma (the-as dma-packet (-> buf base)))
|
||||
)
|
||||
(let* ((context (new 'stack 'draw-context x y w h color))
|
||||
(draw-x (max 1792 (min 2304 (+ (-> context orgx) 1792))))
|
||||
(draw-y
|
||||
(max
|
||||
(min
|
||||
(+ (-> context orgy) (-> *video-parms* screen-miny))
|
||||
(-> *video-parms* screen-maxy)
|
||||
)
|
||||
(-> *video-parms* screen-miny)
|
||||
)
|
||||
)
|
||||
(draw-w (-> context width))
|
||||
(draw-h (-> context height))
|
||||
(end-dma (the-as dma-packet (-> buf base)))
|
||||
)
|
||||
(let* ((a2-2 buf)
|
||||
(dma (the-as dma-packet (-> a2-2 base)))
|
||||
)
|
||||
@@ -742,19 +731,7 @@
|
||||
(defun
|
||||
screen-gradient
|
||||
((arg0 dma-buffer) (arg1 rgba) (arg2 rgba) (arg3 rgba) (arg4 rgba))
|
||||
(let
|
||||
((a1-2
|
||||
((method-of-type draw-context new)
|
||||
(the-as symbol (new 'stack-no-clear 'draw-context))
|
||||
draw-context
|
||||
0
|
||||
0
|
||||
512
|
||||
224
|
||||
(new 'static 'rgba)
|
||||
)
|
||||
)
|
||||
)
|
||||
(let ((a1-2 (new 'stack 'draw-context 0 0 512 224 (new 'static 'rgba))))
|
||||
(set! (-> a1-2 color 0) arg1)
|
||||
(set! (-> a1-2 color 1) arg2)
|
||||
(set! (-> a1-2 color 2) arg3)
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
trajectory
|
||||
((obj trajectory) (arg0 vector) (arg1 vector) (arg2 float) (arg3 float))
|
||||
(let ((f0-1 (/ (vector-vector-xz-distance arg1 arg0) arg2)))
|
||||
((method-of-type trajectory TODO-RENAME-11) obj arg0 arg1 f0-1 arg3)
|
||||
(TODO-RENAME-11 obj arg0 arg1 f0-1 arg3)
|
||||
)
|
||||
(let ((v0-1 0))
|
||||
)
|
||||
@@ -98,7 +98,7 @@
|
||||
(set! f0-3 (fmax (/ (- (- arg2) f0-4) arg3) (/ (+ (- arg2) f0-4) arg3)))
|
||||
)
|
||||
)
|
||||
((method-of-type trajectory TODO-RENAME-11) obj arg0 arg1 f0-3 arg3)
|
||||
(TODO-RENAME-11 obj arg0 arg1 f0-3 arg3)
|
||||
)
|
||||
(let ((v0-1 0))
|
||||
)
|
||||
@@ -118,7 +118,7 @@
|
||||
(if (< 0.0 f1-5)
|
||||
(set! f0-3 (sqrtf f1-5))
|
||||
)
|
||||
((method-of-type trajectory TODO-RENAME-13) obj arg0 arg1 f0-3 arg3)
|
||||
(TODO-RENAME-13 obj arg0 arg1 f0-3 arg3)
|
||||
)
|
||||
(let ((v0-1 0))
|
||||
)
|
||||
@@ -142,7 +142,7 @@
|
||||
)
|
||||
(let
|
||||
((f0-1 (* (-> obj time) (/ (+ 1.0 (the float s2-0)) (the float s3-0)))))
|
||||
((method-of-type trajectory TODO-RENAME-9) obj f0-1 s4-0)
|
||||
(TODO-RENAME-9 obj f0-1 s4-0)
|
||||
)
|
||||
(add-debug-line #t 68 s5-0 s4-0 (new 'static 'rgba :r #xff :a #x80) #f -1)
|
||||
)
|
||||
@@ -151,7 +151,3 @@
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -69,11 +69,11 @@
|
||||
(set! (-> obj period) (* (-> obj period) (-> obj damp-period)))
|
||||
(set! (-> obj ticks) f30-0)
|
||||
(if (< (-> obj damp-period) 0.0)
|
||||
((method-of-type smush-control set-zero!) obj)
|
||||
(set-zero! obj)
|
||||
)
|
||||
)
|
||||
(if (>= f30-0 (-> obj duration))
|
||||
((method-of-type smush-control set-zero!) obj)
|
||||
(set-zero! obj)
|
||||
)
|
||||
(*
|
||||
(sin (/ (* 65536.0 f28-0) (-> obj period)))
|
||||
@@ -130,11 +130,7 @@
|
||||
(arg4 float)
|
||||
(arg5 float)
|
||||
)
|
||||
(when
|
||||
(>=
|
||||
(fabs (* 0.2 (-> obj amp)))
|
||||
(fabs ((method-of-type smush-control get-no-update) obj))
|
||||
)
|
||||
(when (>= (fabs (* 0.2 (-> obj amp))) (fabs (get-no-update obj)))
|
||||
(set! (-> obj amp) arg0)
|
||||
(set! (-> obj period) (the float arg1))
|
||||
(set! (-> obj duration) (the float arg2))
|
||||
@@ -145,7 +141,3 @@
|
||||
)
|
||||
obj
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@
|
||||
|
||||
;; definition for method 9 of type sync-info-paused
|
||||
(defmethod dummy-9 sync-info-paused ((obj sync-info-paused) (arg0 float))
|
||||
(* ((method-of-type sync-info-paused dummy-11) obj) arg0)
|
||||
(* (dummy-11 obj) arg0)
|
||||
)
|
||||
|
||||
;; definition for method 13 of type sync-info
|
||||
@@ -337,12 +337,12 @@
|
||||
|
||||
;; definition for method 12 of type sync-info-eased
|
||||
(defmethod dummy-12 sync-info-eased ((obj sync-info-eased) (arg0 float))
|
||||
(* ((method-of-type sync-info-eased dummy-13) obj) arg0)
|
||||
(* (dummy-13 obj) arg0)
|
||||
)
|
||||
|
||||
;; definition for method 12 of type sync-info-paused
|
||||
(defmethod dummy-12 sync-info-paused ((obj sync-info-paused) (arg0 float))
|
||||
(* ((method-of-type sync-info-paused dummy-13) obj) arg0)
|
||||
(* (dummy-13 obj) arg0)
|
||||
)
|
||||
|
||||
;; definition for method 9 of type delayed-rand-float
|
||||
@@ -427,7 +427,7 @@
|
||||
(arg5 float)
|
||||
(arg6 float)
|
||||
)
|
||||
((method-of-type oscillating-float dummy-9) (-> obj osc) arg0 arg4 arg5 arg6)
|
||||
(dummy-9 (-> obj osc) arg0 arg4 arg5 arg6)
|
||||
(set! (-> obj max-value) arg1)
|
||||
(set! (-> obj min-value) arg2)
|
||||
(set! (-> obj elasticity) arg3)
|
||||
@@ -437,7 +437,7 @@
|
||||
|
||||
;; definition for method 10 of type bouncing-float
|
||||
(defmethod dummy-10 bouncing-float ((obj bouncing-float) (arg0 float))
|
||||
((method-of-type oscillating-float dummy-10) (-> obj osc) arg0)
|
||||
(dummy-10 (-> obj osc) arg0)
|
||||
(set! (-> obj state) 0)
|
||||
(when (>= (-> obj osc value) (-> obj max-value))
|
||||
(set! (-> obj osc value) (-> obj max-value))
|
||||
@@ -510,7 +510,7 @@
|
||||
(the-as int (- (-> *display* base-frame-counter) (-> obj start-time)))
|
||||
(-> obj timer)
|
||||
)
|
||||
((method-of-type delayed-rand-vector dummy-10) obj)
|
||||
(dummy-10 obj)
|
||||
)
|
||||
(-> obj value)
|
||||
)
|
||||
@@ -524,7 +524,7 @@
|
||||
(the-as int (- (-> *display* base-frame-counter) (-> obj start-time)))
|
||||
(-> obj timer)
|
||||
)
|
||||
((method-of-type delayed-rand-vector dummy-10) obj)
|
||||
(dummy-10 obj)
|
||||
(.svf (&-> (-> obj value) quad) vf0)
|
||||
)
|
||||
(-> obj value)
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
((allocation symbol) (type-to-make type) (arg0 int) (arg1 string))
|
||||
(cond
|
||||
(arg1
|
||||
(let* ((s2-1 (max ((method-of-type string length) arg1) arg0))
|
||||
(let* ((s2-1 (max (length arg1) arg0))
|
||||
(a0-4
|
||||
(object-new
|
||||
allocation
|
||||
@@ -277,11 +277,7 @@
|
||||
|
||||
;; definition for function string<?
|
||||
(defun string<? ((a string) (b string))
|
||||
(let
|
||||
((len
|
||||
(min ((method-of-type string length) a) ((method-of-type string length) b))
|
||||
)
|
||||
)
|
||||
(let ((len (min (length a) (length b))))
|
||||
(dotimes (i len)
|
||||
(cond
|
||||
((< (-> a data i) (-> b data i))
|
||||
@@ -298,11 +294,7 @@
|
||||
|
||||
;; definition for function string>?
|
||||
(defun string>? ((a string) (b string))
|
||||
(let
|
||||
((len
|
||||
(min ((method-of-type string length) a) ((method-of-type string length) b))
|
||||
)
|
||||
)
|
||||
(let ((len (min (length a) (length b))))
|
||||
(dotimes (i len)
|
||||
(cond
|
||||
((< (-> a data i) (-> b data i))
|
||||
@@ -319,11 +311,7 @@
|
||||
|
||||
;; definition for function string<=?
|
||||
(defun string<=? ((a string) (b string))
|
||||
(let
|
||||
((len
|
||||
(min ((method-of-type string length) a) ((method-of-type string length) b))
|
||||
)
|
||||
)
|
||||
(let ((len (min (length a) (length b))))
|
||||
(dotimes (i len)
|
||||
(cond
|
||||
((< (-> a data i) (-> b data i))
|
||||
@@ -340,11 +328,7 @@
|
||||
|
||||
;; definition for function string>=?
|
||||
(defun string>=? ((a string) (b string))
|
||||
(let
|
||||
((len
|
||||
(min ((method-of-type string length) a) ((method-of-type string length) b))
|
||||
)
|
||||
)
|
||||
(let ((len (min (length a) (length b))))
|
||||
(dotimes (i len)
|
||||
(cond
|
||||
((< (-> a data i) (-> b data i))
|
||||
@@ -437,8 +421,8 @@
|
||||
|
||||
;; definition for function string-strip-trailing-whitespace!
|
||||
(defun string-strip-trailing-whitespace! ((str string))
|
||||
(when (nonzero? ((method-of-type string length) str))
|
||||
(let ((ptr (&+ (-> str data) (+ ((method-of-type string length) str) -1))))
|
||||
(when (nonzero? (length str))
|
||||
(let ((ptr (&+ (-> str data) (+ (length str) -1))))
|
||||
(while
|
||||
(and
|
||||
(>= (the-as int ptr) (the-as int (-> str data)))
|
||||
|
||||
@@ -2467,19 +2467,15 @@ TEST_F(FormRegressionTest, StringLt) {
|
||||
std::string type = "(function string string symbol)";
|
||||
std::string expected =
|
||||
"(begin\n"
|
||||
" (let\n"
|
||||
" ((s4-1\n"
|
||||
" (min\n"
|
||||
" ((method-of-type string length) arg0)\n"
|
||||
" ((method-of-type string length) arg1)\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" (dotimes\n"
|
||||
" (v1-4 s4-1)\n"
|
||||
" (let ((s4-1 (min (length arg0) (length arg1))))\n"
|
||||
" (dotimes (v1-4 s4-1)\n"
|
||||
" (cond\n"
|
||||
" ((< (-> arg0 data v1-4) (-> arg1 data v1-4)) (return #t))\n"
|
||||
" ((< (-> arg1 data v1-4) (-> arg0 data v1-4)) (return #f))\n"
|
||||
" ((< (-> arg0 data v1-4) (-> arg1 data v1-4))\n"
|
||||
" (return #t)\n"
|
||||
" )\n"
|
||||
" ((< (-> arg1 data v1-4) (-> arg0 data v1-4))\n"
|
||||
" (return #f)\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
@@ -2714,9 +2710,8 @@ TEST_F(FormRegressionTest, StripStripTrailingWhitespace) {
|
||||
std::string type = "(function string symbol)";
|
||||
std::string expected =
|
||||
"(begin\n"
|
||||
" (when (nonzero? ((method-of-type string length) arg0))\n"
|
||||
" (let\n"
|
||||
" ((v1-6 (&+ (-> arg0 data) (+ ((method-of-type string length) arg0) -1))))\n"
|
||||
" (when (nonzero? (length arg0))\n"
|
||||
" (let ((v1-6 (&+ (-> arg0 data) (+ (length arg0) -1))))\n"
|
||||
" (while\n"
|
||||
" (and\n"
|
||||
" (>= (the-as int v1-6) (the-as int (-> arg0 data)))\n"
|
||||
|
||||
Reference in New Issue
Block a user