expr.c 22.2 KB
Newer Older
Alexandre Julliard's avatar
Alexandre Julliard committed
1 2 3 4 5
/*
 * File expr.c - expression handling for Wine internal debugger.
 *
 * Copyright (C) 1997, Eric Youngdale.
 *
6 7 8 9 10 11 12 13 14 15 16 17 18
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Alexandre Julliard's avatar
Alexandre Julliard committed
19 20
 */

21
#include "config.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
22 23
#include <stdlib.h>
#include <string.h>
Marcus Meissner's avatar
Marcus Meissner committed
24
#include "winbase.h"
25
#include "wine/winbase16.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
#include "debugger.h"
#include "expr.h"

#include <stdarg.h>

struct expr
{
  unsigned int	perm;
  unsigned int	type:31;
  union
  {
    struct
    {
      int value;
    } constant;

    struct
    {
      const char * str;
    } string;

    struct
    {
      unsigned int value;
    } u_const;

    struct
    {
      const char * name;
    } symbol;

    struct
    {
59 60
      const char * name;
    } intvar;
Alexandre Julliard's avatar
Alexandre Julliard committed
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76

    struct
    {
      int unop_type;
      struct expr * exp1;
      int	      result;
    } unop;

    struct
    {
      int binop_type;
      int result;
      struct expr * exp1;
      struct expr * exp2;
    } binop;

Alexandre Julliard's avatar
Alexandre Julliard committed
77 78 79 80 81 82
    struct
    {
      struct datatype * cast;
      struct expr     * expr;
    } cast;

Alexandre Julliard's avatar
Alexandre Julliard committed
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
    struct
    {
      struct expr * exp1;
      const char * element_name;
      int result;
    } structure;

    struct
    {
      struct expr * base;
      struct expr * index;
    } array;

    struct
    {
      const char  * funcname;
      int	    nargs;
      int	    result;
      struct expr * arg[5];
    } call;

  } un;
};

#define EXPR_TYPE_CONST		0
#define EXPR_TYPE_US_CONST	1
#define EXPR_TYPE_SYMBOL	2
110
#define EXPR_TYPE_INTVAR	3
Alexandre Julliard's avatar
Alexandre Julliard committed
111 112 113 114 115 116 117
#define EXPR_TYPE_BINOP		4
#define EXPR_TYPE_UNOP		5
#define EXPR_TYPE_STRUCT	6
#define EXPR_TYPE_PSTRUCT	7
#define EXPR_TYPE_ARRAY		8
#define EXPR_TYPE_CALL		9
#define EXPR_TYPE_STRING	10
Alexandre Julliard's avatar
Alexandre Julliard committed
118
#define EXPR_TYPE_CAST		11
Alexandre Julliard's avatar
Alexandre Julliard committed
119 120

static char expr_list[4096];
121
static unsigned int next_expr_free = 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
122 123 124 125 126 127 128 129 130 131

/*
 * This is how we turn an expression address into the actual value.
 * This works well in the 32 bit domain - not sure at all about the
 * 16 bit world.
 */
#define VAL(_exp)	DEBUG_GetExprValue(&_exp, NULL)

