Changeset 214
- Timestamp:
- 10/14/09 22:36:24 (2 years ago)
- Files:
-
- branches/dmd-1.x/src/func.c (modified) (2 diffs)
- branches/dmd-1.x/src/mars.c (modified) (1 diff)
- trunk/src/func.c (modified) (2 diffs)
- trunk/src/json.c (modified) (3 diffs)
- trunk/src/mars.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/dmd-1.x/src/func.c
r202 r214 1504 1504 /* Implementing this is done by having the overriding function call 1505 1505 * nested functions (the fdrequire functions) nested inside the overridden 1506 1506 * function. This requires that the stack layout of the calling function's 1507 1507 * parameters and 'this' pointer be in the same place (as the nested 1508 1508 * function refers to them). 1509 1509 * This is easy for the parameters, as they are all on the stack in the same 1510 1510 * place by definition, since it's an overriding function. The problem is 1511 1511 * getting the 'this' pointer in the same place, since it is a local variable. 1512 1512 * We did some hacks in the code generator to make this happen: 1513 1513 * 1. always generate exception handler frame, or at least leave space for it 1514 1514 * in the frame (Windows 32 SEH only) 1515 1515 * 2. always generate an EBP style frame 1516 1516 * 3. since 'this' is passed in a register that is subsequently copied into 1517 1517 * a stack local, allocate that local immediately following the exception 1518 1518 * handler block, so it is always at the same offset from EBP. 1519 1519 */ 1520 1520 for (int i = 0; i < foverrides.dim; i++) 1521 1521 { 1522 1522 FuncDeclaration *fdv = (FuncDeclaration *)foverrides.data[i]; 1523 1523 sf = fdv->mergeFrequire(sf); 1524 if (fdv->f require)1524 if (fdv->fdrequire) 1525 1525 { 1526 1526 //printf("fdv->frequire: %s\n", fdv->frequire->toChars()); 1527 1527 /* Make the call: 1528 1528 * try { __require(); } 1529 1529 * catch { frequire; } 1530 1530 */ 1531 1531 Expression *eresult = NULL; 1532 1532 Expression *e = new CallExp(loc, new VarExp(loc, fdv->fdrequire), eresult); 1533 1533 Statement *s2 = new ExpStatement(loc, e); 1534 1534 1535 1535 if (sf) 1536 1536 { Catch *c = new Catch(loc, NULL, NULL, sf); 1537 1537 Array *catches = new Array(); 1538 1538 catches->push(c); 1539 1539 sf = new TryCatchStatement(loc, s2, catches); 1540 1540 } 1541 1541 else 1542 1542 sf = s2; 1543 1543 } 1544 1544 } … … 1548 1548 /**************************************************** 1549 1549 * Merge into this function the 'out' contracts of all it overrides. 1550 1550 * 'out's are AND'd together, i.e. all of them need to pass. 1551 1551 */ 1552 1552 1553 1553 Statement *FuncDeclaration::mergeFensure(Statement *sf) 1554 1554 { 1555 1555 /* Same comments as for mergeFrequire(), except that we take care 1556 1556 * of generating a consistent reference to the 'result' local by 1557 1557 * explicitly passing 'result' to the nested function as a reference 1558 1558 * argument. 1559 1559 * This won't work for the 'this' parameter as it would require changing 1560 1560 * the semantic code for the nested function so that it looks on the parameter 1561 1561 * list for the 'this' pointer, something that would need an unknown amount 1562 1562 * of tweaking of various parts of the compiler that I'd rather leave alone. 1563 1563 */ 1564 1564 for (int i = 0; i < foverrides.dim; i++) 1565 1565 { 1566 1566 FuncDeclaration *fdv = (FuncDeclaration *)foverrides.data[i]; 1567 1567 sf = fdv->mergeFensure(sf); 1568 if (fdv->f ensure)1568 if (fdv->fdensure) 1569 1569 { 1570 1570 //printf("fdv->fensure: %s\n", fdv->fensure->toChars()); 1571 1571 // Make the call: __ensure(result) 1572 1572 Expression *eresult = NULL; 1573 1573 if (outId) 1574 1574 eresult = new IdentifierExp(loc, outId); 1575 1575 Expression *e = new CallExp(loc, new VarExp(loc, fdv->fdensure), eresult); 1576 1576 Statement *s2 = new ExpStatement(loc, e); 1577 1577 1578 1578 if (sf) 1579 1579 { 1580 1580 sf = new CompoundStatement(fensure->loc, s2, sf); 1581 1581 } 1582 1582 else 1583 1583 sf = s2; 1584 1584 } 1585 1585 } 1586 1586 return sf; 1587 1587 } 1588 1588 branches/dmd-1.x/src/mars.c
r205 r214 63 63 #elif TARGET_NET 64 64 #else 65 65 #error "fix this" 66 66 #endif 67 67 68 68 #if TARGET_WINDOS 69 69 lib_ext = "lib"; 70 70 #elif TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 71 71 lib_ext = "a"; 72 72 #elif TARGET_NET 73 73 #else 74 74 #error "fix this" 75 75 #endif 76 76 77 77 copyright = "Copyright (c) 1999-2009 by Digital Mars"; 78 78 written = "written by Walter Bright" 79 79 #if TARGET_NET 80 80 "\nMSIL back-end (alpha release) by Cristian L. Vlasceanu and associates."; 81 81 #endif 82 82 ; 83 version = "v1.05 0";83 version = "v1.051"; 84 84 global.structalign = 8; 85 85 86 86 memset(¶ms, 0, sizeof(Param)); 87 87 } 88 88 89 89 char *Loc::toChars() 90 90 { 91 91 OutBuffer buf; 92 92 char *p; 93 93 94 94 if (filename) 95 95 { 96 96 buf.printf("%s", filename); 97 97 } 98 98 99 99 if (linnum) 100 100 buf.printf("(%d)", linnum); 101 101 buf.writeByte(0); 102 102 return (char *)buf.extractData(); 103 103 } trunk/src/func.c
r202 r214 1533 1533 /* Implementing this is done by having the overriding function call 1534 1534 * nested functions (the fdrequire functions) nested inside the overridden 1535 1535 * function. This requires that the stack layout of the calling function's 1536 1536 * parameters and 'this' pointer be in the same place (as the nested 1537 1537 * function refers to them). 1538 1538 * This is easy for the parameters, as they are all on the stack in the same 1539 1539 * place by definition, since it's an overriding function. The problem is 1540 1540 * getting the 'this' pointer in the same place, since it is a local variable. 1541 1541 * We did some hacks in the code generator to make this happen: 1542 1542 * 1. always generate exception handler frame, or at least leave space for it 1543 1543 * in the frame (Windows 32 SEH only) 1544 1544 * 2. always generate an EBP style frame 1545 1545 * 3. since 'this' is passed in a register that is subsequently copied into 1546 1546 * a stack local, allocate that local immediately following the exception 1547 1547 * handler block, so it is always at the same offset from EBP. 1548 1548 */ 1549 1549 for (int i = 0; i < foverrides.dim; i++) 1550 1550 { 1551 1551 FuncDeclaration *fdv = (FuncDeclaration *)foverrides.data[i]; 1552 1552 sf = fdv->mergeFrequire(sf); 1553 if (fdv->f require)1553 if (fdv->fdrequire) 1554 1554 { 1555 1555 //printf("fdv->frequire: %s\n", fdv->frequire->toChars()); 1556 1556 /* Make the call: 1557 1557 * try { __require(); } 1558 1558 * catch { frequire; } 1559 1559 */ 1560 1560 Expression *eresult = NULL; 1561 1561 Expression *e = new CallExp(loc, new VarExp(loc, fdv->fdrequire, 0), eresult); 1562 1562 Statement *s2 = new ExpStatement(loc, e); 1563 1563 1564 1564 if (sf) 1565 1565 { Catch *c = new Catch(loc, NULL, NULL, sf); 1566 1566 Array *catches = new Array(); 1567 1567 catches->push(c); 1568 1568 sf = new TryCatchStatement(loc, s2, catches); 1569 1569 } 1570 1570 else 1571 1571 sf = s2; 1572 1572 } 1573 1573 } … … 1577 1577 /**************************************************** 1578 1578 * Merge into this function the 'out' contracts of all it overrides. 1579 1579 * 'out's are AND'd together, i.e. all of them need to pass. 1580 1580 */ 1581 1581 1582 1582 Statement *FuncDeclaration::mergeFensure(Statement *sf) 1583 1583 { 1584 1584 /* Same comments as for mergeFrequire(), except that we take care 1585 1585 * of generating a consistent reference to the 'result' local by 1586 1586 * explicitly passing 'result' to the nested function as a reference 1587 1587 * argument. 1588 1588 * This won't work for the 'this' parameter as it would require changing 1589 1589 * the semantic code for the nested function so that it looks on the parameter 1590 1590 * list for the 'this' pointer, something that would need an unknown amount 1591 1591 * of tweaking of various parts of the compiler that I'd rather leave alone. 1592 1592 */ 1593 1593 for (int i = 0; i < foverrides.dim; i++) 1594 1594 { 1595 1595 FuncDeclaration *fdv = (FuncDeclaration *)foverrides.data[i]; 1596 1596 sf = fdv->mergeFensure(sf); 1597 if (fdv->f ensure)1597 if (fdv->fdensure) 1598 1598 { 1599 1599 //printf("fdv->fensure: %s\n", fdv->fensure->toChars()); 1600 1600 // Make the call: __ensure(result) 1601 1601 Expression *eresult = NULL; 1602 1602 if (outId) 1603 1603 eresult = new IdentifierExp(loc, outId); 1604 1604 Expression *e = new CallExp(loc, new VarExp(loc, fdv->fdensure, 0), eresult); 1605 1605 Statement *s2 = new ExpStatement(loc, e); 1606 1606 1607 1607 if (sf) 1608 1608 { 1609 1609 sf = new CompoundStatement(fensure->loc, s2, sf); 1610 1610 } 1611 1611 else 1612 1612 sf = s2; 1613 1613 } 1614 1614 } 1615 1615 return sf; 1616 1616 } 1617 1617 trunk/src/json.c
r204 r214 154 154 buf->printf("%d", value); 155 155 buf->writestring(",\n"); 156 156 } 157 157 158 158 void JsonRemoveComma(OutBuffer *buf) 159 159 { 160 160 if (buf->offset >= 2 && 161 161 buf->data[buf->offset - 2] == ',' && 162 162 buf->data[buf->offset - 1] == '\n') 163 163 buf->offset -= 2; 164 164 } 165 165 166 166 void Dsymbol::toJsonBuffer(OutBuffer *buf) 167 167 { 168 168 } 169 169 170 170 void Module::toJsonBuffer(OutBuffer *buf) 171 171 { 172 172 buf->writestring("{\n"); 173 173 174 JsonProperty(buf, Pname, md->toChars()); 174 if (md) 175 JsonProperty(buf, Pname, md->toChars()); 175 176 176 177 JsonProperty(buf, Pkind, kind()); 177 178 178 179 JsonProperty(buf, Pfile, srcfile->toChars()); 179 180 180 181 if (comment) 181 182 JsonProperty(buf, Pcomment, (const char *)comment); 182 183 183 184 JsonString(buf, Pmembers); 184 185 buf->writestring(" : [\n"); 185 186 186 187 size_t offset = buf->offset; 187 188 for (int i = 0; i < members->dim; i++) 188 189 { Dsymbol *s = (Dsymbol *)members->data[i]; 189 190 if (offset != buf->offset) 190 { buf->writestring(", ");191 { buf->writestring(",\n"); 191 192 offset = buf->offset; 192 193 } 193 194 s->toJsonBuffer(buf); 194 195 } 195 196 197 JsonRemoveComma(buf); 196 198 buf->writestring("]\n"); 197 199 198 200 buf->writestring("}\n"); 199 201 } 200 202 201 203 void AttribDeclaration::toJsonBuffer(OutBuffer *buf) 202 204 { 203 205 //printf("AttribDeclaration::toJsonBuffer()\n"); 204 206 205 207 Array *d = include(NULL, NULL); 206 208 207 209 if (d) 208 210 { 209 211 for (unsigned i = 0; i < d->dim; i++) 210 212 { Dsymbol *s = (Dsymbol *)d->data[i]; 211 213 //printf("AttribDeclaration::toJsonBuffer %s\n", s->toChars()); 212 214 s->toJsonBuffer(buf); 213 215 } 214 216 } 215 217 } … … 272 274 if (comment) 273 275 JsonProperty(buf, Pcomment, (const char *)comment); 274 276 if (loc.linnum) 275 277 JsonProperty(buf, Pline, loc.linnum); 276 278 277 279 ClassDeclaration *cd = isClassDeclaration(); 278 280 if (cd) 279 281 { 280 282 if (cd->baseClass) 281 283 { 282 284 JsonProperty(buf, "base", cd->baseClass->toChars()); 283 285 } 284 286 if (cd->interfaces_dim) 285 287 { 286 288 JsonString(buf, "interfaces"); 287 289 buf->writestring(" : [\n"); 288 290 size_t offset = buf->offset; 289 291 for (int i = 0; i < cd->interfaces_dim; i++) 290 292 { BaseClass *b = cd->interfaces[i]; 291 293 if (offset != buf->offset) 292 { buf->writestring(", ");294 { buf->writestring(",\n"); 293 295 offset = buf->offset; 294 296 } 295 297 JsonString(buf, b->base->toChars()); 296 298 } 299 JsonRemoveComma(buf); 297 300 buf->writestring("],\n"); 298 301 } 299 302 } 300 303 301 304 JsonString(buf, Pmembers); 302 305 buf->writestring(" : [\n"); 303 306 size_t offset = buf->offset; 304 307 for (int i = 0; i < members->dim; i++) 305 308 { Dsymbol *s = (Dsymbol *)members->data[i]; 306 309 if (offset != buf->offset) 307 { buf->writestring(", ");310 { buf->writestring(",\n"); 308 311 offset = buf->offset; 309 312 } 310 313 s->toJsonBuffer(buf); 311 314 } 315 JsonRemoveComma(buf); 312 316 buf->writestring("]\n"); 313 317 314 318 buf->writestring("}\n"); 315 319 } 316 320 317 321 void TemplateDeclaration::toJsonBuffer(OutBuffer *buf) 318 322 { 319 323 //printf("TemplateDeclaration::toJsonBuffer()\n"); 320 324 321 325 buf->writestring("{\n"); 322 326 323 327 JsonProperty(buf, Pname, toChars()); 324 328 JsonProperty(buf, Pkind, kind()); 325 329 if (comment) 326 330 JsonProperty(buf, Pcomment, (const char *)comment); 327 331 328 332 if (loc.linnum) 329 333 JsonProperty(buf, Pline, loc.linnum); 330 334 331 335 JsonString(buf, Pmembers); 332 336 buf->writestring(" : [\n"); 333 337 size_t offset = buf->offset; 334 338 for (int i = 0; i < members->dim; i++) 335 339 { Dsymbol *s = (Dsymbol *)members->data[i]; 336 340 if (offset != buf->offset) 337 { buf->writestring(", ");341 { buf->writestring(",\n"); 338 342 offset = buf->offset; 339 343 } 340 344 s->toJsonBuffer(buf); 341 345 } 346 JsonRemoveComma(buf); 342 347 buf->writestring("]\n"); 343 348 344 349 buf->writestring("}\n"); 345 350 } 346 351 347 352 void EnumDeclaration::toJsonBuffer(OutBuffer *buf) 348 353 { 349 354 //printf("EnumDeclaration::toJsonBuffer()\n"); 350 355 if (isAnonymous()) 351 356 { 352 357 if (members) 353 358 { 354 359 for (int i = 0; i < members->dim; i++) 355 360 { 356 361 Dsymbol *s = (Dsymbol *)members->data[i]; 357 362 s->toJsonBuffer(buf); 358 363 buf->writestring(",\n"); 359 364 } 360 365 JsonRemoveComma(buf); 361 366 } … … 364 369 365 370 buf->writestring("{\n"); 366 371 367 372 JsonProperty(buf, Pname, toChars()); 368 373 JsonProperty(buf, Pkind, kind()); 369 374 if (comment) 370 375 JsonProperty(buf, Pcomment, (const char *)comment); 371 376 372 377 if (loc.linnum) 373 378 JsonProperty(buf, Pline, loc.linnum); 374 379 375 380 if (memtype) 376 381 JsonProperty(buf, "base", memtype->toChars()); 377 382 378 383 JsonString(buf, Pmembers); 379 384 buf->writestring(" : [\n"); 380 385 size_t offset = buf->offset; 381 386 for (int i = 0; i < members->dim; i++) 382 387 { Dsymbol *s = (Dsymbol *)members->data[i]; 383 388 if (offset != buf->offset) 384 { buf->writestring(", ");389 { buf->writestring(",\n"); 385 390 offset = buf->offset; 386 391 } 387 392 s->toJsonBuffer(buf); 388 393 } 394 JsonRemoveComma(buf); 389 395 buf->writestring("]\n"); 390 396 391 397 buf->writestring("}\n"); 392 398 } 393 399 394 400 void EnumMember::toJsonBuffer(OutBuffer *buf) 395 401 { 396 402 //printf("EnumMember::toJsonBuffer()\n"); 397 403 buf->writestring("{\n"); 398 404 399 405 JsonProperty(buf, Pname, toChars()); 400 406 JsonProperty(buf, Pkind, kind()); 401 407 402 408 if (comment) 403 409 JsonProperty(buf, Pcomment, (const char *)comment); 404 410 405 411 if (loc.linnum) 406 412 JsonProperty(buf, Pline, loc.linnum); 407 413 408 414 JsonRemoveComma(buf); trunk/src/mars.c
r208 r214 63 63 #elif TARGET_NET 64 64 #else 65 65 #error "fix this" 66 66 #endif 67 67 68 68 #if TARGET_WINDOS 69 69 lib_ext = "lib"; 70 70 #elif TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 71 71 lib_ext = "a"; 72 72 #elif TARGET_NET 73 73 #else 74 74 #error "fix this" 75 75 #endif 76 76 77 77 copyright = "Copyright (c) 1999-2009 by Digital Mars"; 78 78 written = "written by Walter Bright" 79 79 #if TARGET_NET 80 80 "\nMSIL back-end (alpha release) by Cristian L. Vlasceanu and associates."; 81 81 #endif 82 82 ; 83 version = "v2.03 5";83 version = "v2.036"; 84 84 global.structalign = 8; 85 85 86 86 memset(¶ms, 0, sizeof(Param)); 87 87 } 88 88 89 89 char *Loc::toChars() 90 90 { 91 91 OutBuffer buf; 92 92 char *p; 93 93 94 94 if (filename) 95 95 { 96 96 buf.printf("%s", filename); 97 97 } 98 98 99 99 if (linnum) 100 100 buf.printf("(%d)", linnum); 101 101 buf.writeByte(0); 102 102 return (char *)buf.extractData(); 103 103 }
