Package railo.transformer.bytecode.expression.var

Source Code of railo.transformer.bytecode.expression.var.Assign

package railo.transformer.bytecode.expression.var;

import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;

import railo.runtime.type.scope.Scope;
import railo.runtime.type.scope.ScopeFactory;
import railo.runtime.type.scope.ScopeSupport;
import railo.transformer.bytecode.BytecodeContext;
import railo.transformer.bytecode.BytecodeException;
import railo.transformer.bytecode.expression.Expression;
import railo.transformer.bytecode.expression.ExpressionBase;
import railo.transformer.bytecode.literal.LitString;
import railo.transformer.bytecode.util.ExpressionUtil;
import railo.transformer.bytecode.util.TypeScope;
import railo.transformer.bytecode.util.Types;

public class Assign extends ExpressionBase {

  //final static Method[] METHODS_SCOPE_SET = new Method[6];
 


//  java.lang.Object set(String,Object)
    private final static Method METHOD_SCOPE_SET = new Method("set",
      Types.OBJECT,
      new Type[]{Types.STRING,Types.OBJECT});
   
//  java.lang.Object set(String,Object)
    private final static Method METHOD_SCOPE_SET_KEY = new Method("set",
      Types.OBJECT,
      new Type[]{Types.COLLECTION_KEY,Types.OBJECT});
 
// .setArgument(obj)
    private final static Method SET_ARGUMENT = new Method("setArgument",
      Types.OBJECT,
      new Type[]{Types.OBJECT});
   
   
    // Object touch (Object,String)
    private final static Method TOUCH = new Method("touch",
      Types.OBJECT,
      new Type[]{Types.OBJECT,Types.STRING});

    // Object touch (Object,String)
    private final static Method TOUCH_KEY = new Method("touch",
      Types.OBJECT,
      new Type[]{Types.OBJECT,Types.COLLECTION_KEY});
   

    //Object set (Object,String,Object)
    private final static Method SET_KEY = new Method("set",
      Types.OBJECT,
      new Type[]{Types.OBJECT,Types.COLLECTION_KEY,Types.OBJECT});
   
    //Object set (Object,String,Object)
    private final static Method SET = new Method("set",
      Types.OBJECT,
      new Type[]{Types.OBJECT,Types.STRING,Types.OBJECT});

    // Object getFunction (Object,String,Object[])
    private final static Method GET_FUNCTION = new Method("getFunction",
      Types.OBJECT,
      new Type[]{Types.OBJECT,Types.STRING,Types.OBJECT_ARRAY});
   
    // Object getFunctionWithNamedValues (Object,String,Object[])
    private final static Method GET_FUNCTION_WITH_NAMED_ARGS = new Method("getFunctionWithNamedValues",
      Types.OBJECT,
      new Type[]{Types.OBJECT,Types.STRING,Types.OBJECT_ARRAY});
 

    // Object getFunction (Object,String,Object[])
    private final static Method GET_FUNCTION_KEY = new Method("getFunction",
      Types.OBJECT,
      new Type[]{Types.OBJECT,Types.COLLECTION_KEY,Types.OBJECT_ARRAY});
   
    // Object getFunctionWithNamedValues (Object,String,Object[])
    private final static Method GET_FUNCTION_WITH_NAMED_ARGS_KEY = new Method("getFunctionWithNamedValues",
      Types.OBJECT,
      new Type[]{Types.OBJECT,Types.COLLECTION_KEY,Types.OBJECT_ARRAY});
 
 
  private Variable variable;
  private Expression value;


  /**
   * Constructor of the class
   * @param variable
   * @param value
   */
  public Assign(Variable variable, Expression value) {
    super(variable.getStart(),variable.getEnd());
    this.variable=variable;
    this.value=value;
    //this.returnOldValue=returnOldValue;
  }
 

