Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   ***** BEGIN LICENSE BLOCK *****
   * Version: EPL 1.0/GPL 2.0/LGPL 2.1
   *
   * The contents of this file are subject to the Eclipse Public
   * License Version 1.0 (the "License"); you may not use this file
   * except in compliance with the License. You may obtain a copy of
   * the License at http://www.eclipse.org/legal/epl-v10.html
   *
  * Software distributed under the License is distributed on an "AS
  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  * implied. See the License for the specific language governing
  * rights and limitations under the License.
  * 
  * Alternatively, the contents of this file may be used under the terms of
  * either of the GNU General Public License Version 2 or later (the "GPL"),
  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the EPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the EPL, the GPL or the LGPL.
  ***** END LICENSE BLOCK *****/
 
 package org.jruby.compiler.impl;
 
 import org.jruby.Ruby;
 import  org.objectweb.asm.Label;
 import static org.jruby.util.CodegenUtils.*;

Author(s):
headius
 
     public HeapBasedVariableCompiler(
             BaseBodyCompiler methodCompiler,
             SkinnyMethodAdapter method,
             StaticScope scope,
             boolean specificArity,
             int argsIndex,
             int firstTempIndex) {
         super(methodCompilermethodscopespecificArityargsIndexfirstTempIndex);
     }
 
     public void beginMethod(CompilerCallback argsCallbackStaticScope scope) {
         // store the local vars in a local variable if there are any
         if (scope.getNumberOfVariables() > 0) {
             .loadThreadContext();
             .invokeThreadContext("getCurrentScope"sig(DynamicScope.class));
             .astore(.getDynamicScopeIndex());
 
             // if more than 4 locals, get and populate the locals array too
             if (scope.getNumberOfVariables() > 4) {
                 .aload(.getDynamicScopeIndex());
                 .invokevirtual(p(DynamicScope.class), "getValues"sig(IRubyObject[].class));
                 .astore(.getVarsArrayIndex());
 
                 // fill local vars with nil, to avoid checking every access.
                 .aload(.getVarsArrayIndex());
                 .loadRuntime();
                 .invokeUtilityMethod("fillNil"sig(void.classIRubyObject[].classRuby.class));
             }
         }
 
         if (argsCallback != null) {
             argsCallback.call();
         }
         
         // default for starting tempVariableIndex is ok
     }
     
     public void declareLocals(StaticScope scope, Label start, Label end) {
         // declare locals for Java debugging purposes
         .visitLocalVariable("locals"ci(DynamicScope.class), nullstartend.getDynamicScopeIndex());
     }
 
     public void beginClass(StaticScope scope) {
         assert scope != null : "compiling a class body with no scope";
         
         // store the local vars in a local variable for preparing the class (using previous scope)
         .loadThreadContext();
         .invokeThreadContext("getCurrentScope"sig(DynamicScope.class));
         .dup();
         .invokevirtual(p(DynamicScope.class), "getValues"sig(IRubyObject[].class));
         
         // store the new local vars in a local variable
         .loadThreadContext();
         .invokeThreadContext("getCurrentScope"sig(DynamicScope.class));
        // if more than 4 locals, get the locals array too
        if (scope.getNumberOfVariables() > 4) {
            .invokevirtual(p(DynamicScope.class), "getValues"sig(IRubyObject[].class));
            .astore(.getVarsArrayIndex());
        }
        if (scope.getNumberOfVariables() >= 1) {
            switch (scope.getNumberOfVariables()) {
            case 1:
                .loadNil();
                assignLocalVariable(0, false);
                break;
            case 2:
                .loadNil();
                assignLocalVariable(0,true);
                assignLocalVariable(1,false);
                break;
            case 3:
                .loadNil();
                assignLocalVariable(0,true);
                assignLocalVariable(1,true);
                assignLocalVariable(2,false);
                break;
            case 4:
                .loadNil();
                assignLocalVariable(0,true);
                assignLocalVariable(1,true);
                assignLocalVariable(2,true);
                assignLocalVariable(3,false);
                break;
            default:
                .aload(.getVarsArrayIndex());
                .loadNil();
                assignLocalVariable(0,true);
                assignLocalVariable(1,true);
                assignLocalVariable(2,true);
                assignLocalVariable(3,false);
                .loadRuntime();
                .invokeUtilityMethod("fillNil"sig(void.classIRubyObject[].classRuby.class));
            }
        }
    }
    public void beginClosure(CompilerCallback argsCallbackStaticScope scope) {
        assert scope != null : "compiling a closure body with no scope";
        
        .invokeThreadContext("getCurrentScope"sig(DynamicScope.class));
        // if more than 4 locals, get the locals array too
        if (scope.getNumberOfVariables() > 4) {
            .invokevirtual(p(DynamicScope.class), "getValues"sig(IRubyObject[].class));
            .astore(.getVarsArrayIndex());
        }
        
        if (scope.getNumberOfVariables() >= 1) {
            switch (scope.getNumberOfVariables()) {
            case 1:
                .loadNil();
                assignLocalVariable(0, false);
                break;
            case 2:
                .loadNil();
                assignLocalVariable(0,true);
                assignLocalVariable(1,false);
                break;
            case 3:
                .loadNil();
                assignLocalVariable(0,true);
                assignLocalVariable(1,true);
                assignLocalVariable(2,false);
                break;
            case 4:
                .loadNil();
                assignLocalVariable(0,true);
                assignLocalVariable(1,true);
                assignLocalVariable(2,true);
                assignLocalVariable(3,false);
                break;
            default:
                .aload(.getVarsArrayIndex());
                .loadNil();
                assignLocalVariable(0,true);
                assignLocalVariable(1,true);
                assignLocalVariable(2,true);
                assignLocalVariable(3,false);
                .loadRuntime();
                .invokeUtilityMethod("fillNil"sig(void.classIRubyObject[].classRuby.class));
            }
        }
        if (argsCallback != null) {
            // load block
            .loadRuntime();
            .aload(.getClosureIndex());
            .invokeUtilityMethod("processBlockArgument"sig(IRubyObject.classparams(Ruby.classBlock.class)));
            // load args (the IRubyObject representing incoming normal args)
            .aload();
            argsCallback.call();
        }
    }
    public void beginFlatClosure(CompilerCallback argsCallbackStaticScope scope) {
        .invokeThreadContext("getCurrentScope"sig(DynamicScope.class));
        // if more than 4 locals, get the locals array too
        if (scope.getNumberOfVariables() > 4) {
            .invokevirtual(p(DynamicScope.class), "getValues"sig(IRubyObject[].class));
            .astore(.getVarsArrayIndex());
        }
        // no variable initialization, because we're reusing parent's scope (flat)
        if (argsCallback != null) {
            // load block
            .loadRuntime();
            .aload(.getClosureIndex());
            .invokeUtilityMethod("processBlockArgument"sig(IRubyObject.classparams(Ruby.classBlock.class)));
            // load args (the IRubyObject representing incoming normal args)
            .aload();
            argsCallback.call();
        }
    }
    public void assignLocalVariable(int index,boolean expr) {
        switch (index) {
        case 0:
            .swap();
            .invokevirtual(p(DynamicScope.class), "setValueZeroDepthZero"sig(IRubyObject.classparams(IRubyObject.class)));
            if (!expr.pop();
            break;
        case 1:
            .swap();
            .invokevirtual(p(DynamicScope.class), "setValueOneDepthZero"sig(IRubyObject.classparams(IRubyObject.class)));
            if (!expr.pop();
            break;
        case 2:
            .swap();
            .invokevirtual(p(DynamicScope.class), "setValueTwoDepthZero"sig(IRubyObject.classparams(IRubyObject.class)));
            if (!expr.pop();
            break;
        case 3:
            .swap();
            .invokevirtual(p(DynamicScope.class), "setValueThreeDepthZero"sig(IRubyObject.classparams(IRubyObject.class)));
            if (!expr.pop();
            break;
        default:
            if (expr.dup();
            .aload(.getVarsArrayIndex());
            .swap();
            .pushInt(index);
            .swap();
            .arraystore();
            break;
        }
        // for specific-index cases, clean up non-expression values
    }
    public void assignLocalVariable(int indexCompilerCallback valueboolean expr) {
        switch (index) {
        case 0:
            value.call();
            .invokevirtual(p(DynamicScope.class), "setValueZeroDepthZero"sig(IRubyObject.classparams(IRubyObject.class)));
            if (!expr.pop();
            break;
        case 1:
            value.call();
            .invokevirtual(p(DynamicScope.class), "setValueOneDepthZero"sig(IRubyObject.classparams(IRubyObject.class)));
            if (!expr.pop();
            break;
        case 2:
            value.call();
            .invokevirtual(p(DynamicScope.class), "setValueTwoDepthZero"sig(IRubyObject.classparams(IRubyObject.class)));
            if (!expr.pop();
            break;
        case 3:
            value.call();
            .invokevirtual(p(DynamicScope.class), "setValueThreeDepthZero"sig(IRubyObject.classparams(IRubyObject.class)));
            if (!expr.pop();
            break;
        default:
            .aload(.getVarsArrayIndex());
            .pushInt(index);
            value.call();
            if (expr.dup_x2();
            .arraystore();
            break;
        }
    }
    public void assignLocalVariable(int indexint depth,boolean expr) {
        if (depth == 0) {
            assignLocalVariable(indexexpr);
            return;
        }
        assignHeapLocal(depthindexexpr);
    }
    public void assignLocalVariable(int indexint depthCompilerCallback value,boolean expr) {
        if (depth == 0) {
            assignLocalVariable(indexvalueexpr);
            return;
        }
        assignHeapLocal(valuedepthindexexpr);
    }
    public void retrieveLocalVariable(int index) {
        switch (index) {
        case 0:
            .loadNil();
            .invokevirtual(p(DynamicScope.class), "getValueZeroDepthZeroOrNil"sig(IRubyObject.classIRubyObject.class));
            break;
        case 1:
            .loadNil();
            .invokevirtual(p(DynamicScope.class), "getValueOneDepthZeroOrNil"sig(IRubyObject.classIRubyObject.class));
            break;
        case 2:
            .loadNil();
            .invokevirtual(p(DynamicScope.class), "getValueTwoDepthZeroOrNil"sig(IRubyObject.classIRubyObject.class));
            break;
        case 3:
            .loadNil();
            .invokevirtual(p(DynamicScope.class), "getValueThreeDepthZeroOrNil"sig(IRubyObject.classIRubyObject.class));
            break;
        default:
            .aload(.getVarsArrayIndex());
            .pushInt(index);
            .arrayload();
        }
    }
    public void retrieveLocalVariable(int indexint depth) {
        if (depth == 0) {
            retrieveLocalVariable(index);
            return;
        }
        
        retrieveHeapLocal(depthindex);
    }
    public boolean isHeap() {
        return true;
    }
New to GrepCode? Check out our FAQ X