goalc: support static arrays of types (#2140)

draft because using the array is a little weird still, don't feel like
dealing with window's slow debugging builds today.

I get the following weird error:
```clj
(define test-array (new 'static 'boxed-array :type type vector))
gr> (-> test-array 0)
1538004        #x1777d4              0.0000        vector
gr> (type? (-> test-array 0) type)
1342757        #x147d25              0.0000        #t
gr> (new 'static (-> test-array 0))
-- Compilation Error! --
Got 3 arguments, but expected 2
Form:
(-> test-array 0)
Location:
Program string:1
(new 'static (-> test-array 0))
^
Code:
(new 'static (-> test-array 0))
```

Maybe this is expected though and the `new` method wants a symbol, not a
type?

Fixes #2060

Co-authored-by: water <awaterford111445@gmail.com>
This commit is contained in:
Tyler Wilding 2023-01-21 21:40:39 -05:00 committed by GitHub
parent abf61a94fb
commit 98393c6f4c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 267 additions and 6 deletions

View file

@ -37282,7 +37282,6 @@
) )
|# |#
#|
(deftype turret-info (basic) (deftype turret-info (basic)
((process uint32 :offset-assert 4) ((process uint32 :offset-assert 4)
(handle uint64 :offset-assert 8) (handle uint64 :offset-assert 8)
@ -37295,7 +37294,6 @@
:size-assert #x40 :size-assert #x40
:flag-assert #x900000040 :flag-assert #x900000040
) )
|#
#| #|
(deftype turret-path-event (structure) (deftype turret-path-event (structure)

View file

@ -856,7 +856,20 @@ void Compiler::fill_static_array_inline(const goos::Object& form,
ASSERT(deref_info.mem_deref); ASSERT(deref_info.mem_deref);
for (int arg_idx = 0; arg_idx < args_array_length; arg_idx++) { for (int arg_idx = 0; arg_idx < args_array_length; arg_idx++) {
int elt_offset = offset + arg_idx * deref_info.stride; int elt_offset = offset + arg_idx * deref_info.stride;
auto sr = compile_static(args_array[arg_idx], env); const auto& arg = args_array[arg_idx];
// Special case for symbols that refer to types
StaticResult sr;
if (content_type == TypeSpec("type") && arg.is_symbol()) {
const auto& type_name = arg.as_symbol()->name;
std::optional<int> expected_method_count = m_ts.try_get_type_method_count(type_name);
if (!expected_method_count) {
throw_compiler_error(form, "Undeclared type used in inline-array - {}", type_name);
}
sr = StaticResult::make_type_ref(type_name, expected_method_count.value());
} else {
sr = compile_static(arg, env);
}
if (is_integer(content_type)) { if (is_integer(content_type)) {
typecheck(form, TypeSpec("integer"), sr.typespec()); typecheck(form, TypeSpec("integer"), sr.typespec());
} else { } else {
@ -883,8 +896,10 @@ void Compiler::fill_static_array_inline(const goos::Object& form,
throw_compiler_error(form, "The integer {} doesn't fit in element {} of array of {}", throw_compiler_error(form, "The integer {} doesn't fit in element {} of array of {}",
sr.constant().print(), arg_idx, content_type.print()); sr.constant().print(), arg_idx, content_type.print());
} }
} // TODO - handle type case here as well } else if (sr.is_type()) {
else if (sr.is_func()) { ASSERT(deref_info.stride == 4);
structure->add_type_record(sr.symbol_name(), elt_offset);
} else if (sr.is_func()) {
ASSERT(deref_info.stride == 4); ASSERT(deref_info.stride == 4);
structure->add_function_record(sr.function(), elt_offset); structure->add_function_record(sr.function(), elt_offset);
} else { } else {

View file

@ -0,0 +1,230 @@
;;-*-Lisp-*-
(in-package goal)
;; definition of type target
(deftype target (process-focusable)
((self-override target :offset 32)
(control control-info :offset 128)
(fact-override fact-info-target :offset 160)
(skel2 joint-control :offset-assert 204)
(shadow-backup shadow-geo :offset-assert 208)
(target-flags uint32 :offset 188)
(game game-info :offset-assert 212)
(neck joint-mod :offset-assert 216)
(head joint-mod :offset-assert 220)
(upper-body joint-mod :offset-assert 224)
(horns joint-mod :offset-assert 228)
(hair joint-mod 2 :offset-assert 232)
(darkjak-interp float :offset-assert 240)
(darkjak-giant-interp float :offset-assert 244)
(arm-ik joint-mod-ik 2 :offset-assert 248)
(leg-ik joint-mod-ik 2 :offset-assert 256)
(foot joint-mod 2 :offset-assert 264)
(mech-ik joint-mod-ik 2 :offset-assert 272)
(init-time time-frame :offset 272)
(teleport-time time-frame :offset-assert 280)
(state-hook-time time-frame :offset-assert 288)
(state-hook (function none :behavior target) :offset-assert 296)
(cam-user-mode symbol :offset-assert 300)
(sidekick (pointer sidekick) :offset-assert 304)
(manipy (pointer manipy) :offset-assert 308)
(mirror (pointer process-drawable) :offset-assert 312)
(attack-info attack-info :inline :offset-assert 320)
(attack-info-rec attack-info :inline :offset-assert 480)
(attack-info-old attack-info 8 :inline :offset-assert 640)
(anim-seed uint64 :offset-assert 1920)
(alt-cam-pos vector :inline :offset-assert 1936)
(current-level level :offset-assert 1952)
(saved-pos transformq :inline :offset-assert 1968)
(saved-owner uint64 :offset-assert 2016)
(alt-neck-pos vector :inline :offset-assert 2032)
(focus-search (array collide-shape) :offset-assert 2048)
(excitement float :offset-assert 2052)
(shock-effect-time time-frame :offset-assert 2056)
(beard? symbol :offset-assert 2064)
(spool-anim spool-anim :offset-assert 2068)
(ambient-time time-frame :offset-assert 2072)
(fp-hud handle :offset-assert 2080)
(no-load-wait uint64 :offset-assert 2088)
(no-look-around-wait uint64 :offset-assert 2096)
(burn-proc handle :offset-assert 2104)
(pre-joint-hook (function none :behavior target) :offset-assert 2112)
(notify handle :offset-assert 2120)
(mode-cache basic :offset-assert 2128)
(mode-param1 handle :offset-assert 2136)
(mode-param2 uint64 :offset-assert 2144)
(mode-param3 uint64 :offset-assert 2152)
(tobot-state state :offset-assert 2160)
(tobot? symbol :offset-assert 2164)
(tobot-recorder basic :offset-assert 2168)
(color-effect basic :offset-assert 2172)
(color-effect-start-time time-frame :offset-assert 2176)
(color-effect-duration uint64 :offset-assert 2184)
(racer racer-info :offset-assert 2192)
(tube tube-info :offset-assert 2196)
(flut flut-info :offset-assert 2200)
(board board-info :offset-assert 2204)
(pilot pilot-info :offset-assert 2208)
(gun gun-info :offset-assert 2212)
(mech mech-info :offset-assert 2216)
(turret basic :offset-assert 2220)
(darkjak darkjak-info :offset-assert 2224)
(indax indax-info :offset-assert 2228)
)
:heap-base #x840
:method-count-assert 29
:size-assert #x8b8
:flag-assert #x1d084008b8
(:methods
(do-edge-grabs (_type_ collide-cache collide-edge-spec) none 27)
(init-target (_type_ continue-point symbol) none :behavior target 28)
)
(:states
target-carry-drop
target-carry-falling
(target-carry-hit-ground symbol)
(target-carry-jump float float)
target-carry-stance
target-carry-throw
target-carry-walk
(target-flut-start handle)
target-indax-start
(target-racing-start handle)
(target-tube-start handle)
(target-warp-in vector vector target)
(target-warp-out vector vector target)
)
)
;; definition for method 3 of type target
(defmethod inspect target ((obj target))
(when (not obj)
(set! obj obj)
(goto cfg-4)
)
(let ((t9-0 (method-of-type process-focusable inspect)))
(t9-0 obj)
)
(format #t "~2Tcontrol: ~A~%" (-> obj control))
(format #t "~2Tskel2: ~A~%" (-> obj skel2))
(format #t "~2Tshadow-backup: ~A~%" (-> obj shadow-backup))
(format #t "~2Ttarget-flags: ~D~%" (-> obj state-flags))
(format #t "~2Tgame: ~A~%" (-> obj game))
(format #t "~2Tneck: ~A~%" (-> obj neck))
(format #t "~2Thead: ~A~%" (-> obj head))
(format #t "~2Tupper-body: ~A~%" (-> obj upper-body))
(format #t "~2Thorns: ~A~%" (-> obj horns))
(format #t "~2Thair[2] @ #x~X~%" (-> obj hair))
(format #t "~2Tdarkjak-interp: ~f~%" (-> obj darkjak-interp))
(format #t "~2Tdarkjak-giant-interp: ~f~%" (-> obj darkjak-giant-interp))
(format #t "~2Tarm-ik[2] @ #x~X~%" (-> obj arm-ik))
(format #t "~2Tleg-ik[2] @ #x~X~%" (-> obj leg-ik))
(format #t "~2Tfoot[2] @ #x~X~%" (-> obj foot))
(format #t "~2Tinit-time: ~D~%" (-> obj init-time))
(format #t "~2Tteleport-time: ~D~%" (-> obj teleport-time))
(format #t "~2Tstate-hook-time: ~D~%" (-> obj state-hook-time))
(format #t "~2Tstate-hook: ~A~%" (-> obj state-hook))
(format #t "~2Tcam-user-mode: ~A~%" (-> obj cam-user-mode))
(format #t "~2Tsidekick: #x~X~%" (-> obj sidekick))
(format #t "~2Tmanipy: #x~X~%" (-> obj manipy))
(format #t "~2Tmirror: #x~X~%" (-> obj mirror))
(format #t "~2Tattack-info: #<attack-info @ #x~X>~%" (-> obj attack-info))
(format #t "~2Tattack-info-rec: #<attack-info @ #x~X>~%" (-> obj attack-info-rec))
(format #t "~2Tattack-info-old[8] @ #x~X~%" (-> obj attack-info-old))
(format #t "~2Tanim-seed: ~D~%" (-> obj anim-seed))
(format #t "~2Talt-cam-pos: ~`vector`P~%" (-> obj alt-cam-pos))
(format #t "~2Tcurrent-level: ~A~%" (-> obj current-level))
(format #t "~2Tsaved-pos: #<transformq @ #x~X>~%" (-> obj saved-pos))
(format #t "~2Tsaved-owner: ~D~%" (-> obj saved-owner))
(format #t "~2Talt-neck-pos: ~`vector`P~%" (-> obj alt-neck-pos))
(format #t "~2Tfocus-search: ~A~%" (-> obj focus-search))
(format #t "~2Texcitement: ~f~%" (-> obj excitement))
(format #t "~2Tshock-effect-time: ~D~%" (-> obj shock-effect-time))
(format #t "~2Tbeard?: ~A~%" (-> obj beard?))
(format #t "~2Tspool-anim: ~A~%" (-> obj spool-anim))
(format #t "~2Tambient-time: ~D~%" (-> obj ambient-time))
(format #t "~2Tfp-hud: ~D~%" (-> obj fp-hud))
(format #t "~2Tno-load-wait: ~D~%" (-> obj no-load-wait))
(format #t "~2Tno-look-around-wait: ~D~%" (-> obj no-look-around-wait))
(format #t "~2Tburn-proc: ~D~%" (-> obj burn-proc))
(format #t "~2Tpre-joint-hook: ~A~%" (-> obj pre-joint-hook))
(format #t "~2Tnotify: ~D~%" (-> obj notify))
(format #t "~2Tmode-cache: ~A~%" (-> obj mode-cache))
(format #t "~2Tmode-param1: ~D~%" (-> obj mode-param1))
(format #t "~2Tmode-param2: ~A~%" (-> obj mode-param2))
(format #t "~2Tmode-param3: ~A~%" (-> obj mode-param3))
(format #t "~2Ttobot-state: ~A~%" (-> obj tobot-state))
(format #t "~2Ttobot?: ~A~%" (-> obj tobot?))
(format #t "~2Ttobot-recorder: ~A~%" (-> obj tobot-recorder))
(format #t "~2Tcolor-effect: ~A~%" (-> obj color-effect))
(format #t "~2Tcolor-effect-start-time: ~D~%" (-> obj color-effect-start-time))
(format #t "~2Tcolor-effect-duration: ~D~%" (-> obj color-effect-duration))
(format #t "~2Tracer: ~A~%" (-> obj racer))
(format #t "~2Ttube: ~A~%" (-> obj tube))
(format #t "~2Tflut: ~A~%" (-> obj flut))
(format #t "~2Tboard: ~A~%" (-> obj board))
(format #t "~2Tpilot: ~A~%" (-> obj pilot))
(format #t "~2Tgun: ~A~%" (-> obj gun))
(format #t "~2Tmech: ~A~%" (-> obj mech))
(format #t "~2Tturret: ~A~%" (-> obj turret))
(format #t "~2Tdarkjak: ~A~%" (-> obj darkjak))
(format #t "~2Tindax: ~A~%" (-> obj indax))
(label cfg-4)
obj
)
;; definition (perm) for symbol *target*, type target
(define-perm *target* target #f)
;; definition of type sidekick
(deftype sidekick (process-drawable)
((parent-override (pointer target) :offset 16)
(control control-info :offset 128)
(anim-seed uint64 :offset 208)
(shadow-in-movie? symbol :offset-assert 216)
(special-anim-time time-frame :offset-assert 224)
(special-anim-interp float :offset-assert 232)
(special-anim-frame float :offset-assert 236)
(offset transformq :inline :offset-assert 240)
(mirror (pointer process-drawable) :offset-assert 288)
)
:heap-base #xb0
:method-count-assert 20
:size-assert #x124
:flag-assert #x1400b00124
(:states
sidekick-clone
)
)
;; definition for method 3 of type sidekick
(defmethod inspect sidekick ((obj sidekick))
(when (not obj)
(set! obj obj)
(goto cfg-4)
)
(let ((t9-0 (method-of-type process-drawable inspect)))
(t9-0 obj)
)
(format #t "~2Tcontrol: ~A~%" (-> obj root))
(format #t "~2Tstate-time: ~D~%" (-> obj state-time))
(format #t "~2Tanim-seed: ~D~%" (-> obj anim-seed))
(format #t "~2Tshadow-in-movie?: ~A~%" (-> obj shadow-in-movie?))
(format #t "~2Tspecial-anim-time: ~D~%" (-> obj special-anim-time))
(format #t "~2Tspecial-anim-interp: ~f~%" (-> obj special-anim-interp))
(format #t "~2Tspecial-anim-frame: ~f~%" (-> obj special-anim-frame))
(format #t "~2Toffset: #<transformq @ #x~X>~%" (-> obj offset))
(format #t "~2Tmirror: #x~X~%" (-> obj mirror))
(label cfg-4)
obj
)
;; definition (perm) for symbol *sidekick*, type sidekick
(define-perm *sidekick* sidekick #f)
;; failed to figure out what this is:
(new 'static 'boxed-array :type type pilot-info mech-info turret-info indax-info tube-info)

View file

@ -664,7 +664,7 @@ TEST_F(FormRegressionTestJak1, DmaSyncCrash) {
test_with_expr(func, type, expected); test_with_expr(func, type, expected);
} }
TEST_F(FormRegressionTestJak1, DmaSendDraft) { TEST_F(FormRegressionTestJak1, DmaSend) {
std::string func = std::string func =
"sll r0, r0, 0\n" "sll r0, r0, 0\n"
" daddiu sp, sp, -64\n" " daddiu sp, sp, -64\n"

View file

@ -0,0 +1,13 @@
;; make a type
(deftype test-basic (basic)
((num int32)))
;; declare an array that stores these types
(define test-array (new 'static 'boxed-array :type type test-basic))
;; use the array to make something
(define test-instance-basic
(new 'static 'test-basic :num 1234))
(when (basic-type? test-instance-basic (-> test-array 0))
(format #t "matched!~%"))

View file

@ -771,6 +771,11 @@ TEST_F(WithGameTests, StaticLambdaArray) {
{"2\n1\n0\n"}); {"2\n1\n0\n"});
} }
TEST_F(WithGameTests, StaticTypeArray) {
shared_compiler->runner.run_static_test(testCategory, "test-static-array-of-types.gc",
{"matched!\n0\n"});
}
TEST_F(WithGameTests, MethodReplace) { TEST_F(WithGameTests, MethodReplace) {
shared_compiler->runner.run_static_test(testCategory, "test-method-replace.gc", shared_compiler->runner.run_static_test(testCategory, "test-method-replace.gc",
{"relocate! foo: 123 heap: 1 name: 2\n0\n"}); {"relocate! foo: 123 heap: 1 name: 2\n0\n"});