Package org.formulacompiler.compiler.internal.bytecode

Source Code of org.formulacompiler.compiler.internal.bytecode.RootSectionCompiler

/*
* Copyright (c) 2006-2009 by Abacus Research AG, Switzerland.
* All rights reserved.
*
* This file is part of the Abacus Formula Compiler (AFC).
*
* For commercial licensing, please contact sales(at)formulacompiler.com.
*
* AFC is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AFC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AFC.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.formulacompiler.compiler.internal.bytecode;

import static org.formulacompiler.compiler.internal.bytecode.ByteCodeEngineCompiler.*;

import org.formulacompiler.compiler.CompilerException;
import org.formulacompiler.compiler.internal.model.SectionModel;
import org.formulacompiler.runtime.ComputationMode;
import org.formulacompiler.runtime.internal.spreadsheet.CellAddressImpl;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.GeneratorAdapter;

final class RootSectionCompiler extends SectionCompiler
{
  private static final org.objectweb.asm.commons.Method EMPTY_CONSTRUCTOR_METHOD = org.objectweb.asm.commons.Method
      .getMethod( "void <init>()" );
  private static final org.objectweb.asm.commons.Method RESET_METHOD = org.objectweb.asm.commons.Method
      .getMethod( "void reset()" );


  RootSectionCompiler( ByteCodeEngineCompiler _compiler, SectionModel _model, boolean _computationListenerEnabled )
  {
    super( _compiler, _model, GEN_ROOT_NAME, _computationListenerEnabled );
  }

  @Override
  protected SectionCompiler parentSectionCompiler()
  {
    return null;
  }

  @Override
  protected RootSectionCompiler rootSectionCompiler()
  {
    return this;
  }


  @Override
  protected void buildMembers()
  {
    super.buildMembers();
    buildEnvironmentMember();
  }

  private void buildEnvironmentMember()
  {
    // Package visible so subsections can read it.
    newField( Opcodes.ACC_FINAL, ENV_MEMBER_NAME, ENV_DESC );
  }


  private MethodCompiler constructor;

  @Override
  protected void buildConstructorWithInputs() throws CompilerException
  {

    this.constructor = new MethodCompiler( RootSectionCompiler.this, 0, "<init>", "(" + inputType().getDescriptor() + ENV_DESC + ")V" )
    {
      @Override
      protected void compileBody() throws CompilerException
      {
        GeneratorAdapter mv = mv();

        // super( _inputs ); or super();
        callInheritedConstructor( mv, 1 );

        // this.environment = _environment;
        mv.loadThis();
        mv.loadArg( 1 );
        mv.putField( section().classType(), ENV_MEMBER_NAME, ENV_CLASS );

        // this.inputs = _inputs;
        if (hasInputs()) {
          mv.loadThis();
          mv.loadArg( 0 );
          storeInputs( mv );
        }

        //this.sectionInfo = new SectionInfoImpl(...);
        if (isComputationListenerEnabled()) {
          mv.loadThis();
          mv.push( -1 ); //section index
          final ExpressionCompilerForNumbers c = numericCompiler();
          c.compile_util_createSectionInfo( model().getName(),
              null, CellAddressImpl.BROKEN_REF, CellAddressImpl.BROKEN_REF,
              null, CellAddressImpl.BROKEN_REF, CellAddressImpl.BROKEN_REF );
          mv.putField( section().classType(), SECTION_INFO_MEMBER_NAME, SECTION_INFO_CLASS );
        }

        if (RootSectionCompiler.this.computationTimeCompiled) {
          mv.loadThis();
          mv.newInstance( COMP_TIME_CLASS );
          mv.dup();
          mv.invokeConstructor( COMP_TIME_CLASS, EMPTY_CONSTRUCTOR_METHOD );
          mv.putField( section().classType(), COMP_TIME_MEMBER_NAME, COMP_TIME_CLASS );
        }

        if (RootSectionCompiler.this.computationModeCompiled) {
          mv.loadThis();
          final ComputationMode computationMode = model().getEngine().getComputationMode();
          mv.getStatic( COMP_MODE_CLASS, computationMode.name(), COMP_MODE_CLASS );
          mv.putField( classType(), COMP_MODE_MEMBER_NAME, COMP_MODE_CLASS );
        }

        mv.visitInsn( Opcodes.RETURN );
      }
    };
  }

  @Override
  protected void finalizeConstructor() throws CompilerException
  {
    this.constructor.compile();
  }


  @Override
  protected void compileEnvironmentAccess( GeneratorAdapter _mv )
  {
    _mv.loadThis();
    _mv.getField( classType(), ENV_MEMBER_NAME, ENV_CLASS );
  }


  private boolean computationModeCompiled = false;

  private void compileComputationMode()
  {
    if (!this.computationModeCompiled) {
      newField( Opcodes.ACC_FINAL, COMP_MODE_MEMBER_NAME, COMP_MODE_DESC );
      this.computationModeCompiled = true;
    }
  }

  @Override
  protected void compileComputationModeAccess( GeneratorAdapter _mv )
  {
    _mv.loadThis();
    compileComputationModeAccessGivenThis( _mv );
  }

  void compileComputationModeAccessGivenThis( GeneratorAdapter _mv )
  {
    compileComputationMode();
    _mv.getField( classType(), COMP_MODE_MEMBER_NAME, COMP_MODE_CLASS );
  }


  private boolean computationTimeCompiled = false;

  private void compileComputationTime()
  {
    if (!this.computationTimeCompiled) {
      newField( Opcodes.ACC_FINAL, COMP_TIME_MEMBER_NAME, COMP_TIME_DESC );
      if (hasReset()) {
        GeneratorAdapter mv = resetter();
        mv.loadThis();
        mv.getField( classType(), COMP_TIME_MEMBER_NAME, COMP_TIME_CLASS );
        mv.invokeVirtual( COMP_TIME_CLASS, RESET_METHOD );
      }
      this.computationTimeCompiled = true;
    }
  }

  @Override
  protected void compileComputationTimeAccess( GeneratorAdapter _mv )
  {
    _mv.loadThis();
    compileComputationTimeAccessGivenThis( _mv );
  }

  void compileComputationTimeAccessGivenThis( GeneratorAdapter _mv )
  {
    compileComputationTime();
    _mv.getField( classType(), COMP_TIME_MEMBER_NAME, COMP_TIME_CLASS );
  }

}
TOP

Related Classes of org.formulacompiler.compiler.internal.bytecode.RootSectionCompiler

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.