Package org.perl6.nqp.jast2bc

Source Code of org.perl6.nqp.jast2bc.JastMethod

package org.perl6.nqp.jast2bc;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.objectweb.asm.Label;
import org.objectweb.asm.Type;

import static org.perl6.nqp.runtime.Ops.*;
import org.perl6.nqp.runtime.ThreadContext;

import static org.perl6.nqp.jast2bc.JASTCompiler.processType;
import org.perl6.nqp.jast2bc.JASTCompiler.LabelInfo;
import org.perl6.nqp.jast2bc.JASTCompiler.VariableDef;

import org.perl6.nqp.sixmodel.SixModelObject;

public class JastMethod {
    public String name;
    public boolean isStatic = false;
    public Type returns;
    public List<Type> arguments = new ArrayList<Type>();
    public Map<String, VariableDef> locals = new HashMap<String, VariableDef>();
    public SixModelObject instructions;
    public String crName;
    public String crCuid;
    public int crOuter = -2; // -1 = has no outer  -2 = not a coderef
    public List<String> crOlex = new ArrayList<String>();
    public List<String> crIlex = new ArrayList<String>();
    public List<String> crNlex = new ArrayList<String>();
    public List<String> crSlex = new ArrayList<String>();
    public long[] crHandlers;
    public boolean hasExitHandler = false;
    public short argsExpectation = 0;
    public boolean isThunk = false;

    Label beginAll, endAll;
    Map<String, LabelInfo> labels = new HashMap<String, LabelInfo>();

    public JastMethod(SixModelObject jast, SixModelObject jastMethod, ThreadContext tc) throws Exception {
        if (istype(jast, jastMethod, tc) == 0)
            throw new Exception("JAST node isn't a JAST::Method");

        SixModelObject iter;
        beginAll = new Label();
        endAll = new Label();
        int curArgIndex = 1;

        name = getattr_s(jast, jastMethod, "$!name", nameHint, tc);
        returns = processType(getattr(jast, jastMethod, "$!returns", returnsHint, tc).get_str(tc));
        isStatic = getattr_i(jast, jastMethod, "$!static", staticHint, tc) != 0;
        if (isStatic)
            curArgIndex = 0;

        iter = iter(getattr(jast, jastMethod, "@!arguments", argumentsHint, tc), tc);
        while (istrue(iter, tc) != 0) {
            SixModelObject pair = iter.shift_boxed(tc);
            String name = pair.at_pos_boxed(tc, 0).get_str(tc);
            Type type = processType(pair.at_pos_boxed(tc, 1).get_str(tc));
            arguments.add(type);
            if (locals.containsKey(name))
                throw new Exception("Duplicate local name: " + name);
            locals.put(name, new VariableDef(curArgIndex, type.getDescriptor(), beginAll, endAll));
            curArgIndex += (type == Type.LONG_TYPE || type == Type.DOUBLE_TYPE ? 2 : 1);
        }

        iter = iter(getattr(jast, jastMethod, "@!locals", localsHint, tc), tc);
        while (istrue(iter, tc) != 0) {
            SixModelObject pair = iter.shift_boxed(tc);
            String name = pair.at_pos_boxed(tc, 0).get_str(tc);
            Type type = processType(pair.at_pos_boxed(tc, 1).get_str(tc));
            if (locals.containsKey(name))
                throw new Exception("Duplicate local name: " + name);
            locals.put(name, new VariableDef(curArgIndex, type.getDescriptor(), beginAll, endAll));
            curArgIndex += (type == Type.LONG_TYPE || type == Type.DOUBLE_TYPE ? 2 : 1);
        }

        instructions = getattr(jast, jastMethod, "@!instructions", instructionsHint, tc);

        crName = getattr_s(jast, jastMethod, "$!cr_name", crNameHint, tc);
        crCuid = getattr_s(jast, jastMethod, "$!cr_cuid", crCuidHint, tc);
        crOuter = (int) getattr_i(jast, jastMethod, "$!cr_outer", crOuterHint, tc);

        fillList(crOlex, getattr(jast, jastMethod, "@!cr_olex", crOlexHint, tc), tc);
        fillList(crIlex, getattr(jast, jastMethod, "@!cr_ilex", crIlexHint, tc), tc);
        fillList(crNlex, getattr(jast, jastMethod, "@!cr_nlex", crNlexHint, tc), tc);
        fillList(crSlex, getattr(jast, jastMethod, "@!cr_slex", crSlexHint, tc), tc);

        SixModelObject handlersList = getattr(jast, jastMethod, "@!cr_handlers", crHandlersHint, tc);
        iter = iter(handlersList, tc);
        crHandlers = new long[(int) elems(handlersList, tc)];
        for (int i = 0; istrue(iter, tc) != 0; i++) {
            crHandlers[i] = iter.shift_boxed(tc).get_int(tc);
        }
        hasExitHandler = getattr_i(jast, jastMethod, "$!has_exit_handler", hasExitHandlerHint, tc) != 0;
        argsExpectation = (short) getattr_i(jast, jastMethod, "$!args_expectation", argsExpectationHint, tc);
        try {
            isThunk = getattr_i(jast, jastMethod, "$!is_thunk", isThunkHint, tc) != 0;
        } catch (Throwable t) {
            /* Most likely a version of the node without the field. */
        }
    }