static
struct expr *
132
DEBUG_GetFreeExpr(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
133 134 135 136 137 138
{
  struct expr * rtn;

  rtn =  (struct expr *) &expr_list[next_expr_free];

  next_expr_free += sizeof(struct expr);
Eric Pouech's avatar
Eric Pouech committed
139 140
  assert(next_expr_free < sizeof(expr_list));

Alexandre Julliard's avatar
Alexandre Julliard committed
141 142 143 144
  return rtn;
}

void
145
DEBUG_FreeExprMem(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
146 147 148 149
{
  next_expr_free = 0;
}

Alexandre Julliard's avatar
Alexandre Julliard committed
150 151 152 153 154 155 156 157 158 159 160 161
struct expr *
DEBUG_TypeCastExpr(struct datatype * dt, struct expr * exp)
{
  struct expr * ex;

  ex = DEBUG_GetFreeExpr();

  ex->type        = EXPR_TYPE_CAST;
  ex->un.cast.cast = dt;
  ex->un.cast.expr = exp;
  return ex;
}
Alexandre Julliard's avatar
Alexandre Julliard committed
162 163

struct expr *
164
DEBUG_IntVarExpr(const char* name)
Alexandre Julliard's avatar
Alexandre Julliard committed
165 166 167 168 169
{
  struct expr * ex;

  ex = DEBUG_GetFreeExpr();

170 171
  ex->type        = EXPR_TYPE_INTVAR;
  ex->un.intvar.name = name;
Alexandre Julliard's avatar
Alexandre Julliard committed
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
  return ex;
}

struct expr *
DEBUG_SymbolExpr(const char * name)
{
  struct expr * ex;

  ex = DEBUG_GetFreeExpr();

  ex->type        = EXPR_TYPE_SYMBOL;
  ex->un.symbol.name = name;
  return ex;
}

struct expr *
DEBUG_ConstExpr(int value)
{
  struct expr * ex;

  ex = DEBUG_GetFreeExpr();

  ex->type        = EXPR_TYPE_CONST;
  ex->un.constant.value = value;
  return ex;
}

struct expr *
DEBUG_StringExpr(const char * str)
{
  struct expr * ex;
  char * pnt;
  ex = DEBUG_GetFreeExpr();

  ex->type        = EXPR_TYPE_STRING;
  ex->un.string.str = str+1;
  pnt = strrchr(ex->un.string.str, '"');
  if( pnt != NULL )
    {
      *pnt =  '\0';
    }
  return ex;
}

struct expr *
DEBUG_USConstExpr(unsigned int value)
{
  struct expr * ex;

  ex = DEBUG_GetFreeExpr();

  ex->type           = EXPR_TYPE_CONST;
  ex->un.u_const.value = value;
  return ex;
}

struct expr *
DEBUG_BinopExpr(int operator_type, struct expr * exp1, struct expr * exp2)
{
  struct expr * ex;

  ex = DEBUG_GetFreeExpr();

  ex->type           = EXPR_TYPE_BINOP;
  ex->un.binop.binop_type = operator_type;
  ex->un.binop.exp1     = exp1;
  ex->un.binop.exp2     = exp2;
  return ex;
}

struct expr *
DEBUG_UnopExpr(int operator_type, struct expr * exp1)
{
  struct expr * ex;

  ex = DEBUG_GetFreeExpr();

  ex->type           = EXPR_TYPE_UNOP;
  ex->un.unop.unop_type = operator_type;
  ex->un.unop.exp1      = exp1;
  return ex;
}

struct expr *
DEBUG_StructExpr(struct expr * exp, const char * element)
{
  struct expr * ex;

  ex = DEBUG_GetFreeExpr();

  ex->type           = EXPR_TYPE_STRUCT;
  ex->un.structure.exp1 = exp;
  ex->un.structure.element_name = element;
  return ex;
}

struct expr *
DEBUG_StructPExpr(struct expr * exp, const char * element)
{
  struct expr * ex;

  ex = DEBUG_GetFreeExpr();

  ex->type           = EXPR_TYPE_PSTRUCT;
  ex->un.structure.exp1 = exp;
  ex->un.structure.element_name = element;
  return ex;
}

struct expr *
DEBUG_CallExpr(const char * funcname, int nargs, ...)
{
  struct expr * ex;
  va_list ap;
  int i;

  ex = DEBUG_GetFreeExpr();

  ex->type           = EXPR_TYPE_CALL;
  ex->un.call.funcname = funcname;
  ex->un.call.nargs = nargs;

  va_start(ap, nargs);
  for(i=0; i < nargs; i++)
    {
      ex->un.call.arg[i] = va_arg(ap, struct expr *);
    }
  va_end(ap);
  return ex;
}

303
DBG_VALUE DEBUG_EvalExpr(struct expr * exp)
Alexandre Julliard's avatar
Alexandre Julliard committed
304
{
305
  DBG_VALUE	rtn;
Alexandre Julliard's avatar
Alexandre Julliard committed
306
  int		i;
307 308
  DBG_VALUE	exp1;
  DBG_VALUE	exp2;
Alexandre Julliard's avatar
Alexandre Julliard committed
309 310 311 312 313 314 315 316
  unsigned int	cexp[5];
  int		    scale1;
  int		    scale2;
  int		    scale3;
  struct datatype * type1;
  struct datatype * type2;

  rtn.type = NULL;
317
  rtn.cookie = DV_INVALID;
318 319
  rtn.addr.off = 0;
  rtn.addr.seg = 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
320 321 322

  switch(exp->type)
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
323 324 325
    case EXPR_TYPE_CAST:
      rtn = DEBUG_EvalExpr(exp->un.cast.expr);
      rtn.type = exp->un.cast.cast;
326 327
      if (DEBUG_GetType(rtn.type) == DT_POINTER)
	 rtn.cookie = DV_TARGET;
Alexandre Julliard's avatar
Alexandre Julliard committed
328
      break;
Alexandre Julliard's avatar
Alexandre Julliard committed
329
    case EXPR_TYPE_STRING:
330
      rtn.type = DEBUG_GetBasicType(DT_BASIC_STRING);
331 332 333
      rtn.cookie = DV_HOST;
      rtn.addr.off = (unsigned int) &exp->un.string.str;
      rtn.addr.seg = 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
334 335
      break;
    case EXPR_TYPE_CONST:
336
      rtn.type = DEBUG_GetBasicType(DT_BASIC_CONST_INT);
337 338 339
      rtn.cookie = DV_HOST;
      rtn.addr.off = (unsigned int) &exp->un.constant.value;
      rtn.addr.seg = 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
340 341
      break;
    case EXPR_TYPE_US_CONST:
342
      rtn.type = DEBUG_GetBasicType(DT_BASIC_USHORTINT);
343 344 345
      rtn.cookie = DV_HOST;
      rtn.addr.off = (unsigned int) &exp->un.u_const.value;
      rtn.addr.seg = 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
346 347
      break;
    case EXPR_TYPE_SYMBOL:
348
      if( !DEBUG_GetSymbolValue(exp->un.symbol.name, -1, &rtn, FALSE) )
349 350 351 352
      {    
	  DEBUG_Printf(DBG_CHN_MESG, "%s\n", exp->un.symbol.name);
	  RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
      }
Alexandre Julliard's avatar
Alexandre Julliard committed
353 354 355 356 357
      break;
    case EXPR_TYPE_PSTRUCT:
      exp1 =  DEBUG_EvalExpr(exp->un.structure.exp1);
      if( exp1.type == NULL )
	{
358
	   RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
Alexandre Julliard's avatar
Alexandre Julliard committed
359
	}
360
      rtn.cookie = DV_TARGET;
361 362
      rtn.addr.off = DEBUG_TypeDerefPointer(&exp1, &rtn.type);
      if( rtn.type == NULL )
Alexandre Julliard's avatar
Alexandre Julliard committed
363
	{
364
	  RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
Alexandre Julliard's avatar
Alexandre Julliard committed
365
	}
366 367 368 369 370 371 372
      if (!DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
				   &exp->un.structure.result))
      {
	  DEBUG_Printf(DBG_CHN_MESG, "%s\n", exp->un.structure.element_name);
	  RaiseException(DEBUG_STATUS_NO_FIELD, 0, 0, NULL);
      }

Alexandre Julliard's avatar
Alexandre Julliard committed
373 374 375 376
      break;
    case EXPR_TYPE_STRUCT:
      exp1 =  DEBUG_EvalExpr(exp->un.structure.exp1);
      if( exp1.type == NULL )
377
      {
378
	  RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
379
      }
Alexandre Julliard's avatar
Alexandre Julliard committed
380
      rtn = exp1;
381 382 383 384 385 386
      if (!DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
				   &exp->un.structure.result))
      {
	  DEBUG_Printf(DBG_CHN_MESG, "%s\n", exp->un.structure.element_name);
	  RaiseException(DEBUG_STATUS_NO_FIELD, 0, 0, NULL);
      }
Alexandre Julliard's avatar
Alexandre Julliard committed
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407
      break;
    case EXPR_TYPE_CALL:
      /*
       * First, evaluate all of the arguments.  If any of them are not
       * evaluable, then bail.
       */
      for(i=0; i < exp->un.call.nargs; i++)
	{
	  exp1  = DEBUG_EvalExpr(exp->un.call.arg[i]);
	  if( exp1.type == NULL )
	    {
	      return rtn;
	    }
	  cexp[i] = DEBUG_GetExprValue(&exp1, NULL);
	}

      /*
       * Now look up the address of the function itself.
       */
      if( !DEBUG_GetSymbolValue(exp->un.call.funcname, -1, &rtn, FALSE ) )
	{
408
	  RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
Eric Pouech's avatar
Eric Pouech committed
409
	}
Alexandre Julliard's avatar
Alexandre Julliard committed
410

411 412 413 414 415 416 417
#if 0
      /* FIXME: NEWDBG NIY */
      /* Anyway, I wonder how this could work depending on the calling order of
       * the function (cdecl vs pascal for example)
       */
      int		(*fptr)();

418
      fptr = (int (*)()) rtn.addr.off;
Alexandre Julliard's avatar
Alexandre Julliard committed
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439
      switch(exp->un.call.nargs)
	{
	case 0:
	  exp->un.call.result = (*fptr)();
	  break;
	case 1:
	  exp->un.call.result = (*fptr)(cexp[0]);
	  break;
	case 2:
	  exp->un.call.result = (*fptr)(cexp[0], cexp[1]);
	  break;
	case 3:
	  exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2]);
	  break;
	case 4:
	  exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3]);
	  break;
	case 5:
	  exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3], cexp[4]);
	  break;
	}
