@@ -882,44 +882,29 @@ def lightudV(tv):
882882
883883# Dumpers.
884884
885+ # GCobj dumpers.
885886
886- def dump_lj_tnil (tv ):
887- return 'nil'
888-
889-
890- def dump_lj_tfalse (tv ):
891- return 'false'
892-
893-
894- def dump_lj_ttrue (tv ):
895- return 'true'
896-
897-
898- def dump_lj_tlightud (tv ):
899- return 'light userdata @ {}' .format (strx64 (lightudV (tv )))
900-
901-
902- def dump_lj_tstr (tv ):
887+ def dump_lj_gco_str (gcobj ):
903888 return 'string {body} @ {address}' .format (
904- body = strdata (gcval ( tv [ 'gcr' ]) ),
905- address = strx64 (gcval ( tv [ 'gcr' ]) )
889+ body = strdata (gcobj ),
890+ address = strx64 (gcobj )
906891 )
907892
908893
909- def dump_lj_tupval ( tv ):
910- return 'upvalue @ {}' .format (strx64 (gcval ( tv [ 'gcr' ]) ))
894+ def dump_lj_gco_upval ( gcobj ):
895+ return 'upvalue @ {}' .format (strx64 (gcobj ))
911896
912897
913- def dump_lj_tthread ( tv ):
914- return 'thread @ {}' .format (strx64 (gcval ( tv [ 'gcr' ]) ))
898+ def dump_lj_gco_thread ( gcobj ):
899+ return 'thread @ {}' .format (strx64 (gcobj ))
915900
916901
917- def dump_lj_tproto ( tv ):
918- return 'proto @ {}' .format (strx64 (gcval ( tv [ 'gcr' ]) ))
902+ def dump_lj_gco_proto ( gcobj ):
903+ return 'proto @ {}' .format (strx64 (gcobj ))
919904
920905
921- def dump_lj_tfunc ( tv ):
922- func = dbg .cast ('struct GCfuncC *' , gcval ( tv [ 'gcr' ]) )
906+ def dump_lj_gco_func ( gcobj ):
907+ func = dbg .cast ('struct GCfuncC *' , gcobj )
923908 ffid = func ['ffid' ]
924909
925910 if ffid == 0 :
@@ -936,62 +921,115 @@ def dump_lj_tfunc(tv):
936921 return 'fast function #{}' .format (int (ffid ))
937922
938923
939- def dump_lj_ttrace ( tv ):
940- trace = dbg .cast ('struct GCtrace *' , gcval ( tv [ 'gcr' ]) )
924+ def dump_lj_gco_trace ( gcobj ):
925+ trace = dbg .cast ('struct GCtrace *' , gcobj )
941926 return 'trace {traceno} @ {addr}' .format (
942927 traceno = strx64 (trace ['traceno' ]),
943928 addr = strx64 (trace )
944929 )
945930
946931
947- def dump_lj_tcdata ( tv ):
948- return 'cdata @ {}' .format (strx64 (gcval ( tv [ 'gcr' ]) ))
932+ def dump_lj_gco_cdata ( gcobj ):
933+ return 'cdata @ {}' .format (strx64 (gcobj ))
949934
950935
951- def dump_lj_ttab ( tv ):
952- table = dbg .cast ('GCtab *' , gcval ( tv [ 'gcr' ]) )
936+ def dump_lj_gco_tab ( gcobj ):
937+ table = dbg .cast ('GCtab *' , gcobj )
953938 return 'table @ {gcr} (asize: {asize}, hmask: {hmask})' .format (
954939 gcr = strx64 (table ),
955940 asize = table ['asize' ],
956941 hmask = strx64 (table ['hmask' ]),
957942 )
958943
959944
960- def dump_lj_tudata (tv ):
961- return 'userdata @ {}' .format (strx64 (gcval (tv ['gcr' ])))
945+ def dump_lj_gco_udata (gcobj ):
946+ return 'userdata @ {}' .format (strx64 (gcobj ))
947+
948+
949+ def dump_lj_gco_invalid (gcobj ):
950+ return 'not valid type @ {}' .format (strx64 (gcobj ))
951+
952+
953+ # TValue dumpers
954+
955+ def dump_lj_tv_nil (tv ):
956+ return 'nil'
957+
958+
959+ def dump_lj_tv_false (tv ):
960+ return 'false'
961+
962+
963+ def dump_lj_tv_true (tv ):
964+ return 'true'
965+
966+
967+ def dump_lj_tv_lightud (tv ):
968+ return 'light userdata @ {}' .format (strx64 (lightudV (tv )))
969+
970+
971+ # Generate wrappers for TValues containing GCobj.
972+ gco_fn_dumpers = [
973+ fn for fn in globals ().keys () if fn .startswith ('dump_lj_gco' )
974+ ]
975+ for fn_name in gco_fn_dumpers :
976+ wrapped_fn_name = fn_name .replace ('gco' , 'tv' )
977+ # Lambda takes `fn_name` as a reference, so the additional
978+ # lambda is needed to fixate the correct wrapper.
979+ globals ()[wrapped_fn_name ] = (lambda f : (
980+ lambda tv : globals ()[f ](gcval (tv ['gcr' ]))
981+ ))(fn_name )
962982
963983
964- def dump_lj_tnumx (tv ):
984+ def dump_lj_tv_numx (tv ):
965985 if tvisint (tv ):
966986 return 'integer {}' .format (dbg .cast ('int32_t' , tv ['i' ]))
967987 else :
968988 return 'number {}' .format (dbg .cast ('double' , tv ['n' ]))
969989
970990
971- def dump_lj_invalid (tv ):
972- return 'not valid type @ {}' .format (strx64 (gcval (tv ['gcr' ])))
973-
974-
975- dumpers = {
976- 'LJ_TNIL' : dump_lj_tnil ,
977- 'LJ_TFALSE' : dump_lj_tfalse ,
978- 'LJ_TTRUE' : dump_lj_ttrue ,
979- 'LJ_TLIGHTUD' : dump_lj_tlightud ,
980- 'LJ_TSTR' : dump_lj_tstr ,
981- 'LJ_TUPVAL' : dump_lj_tupval ,
982- 'LJ_TTHREAD' : dump_lj_tthread ,
983- 'LJ_TPROTO' : dump_lj_tproto ,
984- 'LJ_TFUNC' : dump_lj_tfunc ,
985- 'LJ_TTRACE' : dump_lj_ttrace ,
986- 'LJ_TCDATA' : dump_lj_tcdata ,
987- 'LJ_TTAB' : dump_lj_ttab ,
988- 'LJ_TUDATA' : dump_lj_tudata ,
989- 'LJ_TNUMX' : dump_lj_tnumx ,
991+ gco_dumpers = {
992+ 'LJ_TSTR' : dump_lj_gco_str ,
993+ 'LJ_TUPVAL' : dump_lj_gco_upval ,
994+ 'LJ_TTHREAD' : dump_lj_gco_thread ,
995+ 'LJ_TPROTO' : dump_lj_gco_proto ,
996+ 'LJ_TFUNC' : dump_lj_gco_func ,
997+ 'LJ_TTRACE' : dump_lj_gco_trace ,
998+ 'LJ_TCDATA' : dump_lj_gco_cdata ,
999+ 'LJ_TTAB' : dump_lj_gco_tab ,
1000+ 'LJ_TUDATA' : dump_lj_gco_udata ,
9901001}
9911002
9921003
1004+ tv_dumpers = {
1005+ 'LJ_TNIL' : dump_lj_tv_nil ,
1006+ 'LJ_TFALSE' : dump_lj_tv_false ,
1007+ 'LJ_TTRUE' : dump_lj_tv_true ,
1008+ 'LJ_TLIGHTUD' : dump_lj_tv_lightud ,
1009+ 'LJ_TSTR' : dump_lj_tv_str , # noqa: F821 # Generated.
1010+ 'LJ_TUPVAL' : dump_lj_tv_upval , # noqa: F821 # Generated.
1011+ 'LJ_TTHREAD' : dump_lj_tv_thread , # noqa: F821 # Generated.
1012+ 'LJ_TPROTO' : dump_lj_tv_proto , # noqa: F821 # Generated.
1013+ 'LJ_TFUNC' : dump_lj_tv_func , # noqa: F821 # Generated.
1014+ 'LJ_TTRACE' : dump_lj_tv_trace , # noqa: F821 # Generated.
1015+ 'LJ_TCDATA' : dump_lj_tv_cdata , # noqa: F821 # Generated.
1016+ 'LJ_TTAB' : dump_lj_tv_tab , # noqa: F821 # Generated.
1017+ 'LJ_TUDATA' : dump_lj_tv_udata , # noqa: F821 # Generated.
1018+ 'LJ_TNUMX' : dump_lj_tv_numx ,
1019+ }
1020+
1021+
1022+ def dump_gcobj (gcobj ):
1023+ return gco_dumpers .get (
1024+ typenames (i2notu32 (gcobj ['gch' ]['gct' ])), dump_lj_gco_invalid
1025+ )(gcobj )
1026+
1027+
9931028def dump_tvalue (tvalue ):
994- return dumpers .get (typenames (itypemap (tvalue )), dump_lj_invalid )(tvalue )
1029+ return tv_dumpers .get (
1030+ typenames (itypemap (tvalue )),
1031+ dump_lj_tv_invalid # noqa: F821 # Generated.
1032+ )(tvalue )
9951033
9961034
9971035def dump_framelink_slot_address (fr ):
@@ -1011,7 +1049,7 @@ def dump_framelink(L, fr):
10111049 p = 'P' if frame_typep (fr ) & FRAME_P else ''
10121050 ),
10131051 d = dbg .cast ('TValue *' , fr ) - dbg .cast ('TValue *' , frame_prev (fr )),
1014- f = dump_lj_tfunc (fr - LJ_FR2 ),
1052+ f = dump_lj_tv_func (fr - LJ_FR2 ), # noqa: F821 # Generated.
10151053 )
10161054
10171055
@@ -1142,6 +1180,35 @@ def execute(self, arg):
11421180 ))
11431181
11441182
1183+ class LJDumpGCobj (dbg .LJBase ):
1184+ '''
1185+ lj-gco <GCobj *>
1186+
1187+ The command receives a pointer to <GCobj> (GCobj address) and dumps
1188+ the type and some info related to it.
1189+
1190+ * LJ_TSTR: string <string payload> @ <gcr>
1191+ * LJ_TUPVAL: upvalue @ <gcr>
1192+ * LJ_TTHREAD: thread @ <gcr>
1193+ * LJ_TPROTO: proto @ <gcr>
1194+ * LJ_TFUNC: <LFUNC|CFUNC|FFUNC>
1195+ <LFUNC>: Lua function @ <gcr>, <nupvals> upvalues, <chunk:line>
1196+ <CFUNC>: C function <mcode address>
1197+ <FFUNC>: fast function #<ffid>
1198+ * LJ_TTRACE: trace <traceno> @ <gcr>
1199+ * LJ_TCDATA: cdata @ <gcr>
1200+ * LJ_TTAB: table @ <gcr> (asize: <asize>, hmask: <hmask>)
1201+ * LJ_TUDATA: userdata @ <gcr>
1202+
1203+ Whether the type of the given address differs from the listed above, then
1204+ error message occurs.
1205+ '''
1206+
1207+ def execute (self , arg ):
1208+ gcobj = dbg .cast ('GCobj *' , dbg .eval (arg ))
1209+ dbg .write ('{}\n ' .format (dump_gcobj (gcobj )))
1210+
1211+
11451212class LJDumpStack (dbg .LJBase ):
11461213 '''
11471214lj-stack [<lua_State *>]
@@ -1303,6 +1370,7 @@ def load(event=None):
13031370 dbg .initialize_extension ({
13041371 'lj-arch' : LJDumpArch ,
13051372 'lj-gc' : LJGC ,
1373+ 'lj-gco' : LJDumpGCobj ,
13061374 'lj-stack' : LJDumpStack ,
13071375 'lj-state' : LJState ,
13081376 'lj-str' : LJDumpString ,
0 commit comments