    private void fillList(List<String> list, SixModelObject smoList, ThreadContext tc) {
        SixModelObject iter = iter(smoList, tc);
        while(istrue(iter, tc) != 0) {
            String value = iter.shift_boxed(tc).get_str(tc);
            list.add(value);
        }
    }

    private static long nameHint, staticHint, returnsHint, argumentsHint,
            localsHint, instructionsHint, crNameHint, crCuidHint, crOuterHint,
            crOlexHint, crIlexHint, crNlexHint, crSlexHint, crHandlersHint,
            hasExitHandlerHint, argsExpectationHint, isThunkHint;
    public static void setup(SixModelObject jastMethod, ThreadContext tc) {
        nameHint            = jastMethod.st.REPR.hint_for(tc, jastMethod.st, jastMethod, "$!name");
        staticHint          = jastMethod.st.REPR.hint_for(tc, jastMethod.st, jastMethod, "$!static");
        returnsHint         = jastMethod.st.REPR.hint_for(tc, jastMethod.st, jastMethod, "$!returns");
        argumentsHint       = jastMethod.st.REPR.hint_for(tc, jastMethod.st, jastMethod, "@!arguments");
        localsHint          = jastMethod.st.REPR.hint_for(tc, jastMethod.st, jastMethod, "@!locals");
        instructionsHint    = jastMethod.st.REPR.hint_for(tc, jastMethod.st, jastMethod, "@!instructions");
        crNameHint          = jastMethod.st.REPR.hint_for(tc, jastMethod.st, jastMethod, "$!cr_name");
        crCuidHint          = jastMethod.st.REPR.hint_for(tc, jastMethod.st, jastMethod, "$!cr_cuid");
        crOuterHint         = jastMethod.st.REPR.hint_for(tc, jastMethod.st, jastMethod, "$!cr_outer");
        crOlexHint          = jastMethod.st.REPR.hint_for(tc, jastMethod.st, jastMethod, "@!cr_olex");
        crIlexHint          = jastMethod.st.REPR.hint_for(tc, jastMethod.st, jastMethod, "@!cr_ilex");
        crNlexHint          = jastMethod.st.REPR.hint_for(tc, jastMethod.st, jastMethod, "@!cr_nlex");
        crSlexHint          = jastMethod.st.REPR.hint_for(tc, jastMethod.st, jastMethod, "@!cr_slex");
        crHandlersHint      = jastMethod.st.REPR.hint_for(tc, jastMethod.st, jastMethod, "@!cr_handlers");
        hasExitHandlerHint  = jastMethod.st.REPR.hint_for(tc, jastMethod.st, jastMethod, "$!has_exit_handler");
        argsExpectationHint = jastMethod.st.REPR.hint_for(tc, jastMethod.st, jastMethod, "$!args_expectation");
        isThunkHint         = jastMethod.st.REPR.hint_for(tc, jastMethod.st, jastMethod, "$!is_thunk");
    }
}
TOP

Related Classes of org.perl6.nqp.jast2bc.JastMethod

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.