440
#else
441
      DEBUG_Printf(DBG_CHN_MESG, "Function call no longer implemented\n");
442 443 444 445 446
      /* would need to set up a call to this function, and then restore the current
       * context afterwards...
       */
      exp->un.call.result = 0;
#endif
447
      rtn.type = DEBUG_GetBasicType(DT_BASIC_INT);
448 449
      rtn.cookie = DV_HOST;
      rtn.addr.off = (unsigned int) &exp->un.call.result;
450

Alexandre Julliard's avatar
Alexandre Julliard committed
451
      break;
452 453 454 455 456 457 458 459 460 461 462
    case EXPR_TYPE_INTVAR:
      {

	 DBG_INTVAR*	div = DEBUG_GetIntVar(exp->un.intvar.name);

	 if (!div) RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
	 rtn.cookie = DV_HOST;
	 rtn.type = div->type;
	 rtn.addr.off = (unsigned int)div->pval;
	 /* EPP FIXME rtn.addr.seg = ?? */
      }
Alexandre Julliard's avatar
Alexandre Julliard committed
463 464 465 466
      break;
    case EXPR_TYPE_BINOP:
      exp1 = DEBUG_EvalExpr(exp->un.binop.exp1);
      exp2 = DEBUG_EvalExpr(exp->un.binop.exp2);
