1 3 package org.python.compiler; 4 5 import java.io.*; 6 import java.util.Vector ; 7 8 class ExceptionLabel 9 { 10 public Label start, end, handler; 11 public int exc; 12 13 public ExceptionLabel(Label start, Label end, Label handler, int exc) { 14 this.start = start; 15 this.end = end; 16 this.handler = handler; 17 this.exc = exc; 18 } 19 } 20 21 22 public class Code extends Attribute 23 { 24 ConstantPool pool; 25 public int stack; 26 int max_stack; 27 public DataOutputStream code; 28 ByteArrayOutputStream stream; 29 String sig; 30 String locals[]; 31 int nlocals; 32 int argcount; 33 int att_name; 34 Vector labels, exceptions; 35 LineNumberTable linenumbers; 36 int returnLocal; 37 38 public Label getLabel() { 39 Label l = new Label(this); 40 addLabel(l); 41 return l; 42 } 43 44 public void addLabel(Label l) { 45 labels.addElement(l); 46 } 47 48 public int size() { 49 return stream.size(); 50 } 51 52 public Code(String sig, ConstantPool pool, boolean isStatic) { 53 this.sig = sig; 54 max_stack = 2; 55 stack = 0; 56 this.pool = pool; 57 stream = new ByteArrayOutputStream(); 58 code = new DataOutputStream(stream); 59 nlocals = -ConstantPool.sigSize(sig, false); 60 if (!isStatic) nlocals = nlocals+1; 61 argcount = nlocals; 62 locals = new String [nlocals+128]; 63 labels = new Vector (); 64 exceptions = new Vector (); 65 try { 66 att_name = pool.UTF8("Code"); 67 } catch (IOException e) { 68 att_name=0; 69 } 70 } 71 72 public int getLocal(String type) { 73 for(int l = argcount; l<nlocals; l++) { 75 if (locals[l] == null) { 76 locals[l] = type; 77 return l; 78 } 79 } 80 if (nlocals >= locals.length) { 81 String [] new_locals = new String [locals.length*2]; 82 System.arraycopy(locals, 0, new_locals, 0, locals.length); 83 locals = new_locals; 84 } 85 locals[nlocals] = type; 86 nlocals += 1; 87 return nlocals-1; 88 } 89 90 public void freeLocal(int l) { 91 if (locals[l] == null) 92 System.out.println("Double free:" + l); 93 locals[l] = null; 94 } 95 96 97 java.util.BitSet finallyLocals = new java.util.BitSet (); 98 99 public int getFinallyLocal(String type) { 100 int l = getLocal(type); 101 finallyLocals.set(l); 102 return l; 103 } 104 105 public void freeFinallyLocal(int l) { 106 finallyLocals.clear(l); 107 freeLocal(l); 108 } 109 110 public int getReturnLocal() { 111 if (returnLocal == 0) 112 returnLocal = getLocal("return"); 113 return returnLocal; 114 } 115 116 public Vector getActiveLocals() { 117 Vector ret = new Vector (); 118 ret.setSize(nlocals); 119 for (int l = argcount; l<nlocals; l++) { 120 if (l == returnLocal || finallyLocals.get(l)) 121 continue; 122 ret.setElementAt(locals[l], l); 123 } 124 return ret; 125 } 126 127 public void addExceptionHandler(Label begin, Label end, 128 Label handler, int exc) 129 { 130 exceptions.addElement(new ExceptionLabel(begin, end, handler, exc)); 131 } 132 133 150 151 public void fixLabels(byte[] bytes) throws IOException { 152 for(int i=0; i<labels.size(); i++) { 153 ((Label)labels.elementAt(i)).fix(bytes); 154 } 155 } 156 157 public void write(DataOutputStream stream) throws IOException { 158 byte[] bytes = this.stream.toByteArray(); 159 160 fixLabels(bytes); 161 162 int n = exceptions.size(); 163 int length = bytes.length+12+8*n;; 164 if (linenumbers != null) 165 length += linenumbers.length(); 166 stream.writeShort(att_name); 167 stream.writeInt(length); 168 stream.writeShort(max_stack); 169 stream.writeShort(nlocals); 170 stream.writeInt(bytes.length); 171 stream.write(bytes); 172 173 stream.writeShort(n); 175 for(int i=0; i<n; i++) { 176 ExceptionLabel e = (ExceptionLabel)exceptions.elementAt(i); 177 stream.writeShort(e.start.getPosition()); 178 stream.writeShort(e.end.getPosition()); 179 stream.writeShort(e.handler.getPosition()); 180 stream.writeShort(e.exc); 181 } 182 if (linenumbers != null) 183 ClassFile.writeAttributes(stream, 184 new Attribute[] { linenumbers }); 185 else 186 ClassFile.writeAttributes(stream, new Attribute[0]); 187 } 188 189 public void push(int i) { 190 stack = stack+i; 192 if (stack > max_stack) max_stack = stack; 193 if (stack < 0) 194 throw new InternalError ("stack < 0: "+stack); 195 } 196 197 public void branch(int b, Label label) throws IOException { 198 int offset = size(); 199 code.writeByte(b); 200 label.setBranch(offset, 2); 201 label.setStack(stack); 202 } 203 204 public void print(String s) throws IOException { 205 getstatic("java/lang/System", "out", "Ljava/io/PrintStream;"); 206 ldc(s); 207 invokevirtual("java/io/PrintStream", "println", 208 "(Ljava/lang/String;)V"); 209 } 210 211 212 public void aaload() throws IOException { 213 code.writeByte(50); 214 push(-1); 215 } 216 217 public void aastore() throws IOException { 218 code.writeByte(83); 219 push(-3); 220 } 221 222 public void aconst_null() throws IOException { 223 code.writeByte(1); 224 push(1); 225 } 226 227 public void aload(int i) throws IOException { 228 if (i >= 0 && i < 4) { 229 code.writeByte(42+i); 230 } else { 231 code.writeByte(25); 232 code.writeByte(i); 233 } 234 push(1); 235 } 236 237 public void anewarray(int c) throws IOException { 238 code.writeByte(189); 239 code.writeShort(c); 240 } 242 243 public void areturn() throws IOException { 244 code.writeByte(176); 245 push(-1); 246 } 247 248 public void arraylength() throws IOException { 249 code.writeByte(190); 250 } 252 253 public void astore(int i) throws IOException { 254 if (i >= 0 && i < 4) { 255 code.writeByte(75+i); 256 } else { 257 code.writeByte(58); 258 code.writeByte(i); 259 } 260 push(-1); 261 } 262 263 public void athrow() throws IOException { 264 code.writeByte(191); 265 push(-1); 266 } 267 268 public void checkcast(int c) throws IOException { 269 code.writeByte(192); 270 code.writeShort(c); 271 } 272 273 public void dload(int i) throws IOException { 274 if (i >= 0 && i < 4) { 275 code.writeByte(38+i); 276 } else { 277 code.writeByte(24); 278 code.writeByte(i); 279 } 280 push(2); 281 } 282 283 public void dreturn() throws IOException { 284 code.writeByte(175); 285 push(-2); 286 } 287 288 public void dup() throws IOException { 289 code.writeByte(89); 290 push(1); 291 } 292 293 public void dup_x1() throws IOException { 294 code.writeByte(90); 295 push(1); 296 } 297 298 public void fload(int i) throws IOException { 299 if (i >= 0 && i < 4) { 300 code.writeByte(34+i); 301 } else { 302 code.writeByte(23); 303 code.writeByte(i); 304 } 305 push(1); 306 } 307 308 public void freturn() throws IOException { 309 code.writeByte(174); 310 push(-1); 311 } 312 313 public void getfield(int c) throws IOException { 314 code.writeByte(180); 315 code.writeShort(c); 316 push(pool.sizes[c]-1); 317 } 318 319 public void getfield(String c, String name, String type) 320 throws IOException 321 { 322 getfield(pool.Fieldref(c, name, type)); 323 } 324 325 public void getstatic(int c) throws IOException { 326 code.writeByte(178); 327 code.writeShort(c); 328 push(pool.sizes[c]); 329 } 330 331 public void getstatic(String c, String name, String type) 332 throws IOException 333 { 334 getstatic(pool.Fieldref(c, name, type)); 335 } 336 337 public void goto_(Label label) throws IOException { 338 branch(167, label); 339 } 340 341 public void iconst(int i) throws IOException { 342 if (i >= -1 && i <= 5) { 343 code.writeByte(3+i); 344 } else { 345 if (i > -127 && i < 128) { 346 code.writeByte(16); 347 if (i < 0) i = 256+i; 348 code.writeByte(i); 349 } else { 350 if (i > -32767 && i < 32768) { 351 code.writeByte(17); 352 if (i < 0) i = i+65536; 353 code.writeShort(i); 354 } else { 355 ldc(pool.Integer(i)); 356 } 357 } 358 } 359 push(1); 360 } 361 362 public void if_icmpne(Label label) throws IOException { 363 push(-2); 364 branch(160, label); 365 } 366 367 public void ifeq(Label label) throws IOException { 368 push(-1); 369 branch(153, label); 370 } 371 372 public void ifne(Label label) throws IOException { 373 push(-1); 374 branch(154, label); 375 } 376 377 public void ifnonnull(Label label) throws IOException { 378 push(-1); 379 branch(199, label); 380 } 381 382 public void ifnull(Label label) throws IOException { 383 push(-1); 384 branch(198, label); 385 } 386 387 public void iinc(int i, int increment) throws IOException { 388 code.writeByte(132); 389 code.writeByte(i); 390 code.writeByte(increment); 391 } 392 393 public void iinc(int i) throws IOException { 394 iinc(i, 1); 395 } 396 397 public void iload(int i) throws IOException { 398 if (i >= 0 && i < 4) { 399 code.writeByte(26+i); 400 } else { 401 code.writeByte(21); 402 code.writeByte(i); 403 } 404 push(1); 405 } 406 407 public void invokespecial(int c) throws IOException { 408 code.writeByte(183); 409 code.writeShort(c); 410 push(pool.sizes[c]-1); 411 } 412 413 public void invokestatic(int c) throws IOException { 414 code.writeByte(184); 415 code.writeShort(c); 416 push(pool.sizes[c]); 417 } 418 419 public void invokevirtual(int c) throws IOException { 420 code.writeByte(182); 421 code.writeShort(c); 422 push(pool.sizes[c]-1); 423 } 424 425 public void invokevirtual(String c, String name, String type) 426 throws IOException 427 { 428 invokevirtual(pool.Methodref(c, name, type)); 429 } 430 431 public void ireturn() throws IOException { 432 code.writeByte(172); 433 push(-1); 434 } 435 436 public void istore(int i) throws IOException { 437 if (i >= 0 && i < 4) { 438 code.writeByte(59+i); 439 } else { 440 code.writeByte(54); 441 code.writeByte(i); 442 } 443 push(-1); 444 } 445 446 public void jsr(Label label) throws IOException { 447 int offset = size(); 449 code.writeByte(168); 450 label.setBranch(offset, 2); 451 label.setStack(stack+1); 452 } 453 454 public void ldc(int c) throws IOException { 455 int size = pool.sizes[c]; 456 if (size == 1) { 457 if (c < 256) { 458 code.writeByte(18); 459 code.writeByte(c); 460 } else { 461 code.writeByte(19); 462 code.writeShort(c); 463 } 464 } else { 465 code.writeByte(20); 466 code.writeShort(c); 467 } 468 469 push(pool.sizes[c]); 470 } 471 472 public void ldc(String s) throws IOException { 473 ldc(pool.String(s)); 474 } 475 476 public void lload(int i) throws IOException { 477 if (i >= 0 && i < 4) { 478 code.writeByte(30+i); 479 } else { 480 code.writeByte(22); 481 code.writeByte(i); 482 } 483 push(2); 484 } 485 486 public void lreturn() throws IOException { 487 code.writeByte(173); 488 push(-2); 489 } 490 491 public void new_(int c) throws IOException { 492 code.writeByte(187); 493 code.writeShort(c); 494 push(1); 495 } 496 497 public void pop() throws IOException { 498 code.writeByte(87); 499 push(-1); 500 } 501 502 public void putfield(int c) throws IOException { 503 code.writeByte(181); 504 code.writeShort(c); 505 push(-pool.sizes[c]-1); 506 } 507 508 public void putfield(String c, String name, String type) 509 throws IOException 510 { 511 putfield(pool.Fieldref(c, name, type)); 512 } 513 514 public void putstatic(int c) throws IOException { 515 code.writeByte(179); 516 code.writeShort(c); 517 push(-pool.sizes[c]); 518 } 519 520 public void putstatic(String c, String name, String type) 521 throws IOException 522 { 523 putstatic(pool.Fieldref(c, name, type)); 524 } 525 526 public void return_() throws IOException { 527 code.writeByte(177); 528 } 529 530 public void ret(int index) throws IOException { 531 code.writeByte(169); 532 code.writeByte(index); 533 } 534 535 public void swap() throws IOException { 536 code.writeByte(95); 537 } 538 539 public void tableswitch(Label def, int low, Label[] labels) 540 throws IOException 541 { 542 int position = size(); 543 push(-1); 544 code.writeByte(170); 545 for(int j=0; j < 3-(position%4); j++) code.writeByte(0); 546 def.setBranch(position, 4); 547 code.writeInt(low); 548 code.writeInt(labels.length-1); 549 for(int i=0; i<labels.length; i++) { 550 labels[i].setBranch(position, 4); 551 } 552 } 553 554 public void setline(int line) throws IOException { 555 if (linenumbers == null) 556 linenumbers = new LineNumberTable(pool); 557 linenumbers.addLine(size(), line); 558 } 559 } 560 | Popular Tags |