adapter.push(tlt.getTagClassName());
adapter.invokeVirtual(Types.PAGE_CONTEXT, USE);
adapter.checkCast(currType);
adapter.storeLocal(currLocal);
TryFinallyVisitor outerTcfv=new TryFinallyVisitor(new OnFinally() {
public void writeOut(BytecodeContext bc) {
adapter.loadArg(0);
adapter.loadLocal(currLocal);
adapter.invokeVirtual(Types.PAGE_CONTEXT, RE_USE);
}
},null);
if(doReuse)outerTcfv.visitTryBegin(bc);
// appendix
if(tlt.hasAppendix()) {
adapter.loadLocal(currLocal);
adapter.push(tag.getAppendix());
adapter.invokeVirtual(currType, SET_APPENDIX);
}
// hasBody
boolean hasBody=tag.getBody()!=null;
if(tlt.isBodyFree() && tlt.hasBodyMethodExists()) {
adapter.loadLocal(currLocal);
adapter.push(hasBody);
adapter.invokeVirtual(currType, HAS_BODY);
}
// attributes
Attribute attr;
// attributeCollection
attr=tag.getAttribute("attributecollection");
if(attr!=null){
int attrType = tag.getTagLibTag().getAttributeType();
if(TagLibTag.ATTRIBUTE_TYPE_NONAME!=attrType) {
tag.removeAttribute("attributecollection");
// TagUtil.setAttributeCollection(Tag, Struct)
adapter.loadArg(0);
adapter.loadLocal(currLocal);
adapter.cast(currType, TAG);
///
Map missings = tag.getMissingAttributes();
if(missings.size()>0) {
ArrayVisitor av=new ArrayVisitor();
av.visitBegin(adapter,MISSING_ATTRIBUTE,missings.size());
Map.Entry entry;
int count=0;
Iterator it = missings.entrySet().iterator();
while(it.hasNext()){
entry=(Entry) it.next();
av.visitBeginItem(adapter, count++);
Variable.registerKey(bc, LitString.toExprString((String)entry.getKey()));
adapter.push((String)entry.getValue());
adapter.invokeStatic(MISSING_ATTRIBUTE, NEW_INSTANCE_MAX);
av.visitEndItem(bc.getAdapter());
}
av.visitEnd();
}
else {
ASMConstants.NULL(adapter);
}
///
attr.getValue().writeOut(bc, Expression.MODE_REF);
adapter.push(attrType);
adapter.invokeStatic(TAG_UTIL, SET_ATTRIBUTE_COLLECTION);
}
}
// metadata
Map<String, Attribute> metadata = tag.getMetaData();
if(metadata!=null){
Iterator<Attribute> it = metadata.values().iterator();
while(it.hasNext()) {
attr=it.next();
adapter.loadLocal(currLocal);
adapter.push(attr.getName());
attr.getValue().writeOut(bc, Expression.MODE_REF);
adapter.invokeVirtual(currType, SET_META_DATA);
}
}
String methodName;
Map attributes = tag.getAttributes();
// static attributes
Iterator it = attributes.values().iterator();
while(it.hasNext()) {
attr=(Attribute) it.next();
if(!attr.isDynamicType()){
Type type = CastOther.getType(attr.getType());
methodName=tag.getTagLibTag().getSetter(attr,type);
adapter.loadLocal(currLocal);
attr.getValue().writeOut(bc, Types.isPrimitiveType(type)?Expression.MODE_VALUE:Expression.MODE_REF);
adapter.invokeVirtual(currType, new Method(methodName,Type.VOID_TYPE,new Type[]{type}));
}
}
// dynamic attributes
it = attributes.values().iterator();
while(it.hasNext()) {
attr=(Attribute) it.next();
if(attr.isDynamicType()){
adapter.loadLocal(currLocal);
adapter.visitInsn(Opcodes.ACONST_NULL);
//adapter.push(attr.getName());
Variable.registerKey(bc, LitString.toExprString(attr.getName()));
attr.getValue().writeOut(bc, Expression.MODE_REF);
adapter.invokeVirtual(currType, SET_DYNAMIC_ATTRIBUTE);
}
}
// Body
if(hasBody){
final int state=adapter.newLocal(Types.INT_VALUE);
// int state=tag.doStartTag();
adapter.loadLocal(currLocal);
adapter.invokeVirtual(currType, DO_START_TAG);
adapter.storeLocal(state);
// if (state!=Tag.SKIP_BODY)
Label endBody=new Label();
adapter.loadLocal(state);
adapter.push(javax.servlet.jsp.tagext.Tag.SKIP_BODY);
adapter.visitJumpInsn(Opcodes.IF_ICMPEQ, endBody);
// pc.initBody(tag, state);
adapter.loadArg(0);
adapter.loadLocal(currLocal);
adapter.loadLocal(state);
adapter.invokeVirtual(Types.PAGE_CONTEXT, INIT_BODY);
OnFinally onFinally = new OnFinally() {
public void writeOut(BytecodeContext bc) {
Label endIf = new Label();
/*if(tlt.handleException() && fcf!=null && fcf.getAfterFinalGOTOLabel()!=null){
ASMUtil.visitLabel(adapter, fcf.getFinalEntryLabel());
}*/
adapter.loadLocal(state);
adapter.push(javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUDE);
adapter.visitJumpInsn(Opcodes.IF_ICMPEQ, endIf);
// ... pc.popBody();
adapter.loadArg(0);
adapter.invokeVirtual(Types.PAGE_CONTEXT, POP_BODY);
adapter.pop();
adapter.visitLabel(endIf);
// tag.doFinally();
if(tlt.handleException()) {
adapter.loadLocal(currLocal);
adapter.invokeVirtual(currType, DO_FINALLY);
}
// GOTO after execution body, used when a continue/break was called before
/*if(fcf!=null) {
Label l = fcf.getAfterFinalGOTOLabel();
if(l!=null)adapter.visitJumpInsn(Opcodes.GOTO, l);
}*/
}
};
if(tlt.handleException()) {
TryCatchFinallyVisitor tcfv=new TryCatchFinallyVisitor(onFinally,fcf);
tcfv.visitTryBegin(bc);
doTry(bc,adapter,tag,currLocal,currType);
int t=tcfv.visitTryEndCatchBeging(bc);
// tag.doCatch(t);
adapter.loadLocal(currLocal);
adapter.loadLocal(t);
//adapter.visitVarInsn(Opcodes.ALOAD,t);
adapter.invokeVirtual(currType, DO_CATCH);
tcfv.visitCatchEnd(bc);
}
else {
TryFinallyVisitor tfv=new TryFinallyVisitor(onFinally,fcf);
tfv.visitTryBegin(bc);
doTry(bc,adapter,tag,currLocal,currType);
tfv.visitTryEnd(bc);
}
adapter.visitLabel(endBody);