package org.nanovm.converter; // // NanoVMTool, Converter and Upload Tool for the NanoVM // Copyright (C) 2005 by Till Harbaum <Till@Harbaum.org> // // This program 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 2 of the License, or // (at your option) any later version. // // This program 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 this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // Parts of this tool are based on public domain code written by Kimberley // Burchett: http://www.kimbly.com/code/classfile/ // // // NativeMapper.java // import java.io.*; import java.util.*; public class NativeMapper { static private Vector<NativeClass> nativeClasses = new Vector<NativeClass>(); static private Vector<NativeMethod> nativeMethods = new Vector<NativeMethod>(); static private Vector<NativeField> nativeFields = new Vector<NativeField>(); static public int lowestNativeId = 9999; // lowest native class id // java doesn't have native classes, but we do class NativeClass { String className; int id; } class NativeMethod { String className; String name; String type; int id; } class NativeField { String className; String name; String type; int id; } public NativeMapper() { System.out.println("Initializing native mapper"); } public void load(String className) { System.out.println("read native " + className); System.out.println("trying to load "+ className + ".native"); // XXXX File inputFile = new File(className + ".native"); try { String line; String fullClassName = null; int fullClassId = 0; FileInputStream in = new FileInputStream(inputFile); BufferedReader reader = new BufferedReader (new InputStreamReader(in)); // read through all lines in file while ((line = reader.readLine()) != null) { StringTokenizer st = new StringTokenizer(line); boolean skipRest = false; int token_cnt = 0; String name = null, value = null, id = null; while(st.hasMoreTokens() && !skipRest) { String token = st.nextToken(); if(token.charAt(0) == '#') skipRest = true; else { NativeMethod nativeMethod = new NativeMethod(); if(token_cnt == 0) name = token; else if(token_cnt == 1) value = token; else if(token_cnt == 2) id = token; else { System.out.println("Ignoring superfluous data: " + token); } token_cnt++; } } if(token_cnt > 0) { // class entry if(name.equalsIgnoreCase("class") && (token_cnt == 3)) { NativeClass nativeClass = new NativeClass(); nativeClass.className = value; nativeClass.id = Integer.parseInt(id); nativeClasses.addElement(nativeClass); if(Integer.parseInt(id) < lowestNativeId) lowestNativeId = Integer.parseInt(id); // save locally for further method processing fullClassName = value; fullClassId = Integer.parseInt(id); } // method entry else if(name.equalsIgnoreCase("method") && (token_cnt == 3)) { if(value.indexOf(':') == -1) { System.out.println("Invalid method reference"); System.exit(-1); } if(fullClassName == null) { System.out.println("Method reference before class"); System.exit(-1); } // seperate class, method and type NativeMethod nativeMethod = new NativeMethod(); nativeMethod.className = fullClassName; nativeMethod.name = value.substring(0, value.indexOf(':')); nativeMethod.type = value.substring( value.indexOf(':')+1, value.length()); nativeMethod.id = Integer.parseInt(id) + (fullClassId << 8); nativeMethods.addElement(nativeMethod); } // field entry else if(name.equalsIgnoreCase("field") && (token_cnt == 3)) { if(value.indexOf(':') == -1) { System.out.println("Invalid field reference"); System.exit(-1); } if(fullClassName == null) { System.out.println("Method reference before class"); System.exit(-1); } // seperate class, method and type NativeField nativeField = new NativeField(); nativeField.className = fullClassName; nativeField.name = value.substring(0, value.indexOf(':')); nativeField.type = value.substring( value.indexOf(':')+1, value.length()); nativeField.id = Integer.parseInt(id) + (fullClassId << 8); nativeFields.addElement(nativeField); } else { System.out.println("Unknown entry in native file: " + name + " + " + token_cnt + " parms"); System.exit(-1); } } } in.close(); } catch(IOException e) { System.out.println("Error reading map"); System.out.println(e.toString()); System.exit(-1); } } public static boolean methodIsNative(String className, String name, String type) { // search through all native methods for(int i=0;i<nativeMethods.size();i++) { NativeMethod nativeMethod = (NativeMethod)nativeMethods.elementAt(i); // check if we have a match if((className.equals(nativeMethod.className)) && (name.equals(nativeMethod.name)) && (type.equals(nativeMethod.type))) return true; } return false; } public static int getMethodId(String className, String name, String type) { // search through all native methods for(int i=0;i<nativeMethods.size();i++) { NativeMethod nativeMethod = (NativeMethod)nativeMethods.elementAt(i); // check if we have a match if((className.equals(nativeMethod.className)) && (name.equals(nativeMethod.name)) && (type.equals(nativeMethod.type))) return nativeMethod.id; } return -1; } public static int getFieldId(String className, String name, String type) { // search through all native fields for(int i=0;i<nativeFields.size();i++) { NativeField nativeField = (NativeField)nativeFields.elementAt(i); // check if we have a match if((className.equals(nativeField.className)) && (name.equals(nativeField.name)) && (type.equals(nativeField.type))) return nativeField.id; } return -1; } public static int getNativeClassId(String className) { // search through all native classes for(int i=0;i<nativeClasses.size();i++) { NativeClass nativeClass = (NativeClass)nativeClasses.elementAt(i); if(nativeClass.className.equals(className)) return nativeClass.id; } return -1; } }