rt/vm/src/main/java/org/apidesign/vm4brwsr/LocalsMapper.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 26 Feb 2013 16:54:16 +0100
changeset 772 d382dacfd73f
parent 442 vm/src/main/java/org/apidesign/vm4brwsr/LocalsMapper.java@b107ed66f2e7
child 810 9eb750594b15
permissions -rw-r--r--
Moving modules around so the runtime is under one master pom and can be built without building other modules that are in the repository
lubomir@319
     1
/**
lubomir@319
     2
 * Back 2 Browser Bytecode Translator
lubomir@319
     3
 * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
lubomir@319
     4
 *
lubomir@319
     5
 * This program is free software: you can redistribute it and/or modify
lubomir@319
     6
 * it under the terms of the GNU General Public License as published by
lubomir@319
     7
 * the Free Software Foundation, version 2 of the License.
lubomir@319
     8
 *
lubomir@319
     9
 * This program is distributed in the hope that it will be useful,
lubomir@319
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
lubomir@319
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
lubomir@319
    12
 * GNU General Public License for more details.
lubomir@319
    13
 *
lubomir@319
    14
 * You should have received a copy of the GNU General Public License
lubomir@319
    15
 * along with this program. Look for COPYING file in the top folder.
lubomir@319
    16
 * If not, see http://opensource.org/licenses/GPL-2.0.
lubomir@319
    17
 */
lubomir@319
    18
package org.apidesign.vm4brwsr;
lubomir@319
    19
lubomir@319
    20
import java.io.IOException;
lubomir@319
    21
import org.apidesign.javap.RuntimeConstants;
lubomir@319
    22
import org.apidesign.javap.TypeArray;
lubomir@319
    23
lubomir@319
    24
