expr.c 28.4 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
 * 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
18
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Alexandre Julliard's avatar
Alexandre Julliard committed
19 20
 */

21
#include "config.h"
22

Alexandre Julliard's avatar
Alexandre Julliard committed
23 24
#include <stdlib.h>
#include <string.h>
25 26
#include <stdarg.h>

Alexandre Julliard's avatar
Alexandre Julliard committed
27 28
#include "debugger.h"
#include "expr.h"
29 30 31
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
Alexandre Julliard's avatar
Alexandre Julliard committed
32 33 34

struct expr
{
35 36
    unsigned int	type;
    union
Alexandre Julliard's avatar
Alexandre Julliard committed
37
    {
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
        struct
        {
            int                 value;
        } s_const;

        struct
        {
            unsigned int        value;
        } u_const;

        struct
        {
            const char*         str;
        } string;

        struct
        {
            const char*         name;
        } symbol;

        struct
        {
            const char*         name;
        } intvar;

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

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

        struct
        {
            struct type_expr_t  cast_to;
            struct expr*        expr;
        } cast;

        struct
        {
            struct expr*        exp1;
            const char*         element_name;
            long int            result;
        } structure;

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

    } un;
Alexandre Julliard's avatar
Alexandre Julliard committed
100 101
};

102 103
#define EXPR_TYPE_S_CONST	0
#define EXPR_TYPE_U_CONST	1
Alexandre Julliard's avatar
Alexandre Julliard committed
104
#define EXPR_TYPE_SYMBOL	2
105
#define EXPR_TYPE_INTVAR	3
Alexandre Julliard's avatar
Alexandre Julliard committed
106 107 108 109
#define EXPR_TYPE_BINOP		4
#define EXPR_TYPE_UNOP		5
#define EXPR_TYPE_STRUCT	6
#define EXPR_TYPE_PSTRUCT	7
110 111 112
#define EXPR_TYPE_CALL		8
#define EXPR_TYPE_STRING	9
#define EXPR_TYPE_CAST		10
Alexandre Julliard's avatar
Alexandre Julliard committed
113 114

static char expr_list[4096];
115
static unsigned int next_expr_free = 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
116

