From 3b666beae26c4bbf617eb395945a0da2ef44b267 Mon Sep 17 00:00:00 2001 From: ManDude <7569514+ManDude@users.noreply.github.com> Date: Thu, 23 Mar 2023 00:41:51 +0000 Subject: [PATCH] [jak2] implement `abandon-thread` (#2396) implements `abandon-thread` for when we want to return from a thread, but are in a `post` thread which normally disallows this. --- goal_src/jak2/engine/anim/aligner.gc | 9 ++----- .../process-drawable/process-drawable.gc | 18 ++++---------- goal_src/jak2/kernel/gkernel.gc | 24 +++++++++++++------ goal_src/jak2/kernel/gstate.gc | 10 ++------ 4 files changed, 25 insertions(+), 36 deletions(-) diff --git a/goal_src/jak2/engine/anim/aligner.gc b/goal_src/jak2/engine/anim/aligner.gc index 6dcc7e310d..f051011732 100644 --- a/goal_src/jak2/engine/anim/aligner.gc +++ b/goal_src/jak2/engine/anim/aligner.gc @@ -9,8 +9,6 @@ ;; DECOMP BEGINS -;; ERROR: Unsupported inline assembly instruction kind - [lw ra, return-from-thread(s7)] -;; ERROR: Unsupported inline assembly instruction kind - [jr ra] (defmethod compute-alignment! align-control ((obj align-control)) (local-vars (a0-10 symbol) (s7-0 none) (ra-0 int)) (rlet ((vf0 :class vf) @@ -30,11 +28,8 @@ ) (else (when (!= (-> v1-7 type) art-joint-anim) - (break!) ;; modified. - ; (go process-drawable-art-error "align joint-anim") - ; (.lw ra-0 return-from-thread s7-0) - ; (.jr ra-0) - ; (nop!) + (go process-drawable-art-error "align joint-anim") + (abandon-thread) 0 ) ) diff --git a/goal_src/jak2/engine/process-drawable/process-drawable.gc b/goal_src/jak2/engine/process-drawable/process-drawable.gc index f13e5317f3..312520e264 100644 --- a/goal_src/jak2/engine/process-drawable/process-drawable.gc +++ b/goal_src/jak2/engine/process-drawable/process-drawable.gc @@ -1203,8 +1203,6 @@ 0 ) -;; ERROR: Unsupported inline assembly instruction kind - [lw ra, return-from-thread(s7)] -;; ERROR: Unsupported inline assembly instruction kind - [jr ra] (defmethod update-anim-data joint-control ((obj joint-control)) (local-vars (s7-0 none) (ra-0 int)) (let ((s5-0 (+ (-> obj active-channels) (-> obj float-channels)))) @@ -1217,11 +1215,8 @@ (let ((s2-0 (-> s3-0 frame-group))) (when (not (and s2-0 (nonzero? s2-0) (= (logand (the-as int s2-0) 7) 4) (= (-> s2-0 type) art-joint-anim))) (go process-drawable-art-error "joint-anim") - (break!) - ;; (.lw ra-0 return-from-thread s7-0) - ;; (.jr ra-0) - ;; (nop!) - ;; 0 + (abandon-thread) + 0 ) (when (nonzero? (-> s2-0 frames flags)) (cond @@ -1246,8 +1241,6 @@ (none) ) -;; ERROR: Unsupported inline assembly instruction kind - [lw ra, return-from-thread(s7)] -;; ERROR: Unsupported inline assembly instruction kind - [jr ra] (defmethod evaluate-joint-control process-drawable ((obj process-drawable)) (local-vars (s1-0 joint-control-channel) (s2-0 int) (s4-0 uint) (s7-0 none) (ra-0 int)) (with-pp @@ -1287,11 +1280,8 @@ (let ((s0-0 (-> s1-0 frame-group))) (when (not (and s0-0 (nonzero? s0-0) (= (logand (the-as int s0-0) 7) 4) (= (-> s0-0 type) art-joint-anim))) (go process-drawable-art-error "joint-anim") - (break!) - ;; (.lw ra-0 return-from-thread s7-0) - ;; (.jr ra-0) - ;; (nop!) - ;; 0 + (abandon-thread) + 0 ) (when (nonzero? (-> s0-0 frames flags)) (cond diff --git a/goal_src/jak2/kernel/gkernel.gc b/goal_src/jak2/kernel/gkernel.gc index 32d25bc329..444074a35a 100644 --- a/goal_src/jak2/kernel/gkernel.gc +++ b/goal_src/jak2/kernel/gkernel.gc @@ -510,6 +510,22 @@ ) ) +(defmacro abandon-thread () + ;; abandon this one too. + ;; NOTE - this is different from GOAL. + ;; GOAL installs this as the return address for this function and returns normally. + ;; but we don't because I don't have an easy way to find where to stick this. + ;; I can't see how this makes a difference, as all non-main threads seem + ;; temporary, but if this turns out to be false, we will need to change this. + `(rlet ((temp) + (off :reg r15 :type uint :reset-here #t)) + (.mov temp return-from-thread) ;; could probably just call this... + (.add temp off) + (.push temp) + (.ret) + ) + ) + (defun reset-and-call ((obj thread) (func function)) "Make the given thread the top thread, reset the stack, and call the function. Sets up a return trampoline so when the function returns it will return to the @@ -2388,13 +2404,7 @@ ;; then go back to the kernel dispatcher immediately. ((= (-> *kernel-context* current-process) obj) (set! (-> obj status) 'dead) - (let ((temp (the uint return-from-thread))) - (rlet ((off :reg r15 :type uint)) - (+! temp off) - (.push temp) - (.ret) - ) - ) + (abandon-thread) ) ;; if you deactivated yourself while initializing, we should go back to ;; the place where initialize was called in another process, not all the way back to the kernel. diff --git a/goal_src/jak2/kernel/gstate.gc b/goal_src/jak2/kernel/gstate.gc index 0a600c6a40..54f8aea9b1 100644 --- a/goal_src/jak2/kernel/gstate.gc +++ b/goal_src/jak2/kernel/gstate.gc @@ -447,14 +447,8 @@ It type checks the arguments for the entry function. ;; but we don't because I don't have an easy way to find where to stick this. ;; I can't see how this makes a difference, as all non-main threads seem ;; temporary, but if this turns out to be false, we will need to change this. - (rlet ((temp) - (off :reg r15 :type uint :reset-here #t)) - (.mov temp return-from-thread) ;; could probably just call this... - (.add temp off) - (.push temp) - (.ret) - #f ;; can't get here - ) + (abandon-thread) + #f ;; can't get here ) ) )