467
      rtn.cookie = DV_HOST;
Alexandre Julliard's avatar
Alexandre Julliard committed
468 469
      if( exp1.type == NULL || exp2.type == NULL )
	{
470
	  RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
Alexandre Julliard's avatar
Alexandre Julliard committed
471
	}
472 473
      if( exp1.type == DEBUG_GetBasicType(DT_BASIC_CONST_INT) && 
          exp2.type == DEBUG_GetBasicType(DT_BASIC_CONST_INT) )
Alexandre Julliard's avatar
Alexandre Julliard committed
474 475 476 477 478
	{
	  rtn.type = exp1.type;
	}
      else
	{
479
          rtn.type = DEBUG_GetBasicType(DT_BASIC_INT);
Alexandre Julliard's avatar
Alexandre Julliard committed
480
	}
481 482
      rtn.addr.seg = 0;
      rtn.addr.off = (unsigned int) &exp->un.binop.result;
Alexandre Julliard's avatar
Alexandre Julliard committed
483 484 485 486 487 488 489 490 491
      switch(exp->un.binop.binop_type)
	{
	case EXP_OP_ADD:
	  type1 = DEBUG_GetPointerType(exp1.type);
	  type2 = DEBUG_GetPointerType(exp2.type);
	  scale1 = 1;
	  scale2 = 1;
	  if( type1 != NULL && type2 != NULL )
	    {
492
	      RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
Alexandre Julliard's avatar
Alexandre Julliard committed
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515
	    }
	  else if( type1 != NULL )
	    {
	      scale2 = DEBUG_GetObjectSize(type1);
	      rtn.type = exp1.type;
	    }
	  else if( type2 != NULL )
	    {
	      scale1 = DEBUG_GetObjectSize(type2);
	      rtn.type = exp2.type;
	    }
	  exp->un.binop.result = (VAL(exp1) * scale1  + scale2 * VAL(exp2));
	  break;
	case EXP_OP_SUB:
	  type1 = DEBUG_GetPointerType(exp1.type);
	  type2 = DEBUG_GetPointerType(exp2.type);
	  scale1 = 1;
	  scale2 = 1;
	  scale3 = 1;
	  if( type1 != NULL && type2 != NULL )
	    {
	      if( type1 != type2 )
		{
516
		  RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
Alexandre Julliard's avatar
Alexandre Julliard committed
517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533
		}
	      scale3 = DEBUG_GetObjectSize(type1);
	    }
	  else if( type1 != NULL )
	    {
	      scale2 = DEBUG_GetObjectSize(type1);
	      rtn.type = exp1.type;
	    }

	  else if( type2 != NULL )
	    {
	      scale1 = DEBUG_GetObjectSize(type2);
	      rtn.type = exp2.type;
	    }
	  exp->un.binop.result = (VAL(exp1) - VAL(exp2)) / scale3;
	  break;
	case EXP_OP_SEG:
534
	  rtn.cookie = DV_TARGET;
535
	  rtn.type = NULL;
536
	  rtn.addr.seg = VAL(exp1);
537
	  rtn.addr.off = VAL(exp2);
Alexandre Julliard's avatar
Alexandre Julliard committed
538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575
	  break;
	case EXP_OP_LOR:
	  exp->un.binop.result = (VAL(exp1) || VAL(exp2));
	  break;
	case EXP_OP_LAND:
	  exp->un.binop.result = (VAL(exp1) && VAL(exp2));
	  break;
	case EXP_OP_OR:
	  exp->un.binop.result = (VAL(exp1) | VAL(exp2));
	  break;
	case EXP_OP_AND:
	  exp->un.binop.result = (VAL(exp1) & VAL(exp2));
	  break;
	case EXP_OP_XOR:
	  exp->un.binop.result = (VAL(exp1) ^ VAL(exp2));
 	  break;
	case EXP_OP_EQ:
	  exp->un.binop.result = (VAL(exp1) == VAL(exp2));
	  break;
	case EXP_OP_GT:
	  exp->un.binop.result = (VAL(exp1) > VAL(exp2));
	  break;
	case EXP_OP_LT:
	  exp->un.binop.result = (VAL(exp1) < VAL(exp2));
	  break;
	case EXP_OP_GE:
	  exp->un.binop.result = (VAL(exp1) >= VAL(exp2));
	  break;
	case EXP_OP_LE:
	  exp->un.binop.result = (VAL(exp1) <= VAL(exp2));
	  break;
	case EXP_OP_NE:
	  exp->un.binop.result = (VAL(exp1) != VAL(exp2));
	  break;
	case EXP_OP_SHL:
	  exp->un.binop.result = ((unsigned) VAL(exp1) << VAL(exp2));
	  break;
	case EXP_OP_SHR:
Alexandre Julliard's avatar
Alexandre Julliard committed
576
	  exp->un.binop.result = ((unsigned) VAL(exp1) >> VAL(exp2));
Alexandre Julliard's avatar
Alexandre Julliard committed
577 578 579 580 581
	  break;
	case EXP_OP_MUL:
	  exp->un.binop.result = (VAL(exp1) * VAL(exp2));
	  break;
	case EXP_OP_DIV:
582
	  if( VAL(exp2) == 0 )
Alexandre Julliard's avatar
Alexandre Julliard committed
583
	    {
584
	       RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
Alexandre Julliard's avatar
Alexandre Julliard committed
585
	    }
586
	  exp->un.binop.result = (VAL(exp1) / VAL(exp2));
Alexandre Julliard's avatar
Alexandre Julliard committed
587 588
	  break;
	case EXP_OP_REM:
589
	  if( VAL(exp2) == 0 )
Alexandre Julliard's avatar
Alexandre Julliard committed
590
	    {
591
	       RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
Alexandre Julliard's avatar
Alexandre Julliard committed
592
	    }
593
	  exp->un.binop.result = (VAL(exp1) % VAL(exp2));
Alexandre Julliard's avatar
Alexandre Julliard committed
594 595 596 597 598
	  break;
	case EXP_OP_ARR:
	  DEBUG_ArrayIndex(&exp1, &rtn, VAL(exp2));
	  break;
	default:
599
	  RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
Alexandre Julliard's avatar
Alexandre Julliard committed
600 601 602 603 604
	  break;
	}
      break;
    case EXPR_TYPE_UNOP:
      exp1 = DEBUG_EvalExpr(exp->un.unop.exp1);
