fix set! missing typecast (#324)

This commit is contained in:
water111 2021-03-17 19:26:35 -04:00 committed by GitHub
parent d60d9b639a
commit 4262145c99
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 934 additions and 30 deletions

View file

@ -353,6 +353,10 @@ goos::Object SimpleExpression::to_form(const std::vector<DecompilerLabel>& label
}
}
std::string SimpleExpression::to_string(const Env& env) const {
return to_form(env.file->labels, env).print();
}
bool SimpleExpression::operator==(const SimpleExpression& other) const {
if (m_kind != other.m_kind) {
return false;

View file

@ -233,6 +233,7 @@ class SimpleExpression {
SimpleExpression(Kind kind, const SimpleAtom& arg0);
SimpleExpression(Kind kind, const SimpleAtom& arg0, const SimpleAtom& arg1);
goos::Object to_form(const std::vector<DecompilerLabel>& labels, const Env& env) const;
std::string to_string(const Env& env) const;
bool operator==(const SimpleExpression& other) const;
bool is_identity() const { return m_kind == Kind::IDENTITY; }
bool is_var() const { return is_identity() && get_arg(0).is_var(); }

View file

@ -359,13 +359,13 @@ TP_Type SimpleExpression::get_type_int2(const TypeState& input,
if (m_kind == Kind::ADD && arg0_type.typespec().base_type() == "pointer" &&
tc(dts, TypeSpec("integer"), arg1_type)) {
// plain pointer plus integer = plain pointer
return TP_Type::make_from_ts(TypeSpec("pointer"));
return TP_Type::make_from_ts(arg0_type.typespec());
}
if (m_kind == Kind::ADD && arg1_type.typespec().base_type() == "pointer" &&
tc(dts, TypeSpec("integer"), arg0_type)) {
// plain pointer plus integer = plain pointer
return TP_Type::make_from_ts(TypeSpec("pointer"));
return TP_Type::make_from_ts(arg1_type.typespec());
}
if (tc(dts, TypeSpec("structure"), arg1_type) && !m_args[0].is_int() &&

View file

@ -1,10 +1,11 @@
#include "Form.h"
#include <algorithm>
#include <utility>
#include "decompiler/ObjectFile/LinkedObjectFile.h"
#include "common/goos/PrettyPrinter.h"
#include "common/type_system/TypeSystem.h"
#include <algorithm>
#include "decompiler/util/DecompilerTypeSystem.h"
namespace decompiler {
@ -289,13 +290,23 @@ SetVarElement::SetVarElement(const RegisterAccess& var,
: m_dst(var),
m_src(value),
m_is_sequence_point(is_sequence_point),
m_src_type(src_type),
m_src_type(std::move(src_type)),
m_var_info(info) {
value->parent_element = this;
}
goos::Object SetVarElement::to_form_internal(const Env& env) const {
assert(active());
auto reg_kind = m_dst.reg().get_kind();
if ((reg_kind == Reg::FPR || reg_kind == Reg::GPR) && env.has_type_analysis()) {
auto expected_type = env.get_variable_type(m_dst, true);
if (!env.dts->ts.tc(expected_type, m_src_type)) {
return pretty_print::build_list(
"set!", m_dst.to_form(env),
pretty_print::build_list("the-as", expected_type.print(), m_src->to_form(env)));
}
}
return pretty_print::build_list("set!", m_dst.to_form(env), m_src->to_form(env));
}

View file

@ -20,6 +20,8 @@
["L86", "_lambda_", true]
],
"gstring": [["L170", "float", true]],
"math": [
["L41", "float", true],
["L34", "float", true],

View file

@ -98,8 +98,15 @@
[17, "s5", "pointer"]
],
// GSTRING
"name=": [
[24, "a1", "symbol"],
[39, "a0", "symbol"]
],
"string-cat-to-last-char": [
[3, "s5", "(pointer uint8)"],
[4, "s5", "string"]
]
}

View file

@ -343,6 +343,11 @@
)
(defmacro empty ()
"The decompiler may use (empty) as the body of a loop with nothing in it."
`(none)
)
;;;;;;;;;;;;;;;;;;;
;; Math Macros
;;;;;;;;;;;;;;;;;;;

View file

@ -1,6 +1,8 @@
;; GCOMMON
(define-extern name= (function basic basic symbol))
(define-extern fact (function int int))
(define-extern max (function int int int))
(define-extern min (function int int int))
;; KERNEL
(declare-type process basic)

View file

@ -0,0 +1,740 @@
;;-*-Lisp-*-
(in-package goal)
;; definition for method 4 of type string
(defmethod length string ((obj string))
(let ((v1-0 (-> obj data)))
(while (nonzero? (-> v1-0 0))
(nop!)
(nop!)
(nop!)
(set! v1-0 (&-> v1-0 1))
)
(&- v1-0 (the-as uint (-> obj data)))
)
)
;; definition for method 5 of type string
(defmethod asize-of string ((obj string))
(+ (+ (-> obj allocated-length) 1) (the-as int (-> string size)))
)
;; definition for function copy-string<-string
(defun copy-string<-string ((arg0 string) (arg1 string))
(let ((v1-0 (-> arg0 data)))
(let ((a1-1 (-> arg1 data)))
(while (nonzero? (-> a1-1 0))
(set! (-> v1-0 0) (-> a1-1 0))
(set! v1-0 (&-> v1-0 1))
(set! a1-1 (&-> a1-1 1))
)
)
(set! (-> v1-0 0) (the-as uint 0))
)
arg0
)
;; definition for method 0 of type string
(defmethod
new
string
((allocation symbol) (type-to-make type) (arg0 int) (arg1 string))
(if arg1 (let* ((s2-1 (max ((method-of-type string length) arg1) arg0))
(a0-4
(object-new
allocation
type-to-make
(+ (+ s2-1 1) (the-as int (-> type-to-make size)))
)
)
)
(set! (-> a0-4 allocated-length) s2-1)
(copy-string<-string a0-4 arg1)
)
(let
((v0-2
(object-new
allocation
type-to-make
(+ (+ arg0 1) (the-as int (-> type-to-make size)))
)
)
)
(set! (-> v0-2 allocated-length) arg0)
v0-2
)
)
)
;; definition for function string=
(defun string= ((str-a string) (str-b string))
(let ((a-ptr (-> str-a data))
(b-ptr (-> str-b data))
)
(if (or (zero? str-a) (zero? str-b))
(return #f)
)
(while (and (nonzero? (-> a-ptr 0)) (nonzero? (-> b-ptr 0)))
(if (!= (-> a-ptr 0) (-> b-ptr 0))
(return #f)
)
(set! a-ptr (&-> a-ptr 1))
(set! b-ptr (&-> b-ptr 1))
)
(and (zero? (-> a-ptr 0)) (zero? (-> b-ptr 0)))
)
)
;; definition for function string-charp=
(defun string-charp= ((str string) (charp (pointer uint8)))
(let ((str-ptr (-> str data)))
(while (and (nonzero? (-> str-ptr 0)) (nonzero? (-> charp 0)))
(if (!= (-> str-ptr 0) (-> charp 0))
(return #f)
)
(set! str-ptr (&-> str-ptr 1))
(set! charp (&-> charp 1))
)
(and (zero? (-> str-ptr 0)) (zero? (-> charp 0)))
)
)
;; definition for function name=
(defun name= ((arg0 basic) (arg1 basic))
(cond
((= arg0 arg1)
#t
)
((and (= (-> arg0 type) string) (= (-> arg1 type) string))
(string= (the-as string arg0) (the-as string arg1))
)
((and (= (-> arg0 type) string) (= (-> arg1 type) symbol))
(string=
(the-as string arg0)
(the-as string (-> (the-as (pointer uint32) (+ #xff38 (the-as int arg1)))))
)
)
((and (= (-> arg1 type) string) (= (-> arg0 type) symbol))
(string=
(the-as string arg1)
(the-as string (-> (the-as (pointer uint32) (+ #xff38 (the-as int arg0)))))
)
)
)
)
;; definition for function copyn-string<-charp
(defun copyn-string<-charp ((str string) (charp (pointer uint8)) (len int))
(let ((str-ptr (-> str data)))
(dotimes (i len)
(set! (-> str-ptr 0) (-> charp 0))
(set! str-ptr (&-> str-ptr 1))
(set! charp (&-> charp 1))
)
(set! (-> str-ptr 0) (the-as uint 0))
)
str
)
;; definition for function string<-charp
(defun string<-charp ((str string) (charp (pointer uint8)))
(let ((str-ptr (-> str data)))
(while (nonzero? (-> charp 0))
(set! (-> str-ptr 0) (-> charp 0))
(set! str-ptr (&-> str-ptr 1))
(set! charp (&-> charp 1))
)
(set! (-> str-ptr 0) (the-as uint 0))
)
str
)
;; definition for function charp<-string
(defun charp<-string ((charp (pointer uint8)) (str string))
(let ((str-ptr (-> str data)))
(while (nonzero? (-> str-ptr 0))
(set! (-> charp 0) (-> str-ptr 0))
(set! charp (&-> charp 1))
(set! str-ptr (&-> str-ptr 1))
)
)
(set! (-> charp 0) (the-as uint 0))
0
)
;; definition for function copy-charp<-charp
(defun copy-charp<-charp ((dst (pointer uint8)) (src (pointer uint8)))
(while (nonzero? (-> src 0))
(set! (-> dst 0) (-> src 0))
(set! dst (&-> dst 1))
(set! src (&-> src 1))
)
(set! (-> dst 0) (the-as uint 0))
dst
)
;; definition for function cat-string<-string
(defun cat-string<-string ((a string) (b string))
(let ((a-ptr (-> a data)))
(let ((b-ptr (-> b data)))
(while (nonzero? (-> a-ptr 0))
(nop!)
(nop!)
(nop!)
(set! a-ptr (&-> a-ptr 1))
)
(while (nonzero? (-> b-ptr 0))
(set! (-> a-ptr 0) (-> b-ptr 0))
(set! a-ptr (&-> a-ptr 1))
(set! b-ptr (&-> b-ptr 1))
)
)
(set! (-> a-ptr 0) (the-as uint 0))
)
a
)
;; definition for function catn-string<-charp
(defun catn-string<-charp ((a string) (b (pointer uint8)) (len int))
(let ((a-ptr (-> a data)))
(while (nonzero? (-> a-ptr 0))
(nop!)
(nop!)
(nop!)
(set! a-ptr (&-> a-ptr 1))
)
(dotimes (i len)
(set! (-> a-ptr 0) (-> b 0))
(set! a-ptr (&-> a-ptr 1))
(set! b (&-> b 1))
)
(set! (-> a-ptr 0) (the-as uint 0))
)
a
)
;; definition for function cat-string<-string_to_charp
(defun
cat-string<-string_to_charp
((a string) (b string) (end-ptr (pointer uint8)))
(let ((b-ptr (-> b data))
(a-ptr (-> a data))
)
(while (nonzero? (-> a-ptr 0))
(nop!)
(nop!)
(nop!)
(set! a-ptr (&-> a-ptr 1))
)
(while
(and (>= (the-as int end-ptr) (the-as int b-ptr)) (nonzero? (-> b-ptr 0)))
(set! (-> a-ptr 0) (-> b-ptr 0))
(set! a-ptr (&-> a-ptr 1))
(set! b-ptr (&-> b-ptr 1))
)
(set! (-> a-ptr 0) (the-as uint 0))
a-ptr
)
)
;; definition for function append-character-to-string
(defun append-character-to-string ((str string) (char uint8))
(let ((str-ptr (-> str data)))
(while (nonzero? (-> str-ptr 0))
(nop!)
(nop!)
(nop!)
(set! str-ptr (&-> str-ptr 1))
)
(set! (-> str-ptr 0) (the-as uint char))
(set! (-> str-ptr 1) (the-as uint 0))
)
(let ((v1-1 0))
)
0
)
;; definition for function charp-basename
(defun charp-basename ((charp (pointer uint8)))
(let ((ptr charp))
(while (nonzero? (-> ptr 0))
(set! ptr (&-> ptr 1))
)
(while (< (the-as int charp) (the-as int ptr))
(set! ptr (&-> ptr -1))
(if (or (= (-> ptr 0) 47) (= (-> ptr 0) 92))
(return (&-> ptr 1))
)
)
)
charp
)
;; definition for function clear
(defun clear ((arg0 string))
(set! (-> arg0 data 0) (the-as uint 0))
arg0
)
;; 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))
)
)
(dotimes (i len)
(cond
((< (-> a data i) (-> b data i))
(return #t)
)
((< (-> b data i) (-> a data i))
(return #f)
)
)
)
)
#f
)
;; 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))
)
)
(dotimes (i len)
(cond
((< (-> a data i) (-> b data i))
(return #f)
)
((< (-> b data i) (-> a data i))
(return #t)
)
)
)
)
#f
)
;; 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))
)
)
(dotimes (i len)
(cond
((< (-> a data i) (-> b data i))
(return #t)
)
((< (-> b data i) (-> a data i))
(return #f)
)
)
)
)
#t
)
;; 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))
)
)
(dotimes (i len)
(cond
((< (-> a data i) (-> b data i))
(return #f)
)
((< (-> b data i) (-> a data i))
(return #t)
)
)
)
)
#t
)
;; definition for symbol *string-tmp-str*, type string
(define *string-tmp-str* (new 'global 'string 128 (the-as string #f)))
;; definition for function string-skip-to-char
(defun string-skip-to-char ((arg0 (pointer uint8)) (arg1 uint))
(while (and (nonzero? (-> arg0 0)) (!= (-> arg0 0) arg1))
(set! arg0 (&-> arg0 1))
)
arg0
)
;; definition for function string-cat-to-last-char
(defun
string-cat-to-last-char
((base-str string) (append-str string) (char uint))
(let ((end-of-append (&-> (the-as (pointer uint8) append-str) 3)))
(let ((location-of-char (string-skip-to-char (-> append-str data) char)))
(when (= (-> location-of-char 0) char)
(until (begin
(set! end-of-append location-of-char)
(set!
location-of-char
(string-skip-to-char (&-> location-of-char 1) char)
)
(!= (-> location-of-char 0) char)
)
(empty)
)
)
)
(cat-string<-string_to_charp base-str append-str end-of-append)
)
)
;; definition for function string-skip-whitespace
(defun string-skip-whitespace ((arg0 (pointer uint8)))
(while
(and
(nonzero? (-> arg0 0))
(or
(= (-> arg0 0) 32)
(= (-> arg0 0) 9)
(= (-> arg0 0) 13)
(= (-> arg0 0) 10)
)
)
(set! arg0 (&-> arg0 1))
)
arg0
)
;; definition for function string-suck-up!
(defun string-suck-up! ((str string) (location (pointer uint8)))
(when (!= location (-> str data))
(let ((str-ptr (-> str data)))
(while (nonzero? (-> location 0))
(set! (-> str-ptr 0) (-> location 0))
(set! str-ptr (&-> str-ptr 1))
(set! location (&-> location 1))
)
(set! (-> str-ptr 0) (the-as uint 0))
)
(let ((v1-3 0))
)
)
#f
)
;; definition for function string-strip-leading-whitespace!
(defun string-strip-leading-whitespace! ((arg0 string))
(let ((a1-0 (string-skip-whitespace (-> arg0 data))))
(string-suck-up! arg0 a1-0)
)
#f
)
;; 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))))
(while
(and
(>= (the-as int ptr) (the-as int (-> str data)))
(or
(= (-> ptr 0) 32)
(= (-> ptr 0) 9)
(= (-> ptr 0) 13)
(= (-> ptr 0) 10)
)
)
(set! ptr (&-> ptr -1))
)
(set! (-> ptr 1) (the-as uint 0))
)
(let ((v1-7 0))
)
)
#f
)
;; definition for function string-strip-whitespace!
(defun string-strip-whitespace! ((arg0 string))
(string-strip-trailing-whitespace! arg0)
(string-strip-leading-whitespace! arg0)
#f
)
;; definition for function string-get-arg!!
(defun string-get-arg!! ((a-str string) (arg string))
(let ((arg-word-start (string-skip-whitespace (-> arg data))))
(cond
((= (-> arg-word-start 0) 34)
(return (begin
(let ((arg-end (&-> arg-word-start 1)))
(let ((arg-start arg-end))
(while
(and
(nonzero? (-> arg-end 0))
(nonzero? (+ (-> arg-end 0) -34))
)
(set! arg-end (&-> arg-end 1))
)
(copyn-string<-charp
a-str
arg-start
(&- arg-end (the-as uint arg-start))
)
)
(when (= (-> arg-end 0) 34)
(set! arg-end (&-> arg-end 1))
(let ((v1-6 arg-end))
)
)
(let ((a1-3 (string-skip-whitespace arg-end)))
(string-suck-up! arg a1-3)
)
)
#t
)
)
)
((nonzero? (-> arg-word-start 0))
(return (begin
(let ((v1-11 arg-word-start))
(while
(and
(nonzero? (-> arg-word-start 0))
(nonzero? (+ (-> arg-word-start 0) -32))
(nonzero? (+ (-> arg-word-start 0) -9))
(nonzero? (+ (-> arg-word-start 0) -13))
(nonzero? (+ (-> arg-word-start 0) -10))
)
(set! arg-word-start (&-> arg-word-start 1))
)
(copyn-string<-charp
a-str
v1-11
(&- arg-word-start (the-as uint v1-11))
)
)
(let ((a1-9 (string-skip-whitespace arg-word-start)))
(string-suck-up! arg a1-9)
)
#t
)
)
)
)
)
#f
)
;; definition for function string->int
(defun string->int ((str string))
(let ((str-ptr (-> str data))
(result 0)
(v1-0 #f)
)
(cond
((= (-> str-ptr 0) 35)
(let ((next-char-1 (&-> str-ptr 1)))
(cond
((or (= (-> next-char-1 0) 120) (= (-> next-char-1 0) 88))
(let ((next-char-2 (&-> next-char-1 1)))
(when (= (-> next-char-2 1) 45)
(set! v1-0 #t)
(set! next-char-2 (&-> next-char-2 1))
(let ((a1-8 next-char-2))
)
)
(while
(or
(and
(>= (-> next-char-2 0) (the-as uint 48))
(>= (the-as uint 57) (-> next-char-2 0))
)
(and
(>= (-> next-char-2 0) (the-as uint 65))
(>= (the-as uint 70) (-> next-char-2 0))
)
(and
(>= (-> next-char-2 0) (the-as uint 97))
(>= (the-as uint 102) (-> next-char-2 0))
)
)
(cond
((and
(>= (-> next-char-2 0) (the-as uint 65))
(>= (the-as uint 70) (-> next-char-2 0))
)
(set!
result
(the-as
int
(+ (+ (-> next-char-2 0) -55) (the-as uint (shl result 4)))
)
)
(let ((a1-14 (the-as uint result)))
)
)
(else
(cond
((and
(>= (-> next-char-2 0) (the-as uint 97))
(>= (the-as uint 102) (-> next-char-2 0))
)
(set!
result
(the-as
int
(+ (+ (-> next-char-2 0) -87) (the-as uint (shl result 4)))
)
)
(let ((a1-20 (the-as uint result)))
)
)
(else
(set!
result
(the-as
int
(+ (+ (-> next-char-2 0) -48) (the-as uint (shl result 4)))
)
)
(let ((a1-23 (the-as uint result)))
)
)
)
)
)
(set! next-char-2 (&-> next-char-2 1))
)
)
)
((or (= (-> next-char-1 0) 98) (= (-> next-char-1 0) 66))
(let ((a0-4 (&-> next-char-1 1)))
(while
(and
(>= (-> a0-4 0) (the-as uint 48))
(>= (the-as uint 49) (-> a0-4 0))
)
(set!
result
(the-as int (+ (+ (-> a0-4 0) -48) (the-as uint (shl result 1))))
)
(set! a0-4 (&-> a0-4 1))
)
)
)
)
)
)
(else
(when (= (-> str-ptr 1) 45)
(set! v1-0 #t)
(set! str-ptr (&-> str-ptr 1))
(let ((a1-47 str-ptr))
)
)
(while
(and
(>= (-> str-ptr 0) (the-as uint 48))
(>= (the-as uint 57) (-> str-ptr 0))
)
(set!
result
(the-as int (+ (+ (-> str-ptr 0) -48) (the-as uint (* 10 result))))
)
(set! str-ptr (&-> str-ptr 1))
)
)
)
(cond
(v1-0
(- result)
)
(else
(empty)
result
)
)
)
)
;; definition for function string->float
(defun string->float ((arg0 string))
(format 0 "string->float left as an excersize for the reader~%")
0.0
)
;; definition for function string-get-int32!!
(defun string-get-int32!! ((arg0 (pointer int32)) (arg1 string))
(cond
((string-get-arg!! *string-tmp-str* arg1)
(set! (-> arg0 0) (string->int *string-tmp-str*))
#t
)
(else
#f
)
)
)
;; definition for function string-get-float!!
(defun string-get-float!! ((arg0 (pointer float)) (arg1 string))
(cond
((string-get-arg!! *string-tmp-str* arg1)
(set! (-> arg0 0) (string->float *string-tmp-str*))
#t
)
(else
#f
)
)
)
;; definition for function string-get-flag!!
(defun
string-get-flag!!
((result (pointer symbol))
(in string)
(first-flag string)
(second-flag string)
)
(if (string-get-arg!! *string-tmp-str* in)
(cond
((or
(string= *string-tmp-str* first-flag)
(string= *string-tmp-str* second-flag)
)
(set! (-> result 0) (string= *string-tmp-str* first-flag))
#t
)
(else
#f
)
)
#f
)
)
;; definition for symbol *debug-draw-pauseable*, type symbol
(define *debug-draw-pauseable* #f)
;; definition for symbol *stdcon0*, type string
(define *stdcon0* (new 'global 'string #x4000 (the-as string #f)))
;; definition for symbol *stdcon1*, type string
(define *stdcon1* (new 'global 'string #x4000 (the-as string #f)))
;; definition for symbol *stdcon*, type string
(define *stdcon* *stdcon0*)
;; definition for symbol *temp-string*, type string
(define *temp-string* (new 'global 'string 256 (the-as string #f)))
;; failed to figure out what this is:
(none)

View file

@ -2625,4 +2625,114 @@ TEST_F(FormRegressionTest, QMemCpy) {
" v0-0\n"
" )";
test_with_expr(func, type, expected);
}
TEST_F(FormRegressionTest, StripStripTrailingWhitespace) {
std::string func =
"sll r0, r0, 0\n"
"L52:\n"
" daddiu sp, sp, -48\n"
" sd ra, 0(sp)\n"
" sq s5, 16(sp)\n"
" sq gp, 32(sp)\n"
" or gp, a0, r0\n"
" or a0, gp, r0\n"
" lw v1, string(s7)\n"
" lwu t9, 32(v1)\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" or v1, v0, r0\n"
" beq v1, r0, L56\n"
" or v1, s7, r0\n"
" daddiu s5, gp, 4\n"
" or a0, gp, r0\n"
" lw v1, string(s7)\n"
" lwu t9, 32(v1)\n"
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" or v1, v0, r0\n"
" daddiu v1, v1, -1\n"
" daddu v1, s5, v1\n"
" beq r0, r0, L54\n"
" sll r0, r0, 0\n"
"L53:\n"
" daddiu v1, v1, -1\n"
"L54:\n"
" daddiu a0, gp, 4\n"
" slt a0, v1, a0\n"
" daddiu a1, s7, 8\n"
" movn a1, s7, a0\n"
" beql s7, a1, L55\n"
" or a0, a1, r0\n"
" lbu a0, 0(v1)\n"
" daddiu a0, a0, -32\n"
" daddiu a1, s7, 8\n"
" movn a1, s7, a0\n"
" bnel s7, a1, L55\n"
" or a0, a1, r0\n"
" lbu a0, 0(v1)\n"
" daddiu a0, a0, -9\n"
" daddiu a1, s7, 8\n"
" movn a1, s7, a0\n"
" bnel s7, a1, L55\n"
" or a0, a1, r0\n"
" lbu a0, 0(v1)\n"
" daddiu a0, a0, -13\n"
" daddiu a1, s7, 8\n"
" movn a1, s7, a0\n"
" bnel s7, a1, L55\n"
" or a0, a1, r0\n"
" lbu a0, 0(v1)\n"
" daddiu a1, a0, -10\n"
" daddiu a0, s7, 8\n"
" movn a0, s7, a1\n"
"L55:\n"
" bne s7, a0, L53\n"
" sll r0, r0, 0\n"
" or a0, s7, r0\n"
" sb r0, 1(v1)\n"
" or v1, r0, r0\n"
"L56:\n"
" or v0, s7, r0\n"
" ld ra, 0(sp)\n"
" lq gp, 32(sp)\n"
" lq s5, 16(sp)\n"
" jr ra\n"
" daddiu sp, sp, 48\n";
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"
" (while\n"
" (and\n"
" (>= (the-as int v1-6) (the-as int (-> arg0 data)))\n"
" (or\n"
" (= (-> v1-6 0) 32)\n"
" (= (-> v1-6 0) 9)\n"
" (= (-> v1-6 0) 13)\n"
" (= (-> v1-6 0) 10)\n"
" )\n"
" )\n"
" (set! v1-6 (&-> v1-6 -1))\n"
" )\n"
" (set! (-> v1-6 1) (the-as uint 0))\n"
" )\n"
" (let ((v1-7 0))\n"
" )\n"
" )\n"
" #f\n"
" )";
test_with_expr(func, type, expected);
}

View file

@ -2350,21 +2350,21 @@ TEST_F(FormRegressionTest, ExprStringToInt) {
std::string type = "(function string int)";
std::string expected =
"(defun test-function ((arg0 string))\n"
" (let\n"
" ((a0-1 (-> arg0 data)) (v0-0 0) (v1-0 #f))\n"
" (let ((a0-1 (-> arg0 data))\n"
" (v0-0 0)\n"
" (v1-0 #f)\n"
" )\n"
" (cond\n"
" ((= (-> a0-1 0) 35)\n"
" (let\n"
" ((a0-2 (&-> a0-1 1)))\n"
" (let ((a0-2 (&-> a0-1 1)))\n"
" (cond\n"
" ((or (= (-> a0-2 0) 120) (= (-> a0-2 0) 88))\n"
" (let\n"
" ((a0-3 (&-> a0-2 1)))\n"
" (when\n"
" (= (-> a0-3 1) 45)\n"
" (let ((a0-3 (&-> a0-2 1)))\n"
" (when (= (-> a0-3 1) 45)\n"
" (set! v1-0 #t)\n"
" (set! a0-3 (&-> a0-3 1))\n"
" (let ((a1-8 a0-3)))\n"
" (let ((a1-8 a0-3))\n"
" )\n"
" )\n"
" (while\n"
" (or\n"
@ -2386,8 +2386,12 @@ TEST_F(FormRegressionTest, ExprStringToInt) {
" (>= (-> a0-3 0) (the-as uint 65))\n"
" (>= (the-as uint 70) (-> a0-3 0))\n"
" )\n"
" (set! v0-0 (+ (+ (-> a0-3 0) -55) (the-as uint (shl v0-0 4))))\n"
" (let ((a1-14 (the-as uint v0-0))))\n"
" (set!\n"
" v0-0\n"
" (the-as int (+ (+ (-> a0-3 0) -55) (the-as uint (shl v0-0 4))))\n"
" )\n"
" (let ((a1-14 (the-as uint v0-0)))\n"
" )\n"
" )\n"
" (else\n"
" (cond\n"
@ -2395,12 +2399,20 @@ TEST_F(FormRegressionTest, ExprStringToInt) {
" (>= (-> a0-3 0) (the-as uint 97))\n"
" (>= (the-as uint 102) (-> a0-3 0))\n"
" )\n"
" (set! v0-0 (+ (+ (-> a0-3 0) -87) (the-as uint (shl v0-0 4))))\n"
" (let ((a1-20 (the-as uint v0-0))))\n"
" (set!\n"
" v0-0\n"
" (the-as int (+ (+ (-> a0-3 0) -87) (the-as uint (shl v0-0 4))))\n"
" )\n"
" (let ((a1-20 (the-as uint v0-0)))\n"
" )\n"
" )\n"
" (else\n"
" (set! v0-0 (+ (+ (-> a0-3 0) -48) (the-as uint (shl v0-0 4))))\n"
" (let ((a1-23 (the-as uint v0-0))))\n"
" (set!\n"
" v0-0\n"
" (the-as int (+ (+ (-> a0-3 0) -48) (the-as uint (shl v0-0 4))))\n"
" )\n"
" (let ((a1-23 (the-as uint v0-0)))\n"
" )\n"
" )\n"
" )\n"
" )\n"
@ -2410,14 +2422,16 @@ TEST_F(FormRegressionTest, ExprStringToInt) {
" )\n"
" )\n"
" ((or (= (-> a0-2 0) 98) (= (-> a0-2 0) 66))\n"
" (let\n"
" ((a0-4 (&-> a0-2 1)))\n"
" (let ((a0-4 (&-> a0-2 1)))\n"
" (while\n"
" (and\n"
" (>= (-> a0-4 0) (the-as uint 48))\n"
" (>= (the-as uint 49) (-> a0-4 0))\n"
" )\n"
" (set! v0-0 (+ (+ (-> a0-4 0) -48) (the-as uint (shl v0-0 1))))\n"
" (set!\n"
" v0-0\n"
" (the-as int (+ (+ (-> a0-4 0) -48) (the-as uint (shl v0-0 1))))\n"
" )\n"
" (set! a0-4 (&-> a0-4 1))\n"
" )\n"
" )\n"
@ -2426,20 +2440,28 @@ TEST_F(FormRegressionTest, ExprStringToInt) {
" )\n"
" )\n"
" (else\n"
" (when\n"
" (= (-> a0-1 1) 45)\n"
" (when (= (-> a0-1 1) 45)\n"
" (set! v1-0 #t)\n"
" (set! a0-1 (&-> a0-1 1))\n"
" (let ((a1-47 a0-1)))\n"
" (let ((a1-47 a0-1))\n"
" )\n"
" )\n"
" (while\n"
" (and (>= (-> a0-1 0) (the-as uint 48)) (>= (the-as uint 57) (-> a0-1 0)))\n"
" (set! v0-0 (+ (+ (-> a0-1 0) -48) (the-as uint (* 10 v0-0))))\n"
" (set! v0-0 (the-as int (+ (+ (-> a0-1 0) -48) (the-as uint (* 10 v0-0)))))\n"
" (set! a0-1 (&-> a0-1 1))\n"
" )\n"
" )\n"
" )\n"
" (cond (v1-0 (- v0-0)) (else (empty) v0-0))\n"
" (cond\n"
" (v1-0\n"
" (- v0-0)\n"
" )\n"
" (else\n"
" (empty)\n"
" v0-0\n"
" )\n"
" )\n"
" )\n"
" )";
test_final_function(func, type, expected);

View file

@ -9,13 +9,13 @@
namespace {
// the object files to test
const std::unordered_set<std::string> g_object_files_to_decompile = {"gcommon", "gstring-h",
"gkernel-h", "gkernel"};
const std::unordered_set<std::string> g_object_files_to_decompile = {
"gcommon", "gstring-h", "gkernel-h", "gkernel", "gstring"};
// the object files to check against a reference in test/decompiler/reference
const std::vector<std::string> g_object_files_to_check_against_reference = {
"gcommon", // NOTE: this file needs work, but adding it for now just to test the framework.
"gstring-h", "gkernel-h", "gkernel"};
"gstring-h", "gkernel-h", "gkernel", "gstring"};
// the functions we expect the decompiler to skip
const std::unordered_set<std::string> expected_skip_in_decompiler = {