1 48 49 package org.openlaszlo.iv.flash.api.action; 50 51 import java.util.*; 52 53 import org.openlaszlo.iv.flash.util.*; 54 import org.openlaszlo.iv.flash.parser.*; 55 import org.openlaszlo.iv.flash.api.*; 56 import org.openlaszlo.iv.flash.context.Context; 57 58 65 public class ASAssembler { 66 67 private HashMap pool = new HashMap(); 68 private HashMap labels = new HashMap(); 69 private IVVector forward_refs = new IVVector(); 70 private IVVector delayed_stack = new IVVector(); 71 private Program p = new Program(); 72 private Stack funcs = new Stack(); 73 74 81 public ASAssembler( FlashFile file ) { 82 if( file.getVersion() < 5 ) { 83 Log.logRB(Resource.ASASMREQFLASH5); 84 } 85 } 86 87 92 public Program toProgram() { 93 flush_stack(); 94 Program prog = new Program(); 95 writePool(prog); 96 prog.body().writeFOB(p.body()); 97 return prog; 98 } 99 100 103 public void nextFrame() { 104 flush_stack(); 105 p.nextFrame(); 106 } 107 108 111 public void prevFrame() { 112 flush_stack(); 113 p.prevFrame(); 114 } 115 116 119 public void play() { 120 flush_stack(); 121 p.play(); 122 } 123 124 128 public void stop() { 129 flush_stack(); 130 p.stop(); 131 } 132 133 136 public void toggleQuality() { 137 flush_stack(); 138 p.toggleQuality(); 139 } 140 141 144 public void stopSounds() { 145 flush_stack(); 146 p.stopSounds(); 147 } 148 149 public void trace() { 150 flush_stack(); 151 p.body().writeByte(Actions.Trace); 152 } 153 154 163 public void add() { 164 flush_stack(); 165 p.body().writeByte(Actions.Add2); 166 } 167 168 179 public void subtract() { 180 flush_stack(); 181 p.subtract(); 182 } 183 184 195 public void multiply() { 196 flush_stack(); 197 p.multiply(); 198 } 199 200 214 public void divide() { 215 flush_stack(); 216 p.divide(); 217 } 218 219 229 public void equal() { 230 flush_stack(); 231 p.body().writeByte( Actions.Equals2 ); 232 } 233 234 244 public void less() { 245 flush_stack(); 246 p.body().writeByte( Actions.Less2 ); 247 } 248 249 262 public void logicalAnd() { 263 flush_stack(); 264 p.logicalAnd(); 265 } 266 267 280 public void logicalOr() { 281 flush_stack(); 282 p.logicalOr(); 283 } 284 285 304 public void logicalNot() { 305 flush_stack(); 306 p.logicalNot(); 307 } 308 309 323 public void stringEqual() { 324 flush_stack(); 325 p.stringEqual(); 326 } 327 328 337 public void stringLength() { 338 flush_stack(); 339 p.stringLength(); 340 } 341 342 355 public void stringLessThan() { 356 flush_stack(); 357 p.stringLessThan(); 358 } 359 360 374 public void subString() { 375 flush_stack(); 376 p.subString(); 377 } 378 379 389 public void addString() { 390 flush_stack(); 391 p.addString(); 392 } 393 394 405 public void mbLength() { 406 flush_stack(); 407 p.mbLength(); 408 } 409 410 423 public void mbChr() { 424 flush_stack(); 425 p.mbChr(); 426 } 427 428 441 public void mbOrd() { 442 flush_stack(); 443 p.mbOrd(); 444 } 445 446 462 public void mbSubString() { 463 flush_stack(); 464 p.mbSubString(); 465 } 466 467 478 public void toInt() { 479 flush_stack(); 480 p.toInt(); 481 } 482 483 493 public void ord() { 494 flush_stack(); 495 p.ord(); 496 } 497 498 508 public void chr() { 509 flush_stack(); 510 p.chr(); 511 } 512 513 524 public void getProperty() { 525 flush_stack(); 526 p.getProperty(); 527 } 528 529 535 public void getProperty( String target, int property ) { 536 push(target); 537 push(property); 538 getProperty(); 539 } 540 541 553 public void setProperty() { 554 flush_stack(); 555 p.setProperty(); 556 } 557 558 565 public void setProperty( String target, int property, Object value ) { 566 push(target); 567 push(property); 568 push(value); 569 setProperty(); 570 } 571 572 584 public void duplicateClip() { 585 flush_stack(); 586 p.cloneClip(); 587 } 588 589 596 public void duplicateClip( String source, String target, int depth ) { 597 push(depth+16384); 598 push(target); 599 push(source); 600 duplicateClip(); 601 } 602 603 612 public void removeClip() { 613 flush_stack(); 614 p.removeClip(); 615 } 616 617 622 public void removeClip( String target ) { 623 push(target); 624 removeClip(); 625 } 626 627 647 public void startDrag() { 648 flush_stack(); 649 p.startDrag(); 650 } 651 652 660 public void endDrag() { 661 flush_stack(); 662 p.endDrag(); 663 } 664 665 675 public void random() { 676 flush_stack(); 677 p.random(); 678 } 679 680 685 public void random( int maximum ) { 686 push(maximum); 687 random(); 688 } 689 690 699 public void getTimer() { 700 flush_stack(); 701 p.getTimer(); 702 } 703 704 710 public void gotoFrame( int frame ) { 711 flush_stack(); 712 p.gotoFrame(frame); 713 } 714 715 720 public void gotoFrameAndPlay( int frame ) { 721 p.gotoFrame(frame); 722 play(); 723 } 724 725 730 public void gotoFrameAndStop( int frame ) { 731 gotoFrame(frame); 732 stop(); 733 } 734 735 749 public void gotoFrameAndPlay() { 750 flush_stack(); 751 p.gotoFrameAndPlay(); 752 } 753 754 768 public void gotoFrameAndStop() { 769 flush_stack(); 770 p.gotoFrameAndStop(); 771 } 772 773 785 public void getURL( String url, String target ) { 786 flush_stack(); 787 p.getURL(url, target); 788 } 789 790 811 public void getURL( int method ) { 812 flush_stack(); 813 p.getURL(method); 814 } 815 816 827 public void loadMovieNum( String url, int level, int method ) { 828 push(url); 829 push("_level"+level); 830 getURL(method); 831 } 832 833 839 public void loadMovieNum( String url, int level ) { 840 loadMovieNum(url, level, 0); 841 } 842 843 854 public void loadMovie( String url, String target, int method ) { 855 push(url); 856 push(target); 857 getURL(0x40+method); 858 } 859 860 866 public void loadMovie( String url, String target ) { 867 loadMovie(url, target, 0); 868 } 869 870 875 public void unloadMovieNum( int level ) { 876 loadMovieNum(null, level); 877 } 878 879 884 public void unloadMovie( String target ) { 885 loadMovie(null, target); 886 } 887 888 896 public void waitForFrame( int frame, int skip ) { 897 flush_stack(); 898 p.waitForFrame(frame, skip); 899 } 900 901 923 public void setTarget( String target ) { 924 flush_stack(); 925 p.setTarget(target); 926 } 927 928 935 public void gotoFrameLabel( String label ) { 936 flush_stack(); 937 p.gotoLabel(label); 938 } 939 940 944 public void pop() { 945 flush_stack(); 946 p.pop(); 947 } 948 949 966 public void label( String name ) { 967 flush_stack(); 968 labels.put(name, new ASLabel(name, p.getPos())); 969 for( int i=0; i<forward_refs.size(); i++ ) { 970 ASLabel fref = (ASLabel) forward_refs.elementAt(i); 971 if( fref.name.equals(name) ) { 972 int offset = fref.offset; 973 p.body().writeWordAt(p.getPos()-offset-2, offset); 974 } 975 } 976 } 977 978 985 public void jump( String label_name ) { 986 flush_stack(); 987 ASLabel l = (ASLabel) labels.get(label_name); 988 if( l != null ) { 989 int offset = l.offset; 990 p.jump(offset-p.getPos()-5); 991 } else { 992 forward_refs.addElement(new ASLabel(label_name, p.getPos()+3)); 993 p.jump(0); 994 } 995 } 996 997 1004 public void jumpIfTrue( String label_name ) { 1005 flush_stack(); 1006 ASLabel l = (ASLabel) labels.get(label_name); 1007 if( l != null ) { 1008 int offset = l.offset; 1009 p.jumpIfTrue(offset-p.getPos()-5); 1010 } else { 1011 forward_refs.addElement(new ASLabel(label_name, p.getPos()+3)); 1012 p.jumpIfTrue(0); 1013 } 1014 } 1015 1016 1021 public void push( String data ) { 1022 delayed_stack.addElement(getString(data)); 1023 } 1024 1025 1030 public void push( float data ) { 1031 delayed_stack.addElement(new Float (data)); 1032 } 1033 1034 1039 public void push( int data ) { 1040 delayed_stack.addElement(new Integer (data)); 1041 } 1042 1043 1048 public void push( double data ) { 1049 delayed_stack.addElement(new Double (data)); 1050 } 1051 1052 1057 public void push( boolean data ) { 1058 delayed_stack.addElement(new Boolean (data)); 1059 } 1060 1061 1066 public void push( Object data ) { 1067 if( data instanceof String ) push( (String )data ); 1068 else if( data instanceof Expr ) ((Expr)data).eval(this); 1069 else delayed_stack.addElement(data); 1070 } 1071 1072 1084 public void setVar() { 1085 flush_stack(); 1086 p.setVar(); 1087 } 1088 1089 1095 public void setVar(String var1, Object data) { 1096 push(var1); 1097 push(data); 1098 setVar(); 1099 } 1100 1101 1106 public void localVar( String var1 ) { 1107 push(var1); 1108 flush_stack(); 1109 p.body().writeByte(Actions.DefineLocal2); 1110 } 1111 1112 1118 public void localVar( String var1, Object data ) { 1119 push(var1); 1120 push(data); 1121 flush_stack(); 1122 p.body().writeByte(Actions.DefineLocal); 1123 } 1124 1125 1133 public void getVar() { 1134 flush_stack(); 1135 p.eval(); 1136 } 1137 1138 1143 public void getVar( String var1 ) { 1144 push(var1); 1145 flush_stack(); 1146 p.eval(); 1147 } 1148 1149 1155 public void getVars( String var1, String var2 ) { 1156 push(var2); 1157 push(var1); 1158 getVar(); 1159 swap(); 1160 getVar(); 1161 } 1162 1163 1166 public void swap() { 1167 flush_stack(); 1168 p.body().writeByte(Actions.StackSwap); 1169 } 1170 1171 1174 public void dup() { 1175 flush_stack(); 1176 p.body().writeByte(Actions.PushDuplicate); 1177 } 1178 1179 1201 public void setMember( String mem, Object value ) { 1202 IVVector t = parseMember(mem); 1203 if( t.size() == 1 ) { 1204 setVar(mem, value); 1205 } else { 1206 String iname = (String ) t.elementAt(0); 1207 getVar(iname); 1208 int i=1; 1209 for( ; i<t.size()-1; i++ ) { 1210 push(t.elementAt(i)); 1211 flush_stack(); 1212 p.getMember(); 1213 } 1214 push(t.elementAt(i)); 1215 push(value); 1216 flush_stack(); 1217 p.setMember(); 1218 } 1219 } 1220 1221 1227 public void setMember() { 1228 flush_stack(); 1229 p.setMember(); 1230 } 1231 1232 1251 public void getMember( String mem ) { 1252 IVVector t = parseMember(mem); 1253 String iname = (String ) t.elementAt(0); 1254 getVar(iname); 1255 if( t.size() > 1 ) { 1256 int i=1; 1257 for( ; i<t.size(); i++ ) { 1258 push(t.elementAt(i)); 1259 flush_stack(); 1260 p.getMember(); 1261 } 1262 } 1263 } 1264 1265 1278 public void getArrayElement( String array_name, int index ) { 1279 getVar(array_name); 1280 push(index); 1281 getMember(); 1282 } 1283 1284 1301 public void getArrayElement( String array_name, Object index ) { 1302 getVar(array_name); 1303 push(index); 1304 getMember(); 1305 } 1306 1307 1322 public void setArrayElement( String array_name, Object index, Object value ) { 1323 getVar(array_name); 1324 push(index); 1325 push(value); 1326 getMember(); 1327 } 1328 1329 1332 public void newObject() { 1333 flush_stack(); 1334 p.newObject(); 1335 } 1336 1337 1350 public void newObject( String class_name, Object [] args ) { 1351 if( args == null || args.length == 0 ) { 1352 push(0); 1353 } else { 1354 for( int i=0; i<args.length; i++ ) { 1355 push(args[i]); 1356 } 1357 push(args.length); 1358 } 1359 newObject(); 1360 } 1361 1362 public void newObject( String class_name, Object arg ) { 1363 newObject(class_name, new Object [] {arg}); 1364 } 1365 1366 public void newObject( String class_name, int arg ) { 1367 newObject(class_name, new Integer (arg)); 1368 } 1369 1370 public void newObject( String class_name, double arg ) { 1371 newObject(class_name, new Double (arg)); 1372 } 1373 1374 public void newObject( String class_name, boolean arg ) { 1375 newObject(class_name, new Boolean (arg)); 1376 } 1377 1378 1403 public void initObject( String [] props, Object [] values ) { 1404 for( int i=0; i<props.length; i++ ) { 1405 push(props[i]); 1406 push(values[i]); 1407 } 1408 push(props.length); 1409 flush_stack(); 1410 p.body().writeByte(Actions.InitObject); 1411 } 1412 1413 1430 public void callMethod( String method, Object [] args ) { 1431 IVVector t = parseMember(method); 1432 if( t.size() == 1 ) { 1433 callFunction(method, args); 1434 } else { 1435 if( args == null || args.length == 0 ) { 1436 push(0); 1437 } else { 1438 for( int i=0; i<args.length; i++ ) { 1439 push(args[i]); 1440 } 1441 push(args.length); 1442 } 1443 String iname = (String ) t.elementAt(0); 1444 getVar(iname); 1445 int i=1; 1446 for( ; i<t.size()-1; i++ ) { 1447 push(t.elementAt(i)); 1448 flush_stack(); 1449 p.getMember(); 1450 } 1451 push(t.elementAt(i)); 1452 callMethod(); 1453 } 1454 } 1455 1456 public void callMethod( String method, Object arg ) { 1457 callMethod(method, new Object [] {arg}); 1458 } 1459 1460 public void callMethod( String method, int arg ) { 1461 callMethod(method, new Integer (arg)); 1462 } 1463 1464 public void callMethod( String method, double arg ) { 1465 callMethod(method, new Double (arg)); 1466 } 1467 1468 public void callMethod( String method, boolean arg ) { 1469 callMethod(method, new Boolean (arg)); 1470 } 1471 1472 1478 public void callMethod() { 1479 flush_stack(); 1480 p.callMethod(); 1481 } 1482 1483 1489 public void getMember() { 1490 flush_stack(); 1491 p.getMember(); 1492 } 1493 1494 1507 public void callFunction( String func_name, Object [] args ) { 1508 if( args == null || args.length == 0 ) { 1509 push(0); 1510 } else { 1511 for( int i=0; i<args.length; i++ ) { 1512 push(args[i]); 1513 } 1514 push(args.length); 1515 } 1516 push(func_name); 1517 flush_stack(); 1518 p.callFunction(); 1519 } 1520 1521 public void callFunction( String func_name, Object arg ) { 1522 callFunction(func_name, new Object [] {arg}); 1523 } 1524 1525 public void callFunction( String func_name, int arg ) { 1526 callFunction(func_name, new Integer (arg)); 1527 } 1528 1529 public void callFunction( String func_name, double arg ) { 1530 callFunction(func_name, new Double (arg)); 1531 } 1532 1533 public void callFunction( String func_name, boolean arg ) { 1534 callFunction(func_name, new Boolean (arg)); 1535 } 1536 1537 1557 public void defineFunction( String func_name, String [] parms ) { 1558 flush_stack(); 1559 FlashBuffer fob = p.body(); 1560 fob.writeByte(Actions.DefineFunction|0x80); int pos = fob.getPos(); 1562 fob.writeWord(0); fob.writeStringZ(func_name); 1564 int num = parms==null? 0: parms.length; 1565 fob.writeWord(num); 1566 for( int i=0; i<num; i++ ) fob.writeStringZ(parms[i]); 1567 fob.writeWordAt(fob.getSize()-pos, pos); 1568 funcs.push(p); 1569 p = new Program(); 1570 } 1571 1572 1577 public void endFunction() { 1578 flush_stack(); 1579 1580 Program prev_p = (Program) funcs.pop(); 1581 prev_p.body().writeWord(p.body().getSize()); 1582 prev_p.body().writeFOB(p.body()); 1583 1584 p = prev_p; 1585 } 1586 1587 1590 public void funcReturn() { 1591 flush_stack(); 1592 p.body().writeByte(Actions.Return); 1593 } 1594 1595 1620 public abstract static class Expr { 1621 public abstract void eval( ASAssembler as ); 1622 } 1623 1624 1626 private IVVector t = new IVVector(); 1627 1628 private IVVector parseMember( String m ) { 1629 t.reset(); 1630 int idx = 0; 1631 for(;;) { 1632 int idx2 = m.indexOf('.', idx); 1633 if( idx2 < 0 ) { 1634 if( idx == 0 ) t.addElement(m); 1635 else t.addElement(m.substring(idx)); 1636 break; 1637 } 1638 t.addElement(m.substring(idx, idx2)); 1639 idx = ++idx2; 1640 } 1641 return t; 1642 } 1643 1644 1650 private Short getString( String s ) { 1651 Short i = (Short ) pool.get(s); 1652 if( i == null ) { 1653 i = new Short ((short) pool.size()); 1654 pool.put(s, i); 1655 } 1656 return i; 1657 } 1658 1659 1664 private void writePool( Program p ) { 1665 if( pool.size() == 0 ) return; 1666 String [] ss = new String [pool.size()]; 1667 Set set = pool.entrySet(); 1668 for( Iterator it = set.iterator(); it.hasNext(); ) { 1669 Map.Entry entry = (Map.Entry) it.next(); 1670 String s = (String ) entry.getKey(); 1671 int idx = ((Short )entry.getValue()).intValue(); 1672 ss[idx] = s; 1673 } 1674 p.addConstantPool(ss); 1675 } 1676 1677 1680 private void flush_stack() { 1681 int n = delayed_stack.size(); 1682 if( n == 0 ) return; 1683 if( n == 1 ) { 1684 p.push(delayed_stack.elementAt(0)); 1685 } else { 1686 Object [] data = new Object [n]; 1687 delayed_stack.copyInto(data); 1688 p.push(data); 1689 } 1690 delayed_stack.reset(); 1691 } 1692 1693 private static class ASLabel { 1694 String name; 1695 int offset; 1696 ASLabel( String name, int offset ) { 1697 this.name = name; 1698 this.offset = offset; 1699 } 1700 } 1701 1702} 1703 1704 | Popular Tags |