605
      rtn.cookie = DV_HOST;
Alexandre Julliard's avatar
Alexandre Julliard committed
606 607
      if( exp1.type == NULL )
	{
608
	  RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
Alexandre Julliard's avatar
Alexandre Julliard committed
609
	}
610 611
      rtn.addr.seg = 0;
      rtn.addr.off = (unsigned int) &exp->un.unop.result;
612
      if( exp1.type == DEBUG_GetBasicType(DT_BASIC_CONST_INT) )
Alexandre Julliard's avatar
Alexandre Julliard committed
613 614 615 616 617
	{
	  rtn.type = exp1.type;
	}
      else
	{
618
	  rtn.type = DEBUG_GetBasicType(DT_BASIC_INT);
Alexandre Julliard's avatar
Alexandre Julliard committed
619
	}
Eric Pouech's avatar
Eric Pouech committed
620
      switch(exp->un.unop.unop_type)
Alexandre Julliard's avatar
Alexandre Julliard committed
621 622 623 624 625 626 627 628 629 630 631
	{
	case EXP_OP_NEG:
	  exp->un.unop.result = -VAL(exp1);
	  break;
	case EXP_OP_NOT:
	  exp->un.unop.result = !VAL(exp1);
	  break;
	case EXP_OP_LNOT:
	  exp->un.unop.result = ~VAL(exp1);
	  break;
	case EXP_OP_DEREF:
632 633 634 635 636 637 638 639 640 641 642 643 644 645
	  /* FIXME: this is currently buggy.
	   * there is no way to tell were the deref:ed value is...
	   * for example:
	   *	x is a pointer to struct s, x being on the stack
	   *		=> exp1 is target, result is target
	   *	x is a pointer to struct s, x being optimized into a reg
	   *		=> exp1 is host, result is target
	   *	x is a pointer to internal variable x
	   *	       	=> exp1 is host, result is host
	   * so we force DV_TARGET, because dereferencing pointers to 
	   * internal variables is very unlikely. a correct fix would be
	   * rather large.
	   */
	  rtn.cookie = DV_TARGET; 
646 647 648 649 650
	  rtn.addr.off = (unsigned int) DEBUG_TypeDerefPointer(&exp1, &rtn.type);
	  if (!rtn.type)
	    {
	      RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
	    }
Alexandre Julliard's avatar
Alexandre Julliard committed
651 652
	  break;
	case EXP_OP_FORCE_DEREF:
653 654 655 656 657 658
	  rtn.cookie = exp1.cookie;
	  rtn.addr.seg = exp1.addr.seg;
	  if (exp1.cookie == DV_TARGET)
	     DEBUG_READ_MEM((void*)exp1.addr.off, &rtn.addr.off, sizeof(rtn.addr.off));
	  else
	     memcpy(&rtn.addr.off, (void*)exp1.addr.off, sizeof(rtn.addr.off));
Alexandre Julliard's avatar
Alexandre Julliard committed
659 660
	  break;
	case EXP_OP_ADDR:
661
          /* FIXME: even for a 16 bit entity ? */
Alexandre Julliard's avatar
Alexandre Julliard committed
662
	  rtn.type = DEBUG_FindOrMakePointerType(exp1.type);
663
	  exp->un.unop.result = exp1.addr.off;
Alexandre Julliard's avatar
Alexandre Julliard committed
664
	  break;
665 666
	default:
	   RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
Alexandre Julliard's avatar
Alexandre Julliard committed
667 668 669
	}
      break;
    default:
670
      DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression (%d).\n", exp->type);
671
      RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
Alexandre Julliard's avatar
Alexandre Julliard committed
672 673 674
      break;
    }

675 676
  assert(rtn.cookie == DV_TARGET || rtn.cookie == DV_HOST);