117
static struct expr* expr_alloc(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
118
{
119
    struct expr*        rtn;
Alexandre Julliard's avatar
Alexandre Julliard committed
120

121
    rtn = (struct expr*)&expr_list[next_expr_free];
Alexandre Julliard's avatar
Alexandre Julliard committed
122

123 124
    next_expr_free += sizeof(struct expr);
    assert(next_expr_free < sizeof(expr_list));
Eric Pouech's avatar
Eric Pouech committed
125

126
    return rtn;
Alexandre Julliard's avatar
Alexandre Julliard committed
127 128
}

129
void expr_free_all(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
130
{
131
    next_expr_free = 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
132 133
}

134
struct expr* expr_alloc_typecast(struct type_expr_t* tet, struct expr* exp)
Alexandre Julliard's avatar
Alexandre Julliard committed
135
{
136
    struct expr*        ex;
Alexandre Julliard's avatar
Alexandre Julliard committed
137

138
    ex = expr_alloc();
Alexandre Julliard's avatar
Alexandre Julliard committed
139

140 141 142 143
    ex->type            = EXPR_TYPE_CAST;
    ex->un.cast.cast_to = *tet;
    ex->un.cast.expr    = exp;
    return ex;
Alexandre Julliard's avatar
Alexandre Julliard committed
144
}
Alexandre Julliard's avatar
Alexandre Julliard committed
145

146
struct expr* expr_alloc_internal_var(const char* name)
Alexandre Julliard's avatar
Alexandre Julliard committed
147
{
148
    struct expr* ex;
Alexandre Julliard's avatar
Alexandre Julliard committed
149

150
    ex = expr_alloc();
Alexandre Julliard's avatar
Alexandre Julliard committed
151

152 153 154
    ex->type           = EXPR_TYPE_INTVAR;
    ex->un.intvar.name = name;
    return ex;
Alexandre Julliard's avatar
Alexandre Julliard committed
155 156
}

157
struct expr* expr_alloc_symbol(const char* name)
Alexandre Julliard's avatar
Alexandre Julliard committed
158
{
159
    struct expr* ex;
Alexandre Julliard's avatar
Alexandre Julliard committed
160

161
    ex = expr_alloc();
Alexandre Julliard's avatar
Alexandre Julliard committed
162

163 164 165
    ex->type           = EXPR_TYPE_SYMBOL;
    ex->un.symbol.name = name;
    return ex;
Alexandre Julliard's avatar
Alexandre Julliard committed
166 167
}

168
struct expr* expr_alloc_sconstant(int value)
Alexandre Julliard's avatar
Alexandre Julliard committed
169
{
170
    struct expr*        ex;
Alexandre Julliard's avatar
Alexandre Julliard committed
171

172
    ex = expr_alloc();
Alexandre Julliard's avatar
Alexandre Julliard committed
173

174 175 176
    ex->type             = EXPR_TYPE_S_CONST;
    ex->un.s_const.value = value;
    return ex;
Alexandre Julliard's avatar
Alexandre Julliard committed
177 178
}

179
struct expr* expr_alloc_uconstant(unsigned int value)
Alexandre Julliard's avatar
Alexandre Julliard committed
180
{
181 182 183 184 185 186 187
    struct expr*        ex;

    ex = expr_alloc();

    ex->type             = EXPR_TYPE_U_CONST;
    ex->un.u_const.value = value;
    return ex;
Alexandre Julliard's avatar
Alexandre Julliard committed
188 189
}

190
struct expr* expr_alloc_string(const char* str)
Alexandre Julliard's avatar
Alexandre Julliard committed
191
{
192
    struct expr*        ex;
Alexandre Julliard's avatar
Alexandre Julliard committed
193

194
    ex = expr_alloc();
Alexandre Julliard's avatar
Alexandre Julliard committed
195

196
    ex->type          = EXPR_TYPE_STRING;
197
    ex->un.string.str = str;
198
    return ex;
Alexandre Julliard's avatar
Alexandre Julliard committed
199 200
}

201
struct expr* expr_alloc_binary_op(int op_type, struct expr* exp1, struct expr* exp2)
Alexandre Julliard's avatar
Alexandre Julliard committed
202
{
203
    struct expr*        ex;
Alexandre Julliard's avatar
Alexandre Julliard committed
204

205
    ex = expr_alloc();
Alexandre Julliard's avatar
Alexandre Julliard committed
206

207 208 209 210 211
    ex->type                = EXPR_TYPE_BINOP;
    ex->un.binop.binop_type = op_type;
    ex->un.binop.exp1       = exp1;
    ex->un.binop.exp2       = exp2;
    return ex;
Alexandre Julliard's avatar
Alexandre Julliard committed
212 213
}

214
struct expr* expr_alloc_unary_op(int op_type, struct expr* exp1)
Alexandre Julliard's avatar
Alexandre Julliard committed
215
{
216
    struct expr*        ex;
Alexandre Julliard's avatar
Alexandre Julliard committed
217

218
    ex = expr_alloc();
Alexandre Julliard's avatar
Alexandre Julliard committed
219

220 221 222 223
    ex->type              = EXPR_TYPE_UNOP;
    ex->un.unop.unop_type = op_type;
    ex->un.unop.exp1      = exp1;
    return ex;
Alexandre Julliard's avatar
Alexandre Julliard committed
224 225
}

226
struct expr* expr_alloc_struct(struct expr* exp, const char* element)
Alexandre Julliard's avatar
Alexandre Julliard committed
227
{
228
    struct expr*        ex;
Alexandre Julliard's avatar
Alexandre Julliard committed
229

230
    ex = expr_alloc();
Alexandre Julliard's avatar
Alexandre Julliard committed
231

232 233 234 235
    ex->type                      = EXPR_TYPE_STRUCT;
    ex->un.structure.exp1         = exp;
    ex->un.structure.element_name = element;
    return ex;
Alexandre Julliard's avatar
Alexandre Julliard committed
236 237
}

238
struct expr* expr_alloc_pstruct(struct expr* exp, const char* element)
Alexandre Julliard's avatar
Alexandre Julliard committed
239
{
240
    struct expr*        ex;
Alexandre Julliard's avatar
Alexandre Julliard committed
241

242
    ex = expr_alloc();
Alexandre Julliard's avatar
Alexandre Julliard committed
243

244 245 246 247
    ex->type                      = EXPR_TYPE_PSTRUCT;
    ex->un.structure.exp1         = exp;
    ex->un.structure.element_name = element;
    return ex;
Alexandre Julliard's avatar
Alexandre Julliard committed
248 249
}

250
struct expr* expr_alloc_func_call(const char* funcname, int nargs, ...)
Alexandre Julliard's avatar
Alexandre Julliard committed
251
{
252 253 254
    struct expr*        ex;
    va_list             ap;
    int                 i;
Alexandre Julliard's avatar
Alexandre Julliard committed
255

256
    ex = expr_alloc();
Alexandre Julliard's avatar
Alexandre Julliard committed
257

258 259 260
    ex->type             = EXPR_TYPE_CALL;
    ex->un.call.funcname = funcname;
    ex->un.call.nargs    = nargs;
Alexandre Julliard's avatar
Alexandre Julliard committed
261

262 263
    va_start(ap, nargs);
    for (i = 0; i < nargs; i++)
Alexandre Julliard's avatar
Alexandre Julliard committed
264
    {
265
        ex->un.call.arg[i] = va_arg(ap, struct expr*);
Alexandre Julliard's avatar
Alexandre Julliard committed
266
    }
267 268
    va_end(ap);
    return ex;
Alexandre Julliard's avatar
Alexandre Julliard committed
269 270
}

271 272 273 274 275
/******************************************************************
 *		expr_eval
 *
 */
struct dbg_lvalue expr_eval(struct expr* exp)
Alexandre Julliard's avatar
Alexandre Julliard committed
276
{
277 278 279 280 281
    struct dbg_lvalue                   rtn;
    int		                        i;
    struct dbg_lvalue                   exp1;
    struct dbg_lvalue                   exp2;
    unsigned int	                cexp[5];
282
    DWORD64	                        scale1, scale2, scale3;
283
    struct dbg_type                     type1, type2;
284 285
    DWORD                               tag;
    const struct dbg_internal_var*      div;
286

287
    rtn.cookie       = 0;
288 289
    rtn.type.id      = dbg_itype_none;
    rtn.type.module  = 0;
290 291 292 293 294
    rtn.addr.Mode    = AddrModeFlat;
    rtn.addr.Offset  = 0;
    rtn.addr.Segment = 0;

    switch (exp->type)
Alexandre Julliard's avatar
Alexandre Julliard committed
295
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
296
    case EXPR_TYPE_CAST:
297 298 299 300 301 302 303
        /* this is really brute force, we simply change the type... without 
         * checking if this is right or not
         */
        rtn = expr_eval(exp->un.cast.expr);
        switch (exp->un.cast.cast_to.type)
        {
        case type_expr_type_id:
304
            if (exp->un.cast.cast_to.u.type.id == dbg_itype_none)
305 306 307 308
            {
                dbg_printf("Can't cast to unknown type\n");
                RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
            }
309
            rtn.type = exp->un.cast.cast_to.u.type;
310 311 312 313
            break;
        case type_expr_udt_class:
        case type_expr_udt_struct:
        case type_expr_udt_union:
314 315
            rtn.type = types_find_type(rtn.type.module, exp->un.cast.cast_to.u.name,
                                       SymTagUDT);
316
            if (rtn.type.id == dbg_itype_none)
317 318 319 320 321 322
            {
                dbg_printf("Can't cast to UDT %s\n", exp->un.cast.cast_to.u.name);
                RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
            }
            break;
        case type_expr_enumeration:
323 324
            rtn.type = types_find_type(rtn.type.module, exp->un.cast.cast_to.u.name,
                                       SymTagEnum);
325
            if (rtn.type.id == dbg_itype_none)
326 327 328 329 330 331 332 333 334 335 336
            {
                dbg_printf("Can't cast to enumeration %s\n", exp->un.cast.cast_to.u.name);
                RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
            }
            break;
        default:
            dbg_printf("Unsupported cast type %u\n", exp->un.cast.cast_to.type);
            RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
        }
        for (i = 0; i < exp->un.cast.cast_to.deref_count; i++)
        {
337 338
            rtn.type = types_find_pointer(&rtn.type);
            if (rtn.type.id == dbg_itype_none)
339 340 341 342 343 344
            {
                dbg_printf("Cannot find pointer type\n");
                RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
            }
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
345
    case EXPR_TYPE_STRING:
346 347 348
        rtn.cookie      = DLV_HOST;
        rtn.type.id     = dbg_itype_astring;
        rtn.type.module = 0;
349 350 351 352
        rtn.addr.Offset = (unsigned int)&exp->un.string.str;
        break;
    case EXPR_TYPE_U_CONST:
        rtn.cookie      = DLV_HOST;
353 354
        rtn.type.id     = dbg_itype_unsigned_int;
        rtn.type.module = 0;
355 356 357 358
        rtn.addr.Offset = (unsigned int)&exp->un.u_const.value;
        break;
    case EXPR_TYPE_S_CONST:
        rtn.cookie      = DLV_HOST;
359 360
        rtn.type.id     = dbg_itype_signed_int;
        rtn.type.module = 0;
361 362
        rtn.addr.Offset = (unsigned int)&exp->un.s_const.value;
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
363
    case EXPR_TYPE_SYMBOL:
364 365 366 367 368 369 370 371 372 373 374 375
        switch (symbol_get_lvalue(exp->un.symbol.name, -1, &rtn, FALSE))
        {
        case sglv_found:
            break;
        case sglv_unknown:
            RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
            /* should never be here */
        case sglv_aborted:
            RaiseException(DEBUG_STATUS_ABORT, 0, 0, NULL);
            /* should never be here */
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
376
    case EXPR_TYPE_PSTRUCT:
377
        exp1 = expr_eval(exp->un.structure.exp1);
378 379
        if (exp1.type.id == dbg_itype_none || !types_deref(&exp1, &rtn) ||
            rtn.type.id == dbg_itype_none)
380 381 382 383 384 385 386 387
            RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
        if (!types_udt_find_element(&rtn, exp->un.structure.element_name,
                                    &exp->un.structure.result))
        {
            dbg_printf("%s\n", exp->un.structure.element_name);
            RaiseException(DEBUG_STATUS_NO_FIELD, 0, 0, NULL);
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
388
    case EXPR_TYPE_STRUCT:
389
        exp1 = expr_eval(exp->un.structure.exp1);
390
        if (exp1.type.id == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
391 392 393 394 395 396 397 398
        rtn = exp1;
        if (!types_udt_find_element(&rtn, exp->un.structure.element_name,
                                    &exp->un.structure.result))
        {
            dbg_printf("%s\n", exp->un.structure.element_name);
            RaiseException(DEBUG_STATUS_NO_FIELD, 0, 0, NULL);
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
399
    case EXPR_TYPE_CALL:
400 401 402 403 404
        /*
         * First, evaluate all of the arguments.  If any of them are not
         * evaluable, then bail.
         */
        for (i = 0; i < exp->un.call.nargs; i++)
Alexandre Julliard's avatar
Alexandre Julliard committed
405
	{
406
            exp1 = expr_eval(exp->un.call.arg[i]);
407
            if (exp1.type.id == dbg_itype_none)
408 409
                RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
            cexp[i] = types_extract_as_integer(&exp1);
Alexandre Julliard's avatar
Alexandre Julliard committed
410 411
	}

412 413 414 415 416 417 418 419 420 421 422 423 424 425
        /*
         * Now look up the address of the function itself.
         */
        switch (symbol_get_lvalue(exp->un.call.funcname, -1, &rtn, FALSE))
        {
        case sglv_found:
            break;
        case sglv_unknown:
            RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
            /* should never be here */
        case sglv_aborted:
            RaiseException(DEBUG_STATUS_ABORT, 0, 0, NULL);
            /* should never be here */
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
426

427
#if 0
428 429 430 431 432 433 434 435
        /* 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)();

        fptr = (int (*)()) rtn.addr.off;
        switch (exp->un.call.nargs)
Alexandre Julliard's avatar
Alexandre Julliard committed
436 437
	{
	case 0:
438 439
            exp->un.call.result = (*fptr)();
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
440
	case 1:
441 442
            exp->un.call.result = (*fptr)(cexp[0]);
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
443
	case 2:
444 445
            exp->un.call.result = (*fptr)(cexp[0], cexp[1]);
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
446
	case 3:
447 448
            exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2]);
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
449
	case 4:
450 451
            exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3]);
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
452
	case 5:
453 454
            exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3], cexp[4]);
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
455
	}
456
#else
457 458 459 460 461
        dbg_printf("Function call no longer implemented\n");
        /* would need to set up a call to this function, and then restore the current
         * context afterwards...
         */
        exp->un.call.result = 0;
462
#endif
463
        rtn.cookie = DLV_HOST;
464 465
        /* get return type from function signature tupe */
        types_get_info(&rtn.type, TI_GET_TYPE, &rtn.type.id);
466 467
        rtn.addr.Offset = (unsigned int)&exp->un.call.result;
        break;
468
    case EXPR_TYPE_INTVAR:
469
        rtn.cookie = DLV_HOST;
470 471
        if (!(div = dbg_get_internal_var(exp->un.intvar.name)))
            RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
472 473
        rtn.type.id     = div->typeid;
        rtn.type.module = 0;
474 475
        rtn.addr.Offset = (unsigned int)div->pval;
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
476
    case EXPR_TYPE_BINOP:
477
        rtn.cookie = DLV_HOST;
478 479
        exp1 = expr_eval(exp->un.binop.exp1);
        exp2 = expr_eval(exp->un.binop.exp2);
480
        if (exp1.type.id == dbg_itype_none || exp2.type.id == dbg_itype_none)
481
            RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
482 483
        rtn.type.id = dbg_itype_signed_int;
        rtn.type.module = 0;
484
        rtn.addr.Offset = (unsigned int)&exp->un.binop.result;
485 486
        type1 = exp1.type;
        type2 = exp2.type;
487
        switch (exp->un.binop.binop_type)
Alexandre Julliard's avatar
Alexandre Julliard committed
488 489
	{
	case EXP_OP_ADD:
490
            if (!types_get_info(&exp1.type, TI_GET_SYMTAG, &tag) ||
491
                tag != SymTagPointerType ||
492
                !types_get_info(&exp1.type, TI_GET_TYPE, &type1.id))
493 494
                type1.id = dbg_itype_none;
            if (!types_get_info(&exp2.type, TI_GET_SYMTAG, &tag) ||
495
                tag != SymTagPointerType ||
496
                !types_get_info(&exp2.type, TI_GET_TYPE, &type2.id))
497
                type2.id = dbg_itype_none;
498 499
            scale1 = 1;
            scale2 = 1;
500
            if (type1.id != dbg_itype_none && type2.id != dbg_itype_none)
501
                RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
502
            if (type1.id != dbg_itype_none)
Alexandre Julliard's avatar
Alexandre Julliard committed
503
	    {
504 505
                types_get_info(&type1, TI_GET_LENGTH, &scale2);
                rtn.type = exp1.type;
Alexandre Julliard's avatar
Alexandre Julliard committed
506
	    }
507
            else if (type2.id != dbg_itype_none)
Alexandre Julliard's avatar
Alexandre Julliard committed
508
	    {
509 510
                types_get_info(&type2, TI_GET_LENGTH, &scale1);
                rtn.type = exp2.type;
Alexandre Julliard's avatar
Alexandre Julliard committed
511
	    }
512 513
            exp->un.binop.result = types_extract_as_integer(&exp1) * (DWORD)scale1 +
                (DWORD)scale2 * types_extract_as_integer(&exp2);
514
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
515
	case EXP_OP_SUB:
516
            if (!types_get_info(&exp1.type, TI_GET_SYMTAG, &tag) ||
517
                tag != SymTagPointerType ||
518
                !types_get_info(&exp1.type, TI_GET_TYPE, &type1.id))
519 520
                type1.id = dbg_itype_none;
            if (!types_get_info(&exp2.type, TI_GET_SYMTAG, &tag) ||
521
                tag != SymTagPointerType ||
522
                !types_get_info(&exp2.type, TI_GET_TYPE, &type2.id))
523
                type2.id = dbg_itype_none;
524 525 526
            scale1 = 1;
            scale2 = 1;
            scale3 = 1;
527
            if (type1.id != dbg_itype_none && type2.id != dbg_itype_none)
Alexandre Julliard's avatar
Alexandre Julliard committed
528
	    {
529 530 531 532
                WINE_FIXME("This may fail (if module base address are wrongly calculated)\n");
                if (memcmp(&type1, &type2, sizeof(struct dbg_type)))
                    RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
                types_get_info(&type1, TI_GET_LENGTH, &scale3);
Alexandre Julliard's avatar
Alexandre Julliard committed
533
	    }
534
            else if (type1.id != dbg_itype_none)
Alexandre Julliard's avatar
Alexandre Julliard committed
535
	    {
536 537
                types_get_info(&type1, TI_GET_LENGTH, &scale2);
                rtn.type = exp1.type;
Alexandre Julliard's avatar
Alexandre Julliard committed
538
	    }
539
            else if (type2.id != dbg_itype_none)
Alexandre Julliard's avatar
Alexandre Julliard committed
540
	    {
541 542
                types_get_info(&type2, TI_GET_LENGTH, &scale1);
                rtn.type = exp2.type;
Alexandre Julliard's avatar
Alexandre Julliard committed
543
	    }
544 545
            exp->un.binop.result = (types_extract_as_integer(&exp1) * (DWORD)scale1 - 
                                    types_extract_as_integer(&exp2) * (DWORD)scale2) / (DWORD)scale3;
546
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
547
	case EXP_OP_SEG:
548
            rtn.type.id = dbg_itype_segptr;
549
            rtn.type.module = 0;
550 551
            be_cpu->build_addr(dbg_curr_thread->handle, &dbg_context, &rtn.addr,
                               types_extract_as_integer(&exp1), types_extract_as_integer(&exp2));
552
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
553
	case EXP_OP_LOR:
554 555
            exp->un.binop.result = (types_extract_as_integer(&exp1) || types_extract_as_integer(&exp2));
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
556
	case EXP_OP_LAND:
557 558
            exp->un.binop.result = (types_extract_as_integer(&exp1) && types_extract_as_integer(&exp2));
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
559
	case EXP_OP_OR:
560 561
            exp->un.binop.result = (types_extract_as_integer(&exp1) | types_extract_as_integer(&exp2));
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
562
	case EXP_OP_AND:
563 564
            exp->un.binop.result = (types_extract_as_integer(&exp1) & types_extract_as_integer(&exp2));
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
565
	case EXP_OP_XOR:
566 567
            exp->un.binop.result = (types_extract_as_integer(&exp1) ^ types_extract_as_integer(&exp2));
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
568
	case EXP_OP_EQ:
569 570
            exp->un.binop.result = (types_extract_as_integer(&exp1) == types_extract_as_integer(&exp2));
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
571
	case EXP_OP_GT:
572 573
            exp->un.binop.result = (types_extract_as_integer(&exp1) > types_extract_as_integer(&exp2));
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
574
	case EXP_OP_LT:
575 576
            exp->un.binop.result = (types_extract_as_integer(&exp1) < types_extract_as_integer(&exp2));
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
577
	case EXP_OP_GE:
578 579
            exp->un.binop.result = (types_extract_as_integer(&exp1) >= types_extract_as_integer(&exp2));
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
580
	case EXP_OP_LE:
581 582
            exp->un.binop.result = (types_extract_as_integer(&exp1) <= types_extract_as_integer(&exp2));
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
583
	case EXP_OP_NE:
584 585
            exp->un.binop.result = (types_extract_as_integer(&exp1) != types_extract_as_integer(&exp2));
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
586
	case EXP_OP_SHL:
587 588
            exp->un.binop.result = ((unsigned long)types_extract_as_integer(&exp1) << types_extract_as_integer(&exp2));
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
589
	case EXP_OP_SHR:
590 591
            exp->un.binop.result = ((unsigned long)types_extract_as_integer(&exp1) >> types_extract_as_integer(&exp2));
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
592
	case EXP_OP_MUL:
593 594
            exp->un.binop.result = (types_extract_as_integer(&exp1) * types_extract_as_integer(&exp2));
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
595
	case EXP_OP_DIV:
596 597 598
            if (types_extract_as_integer(&exp2) == 0) RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
            exp->un.binop.result = (types_extract_as_integer(&exp1) / types_extract_as_integer(&exp2));
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
599
	case EXP_OP_REM:
600 601 602
            if (types_extract_as_integer(&exp2) == 0) RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
            exp->un.binop.result = (types_extract_as_integer(&exp1) % types_extract_as_integer(&exp2));
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
603
	case EXP_OP_ARR:
604 605 606 607
            if (!types_array_index(&exp1, types_extract_as_integer(&exp2), &rtn))
                RaiseException(DEBUG_STATUS_CANT_DEREF, 0, 0, NULL);
            break;
	default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
Alexandre Julliard's avatar
Alexandre Julliard committed
608
	}
609
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
610
    case EXPR_TYPE_UNOP:
611
        rtn.cookie = DLV_HOST;
612 613
        exp1 = expr_eval(exp->un.unop.exp1);
        if (exp1.type.id == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
614
        rtn.addr.Offset = (unsigned int)&exp->un.unop.result;
615 616
        rtn.type.id     = dbg_itype_signed_int;
        rtn.type.module = 0;
617
        switch (exp->un.unop.unop_type)
Alexandre Julliard's avatar
Alexandre Julliard committed
618 619
	{
	case EXP_OP_NEG:
620 621
            exp->un.unop.result = -types_extract_as_integer(&exp1);
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
622
	case EXP_OP_NOT:
623 624
            exp->un.unop.result = !types_extract_as_integer(&exp1);
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
625
	case EXP_OP_LNOT:
626 627
            exp->un.unop.result = ~types_extract_as_integer(&exp1);
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
628
	case EXP_OP_DEREF:
629 630 631
            if (!types_deref(&exp1, &rtn))
                RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
632
	case EXP_OP_FORCE_DEREF:
633 634 635 636
            rtn = exp1;
            if (exp1.cookie == DLV_TARGET)
                dbg_read_memory(memory_to_linear_addr(&exp1.addr), &rtn.addr.Offset, sizeof(rtn.addr.Offset));
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
637
	case EXP_OP_ADDR:
638 639 640 641
            /* only do it on linear addresses */
            if (exp1.addr.Mode != AddrModeFlat)
                RaiseException(DEBUG_STATUS_CANT_DEREF, 0, 0, NULL);
            exp->un.unop.result = (unsigned int)memory_to_linear_addr(&exp1.addr);
642
            rtn.type = types_find_pointer(&exp1.type);
643 644
            if (rtn.type.id == dbg_itype_none)
                RaiseException(DEBUG_STATUS_CANT_DEREF, 0, 0, NULL);
645 646
            break;
	default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
Alexandre Julliard's avatar
Alexandre Julliard committed
647
	}
648
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
649
    default:
650 651 652
        WINE_FIXME("Unexpected expression (%d).\n", exp->type);
        RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
653 654
    }

655
    return rtn;
Alexandre Julliard's avatar
Alexandre Julliard committed
656 657
}

658
int expr_print(const struct expr* exp)
Alexandre Julliard's avatar
Alexandre Julliard committed
659
{
660 661
    int		        i;
    struct dbg_type     type;
Alexandre Julliard's avatar
Alexandre Julliard committed
662

663
    switch (exp->type)
Alexandre Julliard's avatar
Alexandre Julliard committed
664
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
665
    case EXPR_TYPE_CAST:
666 667 668 669 670
        WINE_FIXME("No longer supported (missing module base)\n");
        dbg_printf("((");
        switch (exp->un.cast.cast_to.type)
        {
        case type_expr_type_id:
671 672 673
            type.module = 0;
            type.id = exp->un.cast.cast_to.type;
            types_print_type(&type, FALSE); break;
674 675 676 677 678 679 680 681 682 683 684 685 686 687 688
        case type_expr_udt_class:
            dbg_printf("class %s", exp->un.cast.cast_to.u.name); break;
        case type_expr_udt_struct:
            dbg_printf("struct %s", exp->un.cast.cast_to.u.name); break;
        case type_expr_udt_union:
            dbg_printf("union %s", exp->un.cast.cast_to.u.name); break;
        case type_expr_enumeration:
            dbg_printf("enum %s", exp->un.cast.cast_to.u.name); break;
        }
        for (i = 0; i < exp->un.cast.cast_to.deref_count; i++)
            dbg_printf("*");
        dbg_printf(")");
        expr_print(exp->un.cast.expr);
        dbg_printf(")");
        break;
689
    case EXPR_TYPE_INTVAR:
690 691 692 693 694 695 696 697
        dbg_printf("$%s", exp->un.intvar.name);
        break;
    case EXPR_TYPE_U_CONST:
        dbg_printf("%u", exp->un.u_const.value);
        break;
    case EXPR_TYPE_S_CONST:
        dbg_printf("%d", exp->un.s_const.value);
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
698
    case EXPR_TYPE_STRING:
699 700
        dbg_printf("\"%s\"", exp->un.string.str);
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
701
    case EXPR_TYPE_SYMBOL:
702 703
        dbg_printf("%s" , exp->un.symbol.name);
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
704
    case EXPR_TYPE_PSTRUCT:
705 706 707
        expr_print(exp->un.structure.exp1);
        dbg_printf("->%s", exp->un.structure.element_name);
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
708
    case EXPR_TYPE_STRUCT:
709 710 711
        expr_print(exp->un.structure.exp1);
        dbg_printf(".%s", exp->un.structure.element_name);
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
712
    case EXPR_TYPE_CALL:
713 714
        dbg_printf("%s(",exp->un.call.funcname);
        for (i = 0; i < exp->un.call.nargs; i++)
Alexandre Julliard's avatar
Alexandre Julliard committed
715
	{
716 717
            expr_print(exp->un.call.arg[i]);
            if (i != exp->un.call.nargs - 1) dbg_printf(", ");
Alexandre Julliard's avatar
Alexandre Julliard committed
718
	}
719 720
        dbg_printf(")");
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
721
    case EXPR_TYPE_BINOP:
722 723 724
        dbg_printf("(");
        expr_print(exp->un.binop.exp1);
        switch (exp->un.binop.binop_type)
Alexandre Julliard's avatar
Alexandre Julliard committed
725
	{
726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746
	case EXP_OP_ADD:        dbg_printf(" + ");    break;
	case EXP_OP_SUB:        dbg_printf(" - ");    break;
	case EXP_OP_SEG:        dbg_printf(":");      break;
	case EXP_OP_LOR:        dbg_printf(" || ");   break;
	case EXP_OP_LAND:       dbg_printf(" && ");   break;
	case EXP_OP_OR:         dbg_printf(" | ");    break;
	case EXP_OP_AND:        dbg_printf(" & ");    break;
	case EXP_OP_XOR:        dbg_printf(" ^ ");    break;
	case EXP_OP_EQ:         dbg_printf(" == ");   break;
	case EXP_OP_GT:         dbg_printf(" > ");    break;
	case EXP_OP_LT:         dbg_printf(" < ");    break;
	case EXP_OP_GE:         dbg_printf(" >= ");   break;
	case EXP_OP_LE:         dbg_printf(" <= ");   break;
	case EXP_OP_NE:         dbg_printf(" != ");   break;
	case EXP_OP_SHL:        dbg_printf(" << ");   break;
	case EXP_OP_SHR:        dbg_printf(" >> ");   break;
	case EXP_OP_MUL:        dbg_printf(" * ");    break;
	case EXP_OP_DIV:        dbg_printf(" / ");    break;
	case EXP_OP_REM:        dbg_printf(" %% ");   break;
	case EXP_OP_ARR:        dbg_printf("[");      break;
	default:                                      break;
Alexandre Julliard's avatar
Alexandre Julliard committed
747
	}
748 749 750 751
        expr_print(exp->un.binop.exp2);
        if (exp->un.binop.binop_type == EXP_OP_ARR) dbg_printf("]");
        dbg_printf(")");
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
752
    case EXPR_TYPE_UNOP:
753
        switch (exp->un.unop.unop_type)
Alexandre Julliard's avatar
Alexandre Julliard committed
754
	{
755 756 757 758 759
	case EXP_OP_NEG:        dbg_printf("-");      break;
	case EXP_OP_NOT:        dbg_printf("!");      break;
	case EXP_OP_LNOT:       dbg_printf("~");      break;
	case EXP_OP_DEREF:      dbg_printf("*");      break;
	case EXP_OP_ADDR:       dbg_printf("&");      break;
Alexandre Julliard's avatar
Alexandre Julliard committed
760
	}
761 762
        expr_print(exp->un.unop.exp1);
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
763
    default:
764 765 766
        WINE_FIXME("Unexpected expression (%u).\n", exp->type);
        RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
767 768
    }

769
    return TRUE;
Alexandre Julliard's avatar
Alexandre Julliard committed
770 771
}

Mike McCormack's avatar
Mike McCormack committed
772
struct expr* expr_clone(const struct expr* exp, BOOL *local_binding)
Alexandre Julliard's avatar
Alexandre Julliard committed
773
{
774 775
    int		        i;
    struct expr*        rtn;
Alexandre Julliard's avatar
Alexandre Julliard committed
776

777
    rtn = HeapAlloc(GetProcessHeap(), 0, sizeof(struct expr));
Alexandre Julliard's avatar
Alexandre Julliard committed
778

779 780 781 782
    /*
     * First copy the contents of the expression itself.
     */
    *rtn = *exp;
Alexandre Julliard's avatar
Alexandre Julliard committed
783

784
    switch (exp->type)
Alexandre Julliard's avatar
Alexandre Julliard committed
785
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
786
    case EXPR_TYPE_CAST:
787
        rtn->un.cast.expr = expr_clone(exp->un.cast.expr, local_binding);
788
        break;
789
    case EXPR_TYPE_INTVAR:
790 791 792 793 794
        rtn->un.intvar.name = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp->un.intvar.name) + 1), exp->un.intvar.name);
        break;
    case EXPR_TYPE_U_CONST:
    case EXPR_TYPE_S_CONST:
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
795
    case EXPR_TYPE_STRING:
796 797
        rtn->un.string.str = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp->un.string.str) + 1), exp->un.string.str);
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
798
    case EXPR_TYPE_SYMBOL:
799
        rtn->un.symbol.name = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp->un.symbol.name) + 1), exp->un.symbol.name);