  public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException {
      GeneratorAdapter adapter = bc.getAdapter();
    int count=variable.countFM+variable.countDM;
        // count 0
        if(count==0){
          if(variable.ignoredFirstMember() && variable.scope==ScopeSupport.SCOPE_VAR){
          //print.dumpStack();
            return Types.VOID;
        }
          return _writeOutEmpty(bc);
        }
       
        boolean doOnlyScope=variable.scope==Scope.SCOPE_LOCAL;
     
      Type rtn=Types.OBJECT;
      //boolean last;
      for(int i=doOnlyScope?0:1;i<count;i++) {
      adapter.loadArg(0);
      }
    rtn=_writeOutFirst(bc, (variable.members.get(0)),mode,count==1,doOnlyScope);
     
    // pc.get(
    for(int i=doOnlyScope?0:1;i<count;i++) {
      Member member=(variable.members.get(i));
      boolean last=(i+1)==count;
     
     
      // Data Member
      if(member instanceof DataMember)  {
        //((DataMember)member).getName().writeOut(bc, MODE_REF);
          boolean isKey=Variable.registerKey(bc, ((DataMember)member).getName());
       
          if(last)value.writeOut(bc, MODE_REF);
          if(isKey)adapter.invokeVirtual(Types.PAGE_CONTEXT,last?SET_KEY:TOUCH_KEY);
          else adapter.invokeVirtual(Types.PAGE_CONTEXT,last?SET:TOUCH);
            rtn=Types.OBJECT;
      }
     
      // UDF
      else if(member instanceof UDF) {
        if(last)throw new BytecodeException("can't asign value to a user defined function",getStart());
        UDF udf=(UDF) member;
        boolean isKey=Variable.registerKey(bc, udf.getName());
        //udf.getName().writeOut(bc, MODE_REF);
        ExpressionUtil.writeOutExpressionArray(bc, Types.OBJECT, udf.getArguments());
       
        if(isKey)adapter.invokeVirtual(Types.PAGE_CONTEXT,udf.hasNamedArgs()?GET_FUNCTION_WITH_NAMED_ARGS_KEY:GET_FUNCTION_KEY);
        else adapter.invokeVirtual(Types.PAGE_CONTEXT,udf.hasNamedArgs()?GET_FUNCTION_WITH_NAMED_ARGS:GET_FUNCTION);
        rtn=Types.OBJECT;
      }
      }
      return rtn;
  }

  private Type _writeOutFirst(BytecodeContext bc, Member member, int mode, boolean last, boolean doOnlyScope) throws BytecodeException {
   
    if(member instanceof DataMember) {
      return _writeOutOneDataMember(bc,(DataMember)member,last,doOnlyScope);
      //return Variable._writeOutFirstDataMember(adapter,(DataMember)member,variable.scope, last);
    }
      else if(member instanceof UDF) {
        if(last)throw new BytecodeException("can't assign value to a user defined function",getStart());
        return Variable._writeOutFirstUDF(bc,(UDF)member,variable.scope,doOnlyScope);
      }
      else {
        if(last)throw new BytecodeException("can't assign value to a built in function",getStart());
        return Variable._writeOutFirstBIF(bc,(BIF)member,mode,last,getStart());
      }
  }



  private Type _writeOutOneDataMember(BytecodeContext bc, DataMember member,boolean last, boolean doOnlyScope) throws BytecodeException {
      GeneratorAdapter adapter = bc.getAdapter();
   
      if(doOnlyScope){
        adapter.loadArg(0);
        if(variable.scope==Scope.SCOPE_LOCAL){
          return TypeScope.invokeScope(adapter, TypeScope.METHOD_LOCAL_TOUCH,Types.PAGE_CONTEXT);
        }
        return TypeScope.invokeScope(adapter, variable.scope);
      }
     
      // pc.get
    adapter.loadArg(0);
    if(last) {
      TypeScope.invokeScope(adapter, variable.scope);
      //adapter.invokeVirtual(Types.PAGE_CONTEXT,TypeScope.METHODS[variable.scope]);
     
      boolean isKey=Variable.registerKey(bc, member.getName());
      value.writeOut(bc, MODE_REF);
     
      if(isKey)adapter.invokeInterface(TypeScope.SCOPES[variable.scope],METHOD_SCOPE_SET_KEY);
      else adapter.invokeInterface(TypeScope.SCOPES[variable.scope],METHOD_SCOPE_SET);
     
    }
    else {
      adapter.loadArg(0);
      TypeScope.invokeScope(adapter, variable.scope);
      if(Variable.registerKey(bc, member.getName()))
          adapter.invokeVirtual(Types.PAGE_CONTEXT,TOUCH_KEY);
        else
          adapter.invokeVirtual(Types.PAGE_CONTEXT,TOUCH);
    }
    return Types.OBJECT;
   
   
  }

  private Type _writeOutEmpty(BytecodeContext bc) throws BytecodeException {
    GeneratorAdapter adapter = bc.getAdapter();

    if(variable.scope==Scope.SCOPE_ARGUMENTS) {
      adapter.loadArg(0);
      TypeScope.invokeScope(adapter, Scope.SCOPE_ARGUMENTS);
      value.writeOut(bc, MODE_REF);
      adapter.invokeInterface(TypeScope.SCOPE_ARGUMENT,SET_ARGUMENT);
    }
    else {
      adapter.loadArg(0);
      TypeScope.invokeScope(adapter, Scope.SCOPE_UNDEFINED);
      Variable.registerKey(bc,LitString.toExprString(ScopeFactory.toStringScope(variable.scope,"undefined")));
      value.writeOut(bc, MODE_REF);
      adapter.invokeInterface(TypeScope.SCOPES[Scope.SCOPE_UNDEFINED],METHOD_SCOPE_SET_KEY);
    }
   
   
    return Types.OBJECT;
  }

  /**
   * @return the value
   */
  public Expression getValue() {
    return value;
  }


  /**
   * @return the variable
   */
  public Variable getVariable() {
    return variable;
  }
}
TOP

Related Classes of railo.transformer.bytecode.expression.var.Assign

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.