2 * File expr.c - expression handling for Wine internal debugger.
4 * Copyright (C) 1997, Eric Youngdale.
14 #include "wine/winbase16.h"
70 struct datatype
* cast
;
77 const char * element_name
;
89 const char * funcname
;
98 #define EXPR_TYPE_CONST 0
99 #define EXPR_TYPE_US_CONST 1
100 #define EXPR_TYPE_SYMBOL 2
101 #define EXPR_TYPE_REGISTER 3
102 #define EXPR_TYPE_BINOP 4
103 #define EXPR_TYPE_UNOP 5
104 #define EXPR_TYPE_STRUCT 6
105 #define EXPR_TYPE_PSTRUCT 7
106 #define EXPR_TYPE_ARRAY 8
107 #define EXPR_TYPE_CALL 9
108 #define EXPR_TYPE_STRING 10
109 #define EXPR_TYPE_CAST 11
111 static char expr_list
[4096];
112 static int next_expr_free
= 0;
115 * This is how we turn an expression address into the actual value.
116 * This works well in the 32 bit domain - not sure at all about the
119 #define VAL(_exp) DEBUG_GetExprValue(&_exp, NULL)
127 rtn
= (struct expr
*) &expr_list
[next_expr_free
];
129 next_expr_free
+= sizeof(struct expr
);
130 assert(next_expr_free
< sizeof(expr_list
));
142 DEBUG_TypeCastExpr(struct datatype
* dt
, struct expr
* exp
)
146 ex
= DEBUG_GetFreeExpr();
148 ex
->type
= EXPR_TYPE_CAST
;
149 ex
->un
.cast
.cast
= dt
;
150 ex
->un
.cast
.expr
= exp
;
155 DEBUG_RegisterExpr(enum debug_regs regno
)
159 ex
= DEBUG_GetFreeExpr();
161 ex
->type
= EXPR_TYPE_REGISTER
;
162 ex
->un
.rgister
.reg
= regno
;
167 DEBUG_SymbolExpr(const char * name
)
171 ex
= DEBUG_GetFreeExpr();
173 ex
->type
= EXPR_TYPE_SYMBOL
;
174 ex
->un
.symbol
.name
= name
;
179 DEBUG_ConstExpr(int value
)
183 ex
= DEBUG_GetFreeExpr();
185 ex
->type
= EXPR_TYPE_CONST
;
186 ex
->un
.constant
.value
= value
;
191 DEBUG_StringExpr(const char * str
)
195 ex
= DEBUG_GetFreeExpr();
197 ex
->type
= EXPR_TYPE_STRING
;
198 ex
->un
.string
.str
= str
+1;
199 pnt
= strrchr(ex
->un
.string
.str
, '"');
208 DEBUG_USConstExpr(unsigned int value
)
212 ex
= DEBUG_GetFreeExpr();
214 ex
->type
= EXPR_TYPE_CONST
;
215 ex
->un
.u_const
.value
= value
;
220 DEBUG_BinopExpr(int operator_type
, struct expr
* exp1
, struct expr
* exp2
)
224 ex
= DEBUG_GetFreeExpr();
226 ex
->type
= EXPR_TYPE_BINOP
;
227 ex
->un
.binop
.binop_type
= operator_type
;
228 ex
->un
.binop
.exp1
= exp1
;
229 ex
->un
.binop
.exp2
= exp2
;
234 DEBUG_UnopExpr(int operator_type
, struct expr
* exp1
)
238 ex
= DEBUG_GetFreeExpr();
240 ex
->type
= EXPR_TYPE_UNOP
;
241 ex
->un
.unop
.unop_type
= operator_type
;
242 ex
->un
.unop
.exp1
= exp1
;
247 DEBUG_StructExpr(struct expr
* exp
, const char * element
)
251 ex
= DEBUG_GetFreeExpr();
253 ex
->type
= EXPR_TYPE_STRUCT
;
254 ex
->un
.structure
.exp1
= exp
;
255 ex
->un
.structure
.element_name
= element
;
260 DEBUG_StructPExpr(struct expr
* exp
, const char * element
)
264 ex
= DEBUG_GetFreeExpr();
266 ex
->type
= EXPR_TYPE_PSTRUCT
;
267 ex
->un
.structure
.exp1
= exp
;
268 ex
->un
.structure
.element_name
= element
;
273 DEBUG_CallExpr(const char * funcname
, int nargs
, ...)
279 ex
= DEBUG_GetFreeExpr();
281 ex
->type
= EXPR_TYPE_CALL
;
282 ex
->un
.call
.funcname
= funcname
;
283 ex
->un
.call
.nargs
= nargs
;
286 for(i
=0; i
< nargs
; i
++)
288 ex
->un
.call
.arg
[i
] = va_arg(ap
, struct expr
*);
295 DEBUG_EvalExpr(struct expr
* exp
)
301 unsigned int cexp
[5];
305 struct datatype
* type1
;
306 struct datatype
* type2
;
315 rtn
= DEBUG_EvalExpr(exp
->un
.cast
.expr
);
316 rtn
.type
= exp
->un
.cast
.cast
;
318 case EXPR_TYPE_STRING
:
319 rtn
.type
= DEBUG_TypeString
;
320 rtn
.off
= (unsigned int) &exp
->un
.string
.str
;
323 case EXPR_TYPE_CONST
:
324 rtn
.type
= DEBUG_TypeIntConst
;
325 rtn
.off
= (unsigned int) &exp
->un
.constant
.value
;
328 case EXPR_TYPE_US_CONST
:
329 rtn
.type
= DEBUG_TypeUSInt
;
330 rtn
.off
= (unsigned int) &exp
->un
.u_const
.value
;
333 case EXPR_TYPE_SYMBOL
:
334 if( !DEBUG_GetSymbolValue(exp
->un
.symbol
.name
, -1, &rtn
, FALSE
) )
336 RaiseException(DEBUG_STATUS_NO_SYMBOL
, 0, 0, NULL
);
339 case EXPR_TYPE_PSTRUCT
:
340 exp1
= DEBUG_EvalExpr(exp
->un
.structure
.exp1
);
341 if( exp1
.type
== NULL
)
345 rtn
.off
= DEBUG_TypeDerefPointer(&exp1
, &type1
);
351 DEBUG_FindStructElement(&rtn
, exp
->un
.structure
.element_name
,
352 &exp
->un
.structure
.result
);
354 case EXPR_TYPE_STRUCT
:
355 exp1
= DEBUG_EvalExpr(exp
->un
.structure
.exp1
);
356 if( exp1
.type
== NULL
)
361 DEBUG_FindStructElement(&rtn
, exp
->un
.structure
.element_name
,
362 &exp
->un
.structure
.result
);
366 * First, evaluate all of the arguments. If any of them are not
367 * evaluable, then bail.
369 for(i
=0; i
< exp
->un
.call
.nargs
; i
++)
371 exp1
= DEBUG_EvalExpr(exp
->un
.call
.arg
[i
]);
372 if( exp1
.type
== NULL
)
376 cexp
[i
] = DEBUG_GetExprValue(&exp1
, NULL
);
380 * Now look up the address of the function itself.
382 if( !DEBUG_GetSymbolValue(exp
->un
.call
.funcname
, -1, &rtn
, FALSE
) )
384 fprintf(stderr
, "Failed to find symbol\n");
389 /* FIXME: NEWDBG NIY */
390 /* Anyway, I wonder how this could work depending on the calling order of
391 * the function (cdecl vs pascal for example)
395 fptr
= (int (*)()) rtn
.off
;
396 switch(exp
->un
.call
.nargs
)
399 exp
->un
.call
.result
= (*fptr
)();
402 exp
->un
.call
.result
= (*fptr
)(cexp
[0]);
405 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1]);
408 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1], cexp
[2]);
411 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1], cexp
[2], cexp
[3]);
414 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1], cexp
[2], cexp
[3], cexp
[4]);
418 fprintf(stderr
, "Function call no longer implemented\n");
419 /* would need to set up a call to this function, and then restore the current
420 * context afterwards...
422 exp
->un
.call
.result
= 0;
424 rtn
.type
= DEBUG_TypeInt
;
425 rtn
.off
= (unsigned int) &exp
->un
.call
.result
;
428 case EXPR_TYPE_REGISTER
:
429 rtn
.type
= DEBUG_TypeIntConst
;
430 exp
->un
.rgister
.result
= DEBUG_GetRegister(exp
->un
.rgister
.reg
);
431 rtn
.off
= (unsigned int) &exp
->un
.rgister
.result
;
433 if( exp
->un
.rgister
.reg
== REG_EIP
)
434 rtn
.seg
= DEBUG_context
.SegCs
;
436 rtn
.seg
= DEBUG_context
.SegDs
;
438 DEBUG_FixAddress( &rtn
, 0 );
440 case EXPR_TYPE_BINOP
:
441 exp1
= DEBUG_EvalExpr(exp
->un
.binop
.exp1
);
442 exp2
= DEBUG_EvalExpr(exp
->un
.binop
.exp2
);
443 if( exp1
.type
== NULL
|| exp2
.type
== NULL
)
447 if( exp1
.type
== DEBUG_TypeIntConst
&& exp2
.type
== DEBUG_TypeIntConst
)
449 rtn
.type
= exp1
.type
;
453 rtn
.type
= DEBUG_TypeInt
;
455 rtn
.off
= (unsigned int) &exp
->un
.binop
.result
;
456 switch(exp
->un
.binop
.binop_type
)
459 type1
= DEBUG_GetPointerType(exp1
.type
);
460 type2
= DEBUG_GetPointerType(exp2
.type
);
463 if( type1
!= NULL
&& type2
!= NULL
)
467 else if( type1
!= NULL
)
469 scale2
= DEBUG_GetObjectSize(type1
);
470 rtn
.type
= exp1
.type
;
472 else if( type2
!= NULL
)
474 scale1
= DEBUG_GetObjectSize(type2
);
475 rtn
.type
= exp2
.type
;
478 exp
->un
.binop
.result
= (VAL(exp1
) * scale1
+ scale2
* VAL(exp2
));
481 type1
= DEBUG_GetPointerType(exp1
.type
);
482 type2
= DEBUG_GetPointerType(exp2
.type
);
486 if( type1
!= NULL
&& type2
!= NULL
)
492 scale3
= DEBUG_GetObjectSize(type1
);
494 else if( type1
!= NULL
)
496 scale2
= DEBUG_GetObjectSize(type1
);
497 rtn
.type
= exp1
.type
;
500 else if( type2
!= NULL
)
502 scale1
= DEBUG_GetObjectSize(type2
);
503 rtn
.type
= exp2
.type
;
506 exp
->un
.binop
.result
= (VAL(exp1
) - VAL(exp2
)) / scale3
;
510 exp
->un
.binop
.result
= VAL(exp2
);
512 DEBUG_FixSegment(&rtn
);
517 exp
->un
.binop
.result
= (VAL(exp1
) || VAL(exp2
));
521 exp
->un
.binop
.result
= (VAL(exp1
) && VAL(exp2
));
525 exp
->un
.binop
.result
= (VAL(exp1
) | VAL(exp2
));
529 exp
->un
.binop
.result
= (VAL(exp1
) & VAL(exp2
));
533 exp
->un
.binop
.result
= (VAL(exp1
) ^ VAL(exp2
));
537 exp
->un
.binop
.result
= (VAL(exp1
) == VAL(exp2
));
541 exp
->un
.binop
.result
= (VAL(exp1
) > VAL(exp2
));
545 exp
->un
.binop
.result
= (VAL(exp1
) < VAL(exp2
));
549 exp
->un
.binop
.result
= (VAL(exp1
) >= VAL(exp2
));
553 exp
->un
.binop
.result
= (VAL(exp1
) <= VAL(exp2
));
557 exp
->un
.binop
.result
= (VAL(exp1
) != VAL(exp2
));
561 exp
->un
.binop
.result
= ((unsigned) VAL(exp1
) << VAL(exp2
));
565 exp
->un
.binop
.result
= ((unsigned) VAL(exp1
) >> VAL(exp2
));
569 exp
->un
.binop
.result
= (VAL(exp1
) * VAL(exp2
));
575 exp
->un
.binop
.result
= (VAL(exp1
) / VAL(exp2
));
588 exp
->un
.binop
.result
= (VAL(exp1
) % VAL(exp2
));
598 DEBUG_ArrayIndex(&exp1
, &rtn
, VAL(exp2
));
605 exp1
= DEBUG_EvalExpr(exp
->un
.unop
.exp1
);
606 if( exp1
.type
== NULL
)
610 rtn
.off
= (unsigned int) &exp
->un
.unop
.result
;
611 if( exp1
.type
== DEBUG_TypeIntConst
)
613 rtn
.type
= exp1
.type
;
617 rtn
.type
= DEBUG_TypeInt
;
619 switch(exp
->un
.unop
.unop_type
)
623 exp
->un
.unop
.result
= -VAL(exp1
);
627 exp
->un
.unop
.result
= !VAL(exp1
);
631 exp
->un
.unop
.result
= ~VAL(exp1
);
635 rtn
.off
= (unsigned int) DEBUG_TypeDerefPointer(&exp1
, &rtn
.type
);
637 case EXP_OP_FORCE_DEREF
:
639 rtn
.off
= DEBUG_READ_MEM((void*)exp1
.off
, &rtn
.off
, sizeof(rtn
.off
));
643 rtn
.type
= DEBUG_FindOrMakePointerType(exp1
.type
);
644 exp
->un
.unop
.result
= exp1
.off
;
649 fprintf(stderr
,"Unexpected expression.\n");
659 DEBUG_DisplayExpr(struct expr
* exp
)
667 fprintf(stderr
, "((");
668 DEBUG_PrintTypeCast(exp
->un
.cast
.cast
);
669 fprintf(stderr
, ")");
670 DEBUG_DisplayExpr(exp
->un
.cast
.expr
);
671 fprintf(stderr
, ")");
673 case EXPR_TYPE_REGISTER
:
674 DEBUG_PrintRegister(exp
->un
.rgister
.reg
);
676 case EXPR_TYPE_US_CONST
:
677 fprintf(stderr
, "%ud", exp
->un
.u_const
.value
);
679 case EXPR_TYPE_CONST
:
680 fprintf(stderr
, "%d", exp
->un
.u_const
.value
);
682 case EXPR_TYPE_STRING
:
683 fprintf(stderr
, "\"%s\"", exp
->un
.string
.str
);
685 case EXPR_TYPE_SYMBOL
:
686 fprintf(stderr
, "%s" , exp
->un
.symbol
.name
);
688 case EXPR_TYPE_PSTRUCT
:
689 DEBUG_DisplayExpr(exp
->un
.structure
.exp1
);
690 fprintf(stderr
, "->%s", exp
->un
.structure
.element_name
);
692 case EXPR_TYPE_STRUCT
:
693 DEBUG_DisplayExpr(exp
->un
.structure
.exp1
);
694 fprintf(stderr
, ".%s", exp
->un
.structure
.element_name
);
697 fprintf(stderr
, "%s(",exp
->un
.call
.funcname
);
698 for(i
=0; i
< exp
->un
.call
.nargs
; i
++)
700 DEBUG_DisplayExpr(exp
->un
.call
.arg
[i
]);
701 if( i
!= exp
->un
.call
.nargs
- 1 )
703 fprintf(stderr
, ", ");
706 fprintf(stderr
, ")");
708 case EXPR_TYPE_BINOP
:
709 fprintf(stderr
, "( ");
710 DEBUG_DisplayExpr(exp
->un
.binop
.exp1
);
711 switch(exp
->un
.binop
.binop_type
)
714 fprintf(stderr
, " + ");
717 fprintf(stderr
, " - ");
720 fprintf(stderr
, ":");
723 fprintf(stderr
, " || ");
726 fprintf(stderr
, " && ");
729 fprintf(stderr
, " | ");
732 fprintf(stderr
, " & ");
735 fprintf(stderr
, " ^ ");
738 fprintf(stderr
, " == ");
741 fprintf(stderr
, " > ");
744 fprintf(stderr
, " < ");
747 fprintf(stderr
, " >= ");
750 fprintf(stderr
, " <= ");
753 fprintf(stderr
, " != ");
756 fprintf(stderr
, " << ");
759 fprintf(stderr
, " >> ");
762 fprintf(stderr
, " * ");
765 fprintf(stderr
, " / ");
768 fprintf(stderr
, " %% ");
771 fprintf(stderr
, "[");
776 DEBUG_DisplayExpr(exp
->un
.binop
.exp2
);
777 if( exp
->un
.binop
.binop_type
== EXP_OP_ARR
)
779 fprintf(stderr
, "]");
781 fprintf(stderr
, " )");
784 switch(exp
->un
.unop
.unop_type
)
787 fprintf(stderr
, "-");
790 fprintf(stderr
, "!");
793 fprintf(stderr
, "~");
796 fprintf(stderr
, "*");
799 fprintf(stderr
, "&");
802 DEBUG_DisplayExpr(exp
->un
.unop
.exp1
);
805 fprintf(stderr
,"Unexpected expression.\n");
814 DEBUG_CloneExpr(struct expr
* exp
)
819 rtn
= (struct expr
*) DBG_alloc(sizeof(struct expr
));
822 * First copy the contents of the expression itself.
830 rtn
->un
.cast
.expr
= DEBUG_CloneExpr(exp
->un
.cast
.expr
);
832 case EXPR_TYPE_REGISTER
:
833 case EXPR_TYPE_US_CONST
:
834 case EXPR_TYPE_CONST
:
836 case EXPR_TYPE_STRING
:
837 rtn
->un
.string
.str
= DBG_strdup(exp
->un
.string
.str
);
839 case EXPR_TYPE_SYMBOL
:
840 rtn
->un
.symbol
.name
= DBG_strdup(exp
->un
.symbol
.name
);
842 case EXPR_TYPE_PSTRUCT
:
843 case EXPR_TYPE_STRUCT
:
844 rtn
->un
.structure
.exp1
= DEBUG_CloneExpr(exp
->un
.structure
.exp1
);
845 rtn
->un
.structure
.element_name
= DBG_strdup(exp
->un
.structure
.element_name
);
848 for(i
=0; i
< exp
->un
.call
.nargs
; i
++)
850 rtn
->un
.call
.arg
[i
] = DEBUG_CloneExpr(exp
->un
.call
.arg
[i
]);
852 rtn
->un
.call
.funcname
= DBG_strdup(exp
->un
.call
.funcname
);
854 case EXPR_TYPE_BINOP
:
855 rtn
->un
.binop
.exp1
= DEBUG_CloneExpr(exp
->un
.binop
.exp1
);
856 rtn
->un
.binop
.exp2
= DEBUG_CloneExpr(exp
->un
.binop
.exp2
);
859 rtn
->un
.unop
.exp1
= DEBUG_CloneExpr(exp
->un
.unop
.exp1
);
862 fprintf(stderr
,"Unexpected expression.\n");
872 * Recursively go through an expression tree and free all memory associated
876 DEBUG_FreeExpr(struct expr
* exp
)
883 DEBUG_FreeExpr(exp
->un
.cast
.expr
);
885 case EXPR_TYPE_REGISTER
:
886 case EXPR_TYPE_US_CONST
:
887 case EXPR_TYPE_CONST
:
889 case EXPR_TYPE_STRING
:
890 DBG_free((char *) exp
->un
.string
.str
);
892 case EXPR_TYPE_SYMBOL
:
893 DBG_free((char *) exp
->un
.symbol
.name
);
895 case EXPR_TYPE_PSTRUCT
:
896 case EXPR_TYPE_STRUCT
:
897 DEBUG_FreeExpr(exp
->un
.structure
.exp1
);
898 DBG_free((char *) exp
->un
.structure
.element_name
);
901 for(i
=0; i
< exp
->un
.call
.nargs
; i
++)
903 DEBUG_FreeExpr(exp
->un
.call
.arg
[i
]);
905 DBG_free((char *) exp
->un
.call
.funcname
);
907 case EXPR_TYPE_BINOP
:
908 DEBUG_FreeExpr(exp
->un
.binop
.exp1
);
909 DEBUG_FreeExpr(exp
->un
.binop
.exp2
);
912 DEBUG_FreeExpr(exp
->un
.unop
.exp1
);
915 fprintf(stderr
,"Unexpected expression.\n");