800 801
        if (local_binding && symbol_is_local(exp->un.symbol.name))
            *local_binding = TRUE;
802
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
803 804
    case EXPR_TYPE_PSTRUCT:
    case EXPR_TYPE_STRUCT:
805
        rtn->un.structure.exp1 = expr_clone(exp->un.structure.exp1, local_binding);
806 807
        rtn->un.structure.element_name = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp->un.structure.element_name) + 1), exp->un.structure.element_name);
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
808
    case EXPR_TYPE_CALL:
809 810
        for (i = 0; i < exp->un.call.nargs; i++)
        {
811
            rtn->un.call.arg[i] = expr_clone(exp->un.call.arg[i], local_binding);
Alexandre Julliard's avatar
Alexandre Julliard committed
812
	}
813 814
        rtn->un.call.funcname = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(exp->un.call.funcname) + 1), exp->un.call.funcname);
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
815
    case EXPR_TYPE_BINOP:
816 817
        rtn->un.binop.exp1 = expr_clone(exp->un.binop.exp1, local_binding);
        rtn->un.binop.exp2 = expr_clone(exp->un.binop.exp2, local_binding);
818
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
819
    case EXPR_TYPE_UNOP:
820
        rtn->un.unop.exp1 = expr_clone(exp->un.unop.exp1, local_binding);