Alexandre Julliard's avatar
Alexandre Julliard committed
677 678 679 680 681
  return rtn;
}


int
682
DEBUG_DisplayExpr(const struct expr * exp)
Alexandre Julliard's avatar
Alexandre Julliard committed
683 684 685 686 687
{
  int		i;

  switch(exp->type)
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
688
    case EXPR_TYPE_CAST:
689
      DEBUG_Printf(DBG_CHN_MESG, "((");
Alexandre Julliard's avatar
Alexandre Julliard committed
690
      DEBUG_PrintTypeCast(exp->un.cast.cast);
691
      DEBUG_Printf(DBG_CHN_MESG, ")");
Alexandre Julliard's avatar
Alexandre Julliard committed
692
      DEBUG_DisplayExpr(exp->un.cast.expr);
693
      DEBUG_Printf(DBG_CHN_MESG, ")");
Alexandre Julliard's avatar
Alexandre Julliard committed
694
      break;
695 696
    case EXPR_TYPE_INTVAR:
      DEBUG_Printf(DBG_CHN_MESG, "$%s", exp->un.intvar.name);
Alexandre Julliard's avatar
Alexandre Julliard committed
697 698
      break;
    case EXPR_TYPE_US_CONST:
699
      DEBUG_Printf(DBG_CHN_MESG, "%ud", exp->un.u_const.value);
Alexandre Julliard's avatar
Alexandre Julliard committed
700 701
      break;
    case EXPR_TYPE_CONST:
702
      DEBUG_Printf(DBG_CHN_MESG, "%d", exp->un.u_const.value);
Alexandre Julliard's avatar
Alexandre Julliard committed
703 704
      break;
    case EXPR_TYPE_STRING:
705
      DEBUG_Printf(DBG_CHN_MESG, "\"%s\"", exp->un.string.str); 
Alexandre Julliard's avatar
Alexandre Julliard committed
706 707
      break;
    case EXPR_TYPE_SYMBOL:
708
      DEBUG_Printf(DBG_CHN_MESG, "%s" , exp->un.symbol.name);
Alexandre Julliard's avatar
Alexandre Julliard committed
709 710 711
      break;
    case EXPR_TYPE_PSTRUCT:
      DEBUG_DisplayExpr(exp->un.structure.exp1);
712
      DEBUG_Printf(DBG_CHN_MESG, "->%s", exp->un.structure.element_name);
Alexandre Julliard's avatar
Alexandre Julliard committed
713 714 715
      break;
    case EXPR_TYPE_STRUCT:
      DEBUG_DisplayExpr(exp->un.structure.exp1);
716
      DEBUG_Printf(DBG_CHN_MESG, ".%s", exp->un.structure.element_name);
Alexandre Julliard's avatar
Alexandre Julliard committed
717 718
      break;
    case EXPR_TYPE_CALL:
719
      DEBUG_Printf(DBG_CHN_MESG, "%s(",exp->un.call.funcname);
Alexandre Julliard's avatar
Alexandre Julliard committed
720 721 722 723 724
      for(i=0; i < exp->un.call.nargs; i++)
	{
	  DEBUG_DisplayExpr(exp->un.call.arg[i]);
	  if( i != exp->un.call.nargs - 1 )
	    {
725
	      DEBUG_Printf(DBG_CHN_MESG, ", ");
Alexandre Julliard's avatar
Alexandre Julliard committed
726 727
	    }
	}
728
      DEBUG_Printf(DBG_CHN_MESG, ")");
Alexandre Julliard's avatar
Alexandre Julliard committed
729 730
      break;
    case EXPR_TYPE_BINOP:
731
      DEBUG_Printf(DBG_CHN_MESG, "( ");
Alexandre Julliard's avatar
Alexandre Julliard committed
732 733 734 735
      DEBUG_DisplayExpr(exp->un.binop.exp1);
      switch(exp->un.binop.binop_type)
	{
	case EXP_OP_ADD:
736
 	  DEBUG_Printf(DBG_CHN_MESG, " + ");
Alexandre Julliard's avatar
Alexandre Julliard committed
737 738
	  break;
	case EXP_OP_SUB:
739
 	  DEBUG_Printf(DBG_CHN_MESG, " - ");
Alexandre Julliard's avatar
Alexandre Julliard committed
740 741
	  break;
	case EXP_OP_SEG:
742
 	  DEBUG_Printf(DBG_CHN_MESG, ":");
Alexandre Julliard's avatar
Alexandre Julliard committed
743 744
	  break;
	case EXP_OP_LOR:
745
 	  DEBUG_Printf(DBG_CHN_MESG, " || ");
Alexandre Julliard's avatar
Alexandre Julliard committed
746 747
	  break;
	case EXP_OP_LAND:
748
 	  DEBUG_Printf(DBG_CHN_MESG, " && ");
Alexandre Julliard's avatar
Alexandre Julliard committed
749 750
	  break;
	case EXP_OP_OR:
751
 	  DEBUG_Printf(DBG_CHN_MESG, " | ");
Alexandre Julliard's avatar
Alexandre Julliard committed
752 753
	  break;
	case EXP_OP_AND:
754
 	  DEBUG_Printf(DBG_CHN_MESG, " & ");
Alexandre Julliard's avatar
Alexandre Julliard committed
755 756
	  break;
	case EXP_OP_XOR:
757
 	  DEBUG_Printf(DBG_CHN_MESG, " ^ ");
Alexandre Julliard's avatar
Alexandre Julliard committed
758 759
 	  break;
	case EXP_OP_EQ:
760
 	  DEBUG_Printf(DBG_CHN_MESG, " == ");
Alexandre Julliard's avatar
Alexandre Julliard committed
761 762
	  break;
	case EXP_OP_GT:
763
 	  DEBUG_Printf(DBG_CHN_MESG, " > ");
Alexandre Julliard's avatar
Alexandre Julliard committed
764 765
	  break;
	case EXP_OP_LT:
766
 	  DEBUG_Printf(DBG_CHN_MESG, " < ");
Alexandre Julliard's avatar
Alexandre Julliard committed
767 768
	  break;
	case EXP_OP_GE:
769
 	  DEBUG_Printf(DBG_CHN_MESG, " >= ");
Alexandre Julliard's avatar
Alexandre Julliard committed
770 771
	  break;
	case EXP_OP_LE:
772
 	  DEBUG_Printf(DBG_CHN_MESG, " <= ");
Alexandre Julliard's avatar
Alexandre Julliard committed
773 774
	  break;
	case EXP_OP_NE:
775
 	  DEBUG_Printf(DBG_CHN_MESG, " != ");
Alexandre Julliard's avatar
Alexandre Julliard committed
776 777
	  break;
	case EXP_OP_SHL:
778
 	  DEBUG_Printf(DBG_CHN_MESG, " << ");
Alexandre Julliard's avatar
Alexandre Julliard committed
779 780
	  break;
	case EXP_OP_SHR:
781
 	  DEBUG_Printf(DBG_CHN_MESG, " >> ");
Alexandre Julliard's avatar
Alexandre Julliard committed
782 783
	  break;
	case EXP_OP_MUL:
784
 	  DEBUG_Printf(DBG_CHN_MESG, " * ");
Alexandre Julliard's avatar
Alexandre Julliard committed
785 786
	  break;
	case EXP_OP_DIV:
787
 	  DEBUG_Printf(DBG_CHN_MESG, " / ");
Alexandre Julliard's avatar
Alexandre Julliard committed
788 789
	  break;
	case EXP_OP_REM:
790
 	  DEBUG_Printf(DBG_CHN_MESG, " %% ");
Alexandre Julliard's avatar
Alexandre Julliard committed
791 792
	  break;
	case EXP_OP_ARR:
793
 	  DEBUG_Printf(DBG_CHN_MESG, "[");
Alexandre Julliard's avatar
Alexandre Julliard committed
794 795 796 797 798 799 800
	  break;
	default:
	  break;
	}
      DEBUG_DisplayExpr(exp->un.binop.exp2);
      if( exp->un.binop.binop_type == EXP_OP_ARR )
	{
801
 	  DEBUG_Printf(DBG_CHN_MESG, "]");
Alexandre Julliard's avatar
Alexandre Julliard committed
802
	}
803
      DEBUG_Printf(DBG_CHN_MESG, " )");
Alexandre Julliard's avatar
Alexandre Julliard committed
804 805
      break;
    case EXPR_TYPE_UNOP:
Eric Pouech's avatar
Eric Pouech committed
806
      switch(exp->un.unop.unop_type)
Alexandre Julliard's avatar
Alexandre Julliard committed
807 808
	{
	case EXP_OP_NEG:
809
 	  DEBUG_Printf(DBG_CHN_MESG, "-");
Alexandre Julliard's avatar
Alexandre Julliard committed
810 811
	  break;
	case EXP_OP_NOT:
812
	  DEBUG_Printf(DBG_CHN_MESG, "!");
Alexandre Julliard's avatar
Alexandre Julliard committed
813 814
	  break;
	case EXP_OP_LNOT:
815
	  DEBUG_Printf(DBG_CHN_MESG, "~");
Alexandre Julliard's avatar
Alexandre Julliard committed
816 817
 	  break;
	case EXP_OP_DEREF:
818
	  DEBUG_Printf(DBG_CHN_MESG, "*");
Alexandre Julliard's avatar
Alexandre Julliard committed
819 820
	  break;
	case EXP_OP_ADDR:
821
	  DEBUG_Printf(DBG_CHN_MESG, "&");
Alexandre Julliard's avatar
Alexandre Julliard committed
822 823 824 825 826
	  break;
	}
      DEBUG_DisplayExpr(exp->un.unop.exp1);
      break;
    default:
827
      DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
828
      RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
Alexandre Julliard's avatar
Alexandre Julliard committed
829 830 831 832 833 834 835
      break;
    }

  return TRUE;
}

