cint_eval_asts.c (41896B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: cint_eval_asts.c 8 * Purpose: CINT AST evaluators 9 */ 10 11 #include "cint_eval_asts.h" 12 #include "cint_porting.h" 13 #include "cint_variables.h" 14 #include "cint_internal.h" 15 #include "cint_error.h" 16 #include "cint_debug.h" 17 #include "cint_eval_ast_cint.h" 18 #include "cint_eval_ast_print.h" 19 #include <stdarg.h> 20 21 22 static int __breakable = 0; 23 static int __returnable = 0; 24 25 #define CINT_BREAK() CINT_ERRNO_IS(BREAK) 26 #define CINT_CONTINUE() CINT_ERRNO_IS(CONTINUE) 27 #define CINT_RETURN() CINT_ERRNO_IS(RETURN) 28 #define CINT_EXIT() CINT_ERRNO_IS(EXIT) 29 30 typedef cint_variable_t* (*cint_vararg_f)(cint_ast_t* ast); 31 32 static cint_variable_t* 33 __cint_eval_ast_Empty(cint_ast_t* ast) 34 { 35 return NULL; 36 } 37 38 static cint_variable_t* 39 __cint_eval_ast_Integer(cint_ast_t* ast) 40 { 41 return cint_auto_integer(ast->utype.integer.i); 42 } 43 44 #if CINT_CONFIG_INCLUDE_LONGLONGS == 1 45 static cint_variable_t* 46 __cint_eval_ast_LongLong(cint_ast_t* ast) 47 { 48 return cint_auto_longlong(ast->utype._longlong.i); 49 } 50 #endif 51 52 static cint_variable_t* 53 __cint_eval_ast_String(cint_ast_t* ast) 54 { 55 cint_variable_t* rv; 56 rv = cint_auto_string(ast->utype.string.s); 57 return rv; 58 } 59 60 #if CINT_CONFIG_INCLUDE_DOUBLES == 1 61 static cint_variable_t* 62 __cint_eval_ast_Double(cint_ast_t* ast) 63 { 64 return cint_auto_double(ast->utype._double.d); 65 } 66 #endif 67 68 static cint_variable_t* 69 __cint_eval_ast_Type(cint_ast_t* ast) 70 { 71 return NULL; 72 } 73 74 static cint_variable_t* 75 __cint_eval_ast_Initializer(cint_ast_t* ast) 76 { 77 return NULL; 78 } 79 80 static cint_variable_t* 81 __cint_eval_ast_EnumDef(cint_ast_t* ast) 82 { 83 cint_enum_type_t* cet; 84 cint_enum_map_t* map; 85 cint_ast_t* e; 86 int ecount; 87 int evalue = 0; 88 int map_size; 89 90 /* 91 * Allocate a new cint_enum_type_t structure 92 */ 93 cet = CINT_MALLOC(sizeof(*cet)); 94 if(cet == NULL) { 95 cint_ast_error(ast, CINT_E_MEMORY, "memory allocation failure"); 96 return NULL; 97 } 98 CINT_MEMSET(cet, 0, sizeof(*cet)); 99 100 cet->name = CINT_STRDUP(ast->utype.enumdef.identifier->utype.identifier.s); 101 ecount = cint_ast_count(ast->utype.enumdef.enumerators); 102 103 /* Allocate the map array based on the enum count */ 104 map_size = sizeof(*map)*(ecount+1); 105 map = CINT_MALLOC(map_size); 106 107 if(map == NULL) { 108 cint_ast_error(ast, CINT_E_MEMORY, "memory allocation failure"); 109 cint_datatype_clear_enumeration(cet); 110 return NULL; 111 } 112 CINT_MEMSET(map, 0, map_size); 113 114 /* Initialize map array base on the enumerators */ 115 cet->enum_map = map; 116 for(e = ast->utype.enumdef.enumerators; e; e = e->next, map++) { 117 map->name = CINT_STRDUP(e->utype.enumerator.identifier->utype.identifier.s); 118 if(e->utype.enumerator.value) { 119 cint_variable_t* rv; 120 121 rv = cint_eval_ast(e->utype.enumerator.value); 122 if (rv) { 123 map->value = cint_integer_value(rv); 124 evalue = map->value; 125 } else { 126 cint_ast_error(ast, CINT_E_BAD_AST, "illegal enum value"); 127 cint_datatype_clear_enumeration(cet); 128 return NULL; 129 } 130 } 131 else { 132 map->value = evalue; 133 } 134 evalue++; 135 } 136 map->name = NULL; 137 138 cint_datatype_add_enumeration(cet); 139 140 return NULL; 141 } 142 143 static cint_variable_t* 144 __cint_eval_ast_Enumerator(cint_ast_t* ast) 145 { 146 return NULL; 147 } 148 149 150 static cint_variable_t* 151 __cint_eval_ast_Identifier(cint_ast_t* ast) 152 { 153 cint_variable_t* rv = NULL; 154 int c; 155 cint_datatype_t dt; 156 const char* id = ast->utype.identifier.s; 157 158 /* Special Command Identifiers */ 159 if(!CINT_STRCMP(id, "quit") || 160 !CINT_STRCMP(id, "exit")) { 161 cint_errno = CINT_E_EXIT; 162 return NULL; 163 } 164 165 /* Variables */ 166 if((rv = cint_variable_find(id, 0))) { 167 return rv; 168 } 169 170 /* Enumerations */ 171 if(cint_datatype_enum_find(id, &dt, &c) == CINT_E_NONE) { 172 if(cint_variable_create(&rv, NULL, &dt.desc, CINT_VARIABLE_F_AUTO | CINT_VARIABLE_F_CONST, NULL) != CINT_E_NONE) { 173 cint_internal_error(__FILE__, __LINE__, "could not create enum autovar of type '%s'", dt.desc.basetype); 174 return NULL; 175 } 176 else { 177 *((int*)rv->data) = c; 178 } 179 return rv; 180 } 181 182 183 /* Enumerations and constants */ 184 if(cint_constant_find(id, &c) == CINT_E_NONE) { 185 return cint_auto_integer(c); 186 } 187 188 /* Functions */ 189 if(cint_datatype_find(id, &dt) == CINT_E_NONE) { 190 if(dt.flags & (CINT_DATATYPE_F_FUNC | CINT_DATATYPE_F_FUNC_DYNAMIC)) { 191 cint_parameter_desc_t pdt = { NULL, 0, 0 }; 192 193 pdt.basetype = id; 194 cint_variable_create(&rv, 195 NULL, 196 &pdt, 197 CINT_VARIABLE_F_AUTO | CINT_VARIABLE_F_CONST, 198 NULL); 199 return rv; 200 } 201 } 202 203 if(rv == NULL) { 204 cint_ast_error(ast, CINT_E_BAD_VARIABLE, "identifier '%s' undeclared", ast->utype.identifier.s); 205 } 206 return rv; 207 } 208 209 static int 210 _cint_eval_ast_declaration_parameter(cint_ast_t* ast, 211 char *basetype, 212 int basetype_len, 213 unsigned* basetype_flags, 214 int *pcount_p, 215 int *array_dimension_count, 216 int *array_dimensions) 217 { 218 int rc; 219 cint_variable_t* rv; 220 int pcount; 221 int dim_index; 222 int dimensions[CINT_CONFIG_ARRAY_DIMENSION_LIMIT]; 223 224 if (ast->ntype != cintAstDeclaration) { 225 return cint_ast_error(ast, 226 CINT_E_BAD_AST, 227 "expected declaration"); 228 } 229 230 pcount = ast->utype.declaration.pcount; 231 232 rc = cint_eval_type_list(ast->utype.declaration.type, 233 basetype, basetype_len, 234 basetype_flags, 1); 235 236 if (rc != CINT_E_NONE) { 237 return rc; 238 } 239 240 if(ast->utype.declaration.num_dimension_initializers) { 241 for(dim_index = 0; 242 dim_index < ast->utype.declaration.num_dimension_initializers; 243 dim_index++) { 244 rv = cint_eval_ast( 245 ast->utype.declaration.dimension_initializers[dim_index]); 246 if(rv == NULL || (cint_is_integer(rv) == 0)) { 247 return cint_ast_error(ast, 248 CINT_E_BAD_AST, 249 "illegal array definition"); 250 } 251 dimensions[dim_index] = cint_integer_value(rv); 252 if(dim_index > 0 && dimensions[dim_index] <= 0) { 253 return cint_ast_error(ast, 254 CINT_E_BAD_AST, 255 "illegal array definition"); 256 } 257 } 258 259 if(dimensions[0] <= 0) { 260 if(dimensions[0] == -1 && 261 ast->utype.declaration.num_dimension_initializers == 1 && 262 ast->utype.declaration.init && 263 ast->utype.declaration.init->ntype == cintAstInitializer) { 264 /* 265 * Determine the proper size for this initialized array. 266 * based on the length of the initializer chain 267 */ 268 dimensions[0] = 269 cint_ast_count(ast->utype.declaration.init-> 270 utype.initializer.initializers); 271 } 272 else { 273 return cint_ast_error(ast, 274 CINT_E_BAD_AST, 275 "illegal array definition"); 276 } 277 } 278 } 279 280 if (rc == CINT_E_NONE) { 281 *pcount_p = pcount; 282 *array_dimension_count = 283 ast->utype.declaration.num_dimension_initializers; 284 for(dim_index = 0; 285 dim_index < ast->utype.declaration.num_dimension_initializers; 286 dim_index++) { 287 array_dimensions[dim_index] = dimensions[dim_index]; 288 } 289 } 290 return rc; 291 } 292 293 static cint_variable_t* 294 __cint_eval_ast_Declaration(cint_ast_t* ast) 295 { 296 int rc; 297 cint_variable_t* rv; 298 cint_parameter_desc_t desc; 299 unsigned basetype_flags; 300 char basetype[64]; 301 302 rc = _cint_eval_ast_declaration_parameter(ast, 303 basetype, 304 sizeof(basetype), 305 &basetype_flags, 306 &desc.pcount, 307 &desc.num_dimensions, 308 desc.dimensions); 309 310 if (rc != CINT_E_NONE) { 311 return NULL; 312 } 313 314 desc.name = ast->utype.declaration.identifier->utype.string.s; 315 desc.basetype = basetype; 316 317 if (CINT_STRLEN(desc.basetype) == 0) { 318 cint_ast_error(ast, CINT_E_BAD_VARIABLE, 319 "identifier '%s' has unknown type", desc.name); 320 return NULL; 321 } 322 323 if((rv=cint_variable_find(desc.name, 1)) != NULL) { 324 /* Variable already exists in current scope */ 325 cint_ast_error(ast, CINT_E_BAD_VARIABLE, 326 "identifier '%s' redeclared", desc.name); 327 return NULL; 328 } 329 330 rc = cint_variable_create(&rv, 331 desc.name, 332 &desc, 333 0, 334 NULL); 335 336 if(rc < 0) { 337 if(rc == CINT_E_BAD_TYPE) { 338 cint_ast_error(ast, rc, "cannot declare variable of type '%s'", 339 desc.basetype); 340 } 341 else { 342 cint_ast_error(ast, rc, "variable create error: %s\n", 343 cint_error_name(rc)); 344 } 345 return NULL; 346 } 347 else { 348 349 if(ast->utype.declaration.init) { 350 /* New variable has an initialization expression */ 351 cint_ast_t *id; 352 cint_ast_t *assign; 353 354 /* 355 * Identifier AST 356 */ 357 id = cint_ast_identifier(rv->name); 358 359 /* 360 * Assignment AST 361 */ 362 assign = cint_ast_operator(cintOpAssign, 363 id, 364 ast->utype.declaration.init); 365 cint_eval_ast(assign); 366 367 /* sdk-67627: free the two ast allocated in this scope */ 368 cint_ast_free_single(assign); 369 cint_ast_free_single(id); 370 } 371 372 if(basetype_flags & CINT_AST_TYPE_F_CONST || 373 (desc.num_dimensions != 0 && desc.pcount == 0)) { 374 rv->flags |= CINT_VARIABLE_F_CONST; 375 } 376 if(basetype_flags & CINT_AST_TYPE_F_VOLATILE) { 377 rv->flags |= CINT_VARIABLE_F_VOLATILE; 378 } 379 380 } 381 return rv; 382 } 383 384 static cint_variable_t* 385 __cint_eval_ast_Operator(cint_ast_t* ast) 386 { 387 return cint_eval_operator(ast); 388 } 389 390 391 static int 392 __cint_eval_ast_dimensions_equal(int length0, 393 int length1, 394 int *dimensions0, 395 int *dimensions1) 396 { 397 int i; 398 if(length0 != length1) { 399 return 0; 400 } 401 402 for(i = 0; i < length0; i++) { 403 if(dimensions0[i] != dimensions1[i]) { 404 return 0; 405 } 406 } 407 408 return 1; 409 } 410 411 412 static cint_variable_t* 413 __cint_eval_ast_Function(cint_ast_t* ast) 414 { 415 cint_error_t rc; 416 cint_datatype_t* dtp; 417 cint_variable_t* rv = NULL; 418 cint_fparams_t fparams; 419 cint_parameter_desc_t* pd; 420 cint_ast_t* p; 421 int count; 422 int fcount; 423 cint_function_t* fp; 424 char _rstr[256] = {0}; 425 426 /* 427 * Find the function 428 */ 429 if((dtp = ast->utype.function.dtp) == NULL) { 430 431 dtp = CINT_MALLOC(sizeof(*dtp)); 432 if(dtp == NULL) { 433 cint_ast_error(ast, CINT_E_MEMORY, "memory allocation failure"); 434 return NULL; 435 } 436 437 438 if( ((rc = cint_datatype_find(ast->utype.function.name, dtp)) < 0) || 439 ((dtp->flags & CINT_DATATYPE_FLAGS_FUNC) == 0) ) { 440 cint_ast_error(ast, CINT_E_NOT_FOUND, "identifier '%s' is not a function", ast->utype.function.name); 441 442 CINT_FREE(dtp); 443 return NULL; 444 } 445 446 ast->utype.function.dtp = dtp; 447 } 448 449 fp = dtp->basetype.fp; 450 451 if(dtp->flags & CINT_DATATYPE_F_FUNC_VARARG) { 452 cint_vararg_f func = (cint_vararg_f)fp->addr; 453 return func(ast); 454 } 455 456 /* 457 * Return value? 458 */ 459 if(!cint_parameter_void(fp->params)) { 460 /* Allocate variable to hold return type */ 461 cint_variable_create(&rv, 462 NULL, 463 fp->params, 464 0, 0); 465 if(rv) { 466 fparams.rv = rv->data; 467 } 468 else { 469 fparams.rv = NULL; 470 } 471 } 472 473 /* 474 * Check parameter count 475 */ 476 count = cint_ast_count(ast->utype.function.parameters); 477 fcount = fp->params ? cint_parameter_count(fp->params) - 1 /* Return value doesn't count */ : 0; 478 479 if(fcount == 1 && cint_parameter_void(fp->params+1)) { 480 fcount = 0; 481 } 482 483 if(count != fcount) { 484 cint_ast_error(ast, CINT_E_PARAM, "wrong number of parameters to function '%s' (expected %d but received %d)", 485 fp->name, fcount, count); 486 return NULL; 487 } 488 489 490 /* 491 * Parameters 492 */ 493 for(count = 0, p = ast->utype.function.parameters, pd = fp->params+1; 494 p; 495 count ++, p = p->next, pd++) { 496 497 /* Given parameter value */ 498 cint_variable_t* v = cint_eval_ast(p); 499 cint_datatype_t pdt; 500 501 if(v == NULL) { 502 cint_ast_error(ast, CINT_E_PARAM, "error evaluating argument %d to function '%s'", 503 count+1, fp->name); 504 return NULL; 505 } 506 507 CINT_MEMSET(&pdt, 0, sizeof(pdt)); 508 /* Parameter type */ 509 if(cint_datatype_find(pd->basetype, &pdt) != CINT_E_NONE) { 510 return NULL; 511 } 512 513 if(cint_array_combine_dimensions(&pdt.desc, pd) != CINT_E_NONE) { 514 return NULL; 515 } 516 pdt.desc.pcount += pd->pcount; 517 518 if(cint_type_check(&v->dt, &pdt) == 0) { 519 520 int rc; 521 cint_variable_t* nv; 522 523 /* 524 * Not the same type. Special pointer conversions, where 525 * an extra level of indirection is added. 526 */ 527 528 /* 529 * There may be other type conversions (string to 530 * bcm_mac_t, string to bcm_ip_t) that should be 531 * allowable. 532 */ 533 534 if((!CINT_STRCMP(v->dt.desc.basetype, pdt.desc.basetype) || 535 cint_type_compatible(&v->dt, &pdt) ) && 536 v->dt.desc.pcount == (pdt.desc.pcount-1) && 537 v->dt.desc.num_dimensions == (pdt.desc.num_dimensions -1) && 538 __cint_eval_ast_dimensions_equal( 539 pdt.desc.num_dimensions - 1, 540 v->dt.desc.num_dimensions == 0 ? 541 v->cached_num_dimensions : 542 v->dt.desc.num_dimensions, 543 pdt.desc.dimensions + 1, 544 v->dt.desc.dimensions)) { 545 546 /* 547 * The function expects a pointer to the given argument type. 548 * Enable conversion. 549 */ 550 v = cint_variable_address(v); 551 v->flags &= ~CINT_VARIABLE_F_CONST; 552 } 553 else { 554 555 /* 556 * Can we convert the argument through assignment? 557 */ 558 if((rc = cint_variable_create(&nv, NULL, pd, CINT_VARIABLE_F_AUTO, NULL)) != CINT_E_NONE) { 559 cint_ast_error(ast, rc, "error creating temporary variables"); 560 return NULL; 561 } 562 563 if(cint_eval_operator_internal(ast, cintOpAssign, nv, v) == nv) { 564 /* Conversion successful */ 565 v = nv; 566 } 567 else { 568 char* f1 = cint_datatype_format(&v->dt, _rstr, 1); 569 cint_ast_error(ast, CINT_E_PARAM, "arg %d to function '%s' was wrong type: expected %s, received %s", 570 count+1, fp->name, cint_datatype_format(&pdt, _rstr, 0), f1); 571 CINT_FREE(f1); 572 return NULL; 573 } 574 } 575 } 576 577 /* Parameter is good to go */ 578 if(dtp->flags & CINT_DATATYPE_F_FUNC) { 579 /* Static function call */ 580 fparams.args[count] = v->data; 581 } 582 else { 583 /* Stored for later -- see dynamic function call below */ 584 fparams.args[count] = v; 585 } 586 } 587 588 589 /* 590 * Call function 591 */ 592 if(dtp->flags & CINT_DATATYPE_F_FUNC) { 593 cint_ftrace(fp->name, 1); 594 rc = fp->body.wrapper(&fparams); 595 cint_ftrace(fp->name, 0); 596 } 597 else { 598 599 /* 600 * Clone all function parameters into a new scope using the expected parameter names 601 */ 602 int i; 603 cint_variable_scope_push(fp->name); 604 605 for(i = 0, pd = fp->params+1; 606 i < count; 607 i++, pd++) { 608 609 cint_variable_t* pv = cint_variable_clone((cint_variable_t*)fparams.args[i]); 610 cint_variable_rename(pv, pd->name); 611 cint_variable_auto_save(pv); 612 } 613 614 /* 615 * Evaluate function body 616 */ 617 cint_ftrace(fp->name, 1); 618 __returnable++; 619 rv = cint_eval_asts(fp->body.statements); 620 if(rv) rv = cint_variable_clone(rv); 621 if(cint_errno == CINT_E_RETURN) { 622 cint_errno = CINT_E_NONE; 623 } 624 __returnable--; 625 cint_ftrace(fp->name, 0); 626 627 /* Do not destroy return value when scope is popped */ 628 if(rv) rv->flags |= CINT_VARIABLE_F_NODESTROY; 629 630 /* Pop function scope */ 631 cint_variable_scope_pop(fp->name); 632 633 /* Add return value back into the local scope list */ 634 if(rv) { 635 rv->flags &= ~CINT_VARIABLE_F_NODESTROY; 636 rv->flags &= ~CINT_VARIABLE_F_AUTO; 637 cint_variable_add(rv); 638 } 639 } 640 641 return rv; 642 } 643 644 static cint_variable_t* 645 __cint_eval_ast_Elist(cint_ast_t* ast) 646 { 647 cint_ast_t* p; 648 cint_variable_t* rv = NULL; 649 650 for(p = ast->utype.elist.list; p; p = p->next) { 651 rv = cint_eval_ast(p); 652 } 653 return rv; 654 } 655 656 static cint_variable_t* 657 __cint_eval_ast_While(cint_ast_t* ast) 658 { 659 cint_variable_t* rv; 660 661 __breakable++; 662 663 664 if(ast->utype._while.order) { 665 666 rv = cint_eval_asts(ast->utype._while.statements); 667 668 if(CINT_BREAK()) { 669 cint_errno = CINT_E_NONE; 670 return rv; 671 } else if(CINT_CONTINUE()) { 672 cint_errno = CINT_E_NONE; 673 } else if(CINT_RETURN()) { 674 cint_errno = CINT_E_RETURN; 675 return rv; 676 } 677 } 678 679 while(cint_logical_value(cint_eval_ast(ast->utype._while.condition))) { 680 681 rv = cint_eval_asts(ast->utype._while.statements); 682 683 if(CINT_BREAK()) { 684 cint_errno = CINT_E_NONE; 685 break; 686 } else if(CINT_CONTINUE()) { 687 cint_errno = CINT_E_NONE; 688 continue; 689 } else if(CINT_RETURN()) { 690 cint_errno = CINT_E_RETURN; 691 return rv; 692 } else if (cint_errno != CINT_E_NONE) { 693 break; 694 } 695 } 696 697 __breakable--; 698 return NULL; 699 } 700 701 static int 702 _for_cond(cint_ast_t* ast) 703 { 704 int cond = 1; 705 706 if (ast && ast->ntype != cintAstEmpty) { 707 cond = cint_logical_value(cint_eval_ast(ast)); 708 } 709 710 return cond; 711 } 712 713 static cint_variable_t* 714 __cint_eval_ast_For(cint_ast_t* ast) 715 { 716 cint_variable_t* rv = NULL; 717 718 __breakable++; 719 720 for(cint_eval_ast(ast->utype._for.pre); 721 _for_cond(ast->utype._for.condition); 722 cint_eval_ast(ast->utype._for.post)) { 723 724 rv = cint_eval_asts(ast->utype._for.statements); 725 726 if(CINT_BREAK()) { 727 cint_errno = CINT_E_NONE; 728 break; 729 } 730 731 if(CINT_CONTINUE()) { 732 cint_errno = CINT_E_NONE; 733 continue; 734 } 735 736 if(CINT_RETURN()) { 737 break; 738 } 739 740 if(CINT_EXIT()) { 741 break; 742 } 743 } 744 745 __breakable--; 746 747 return rv; 748 } 749 750 static cint_variable_t* 751 __cint_eval_ast_If(cint_ast_t* ast) 752 { 753 cint_variable_t* rv = NULL; 754 755 if(cint_logical_value(cint_eval_ast(ast->utype._if.condition))) { 756 rv = cint_eval_asts(ast->utype._if.statements); 757 } 758 else if(ast->utype._if._else) { 759 rv = cint_eval_asts(ast->utype._if._else); 760 } 761 return rv; 762 } 763 764 static cint_variable_t* 765 __cint_eval_ast_Return(cint_ast_t* ast) 766 { 767 cint_variable_t* rv = NULL; 768 769 if(!__returnable) { 770 cint_ast_error(ast, CINT_E_BAD_AST, "return statement not within function"); 771 return NULL; 772 } 773 774 if(ast->utype._return.expression) { 775 rv = cint_eval_ast(ast->utype._return.expression); 776 } 777 778 cint_errno = CINT_E_RETURN; 779 return rv; 780 } 781 782 static cint_variable_t* 783 __cint_eval_ast_Continue(cint_ast_t* ast) 784 { 785 if(!__breakable) { 786 cint_ast_error(ast, CINT_E_BAD_AST, "continue statement not within loop"); 787 } 788 else { 789 cint_errno = CINT_E_CONTINUE; 790 } 791 return NULL; 792 } 793 794 static cint_variable_t* 795 __cint_eval_ast_Break(cint_ast_t* ast) 796 { 797 if(!__breakable) { 798 cint_ast_error(ast, CINT_E_BAD_AST, "break statement not within loop"); 799 } 800 else { 801 cint_errno = CINT_E_BREAK; 802 } 803 return NULL; 804 } 805 806 static cint_variable_t* 807 __cint_eval_ast_Switch(cint_ast_t* ast) 808 { 809 cint_ast_t* s; 810 cint_ast_t* _default = NULL; 811 cint_ast_t* eq = NULL; 812 cint_variable_t* rv = NULL; 813 814 /* 815 * If this is a compound statement the brace operators might not get paired properly. 816 * The first open brace will never get executed, since it is not part of a case label. 817 * The final open brace may get executed as we fall through the labels (including the default). 818 * 819 * The trailing closing brace is disabled for this reason. 820 */ 821 s = cint_ast_last(ast->utype._switch.statements); 822 if(cint_operator_type(s) == cintOpCloseBrace) { 823 s->noexec = 1; 824 } 825 826 /* Find and validate default case */ 827 for(s = ast->utype._switch.statements; s; s = s->next) { 828 if( (s->ntype == cintAstCase) && 829 s->utype._case.expression == NULL) { 830 831 if(_default) { 832 cint_ast_error(ast, CINT_E_BAD_AST, "more than one default label in switch statement"); 833 return NULL; 834 } 835 else { 836 _default = s; 837 } 838 } 839 } 840 841 eq = cint_ast_operator(cintOpEqual, ast->utype._switch.expression, NULL); 842 for(s = ast->utype._switch.statements; s; s = s->next) { 843 if( (s->ntype == cintAstCase) && 844 (s->utype._case.expression) ) { 845 846 cint_variable_t* v; 847 848 /* Check the switch expression against the case expression */ 849 eq->utype.operator.right = s->utype._case.expression; 850 v = cint_eval_ast(eq); 851 if(v == NULL) { 852 rv = NULL; 853 break; 854 } 855 856 if(cint_logical_value(v) == 1) { 857 /* Begin executing all statements starting here */ 858 __breakable++; 859 rv = cint_eval_asts(s); 860 __breakable--; 861 if(CINT_BREAK()) { 862 cint_errno = CINT_E_NONE; 863 } 864 if(CINT_RETURN()) { 865 cint_errno = CINT_E_RETURN; 866 } 867 else { 868 rv = NULL; 869 } 870 break; 871 } 872 } 873 } 874 875 /* Free up the AST as the switch evaluation is complete. */ 876 cint_ast_free_single(eq); 877 if (s) { 878 return rv; 879 } 880 881 if(_default) { 882 /* Execute default case */ 883 __breakable++; 884 rv = cint_eval_asts(_default); 885 __breakable--; 886 if(CINT_BREAK()) { 887 cint_errno = CINT_E_NONE; 888 } 889 if(CINT_RETURN()) { 890 cint_errno = CINT_E_RETURN; 891 return rv; 892 } 893 } 894 return NULL; 895 } 896 897 static cint_variable_t* 898 __cint_eval_ast_Case(cint_ast_t* ast) 899 { 900 /* Evaluate all statements in case label */ 901 return cint_eval_asts(ast->utype._case.statements); 902 } 903 904 905 906 static cint_variable_t* 907 __cint_eval_ast_Print(cint_ast_t* ast) 908 { 909 /* cint_eval_ast_print.c */ 910 return cint_eval_ast_Print(ast); 911 } 912 913 static cint_variable_t* 914 __cint_eval_ast_Cint(cint_ast_t* ast) 915 { 916 /* cint_eval_ast_debug.c */ 917 return cint_eval_ast_Cint(ast); 918 } 919 920 static cint_variable_t* 921 __cint_eval_ast_StructureDef(cint_ast_t* ast) 922 { 923 cint_struct_type_t* cst = CINT_MALLOC(sizeof(*cst)); 924 cint_ast_t* m; 925 cint_parameter_desc_t* p0; 926 cint_parameter_desc_t* p; 927 cint_datatype_t dt; 928 int mcount; 929 int ssize = 0; 930 char basetype[64]; 931 int rv; 932 int sm_size; 933 int dim_index; 934 935 if(cst == NULL) { 936 cint_ast_error(ast, CINT_E_MEMORY, "memory allocation failure"); 937 return NULL; 938 } 939 CINT_MEMSET((void *)cst, 0, sizeof(*cst)); 940 941 CINT_MEMSET(&dt, 0, sizeof(dt)); 942 943 if (ast->utype.structuredef.name) { 944 cst->name = 945 CINT_STRDUP(ast->utype.structuredef.name->utype.identifier.s); 946 if (cst->name == NULL) { 947 cint_ast_error(ast, CINT_E_MEMORY, "memory allocation failure"); 948 cint_datatype_clear_structure(cst); 949 return NULL; 950 } 951 } else { 952 cint_ast_error(ast, CINT_E_BAD_AST, "structure name not found"); 953 cint_datatype_clear_structure(cst); 954 return NULL; 955 } 956 957 m = ast->utype.structuredef.members; 958 mcount = cint_ast_count(m); 959 960 sm_size = sizeof(*p)*(mcount+1); 961 cst->struct_members = CINT_MALLOC(sm_size); 962 if (cst->struct_members == NULL) { 963 cint_datatype_clear_structure(cst); 964 cint_ast_error(ast, CINT_E_MEMORY, "memory allocation failure"); 965 return NULL; 966 } 967 CINT_MEMSET((void *)cst->struct_members, 0, sm_size); 968 969 p = (cint_parameter_desc_t *) cst->struct_members; 970 971 p0 = NULL; 972 973 for(; m; m = m->next, p++) { 974 if (m->ntype != cintAstDeclaration) { 975 cint_ast_error(ast, CINT_E_BAD_AST, 976 "invalid structure definition"); 977 cint_datatype_clear_structure(cst); 978 return NULL; 979 } 980 981 /* point of this exercise is to set p->{basetype,name,pcount} 982 and to determine member size. 983 */ 984 p->name = 985 CINT_STRDUP(m->utype.declaration.identifier->utype.string.s); 986 987 rv = _cint_eval_ast_declaration_parameter(m, 988 basetype, 989 sizeof(basetype), 990 NULL, 991 &p->pcount, 992 &p->num_dimensions, 993 p->dimensions); 994 995 if (rv != CINT_E_NONE) { 996 cint_datatype_clear_structure(cst); 997 return NULL; 998 } 999 1000 if (CINT_STRLEN(basetype) > 0) { 1001 /* count and array are already set, so now save the basetype */ 1002 p->basetype = CINT_STRDUP(basetype); 1003 1004 /* Save this structure member in case future structure 1005 members do not have a base type. Every structure member 1006 has a right to a base type. If it does not have a base 1007 type, this function will appoint one. 1008 */ 1009 p0 = p; 1010 } else { 1011 /* This structure member doesn't have a basetype, so use 1012 the basetype from the most recent structure member that 1013 *did* have one. At least one structure member needs to 1014 have a basetype. */ 1015 if (p0 == NULL) { 1016 /* It appears that no structure member had a basetype */ 1017 cint_ast_error(ast, CINT_E_BAD_AST, 1018 "no default member type definition found"); 1019 cint_datatype_clear_structure(cst); 1020 return NULL; 1021 } 1022 p->basetype = CINT_STRDUP(p0->basetype); 1023 p->pcount = p0->pcount; 1024 p->num_dimensions = p0->num_dimensions; 1025 for(dim_index = 0; 1026 dim_index < p0->num_dimensions; 1027 dim_index++) { 1028 p->dimensions[dim_index] = 1029 p0->dimensions[dim_index]; 1030 } 1031 } 1032 1033 if(cint_datatype_find(p->basetype, &dt) != CINT_E_NONE) { 1034 cint_ast_error(ast, CINT_E_BAD_AST, 1035 "unknown type '%s' in structure definition", 1036 p->basetype); 1037 cint_datatype_clear_structure(cst); 1038 return NULL; 1039 } 1040 1041 for(dim_index = 0; 1042 dim_index < p->num_dimensions; 1043 dim_index++) { 1044 dt.desc.dimensions[dim_index + dt.desc.num_dimensions] = 1045 p->dimensions[dim_index]; 1046 } 1047 dt.desc.num_dimensions += p->num_dimensions; 1048 dt.desc.pcount += p->pcount; 1049 1050 ssize += cint_datatype_size(&dt); 1051 1052 /* All members start on a word aligned address */ 1053 while(ssize % 4) ssize++; 1054 1055 } 1056 1057 cst->size = ssize; 1058 cst->maddr = cint_maddr_dynamic_struct_t; 1059 1060 cint_datatype_add_structure(cst); 1061 1062 return NULL; 1063 } 1064 1065 /* function parameter and return types can be a composite type, like 1066 unsigned int, but only one of those AST nodes that comprise the 1067 composite is the 'Type' AST node. */ 1068 static cint_ast_t * 1069 __cint_ast_basetype(cint_ast_t* ast) 1070 { 1071 int rc = CINT_E_NONE; 1072 char basetype[64]; 1073 if(ast) { 1074 rc = cint_eval_type_list(ast, 1075 basetype, sizeof(basetype), 1076 NULL, 0); 1077 if (rc != CINT_E_NONE) { 1078 return NULL; 1079 } 1080 if(CINT_AST(ast,Type) && ast->utype.type.s){ 1081 CINT_FREE((char*) ast->utype.type.s); 1082 } 1083 ast->ntype = cintAstType; 1084 ast->utype.type.s = CINT_STRDUP(basetype); 1085 } 1086 1087 return ast; 1088 } 1089 1090 static cint_variable_t* 1091 __cint_eval_ast_FunctionDef(cint_ast_t* ast) 1092 { 1093 cint_function_t* f; 1094 1095 cint_ast_t* decl = ast->utype.functiondef.declaration; 1096 cint_ast_t* params = ast->utype.functiondef.parameters; 1097 cint_ast_t* ret; 1098 cint_ast_t* name; 1099 1100 cint_parameter_desc_t* p; 1101 int count; 1102 int desc_size; 1103 cint_datatype_t dt; 1104 1105 if (decl == NULL) { 1106 cint_ast_error(ast, CINT_E_BAD_AST, "cannot determine declaration"); 1107 return NULL; 1108 } 1109 if (decl->ntype == cintAstType 1110 || decl->ntype == cintAstInteger 1111 #if CINT_CONFIG_INCLUDE_LONGLONGS == 1 1112 || decl->ntype == cintAstLongLong 1113 #endif 1114 #if CINT_CONFIG_INCLUDE_FLOATS == 1 1115 || decl->ntype == cintAstFloat 1116 #endif 1117 ) { 1118 /* This is a declaration, not a definition, so there's really 1119 nothing to do, yet. */ 1120 return NULL; 1121 } else if (decl->ntype != cintAstDeclaration) { 1122 cint_internal_error(__FILE__, __LINE__, 1123 "Node type %d unexpected", decl->ntype); 1124 return NULL; 1125 } 1126 1127 /* Function name */ 1128 name = decl->utype.declaration.identifier; 1129 if (!CINT_AST(name, Identifier)) { 1130 cint_internal_error(__FILE__, __LINE__, 1131 "Node type %d unexpected", name->ntype); 1132 return NULL; 1133 } 1134 1135 f = CINT_MALLOC(sizeof(*f)); 1136 if (f == NULL) { 1137 cint_ast_error(ast, CINT_E_MEMORY, "memory allocation failure"); 1138 return NULL; 1139 } 1140 CINT_MEMSET(f, 0, sizeof(*f)); 1141 1142 f->name = CINT_STRDUP(name->utype.identifier.s); 1143 1144 /* Return Type */ 1145 ret = __cint_ast_basetype(decl->utype.declaration.type); 1146 1147 if (ret == NULL) { 1148 cint_internal_error(__FILE__, __LINE__, "unknown return type"); 1149 cint_datatype_clear_function(f); 1150 return NULL; 1151 } 1152 1153 if (ret->utype.type.s == NULL) { 1154 cint_internal_error(__FILE__, __LINE__, "unknown return basetype"); 1155 cint_datatype_clear_function(f); 1156 return NULL; 1157 } 1158 1159 /* Number of parameters */ 1160 count = cint_ast_count(params); 1161 1162 /* Allocate parameter description array to hold parameters and return value */ 1163 desc_size = sizeof(*p)*(count+2); 1164 p = CINT_MALLOC(desc_size); 1165 if (p == NULL) { 1166 cint_ast_error(ast, CINT_E_MEMORY, "memory allocation failure"); 1167 cint_datatype_clear_function(f); 1168 return NULL; 1169 } 1170 CINT_MEMSET(p, 0, desc_size); 1171 f->params = p; 1172 1173 p->basetype = CINT_STRDUP(ret->utype.type.s); 1174 p->name = CINT_STRDUP("r"); 1175 p->pcount = decl->utype.declaration.pcount; 1176 p->num_dimensions = 0; 1177 1178 for(count = 1, params = ast->utype.functiondef.parameters; 1179 params; 1180 params = params->next, count++) { 1181 if (CINT_AST(params, Declaration)) { 1182 cint_ast_t *ty; 1183 cint_ast_t *ident = params->utype.declaration.identifier; 1184 1185 ty = __cint_ast_basetype(params->utype.declaration.type); 1186 1187 if (ty == NULL) { 1188 cint_ast_error(ast, CINT_E_BAD_AST, 1189 "param type not found"); 1190 cint_datatype_clear_function(f); 1191 return NULL; 1192 } 1193 1194 if (ident && !CINT_AST(ident, Identifier)) { 1195 cint_ast_error(ast, CINT_E_BAD_AST, 1196 "unexpected param ident AST %d", ident->ntype); 1197 cint_datatype_clear_function(f); 1198 return NULL; 1199 } 1200 1201 /* A NULL basetype is used as a sentinel for the parameter 1202 array, so it is not allowed to be NULL here */ 1203 if (ty->utype.type.s == NULL) { 1204 cint_ast_error(ast, CINT_E_BAD_AST, "base type not found"); 1205 cint_datatype_clear_function(f); 1206 return NULL; 1207 } 1208 1209 1210 1211 p[count].basetype = CINT_STRDUP(ty->utype.type.s); 1212 1213 p[count].name = ident ? 1214 CINT_STRDUP(ident->utype.identifier.s) : NULL; 1215 p[count].pcount = params->utype.declaration.pcount; 1216 p[count].num_dimensions = 0; 1217 /* for CINT, parameters are either IN or INOUT */ 1218 p[count].flags = CINT_PARAM_IN; 1219 if (p[count].pcount > 0) { 1220 cint_ast_t *modifier = params->utype.declaration.type; 1221 1222 /* const pointer is in, else in/out */ 1223 if (!(CINT_AST(modifier, Integer) && 1224 modifier->utype.integer.i == CINT_AST_TYPE_F_CONST)) { 1225 p[count].flags |= CINT_PARAM_OUT; 1226 } 1227 } 1228 } else { 1229 /* If it is not a declaration, treat it as a dummy parameter. 1230 There still needs to be a basetype, though. */ 1231 p[count].basetype = CINT_STRDUP("void"); 1232 } 1233 } 1234 p[count].basetype = NULL; 1235 1236 /* Statements */ 1237 f->body.statements = ast->utype.functiondef.statements; 1238 1239 /* if function is already defined, remove previous definition */ 1240 CINT_MEMSET(&dt, 0, sizeof(dt)); 1241 if(CINT_E_NONE == cint_datatype_find(f->name, &dt)) { 1242 cint_datatype_delete_function(f->name); 1243 } 1244 1245 /* 1246 * Register with interpreter 1247 */ 1248 cint_interpreter_add_function(f); 1249 return NULL; 1250 } 1251 1252 1253 int 1254 cint_interpreter_callback(cint_function_pointer_t* cb, int nargs, int nreturn, ...) 1255 { 1256 int i; 1257 cint_datatype_t dt; 1258 cint_parameter_desc_t* params; 1259 cint_variable_t* v; 1260 const char* fname; 1261 int returns; 1262 int fcount; 1263 int errno_save; 1264 va_list args; 1265 1266 va_start(args,nreturn); 1267 1268 if(cb == NULL) { 1269 cint_internal_error(__FILE__, __LINE__, "callback pointer is NULL"); 1270 va_end(args); 1271 return 0; 1272 } 1273 1274 fname = (char*)cb->data; 1275 1276 if(fname == NULL) { 1277 cint_internal_error(__FILE__, __LINE__, "callback name is NULL"); 1278 va_end(args); 1279 return 0; 1280 } 1281 1282 CINT_MEMSET(&dt, 0, sizeof(dt)); 1283 if(cint_datatype_find(fname, &dt) != 0) { 1284 cint_internal_error(__FILE__, __LINE__, "callback type '%s' was not found", fname); 1285 va_end(args); 1286 return 0; 1287 } 1288 1289 if (CINT_STRLEN(fname) == 0) { 1290 cint_internal_error(__FILE__, __LINE__, "callback name is NULL String"); 1291 va_end(args); 1292 return 0; 1293 } 1294 1295 /* 1296 * Call dynamic function. 1297 * 1298 * Sanity check the signature to detect mismatched type errors. 1299 * This could be augmented to pass full type information back with the parameters. 1300 */ 1301 returns = !cint_parameter_void(dt.basetype.fp->params); 1302 fcount = cint_parameter_count(dt.basetype.fp->params) - 1; 1303 if(cint_parameter_void(dt.basetype.fp->params+1)) fcount--; 1304 1305 if(fcount != nargs) { 1306 cint_internal_error(__FILE__, __LINE__, "callback type '%s' was not passed the correct number of arguments (expected %d, received %d)", 1307 fname, fcount, nargs); 1308 va_end(args); 1309 return 0; 1310 } 1311 if((returns) && (nreturn == 0)) { 1312 cint_internal_error(__FILE__, __LINE__, "callback type '%s' returns a value but calling function did not specify one", fname); 1313 va_end(args); 1314 return 0; 1315 } 1316 if((returns == 0) && (nreturn)) { 1317 cint_internal_error(__FILE__, __LINE__, "callback type '%s' does not return a value but calling function expects one", fname); 1318 va_end(args); 1319 return 0; 1320 } 1321 1322 cint_variable_scope_push(fname); 1323 for(i = 0, params = dt.basetype.fp->params+1; params && params->basetype; params++, i++) { 1324 void* addr; 1325 if(cint_parameter_void(params)) { 1326 continue; 1327 } 1328 /* Get the address of this variable */ 1329 addr = va_arg(args, void*); 1330 1331 /* Create a variable of the appropriate type with this address */ 1332 cint_variable_create(&v, 1333 params->name, 1334 params, 1335 CINT_VARIABLE_F_SDATA, 1336 addr); 1337 } 1338 /* Evaluate function body */ 1339 cint_ftrace(dt.basetype.fp->name, 1); 1340 __returnable++; 1341 errno_save = cint_errno; 1342 v = cint_eval_asts(dt.basetype.fp->body.statements); 1343 cint_errno = errno_save; 1344 __returnable--; 1345 cint_ftrace(dt.basetype.fp->name, 0); 1346 1347 /* Return value? */ 1348 if(v && returns) { 1349 void* addr = va_arg(args, void*); 1350 if(addr) { 1351 cint_datatype_t rt; 1352 CINT_MEMSET(&rt, 0, sizeof(rt)); 1353 if (cint_datatype_find(dt.basetype.fp->params->basetype, &rt) != 0) { 1354 cint_internal_error(__FILE__, __LINE__, 1355 "callback return type '%s' was not found", 1356 dt.basetype.fp->params->basetype); 1357 va_end(args); 1358 return 0; 1359 } 1360 1361 if (cint_type_check(&rt, &v->dt)) { 1362 CINT_MEMCPY(addr, v->data, v->size); 1363 } else { 1364 /* At least clear out the return value to avoid 1365 valgrind complaints. */ 1366 int size; 1367 1368 size = cint_datatype_size(&rt); 1369 if (size > 0) { 1370 CINT_MEMSET(addr, 0, size); 1371 } 1372 cint_ast_error(dt.basetype.fp->body.statements, 1373 CINT_E_BAD_AST, 1374 "return type mismatch"); 1375 } 1376 } 1377 } 1378 1379 cint_variable_scope_pop(fname); 1380 1381 va_end(args); 1382 1383 return 0; 1384 } 1385 1386 1387 1388 1389 1390 struct { 1391 const char* name; 1392 cint_variable_t* (*handler)(cint_ast_t* ast); 1393 } __ast_handler_table[] = { 1394 1395 #define CINT_AST_LIST_ENTRY(_entry) { #_entry, __cint_eval_ast_##_entry }, 1396 #include "cint_ast_entry.h" 1397 1398 { NULL } 1399 }; 1400 1401 cint_variable_t* 1402 cint_eval_ast(cint_ast_t* ast) 1403 { 1404 cint_variable_t* rv = NULL; 1405 cint_ast_type_t type; 1406 1407 cint_atrace(ast); 1408 1409 if(ast == NULL) { 1410 return NULL; 1411 } 1412 1413 type = ast->ntype; 1414 1415 if(type < 0 || type >= cintAstLast) { 1416 return NULL; 1417 } 1418 1419 CINT_DTRACE(("AST: %s", __ast_handler_table[type].name)); 1420 if(ast->noexec) { 1421 CINT_DTRACE((" marked as noexec\n")); 1422 } 1423 else { 1424 rv = __ast_handler_table[type].handler(ast); 1425 } 1426 return rv; 1427 } 1428 1429 cint_variable_t* 1430 cint_eval_asts(cint_ast_t* ast) 1431 { 1432 cint_variable_t* rv = NULL; 1433 cint_ast_t* p; 1434 1435 cint_errno = CINT_E_NONE; 1436 1437 for(p = ast; p && (cint_errno == CINT_E_NONE); p = p->next) { 1438 rv = cint_eval_ast(p); 1439 } 1440 cint_variable_auto_save(rv); 1441 cint_variable_auto_clear(); 1442 return rv; 1443 }