821
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
822
    default:
823 824 825
        WINE_FIXME("Unexpected expression (%u).\n", exp->type);
        RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
826 827
    }

828
    return rtn;
Alexandre Julliard's avatar
Alexandre Julliard committed
829 830 831 832 833 834 835
}


/*
 * Recursively go through an expression tree and free all memory associated
 * with it.
 */
836
int expr_free(struct expr* exp)
Alexandre Julliard's avatar
Alexandre Julliard committed
837
{
838
    int i;
Alexandre Julliard's avatar
Alexandre Julliard committed
839

840
    switch (exp->type)
Alexandre Julliard's avatar
Alexandre Julliard committed
841
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
842
    case EXPR_TYPE_CAST:
843 844
        expr_free(exp->un.cast.expr);
        break;
845
    case EXPR_TYPE_INTVAR:
846 847 848 849 850
        HeapFree(GetProcessHeap(), 0, (char*)exp->un.intvar.name);
        break;
    case EXPR_TYPE_U_CONST:
    case EXPR_TYPE_S_CONST:
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
851
    case EXPR_TYPE_STRING:
852 853
        HeapFree(GetProcessHeap(), 0, (char*)exp->un.string.str);
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
854
    case EXPR_TYPE_SYMBOL:
855 856
        HeapFree(GetProcessHeap(), 0, (char*)exp->un.symbol.name);
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
857 858
    case EXPR_TYPE_PSTRUCT:
    case EXPR_TYPE_STRUCT:
859 860 861
        expr_free(exp->un.structure.exp1);
        HeapFree(GetProcessHeap(), 0, (char*)exp->un.structure.element_name);
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
862
    case EXPR_TYPE_CALL:
863
        for (i = 0; i < exp->un.call.nargs; i++)
Alexandre Julliard's avatar
Alexandre Julliard committed
864
	{
865
            expr_free(exp->un.call.arg[i]);
Alexandre Julliard's avatar
Alexandre Julliard committed
866
	}
867 868
        HeapFree(GetProcessHeap(), 0, (char*)exp->un.call.funcname);
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
869
    case EXPR_TYPE_BINOP:
870 871 872
        expr_free(exp->un.binop.exp1);
        expr_free(exp->un.binop.exp2);
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
873
    case EXPR_TYPE_UNOP:
874 875
        expr_free(exp->un.unop.exp1);
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
876
    default:
877 878 879
        WINE_FIXME("Unexpected expression (%u).\n", exp->type);
        RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
880 881
    }

882 883
    HeapFree(GetProcessHeap(), 0, exp);
    return TRUE;
Alexandre Julliard's avatar
Alexandre Julliard committed
884
}