struct expr *
836
DEBUG_CloneExpr(const struct expr * exp)
Alexandre Julliard's avatar
Alexandre Julliard committed
837 838 839 840
{
  int		i;
  struct expr * rtn;

841
  rtn = (struct expr *) DBG_alloc(sizeof(struct expr));
Alexandre Julliard's avatar
Alexandre Julliard committed
842 843 844 845 846 847 848 849 850

  /*
   * First copy the contents of the expression itself.
   */
  *rtn = *exp;


  switch(exp->type)
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
851 852 853
    case EXPR_TYPE_CAST:
      rtn->un.cast.expr = DEBUG_CloneExpr(exp->un.cast.expr);
      break;
854 855 856
    case EXPR_TYPE_INTVAR:
      rtn->un.intvar.name = DBG_strdup(exp->un.intvar.name);
      break;
Alexandre Julliard's avatar
Alexandre Julliard committed
857 858 859 860
    case EXPR_TYPE_US_CONST:
    case EXPR_TYPE_CONST:
      break;
    case EXPR_TYPE_STRING:
861
      rtn->un.string.str = DBG_strdup(exp->un.string.str);
Alexandre Julliard's avatar
Alexandre Julliard committed
862 863
      break;
    case EXPR_TYPE_SYMBOL:
864
      rtn->un.symbol.name = DBG_strdup(exp->un.symbol.name);
Alexandre Julliard's avatar
Alexandre Julliard committed
865 866 867 868
      break;
    case EXPR_TYPE_PSTRUCT:
    case EXPR_TYPE_STRUCT:
      rtn->un.structure.exp1 = DEBUG_CloneExpr(exp->un.structure.exp1);
869
      rtn->un.structure.element_name = DBG_strdup(exp->un.structure.element_name);
Alexandre Julliard's avatar
Alexandre Julliard committed
870 871 872 873 874 875
      break;
    case EXPR_TYPE_CALL:
      for(i=0; i < exp->un.call.nargs; i++)
	{
	  rtn->un.call.arg[i]  = DEBUG_CloneExpr(exp->un.call.arg[i]);
	}
876
      rtn->un.call.funcname = DBG_strdup(exp->un.call.funcname);
Alexandre Julliard's avatar
Alexandre Julliard committed
877 878 879 880 881 882 883 884 885
      break;
    case EXPR_TYPE_BINOP:
      rtn->un.binop.exp1 = DEBUG_CloneExpr(exp->un.binop.exp1);
      rtn->un.binop.exp2 = DEBUG_CloneExpr(exp->un.binop.exp2);
      break;
    case EXPR_TYPE_UNOP:
      rtn->un.unop.exp1 = DEBUG_CloneExpr(exp->un.unop.exp1);
      break;
    default:
886
      DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
887
      RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
Alexandre Julliard's avatar
Alexandre Julliard committed
888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905
      break;
    }

  return rtn;
}