final class LocalsMapper {
lubomir@319
    25
    private final TypeArray argTypeRecords;
lubomir@319
    26
    private final TypeArray localTypeRecords;
lubomir@319
    27
lubomir@319
    28
    public LocalsMapper(final TypeArray stackMapArgs) {
lubomir@319
    29
        final TypeArray initTypeRecords = new TypeArray();
lubomir@319
    30
        updateRecords(initTypeRecords, stackMapArgs);
lubomir@319
    31
lubomir@319
    32
        argTypeRecords = initTypeRecords;
lubomir@319
    33
        localTypeRecords = new TypeArray(initTypeRecords);
lubomir@319
    34
    }
lubomir@319
    35
jaroslav@442
    36
    public void outputArguments(final Appendable out, boolean isStatic) throws IOException {
lubomir@319
    37
        final int argRecordCount = argTypeRecords.getSize();
jaroslav@442
    38
        int first = isStatic ? 0 : 1;
jaroslav@442
    39
        if (argRecordCount > first) {
jaroslav@442
    40
            Variable variable = getVariable(argTypeRecords, first);
lubomir@319
    41
            out.append(variable);
lubomir@319
    42
jaroslav@442
    43
            int i = first + (variable.isCategory2() ? 2 : 1);
lubomir@319
    44
            while (i < argRecordCount) {
lubomir@319
    45
                variable = getVariable(argTypeRecords, i);
lubomir@319
    46
                out.append(", ");
lubomir@319
    47
                out.append(variable);
lubomir@319
    48
                i += variable.isCategory2() ? 2 : 1;
lubomir@319
    49
            }
lubomir@319
    50
        }
lubomir@319
    51
    }
lubomir@319
    52
lubomir@319
    53
    public void syncWithFrameLocals(final TypeArray frameLocals) {
lubomir@319
    54
        updateRecords(localTypeRecords, frameLocals);
lubomir@319
    55
    }
lubomir@319
    56
lubomir@319
    57
    public Variable setI(final int index) {
lubomir@319
    58
        return setT(index, VarType.INTEGER);
lubomir@319
    59
    }
lubomir@319
    60
lubomir@319
    61
    public Variable setL(final int index) {
lubomir@319
    62
        return setT(index, VarType.LONG);
lubomir@319
    63
    }
lubomir@319
    64
lubomir@319
    65
    public Variable setF(final int index) {
lubomir@319
    66
        return setT(index, VarType.FLOAT);
lubomir@319
    67
    }
lubomir@319
    68
lubomir@319
    69
    public Variable setD(final int index) {
lubomir@319
    70
        return setT(index, VarType.DOUBLE);
lubomir@319
    71
    }
lubomir@319
    72
lubomir@319
    73
    public Variable setA(final int index) {
lubomir@319
    74
        return setT(index, VarType.REFERENCE);
lubomir@319
    75
    }
lubomir@319
    76
lubomir@319
    77
    public Variable setT(final int index, final int type) {
lubomir@319
    78
        updateRecord(localTypeRecords, index, type);
lubomir@319
    79
        return Variable.getLocalVariable(type, index);
lubomir@319
    80
    }
lubomir@319
    81
lubomir@319
    82
    public Variable getI(final int index) {
lubomir@319
    83
        return getT(index, VarType.INTEGER);
lubomir@319
    84
    }
lubomir@319
    85
lubomir@319
    86
    public Variable getL(final int index) {
lubomir@319
    87
        return getT(index, VarType.LONG);
lubomir@319
    88
    }
lubomir@319
    89
lubomir@319
    90
    public Variable getF(final int index) {
lubomir@319
    91
        return getT(index, VarType.FLOAT);
lubomir@319
    92
    }
lubomir@319
    93
lubomir@319
    94
    public Variable getD(final int index) {
lubomir@319
    95
        return getT(index, VarType.DOUBLE);
lubomir@319
    96
    }
lubomir@319
    97
lubomir@319
    98
    public Variable getA(final int index) {
lubomir@319
    99
        return getT(index, VarType.REFERENCE);
lubomir@319
   100
    }
lubomir@319
   101
lubomir@319
   102
    public Variable getT(final int index, final int type) {
lubomir@319
   103
        final int oldRecordValue = localTypeRecords.get(index);
lubomir@319
   104
        if ((oldRecordValue & 0xff) != type) {
lubomir@319
   105
            throw new IllegalStateException("Type mismatch");
lubomir@319
   106
        }
lubomir@319
   107
lubomir@319
   108
        return Variable.getLocalVariable(type, index);
lubomir@319
   109
    }
lubomir@319
   110
lubomir@319
   111
    private static void updateRecords(final TypeArray typeRecords,
lubomir@319
   112
                                      final TypeArray stackMapTypes) {
lubomir@319
   113
        final int srcSize = stackMapTypes.getSize();
lubomir@319
   114
        for (int i = 0, dstIndex = 0; i < srcSize; ++i) {
lubomir@319
   115
            final int smType = stackMapTypes.get(i);
lubomir@319
   116
            if (smType == RuntimeConstants.ITEM_Bogus) {
lubomir@319
   117
                ++dstIndex;
lubomir@319
   118
                continue;
lubomir@319
   119
            }
lubomir@319
   120
            final int varType = VarType.fromStackMapType(smType);
lubomir@319
   121
            updateRecord(typeRecords, dstIndex, varType);
lubomir@319
   122
            dstIndex += VarType.isCategory2(varType) ? 2 : 1;
lubomir@319
   123
        }
lubomir@319
   124
    }
lubomir@319
   125
lubomir@319
   126
    private static void updateRecord(final TypeArray typeRecords,
lubomir@319
   127
                                     final int index, final int type) {
lubomir@319
   128
        if (typeRecords.getSize() < (index + 1)) {
lubomir@319
   129
            typeRecords.setSize(index + 1);
lubomir@319
   130
        }
lubomir@319
   131
lubomir@319
   132
        final int oldRecordValue = typeRecords.get(index);
lubomir@319
   133
        final int usedTypesMask =
lubomir@319
   134
                (oldRecordValue >> 8) | (1 << type);
lubomir@319
   135
        typeRecords.set(index, (usedTypesMask << 8) | type);
lubomir@319
   136
    }
lubomir@319
   137
lubomir@319
   138
    private static Variable getVariable(final TypeArray typeRecords,
lubomir@319
   139
                                        final int index) {
lubomir@319
   140
        return Variable.getLocalVariable(typeRecords.get(index) & 0xff, index);
lubomir@319
   141
    }
lubomir@319
   142
}