Package xscript.runtime.instruction

Source Code of xscript.runtime.instruction.XInstructionSetField

package xscript.runtime.instruction;

import java.io.IOException;

import xscript.runtime.XChecks;
import xscript.runtime.XModifier;
import xscript.runtime.XRuntimeException;
import xscript.runtime.XVirtualMachine;
import xscript.runtime.clazz.XClass;
import xscript.runtime.clazz.XField;
import xscript.runtime.clazz.XInputStream;
import xscript.runtime.clazz.XOutputStream;
import xscript.runtime.clazz.XPrimitive;
import xscript.runtime.genericclass.XClassPtr;
import xscript.runtime.object.XObject;
import xscript.runtime.threads.XMethodExecutor;
import xscript.runtime.threads.XThread;

public class XInstructionSetField extends XInstruction {

  private String className;
  private String fieldName;
  private XClassPtr fieldType;
  private XField field;
 
  public XInstructionSetField(XField field){
    className = field.getDeclaringClass().getName();
    fieldName = field.getSimpleName();
    fieldType = field.getType();
    this.field = field;
  }
 
  public XInstructionSetField(XInputStream inputStream) throws IOException{
    className = inputStream.readUTF();
    fieldName = inputStream.readUTF();
    fieldType = XClassPtr.load(inputStream);
  }
 
  @Override
  public void run(XVirtualMachine vm, XThread thread, XMethodExecutor methodExecutor) {
    resolve(vm, methodExecutor);
    long value = methodExecutor.pop(getPrimitiveID(vm));
    long pointer = methodExecutor.oPop();
    XObject object = vm.getObjectProvider().getObject(pointer);
    if(XModifier.isFinal(field.getModifier())){
      XObject _this = vm.getObjectProvider().getObject(methodExecutor.getLocal(0));
      if(methodExecutor.getMethod().getSimpleName().equals("<init>") && _this==object){
        field.finalSet(object, value);
      }else{
        throw new XRuntimeException("Try to write final field %s", field.getName());
      }
    }else{
      field.set(object, value);
    }
  }

  private int getPrimitiveID(XVirtualMachine vm){
    XClass xClass = fieldType.getXClass(vm);
    if(xClass==null)
      return XPrimitive.OBJECT;
    return XPrimitive.getPrimitiveID(xClass);
  }
 
  private void resolve(XVirtualMachine vm, XMethodExecutor methodExecutor){
    if(field==null){
      XClass xClass = vm.getClassProvider().getXClass(className);
      field = xClass.getField(fieldName);
      XChecks.checkAccess(methodExecutor.getMethod().getDeclaringClass(), field);
      if(!field.getType().equals(fieldType)){
        throw new XRuntimeException("Type of field %s has changed", field);
      }
      if(XModifier.isStatic(field.getModifier())){
        throw new XRuntimeException("Field %s is static", field);
      }
    }
  }
 
  @Override
  protected void save(XOutputStream outputStream) throws IOException {
    outputStream.writeUTF(className);
    outputStream.writeUTF(fieldName);
    fieldType.save(outputStream);
  }

  @Override
  public String getSource() {
    return "sf "+className+"."+fieldName+":"+fieldType;
  }

}
TOP

Related Classes of xscript.runtime.instruction.XInstructionSetField

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.