/*
 * Recursively go through an expression tree and free all memory associated
 * with it.
 */
int
DEBUG_FreeExpr(struct expr * exp)
{
  int i;

  switch(exp->type)
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
906 907 908
    case EXPR_TYPE_CAST:
      DEBUG_FreeExpr(exp->un.cast.expr);
      break;
909 910 911
    case EXPR_TYPE_INTVAR:
      DBG_free((char *) exp->un.intvar.name);
      break;
Alexandre Julliard's avatar
Alexandre Julliard committed
912 913 914 915
    case EXPR_TYPE_US_CONST:
    case EXPR_TYPE_CONST:
      break;
    case EXPR_TYPE_STRING:
916
      DBG_free((char *) exp->un.string.str);
Alexandre Julliard's avatar
Alexandre Julliard committed
917 918
      break;
    case EXPR_TYPE_SYMBOL:
919
      DBG_free((char *) exp->un.symbol.name);
Alexandre Julliard's avatar
Alexandre Julliard committed
920 921 922 923
      break;
    case EXPR_TYPE_PSTRUCT:
    case EXPR_TYPE_STRUCT:
      DEBUG_FreeExpr(exp->un.structure.exp1);
924
      DBG_free((char *) exp->un.structure.element_name);
Alexandre Julliard's avatar
Alexandre Julliard committed
925 926 927 928 929 930
      break;
    case EXPR_TYPE_CALL:
      for(i=0; i < exp->un.call.nargs; i++)
	{
	  DEBUG_FreeExpr(exp->un.call.arg[i]);
	}
931
      DBG_free((char *) exp->un.call.funcname);
Alexandre Julliard's avatar
Alexandre Julliard committed
932 933 934 935 936 937 938 939 940
      break;
    case EXPR_TYPE_BINOP:
      DEBUG_FreeExpr(exp->un.binop.exp1);
      DEBUG_FreeExpr(exp->un.binop.exp2);
      break;
    case EXPR_TYPE_UNOP:
      DEBUG_FreeExpr(exp->un.unop.exp1);
      break;
    default:
941
      DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
942
      RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
Alexandre Julliard's avatar
Alexandre Julliard committed
943 944 945
      break;
    }

946
  DBG_free(exp);
Alexandre Julliard's avatar
Alexandre Julliard committed
947 948
  return TRUE;
}