@@ -131,6 +131,68 @@ void *simplify_env_emit_call_static_instr(SimplifyEnv *env, size_t n_operands,
131131 return instr ;
132132}
133133
134+ void * simplify_env_emit_load_field (SimplifyEnv * env , void * receiver ,
135+ const char * name , intptr_t offset ,
136+ HirType type , int borrowed ) {
137+ extern void * hir_c_create_load_field (void * func , void * recv , const char * name ,
138+ intptr_t offset , HirType type , int borrowed );
139+ void * instr = hir_c_create_load_field (env -> func , receiver , name , offset , type , borrowed );
140+ return simplify_env_emit (env , instr );
141+ }
142+
143+ void * simplify_env_emit_cint_to_cbool (SimplifyEnv * env , void * src ) {
144+ void * reg = hir_func_alloc_register (env -> func );
145+ extern void * hir_c_create_cint_to_cbool (void * dst , void * src );
146+ void * instr = hir_c_create_cint_to_cbool (reg , src );
147+ return simplify_env_emit (env , instr );
148+ }
149+
150+ /* ---- emitGetLengthInt64 C helper ----
151+ * Returns ob_size/ma_used/used/length field as CInt64, or NULL. */
152+ static void * emit_get_length_int64_c (SimplifyEnv * env , void * obj ) {
153+ HirType obj_type = hir_register_type (obj );
154+ HirType t_tuple_exact = HIR_TYPE_TUPLEEXACT ;
155+ HirType t_cint64 = HIR_TYPE_CINT64 ;
156+
157+ #ifndef Py_GIL_DISABLED
158+ HirType t_list_exact = HIR_TYPE_SIMPLE (0x00000010000ULL , HIR_TYPE_LIFETIME_TOP );
159+ if (hir_type_is_subtype (obj_type , t_list_exact ) ||
160+ hir_type_is_subtype (obj_type , t_tuple_exact )) {
161+ #else
162+ if (hir_type_is_subtype (obj_type , t_tuple_exact )) {
163+ #endif
164+ HirType unspec = hir_type_unspecialized (& obj_type );
165+ simplify_env_emit_use_type (env , obj , unspec );
166+ return simplify_env_emit_load_field (env , obj , "ob_size" ,
167+ (intptr_t )offsetof(PyVarObject , ob_size ), t_cint64 , 0 );
168+ }
169+
170+ HirType t_unicode_exact = HIR_TYPE_UNICODEEXACT ;
171+ #ifndef Py_GIL_DISABLED
172+ HirType t_dict_exact = HIR_TYPE_DICTEXACT ;
173+ HirType t_set_exact = HIR_TYPE_SIMPLE (0x00000020000ULL , HIR_TYPE_LIFETIME_TOP );
174+ if (hir_type_is_subtype (obj_type , t_dict_exact )) {
175+ HirType unspec = hir_type_unspecialized (& obj_type );
176+ simplify_env_emit_use_type (env , obj , unspec );
177+ return simplify_env_emit_load_field (env , obj , "ma_used" ,
178+ (intptr_t )offsetof(PyDictObject , ma_used ), t_cint64 , 0 );
179+ }
180+ if (hir_type_is_subtype (obj_type , t_set_exact )) {
181+ HirType unspec = hir_type_unspecialized (& obj_type );
182+ simplify_env_emit_use_type (env , obj , unspec );
183+ return simplify_env_emit_load_field (env , obj , "used" ,
184+ (intptr_t )offsetof(PySetObject , used ), t_cint64 , 0 );
185+ }
186+ #endif
187+ if (hir_type_is_subtype (obj_type , t_unicode_exact )) {
188+ HirType unspec = hir_type_unspecialized (& obj_type );
189+ simplify_env_emit_use_type (env , obj , unspec );
190+ return simplify_env_emit_load_field (env , obj , "length" ,
191+ (intptr_t )offsetof(PyASCIIObject , length ), t_cint64 , 0 );
192+ }
193+ return NULL ;
194+ }
195+
134196void * simplify_env_emit_check_neg (SimplifyEnv * env , void * src , void * frame_state ) {
135197 extern void * hir_c_create_check_neg (void * func , void * src , void * fs );
136198 void * instr = hir_c_create_check_neg (env -> func , src , frame_state );
@@ -286,6 +348,12 @@ void *simplify_is_truthy_c(SimplifyEnv *env, const void *instr) {
286348 return simplify_env_emit_primitive_compare (env , HIR_PCMP_Equal , input , right );
287349 }
288350
351+ /* Collection length path: emit GetLengthInt64 + CIntToCBool */
352+ void * size = emit_get_length_int64_c (env , input );
353+ if (size != NULL ) {
354+ return simplify_env_emit_cint_to_cbool (env , size );
355+ }
356+
289357 /* TLongExact: compare with _PyLong_GetZero() */
290358 HirType t_long_exact = HIR_TYPE_LONGEXACT ;
291359 if (hir_type_is_subtype (input_type , t_long_exact )) {
0 commit comments