001 package railo.transformer.bytecode.statement.tag; 002 003 import org.objectweb.asm.Label; 004 import org.objectweb.asm.Opcodes; 005 import org.objectweb.asm.Type; 006 import org.objectweb.asm.commons.GeneratorAdapter; 007 import org.objectweb.asm.commons.Method; 008 009 import railo.runtime.type.scope.Undefined; 010 import railo.runtime.util.NumberIterator; 011 import railo.transformer.bytecode.BytecodeContext; 012 import railo.transformer.bytecode.BytecodeException; 013 import railo.transformer.bytecode.Statement; 014 import railo.transformer.bytecode.cast.CastInt; 015 import railo.transformer.bytecode.expression.Expression; 016 import railo.transformer.bytecode.literal.LitString; 017 import railo.transformer.bytecode.util.Types; 018 import railo.transformer.bytecode.visitor.DecisionIntVisitor; 019 import railo.transformer.bytecode.visitor.NotVisitor; 020 import railo.transformer.bytecode.visitor.OnFinally; 021 import railo.transformer.bytecode.visitor.ParseBodyVisitor; 022 import railo.transformer.bytecode.visitor.TryFinallyVisitor; 023 import railo.transformer.bytecode.visitor.WhileVisitor; 024 025 public class TagGroupUtil { 026 027 028 // Undefined us() 029 public static final Type UNDEFINED = Type.getType(Undefined.class); 030 public static final Method US = new Method( 031 "us", 032 UNDEFINED, 033 new Type[]{}); 034 035 // void addQuery(Query coll) 036 public static final Method ADD_QUERY = new Method( 037 "addQuery", 038 Types.VOID, 039 new Type[]{Types.QUERY}); 040 041 // void removeQuery() 042 public static final Method REMOVE_QUERY = new Method( 043 "removeQuery", 044 Types.VOID, 045 new Type[]{}); 046 047 048 // int getRecordcount() 049 public static final Method GET_RECORDCOUNT = new Method( 050 "getRecordcount", 051 Types.INT_VALUE, 052 new Type[]{}); 053 054 // double range(double number, double from) 055 public static final Method RANGE = new Method( 056 "range", 057 Types.INT_VALUE, 058 new Type[]{Types.INT_VALUE,Types.INT_VALUE}); 059 060 public static final Type NUMBER_ITERATOR = Type.getType(NumberIterator.class); 061 062 // NumberIterator load(double from, double to, double max) 063 public static final Method LOAD_MAX = new Method( 064 "loadMax", 065 NUMBER_ITERATOR, 066 new Type[]{Types.INT_VALUE,Types.INT_VALUE,Types.INT_VALUE}); 067 068 public static final Method LOAD_END = new Method( 069 "loadEnd", 070 NUMBER_ITERATOR, 071 new Type[]{Types.INT_VALUE,Types.INT_VALUE,Types.INT_VALUE}); 072 073 074 // NumberIterator load(double from, double to, double max) 075 public static final Method LOAD_2 = new Method( 076 "load", 077 NUMBER_ITERATOR, 078 new Type[]{Types.INT_VALUE,Types.INT_VALUE}); 079 080 081 // NumberIterator load(NumberIterator ni, Query query, String groupName, boolean caseSensitive) 082 public static final Method LOAD_5 = new Method( 083 "load", 084 NUMBER_ITERATOR, 085 new Type[]{Types.PAGE_CONTEXT, NUMBER_ITERATOR,Types.QUERY,Types.STRING,Types.BOOLEAN_VALUE}); 086 087 // boolean isValid() 088 /*public static final Method IS_VALID_0 = new Method( 089 "isValid", 090 Types.BOOLEAN_VALUE, 091 new Type[]{});*/ 092 093 public static final Method IS_VALID_1 = new Method( 094 "isValid", 095 Types.BOOLEAN_VALUE, 096 new Type[]{Types.INT_VALUE}); 097 098 // int current() 099 public static final Method CURRENT = new Method( 100 "current", 101 Types.INT_VALUE, 102 new Type[]{}); 103 104 // void release(NumberIterator ni) 105 public static final Method REALEASE = new Method( 106 "release", 107 Types.VOID, 108 new Type[]{NUMBER_ITERATOR}); 109 110 // void setCurrent(int current) 111 public static final Method SET_CURRENT = new Method( 112 "setCurrent", 113 Types.VOID, 114 new Type[]{Types.INT_VALUE}); 115 116 117 // void reset() 118 public static final Method RESET = new Method( 119 "reset", 120 Types.VOID, 121 new Type[]{Types.INT_VALUE}); 122 123 // int first() 124 public static final Method FIRST = new Method( 125 "first", 126 Types.INT_VALUE, 127 new Type[]{}); 128 public static final Method GET_ID = new Method( 129 "getId", 130 Types.INT_VALUE, 131 new Type[]{}); 132 133 134 135 136 public static void writeOutTypeQuery(final TagGroup tag, BytecodeContext bc) throws BytecodeException { 137 final GeneratorAdapter adapter = bc.getAdapter(); 138 139 tag.setNumberIterator(adapter.newLocal(NUMBER_ITERATOR)); 140 boolean isOutput=tag.getType()==TagGroup.TAG_OUTPUT; 141 ParseBodyVisitor pbv=isOutput?new ParseBodyVisitor():null; 142 if(isOutput)pbv.visitBegin(bc); 143 144 145 // Query query=pc.getQuery(@query); 146 tag.setQuery(adapter.newLocal(Types.QUERY)); 147 adapter.loadArg(0); 148 Expression val = tag.getAttribute("query").getValue(); 149 val.writeOut(bc, Expression.MODE_REF); 150 if(val instanceof LitString) 151 adapter.invokeVirtual(Types.PAGE_CONTEXT, TagLoop.GET_QUERY_STRING); 152 else 153 adapter.invokeVirtual(Types.PAGE_CONTEXT, TagLoop.GET_QUERY_OBJ); 154 155 adapter.storeLocal(tag.getQuery()); 156 157 158 tag.setPID(adapter.newLocal(Types.INT_VALUE)); 159 adapter.loadArg(0); 160 adapter.invokeVirtual(Types.PAGE_CONTEXT, TagLoop.GET_ID); 161 adapter.storeLocal(tag.getPID()); 162 163 164 165 // int startAt=query.getCurrentrow(); 166 final int startAt=adapter.newLocal(Types.INT_VALUE); 167 adapter.loadLocal(tag.getQuery()); 168 169 adapter.loadLocal(tag.getPID()); 170 //adapter.loadArg(0); 171 //adapter.invokeVirtual(Types.PAGE_CONTEXT, TagLoop.GET_ID); 172 adapter.invokeInterface(Types.QUERY, TagLoop.GET_CURRENTROW_1); 173 174 adapter.storeLocal(startAt); 175 176 177 178 // if(query.getRecordcount()>0) { 179 DecisionIntVisitor div=new DecisionIntVisitor(); 180 div.visitBegin(); 181 adapter.loadLocal(tag.getQuery()); 182 adapter.invokeInterface(Types.QUERY, GET_RECORDCOUNT); 183 div.visitGT(); 184 adapter.push(0); 185 div.visitEnd(bc); 186 Label ifRecCount=new Label(); 187 adapter.ifZCmp(Opcodes.IFEQ, ifRecCount); 188 189 // startrow 190 int from = adapter.newLocal(Types.INT_VALUE); 191 Attribute attrStartRow = tag.getAttribute("startrow"); 192 if(attrStartRow!=null){ 193 // NumberRange.range(@startrow,1) 194 //attrStartRow.getValue().writeOut(bc, Expression.MODE_VALUE); 195 CastInt.toExprInt(attrStartRow.getValue()).writeOut(bc, Expression.MODE_VALUE); 196 //adapter.visitInsn(Opcodes.D2I); 197 adapter.push(1); 198 adapter.invokeStatic(Types.NUMBER_RANGE, RANGE); 199 //adapter.visitInsn(Opcodes.D2I); 200 } 201 else { 202 adapter.push(1); 203 } 204 adapter.storeLocal(from); 205 206 // numberIterator 207 208 209 adapter.loadLocal(from); 210 adapter.loadLocal(tag.getQuery()); 211 adapter.invokeInterface(Types.QUERY, GET_RECORDCOUNT); 212 //adapter.visitInsn(Opcodes.I2D); 213 214 Attribute attrMaxRow = tag.getAttribute("maxrows"); 215 Attribute attrEndRow = tag.getAttribute("endrow"); 216 if(attrMaxRow!=null) { 217 CastInt.toExprInt(attrMaxRow.getValue()).writeOut(bc, Expression.MODE_VALUE); 218 adapter.invokeStatic(NUMBER_ITERATOR, LOAD_MAX); 219 } 220 else if(attrEndRow!=null) { 221 CastInt.toExprInt(attrEndRow.getValue()).writeOut(bc, Expression.MODE_VALUE); 222 adapter.invokeStatic(NUMBER_ITERATOR, LOAD_END); 223 } 224 else { 225 adapter.invokeStatic(NUMBER_ITERATOR, LOAD_2); 226 } 227 adapter.storeLocal(tag.getNumberIterator()); 228 229 // Group 230 Attribute attrGroup = tag.getAttribute("group"); 231 Attribute attrGroupCS = tag.getAttribute("groupcasesensitive"); 232 tag.setGroup(adapter.newLocal(Types.STRING)); 233 final int groupCaseSensitive=adapter.newLocal(Types.BOOLEAN_VALUE); 234 if(attrGroup!=null) { 235 attrGroup.getValue().writeOut(bc, Expression.MODE_REF); 236 adapter.storeLocal(tag.getGroup()); 237 238 if(attrGroupCS!=null) attrGroupCS.getValue().writeOut(bc, Expression.MODE_VALUE); 239 else adapter.push(false); 240 adapter.storeLocal(groupCaseSensitive); 241 } 242 243 // pc.us().addQuery(query); 244 adapter.loadArg(0); 245 adapter.invokeVirtual(Types.PAGE_CONTEXT, US); 246 adapter.loadLocal(tag.getQuery()); 247 adapter.invokeInterface(UNDEFINED, ADD_QUERY); 248 249 // current 250 final int current=adapter.newLocal(Types.INT_VALUE); 251 adapter.loadLocal(from); 252 adapter.push(1); 253 adapter.visitInsn(Opcodes.ISUB); 254 adapter.storeLocal(current); 255 256 257 // Try 258 TryFinallyVisitor tfv=new TryFinallyVisitor(new OnFinally() { 259 public void writeOut(BytecodeContext bc) { 260 // query.reset(); 261 262 // query.go(startAt); 263 adapter.loadLocal(tag.getQuery()); 264 adapter.loadLocal(startAt); 265 266 adapter.loadLocal(tag.getPID()); 267 //adapter.loadArg(0); 268 //adapter.invokeVirtual(Types.PAGE_CONTEXT, TagLoop.GET_ID); 269 adapter.invokeInterface(Types.QUERY, TagLoop.GO); 270 adapter.pop(); 271 272 273 274 275 // pc.us().removeQuery(); 276 adapter.loadArg(0); 277 adapter.invokeVirtual(Types.PAGE_CONTEXT, US); 278 adapter.invokeInterface(UNDEFINED, REMOVE_QUERY); 279 280 // NumberIterator.release(ni); 281 adapter.loadLocal(tag.getNumberIterator()); 282 adapter.invokeStatic(NUMBER_ITERATOR, REALEASE); 283 } 284 },null); 285 tfv.visitTryBegin(bc); 286 WhileVisitor wv = new WhileVisitor(); 287 if(tag instanceof TagLoop) ((TagLoop)tag).setLoopVisitor(wv); 288 wv.visitBeforeExpression(bc); 289 290 //while(ni.isValid()) { 291 adapter.loadLocal(tag.getNumberIterator()); 292 adapter.loadLocal(current); 293 adapter.push(1); 294 adapter.visitInsn(Opcodes.IADD); 295 adapter.invokeVirtual(NUMBER_ITERATOR, IS_VALID_1); 296 297 wv.visitAfterExpressionBeforeBody(bc); 298 299 // if(!query.go(ni.current()))break; 300 adapter.loadLocal(tag.getQuery()); 301 adapter.loadLocal(tag.getNumberIterator()); 302 adapter.invokeVirtual(NUMBER_ITERATOR, CURRENT); 303 304 adapter.loadLocal(tag.getPID()); 305 adapter.invokeInterface(Types.QUERY, TagLoop.GO); 306 307 NotVisitor.visitNot(bc); 308 Label _if=new Label(); 309 adapter.ifZCmp(Opcodes.IFEQ, _if); 310 wv.visitBreak(bc); 311 adapter.visitLabel(_if); 312 313 if(attrGroup!=null) { 314 // NumberIterator oldNi=numberIterator; 315 int oldNi=adapter.newLocal(NUMBER_ITERATOR); 316 adapter.loadLocal(tag.getNumberIterator()); 317 adapter.storeLocal(oldNi); 318 319 // numberIterator=NumberIterator.load(ni,query,group,grp_case); 320 adapter.loadArg(0); 321 adapter.loadLocal(tag.getNumberIterator()); 322 adapter.loadLocal(tag.getQuery()); 323 adapter.loadLocal(tag.getGroup()); 324 adapter.loadLocal(groupCaseSensitive); 325 adapter.invokeStatic(NUMBER_ITERATOR, LOAD_5); 326 adapter.storeLocal(tag.getNumberIterator()); 327 328 // current=oldNi.current(); 329 adapter.loadLocal(oldNi); 330 adapter.invokeVirtual(NUMBER_ITERATOR, CURRENT); 331 adapter.storeLocal(current); 332 333 tag.getBody().writeOut(bc); 334 335 //tmp(adapter,current); 336 337 // NumberIterator.release(ni); 338 adapter.loadLocal(tag.getNumberIterator()); 339 adapter.invokeStatic(NUMBER_ITERATOR, REALEASE); 340 341 // numberIterator=oldNi; 342 adapter.loadLocal(oldNi); 343 adapter.storeLocal(tag.getNumberIterator()); 344 } 345 else { 346 // current=ni.current(); 347 adapter.loadLocal(tag.getNumberIterator()); 348 adapter.invokeVirtual(NUMBER_ITERATOR, CURRENT); 349 adapter.storeLocal(current); 350 351 tag.getBody().writeOut(bc); 352 } 353 354 // ni.setCurrent(current+1); 355 /*adapter.loadLocal(tag.getNumberIterator()); 356 adapter.loadLocal(current); 357 adapter.push(1); 358 adapter.visitInsn(Opcodes.IADD); 359 adapter.invokeVirtual(NUMBER_ITERATOR, SET_CURRENT);*/ 360 361 wv.visitAfterBody(bc,tag.getEnd()); 362 363 tfv.visitTryEnd(bc); 364 365 adapter.visitLabel(ifRecCount); 366 367 368 if(isOutput)pbv.visitEnd(bc); 369 } 370 371 372 373 public static void writeOutTypeGroup(TagGroup tag,BytecodeContext bc) throws BytecodeException { 374 GeneratorAdapter adapter = bc.getAdapter(); 375 boolean isOutput=tag.getType()==TagGroup.TAG_OUTPUT; 376 ParseBodyVisitor pbv=isOutput?new ParseBodyVisitor():null; 377 if(isOutput)pbv.visitBegin(bc); 378 379 // Group 380 Attribute attrGroup = tag.getAttribute("group"); 381 tag.setGroup(adapter.newLocal(Types.STRING)); 382 attrGroup.getValue().writeOut(bc, Expression.MODE_REF); 383 adapter.storeLocal(tag.getGroup()); 384 385 // Group Case Sensitve 386 Attribute attrGroupCS = tag.getAttribute("groupcasesensitive"); 387 int groupCaseSensitive=adapter.newLocal(Types.BOOLEAN_VALUE); 388 if(attrGroupCS!=null) attrGroupCS.getValue().writeOut(bc, Expression.MODE_VALUE); 389 else adapter.push(true); 390 adapter.storeLocal(groupCaseSensitive); 391 392 TagGroup parent = getParentTagGroupQuery(tag,tag.getType()); 393 tag.setNumberIterator(parent.getNumberIterator()); 394 tag.setQuery(parent.getQuery()); 395 //queryImpl = parent.getQueryImpl(); 396 397 // current 398 int current=adapter.newLocal(Types.INT_VALUE); 399 adapter.loadLocal(tag.getNumberIterator()); 400 adapter.invokeVirtual(NUMBER_ITERATOR, CURRENT); 401 adapter.storeLocal(current); 402 403 404 // current 405 int icurrent=adapter.newLocal(Types.INT_VALUE); 406 407 adapter.loadLocal(current); 408 adapter.push(1); 409 adapter.visitInsn(Opcodes.ISUB); 410 adapter.storeLocal(icurrent); 411 412 413 WhileVisitor wv = new WhileVisitor(); 414 if(tag instanceof TagLoop) ((TagLoop)tag).setLoopVisitor(wv); 415 wv.visitBeforeExpression(bc); 416 417 //while(ni.isValid()) { 418 adapter.loadLocal(tag.getNumberIterator()); 419 adapter.loadLocal(icurrent); 420 adapter.push(1); 421 adapter.visitInsn(Opcodes.IADD); 422 adapter.invokeVirtual(NUMBER_ITERATOR, IS_VALID_1); 423 424 wv.visitAfterExpressionBeforeBody(bc); 425 426 // if(!query.go(ni.current()))break; 427 adapter.loadLocal(tag.getQuery()); 428 adapter.loadLocal(tag.getNumberIterator()); 429 adapter.invokeVirtual(NUMBER_ITERATOR, CURRENT); 430 431 adapter.loadArg(0); 432 adapter.invokeVirtual(Types.PAGE_CONTEXT, GET_ID); 433 adapter.invokeInterface(Types.QUERY, TagLoop.GO); 434 435 NotVisitor.visitNot(bc); 436 Label _if=new Label(); 437 adapter.ifZCmp(Opcodes.IFEQ, _if); 438 wv.visitBreak(bc); 439 adapter.visitLabel(_if); 440 441 // NumberIterator oldNi=numberIterator; 442 int oldNi=adapter.newLocal(NUMBER_ITERATOR); 443 444 adapter.loadLocal(tag.getNumberIterator()); 445 adapter.storeLocal(oldNi); 446 447 // numberIterator=NumberIterator.load(ni,query,group,grp_case); 448 adapter.loadArg(0); 449 adapter.loadLocal(tag.getNumberIterator()); 450 adapter.loadLocal(tag.getQuery()); 451 adapter.loadLocal(tag.getGroup()); 452 adapter.loadLocal(groupCaseSensitive); 453 adapter.invokeStatic(NUMBER_ITERATOR, LOAD_5); 454 adapter.storeLocal(tag.getNumberIterator()); 455 456 // current=oldNi.current(); 457 adapter.loadLocal(oldNi); 458 adapter.invokeVirtual(NUMBER_ITERATOR, CURRENT); 459 adapter.storeLocal(icurrent); 460 461 tag.getBody().writeOut(bc); 462 463 //tmp(adapter,current); 464 465 466 // NumberIterator.release(ni); 467 adapter.loadLocal(tag.getNumberIterator()); 468 adapter.invokeStatic(NUMBER_ITERATOR, REALEASE); 469 470 // numberIterator=oldNi; 471 adapter.loadLocal(oldNi); 472 adapter.storeLocal(tag.getNumberIterator()); 473 474 // ni.setCurrent(current+1); 475 /*adapter.loadLocal(tag.getNumberIterator()); 476 adapter.loadLocal(icurrent); 477 adapter.push(1); 478 adapter.visitInsn(Opcodes.IADD); 479 adapter.invokeVirtual(NUMBER_ITERATOR, SET_CURRENT); 480 */ 481 wv.visitAfterBody(bc,tag.getEnd()); 482 483 484 //query.go(ni.current(),pc.getId()) 485 resetCurrentrow(adapter,tag,current); 486 487 // ni.first(); 488 adapter.loadLocal(tag.getNumberIterator()); 489 adapter.invokeVirtual(NUMBER_ITERATOR, FIRST); 490 adapter.pop(); 491 492 493 if(isOutput)pbv.visitEnd(bc); 494 } 495 496 public static void writeOutTypeInnerGroup(TagGroup tag,BytecodeContext bc) throws BytecodeException { 497 GeneratorAdapter adapter = bc.getAdapter(); 498 499 TagGroup parent = getParentTagGroupQuery(tag,tag.getType()); 500 tag.setNumberIterator(parent.getNumberIterator()); 501 tag.setQuery(parent.getQuery()); 502 //queryImpl = parent.getQueryImpl(); 503 504 int current=adapter.newLocal(Types.INT_VALUE); 505 adapter.loadLocal(tag.getNumberIterator()); 506 adapter.invokeVirtual(NUMBER_ITERATOR, CURRENT); 507 adapter.storeLocal(current); 508 509 510 // inner current 511 int icurrent=adapter.newLocal(Types.INT_VALUE); 512 513 adapter.loadLocal(current); 514 adapter.push(1); 515 adapter.visitInsn(Opcodes.ISUB); 516 adapter.storeLocal(icurrent); 517 518 519 520 WhileVisitor wv = new WhileVisitor(); 521 if(tag instanceof TagLoop) ((TagLoop)tag).setLoopVisitor(wv); 522 wv.visitBeforeExpression(bc); 523 524 //while(ni.isValid()) { 525 adapter.loadLocal(tag.getNumberIterator()); 526 adapter.loadLocal(icurrent); 527 adapter.push(1); 528 adapter.visitInsn(Opcodes.IADD); 529 adapter.invokeVirtual(NUMBER_ITERATOR, IS_VALID_1); 530 531 wv.visitAfterExpressionBeforeBody(bc); 532 533 // if(!query.go(ni.current()))break; 534 535 adapter.loadLocal(tag.getQuery()); 536 adapter.loadLocal(tag.getNumberIterator()); 537 adapter.invokeVirtual(NUMBER_ITERATOR, CURRENT); 538 539 adapter.loadArg(0); 540 adapter.invokeVirtual(Types.PAGE_CONTEXT, GET_ID); 541 adapter.invokeInterface(Types.QUERY, TagLoop.GO); 542 543 /*OLD 544 adapter.invokeInterface(Types.QUERY, TagLoop.GO_1); 545 */ 546 NotVisitor.visitNot(bc); 547 Label _if=new Label(); 548 adapter.ifZCmp(Opcodes.IFEQ, _if); 549 wv.visitBreak(bc); 550 adapter.visitLabel(_if); 551 552 // current=ni.current(); 553 adapter.loadLocal(tag.getNumberIterator()); 554 adapter.invokeVirtual(NUMBER_ITERATOR, CURRENT); 555 adapter.storeLocal(icurrent); 556 557 tag.getBody().writeOut(bc); 558 559 // ni.setCurrent(current+1); 560 /*adapter.loadLocal(tag.getNumberIterator()); 561 adapter.loadLocal(icurrent); 562 adapter.push(1); 563 adapter.visitInsn(Opcodes.IADD); 564 adapter.invokeVirtual(NUMBER_ITERATOR, SET_CURRENT);*/ 565 566 wv.visitAfterBody(bc,tag.getEnd()); 567 568 resetCurrentrow(adapter,tag,current); 569 570 571 // ni.first(); 572 adapter.loadLocal(tag.getNumberIterator()); 573 adapter.invokeVirtual(NUMBER_ITERATOR, FIRST); 574 adapter.pop(); 575 } 576 577 public static void writeOutTypeInnerQuery(TagGroup tag,BytecodeContext bc) throws BytecodeException { 578 GeneratorAdapter adapter = bc.getAdapter(); 579 //if(tr ue)return ; 580 TagGroup parent = getParentTagGroupQuery(tag,tag.getType()); 581 tag.setNumberIterator(parent.getNumberIterator()); 582 tag.setQuery(parent.getQuery()); 583 tag.setPID(parent.getPID()); 584 //queryImpl = parent.getQueryImpl(); 585 586 //int currentOuter=ni.current(); 587 int current=adapter.newLocal(Types.INT_VALUE); 588 adapter.loadLocal(tag.getNumberIterator()); 589 adapter.invokeVirtual(NUMBER_ITERATOR, CURRENT); 590 adapter.storeLocal(current); 591 592 // current 593 int icurrent=adapter.newLocal(Types.INT_VALUE); 594 595 adapter.loadLocal(current); 596 adapter.push(1); 597 adapter.visitInsn(Opcodes.ISUB); 598 adapter.storeLocal(icurrent); 599 600 601 WhileVisitor wv = new WhileVisitor(); 602 if(tag instanceof TagLoop) ((TagLoop)tag).setLoopVisitor(wv); 603 wv.visitBeforeExpression(bc); 604 605 //while(ni.isValid()) { 606 adapter.loadLocal(tag.getNumberIterator()); 607 adapter.loadLocal(icurrent); 608 adapter.push(1); 609 adapter.visitInsn(Opcodes.IADD); 610 adapter.invokeVirtual(NUMBER_ITERATOR, IS_VALID_1); 611 612 wv.visitAfterExpressionBeforeBody(bc); 613 614 // if(!query.go(ni.current()))break; 615 adapter.loadLocal(tag.getQuery()); 616 adapter.loadLocal(tag.getNumberIterator()); 617 adapter.invokeVirtual(NUMBER_ITERATOR, CURRENT); 618 619 adapter.loadLocal(tag.getPID()); 620 adapter.invokeInterface(Types.QUERY, TagLoop.GO); 621 622 NotVisitor.visitNot(bc); 623 Label _if=new Label(); 624 adapter.ifZCmp(Opcodes.IFEQ, _if); 625 wv.visitBreak(bc); 626 adapter.visitLabel(_if); 627 628 // current=ni.current(); 629 adapter.loadLocal(tag.getNumberIterator()); 630 adapter.invokeVirtual(NUMBER_ITERATOR, CURRENT); 631 adapter.storeLocal(icurrent); 632 633 tag.getBody().writeOut(bc); 634 635 // ni.setCurrent(current+1); 636 /*adapter.loadLocal(tag.getNumberIterator()); 637 adapter.loadLocal(icurrent); 638 adapter.push(1); 639 adapter.visitInsn(Opcodes.IADD); 640 adapter.invokeVirtual(NUMBER_ITERATOR, SET_CURRENT);*/ 641 642 wv.visitAfterBody(bc,tag.getEnd()); 643 644 645 // ni.setCurrent(currentOuter); 646 adapter.loadLocal(tag.getNumberIterator()); 647 adapter.loadLocal(current); 648 adapter.invokeVirtual(NUMBER_ITERATOR, SET_CURRENT); 649 650 adapter.loadLocal(tag.getQuery()); 651 adapter.loadLocal(current); 652 653 adapter.loadLocal(tag.getPID()); 654 //adapter.loadArg(0); 655 //adapter.invokeVirtual(Types.PAGE_CONTEXT, GET_ID); 656 adapter.invokeInterface(Types.QUERY, TagLoop.GO); 657 adapter.pop(); 658 //adapter.pop(); 659 } 660 661 public static TagGroup getParentTagGroupQuery(Statement st, short type) throws BytecodeException { 662 Statement parent=st.getParent(); 663 if(parent==null) throw new BytecodeException("there is no parent output with query",null); 664 else if(parent instanceof TagGroup && type==((TagGroup)parent).getType()) { 665 if(((TagGroup)parent).hasQuery()) 666 return ((TagGroup)parent); 667 } 668 return getParentTagGroupQuery(parent,type); 669 } 670 671 private static void resetCurrentrow(GeneratorAdapter adapter,TagGroup tg, int current) { 672 //query.go(ni.current(),pc.getId()) 673 adapter.loadLocal(tg.getQuery()); 674 adapter.loadLocal(current); 675 adapter.loadArg(0); 676 adapter.invokeVirtual(Types.PAGE_CONTEXT, GET_ID); 677 adapter.invokeInterface(Types.QUERY, TagLoop.GO); 678 679 /* OLD 680 adapter.invokeInterface(Types.QUERY, TagLoop.GO_1); 681 */ 682 adapter.pop(); 683 684 } 685 686 }