# HG changeset patch # User Lubomir Nerad # Date 1367856368 -7200 # Node ID f5c9934a252cddcf77235c30b46e590d251767ba # Parent 9d6130cb464faf96445ddc5b6271141f875b2e82 Overridable class member access type diff -r 9d6130cb464f -r f5c9934a252c rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon May 06 11:57:29 2013 +0200 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon May 06 18:06:08 2013 +0200 @@ -59,6 +59,11 @@ return classOperation; } + protected String accessMember(String object, String mangledName, + String[] fieldInfoName) throws IOException { + return object + "." + mangledName; + } + protected void declaredClass(ClassData classData, String mangledName) throws IOException { } @@ -94,7 +99,11 @@ */ public String compile(InputStream classFile) throws IOException { - this.jc = new ClassData(classFile); + return compile(new ClassData(classFile)); + } + + protected String compile(ClassData classData) throws IOException { + this.jc = classData; if (jc.getMajor_version() < 50) { throw new IOException("Can't compile " + jc.getClassName() + ". Class file version " + jc.getMajor_version() + "." + jc.getMinor_version() + " - recompile with -target 1.6 (at least)." @@ -1195,10 +1204,11 @@ final int type = VarType.fromFieldType(fi[2].charAt(0)); final String mangleClass = mangleSig(fi[0]); final String mangleClassAccess = accessClass(mangleClass); - emit(out, "var @2 = @4(false)._@3.call(@1);", + emit(out, "var @2 = @3.call(@1);", smapper.popA(), - smapper.pushT(type), fi[1], mangleClassAccess - ); + smapper.pushT(type), + accessMember(mangleClassAccess + "(false)", + "_" + fi[1], fi)); i += 2; break; } @@ -1208,11 +1218,11 @@ final int type = VarType.fromFieldType(fi[2].charAt(0)); final String mangleClass = mangleSig(fi[0]); final String mangleClassAccess = accessClass(mangleClass); - emit(out, "@4(false)._@3.call(@2, @1);", + emit(out, "@3.call(@2, @1);", smapper.popT(type), - smapper.popA(), fi[1], - mangleClassAccess - ); + smapper.popA(), + accessMember(mangleClassAccess + "(false)", + "_" + fi[1], fi)); i += 2; break; } @@ -1220,9 +1230,11 @@ int indx = readUShortArg(byteCodes, i); String[] fi = jc.getFieldInfoName(indx); final int type = VarType.fromFieldType(fi[2].charAt(0)); - emit(out, "var @1 = @2(false)._@3();", + emit(out, "var @1 = @2();", smapper.pushT(type), - accessClass(fi[0].replace('/', '_')), fi[1]); + accessMember(accessClass(fi[0].replace('/', '_')) + + "(false)", + "_" + fi[1], fi)); i += 2; addReference(fi[0]); break; @@ -1231,8 +1243,10 @@ int indx = readUShortArg(byteCodes, i); String[] fi = jc.getFieldInfoName(indx); final int type = VarType.fromFieldType(fi[2].charAt(0)); - emit(out, "@1(false)._@2(@3);", - accessClass(fi[0].replace('/', '_')), fi[1], + emit(out, "@1(@2);", + accessMember(accessClass(fi[0].replace('/', '_')) + + "(false)", + "_" + fi[1], fi), smapper.popT(type)); i += 2; addReference(fi[0]); @@ -1478,12 +1492,12 @@ } final String in = mi[0]; - out.append(accessClass(in.replace('/', '_'))); - out.append("(false)."); - if (mn.startsWith("cons_")) { - out.append("constructor."); - } - out.append(mn); + out.append(accessMember( + accessClass(in.replace('/', '_')) + "(false)", + mn.startsWith("cons_") + ? "constructor." + mn + : mn, + mi)); if (isStatic) { out.append('('); } else { @@ -1522,8 +1536,7 @@ .append(" = "); } - out.append(vars[0]).append('.'); - out.append(mn); + out.append(accessMember(vars[0].toString(), mn, mi)); out.append('('); String sep = ""; for (int j = 1; j < numArguments; ++j) { diff -r 9d6130cb464f -r f5c9934a252c rt/vm/src/main/java/org/apidesign/vm4brwsr/ClassDataCache.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ClassDataCache.java Mon May 06 18:06:08 2013 +0200 @@ -0,0 +1,55 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * 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, version 2 of the License. + * + * 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. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.vm4brwsr; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import org.apidesign.bck2brwsr.core.ExtraJavaScript; +import org.apidesign.vm4brwsr.ByteCodeParser.ClassData; + +@ExtraJavaScript(processByteCode = false, resource="") +final class ClassDataCache { + private static final Object MISSING_CLASS = new Object(); + + private final Bck2Brwsr.Resources resources; + private final Map classDataMap; + + ClassDataCache(final Bck2Brwsr.Resources resources) { + this.resources = resources; + + classDataMap = new HashMap(); + } + + ClassData getClassData(final String className) throws IOException { + Object cacheEntry = classDataMap.get(className); + if (cacheEntry == null) { + final InputStream is = loadClass(resources, className); + cacheEntry = (is != null) ? new ClassData(is) : MISSING_CLASS; + classDataMap.put(className, cacheEntry); + } + + return (cacheEntry != MISSING_CLASS) ? (ClassData) cacheEntry : null; + } + + private static InputStream loadClass(Bck2Brwsr.Resources l, String name) + throws IOException { + return l.get(name + ".class"); // NOI18N + } +} diff -r 9d6130cb464f -r f5c9934a252c rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Mon May 06 11:57:29 2013 +0200 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Mon May 06 18:06:08 2013 +0200 @@ -28,12 +28,15 @@ * @author Jaroslav Tulach */ abstract class VM extends ByteCodeToJavaScript { - protected final Bck2Brwsr.Resources resources; + protected final ClassDataCache classDataCache; + + private final Bck2Brwsr.Resources resources; private final ExportedSymbols exportedSymbols; private VM(Appendable out, Bck2Brwsr.Resources resources) { super(out); this.resources = resources; + this.classDataCache = new ClassDataCache(resources); this.exportedSymbols = new ExportedSymbols(resources); } @@ -231,10 +234,6 @@ } } - private static InputStream loadClass(Bck2Brwsr.Resources l, String name) throws IOException { - return l.get(name + ".class"); // NOI18N - } - static String toString(String name) throws IOException { StringBuilder sb = new StringBuilder(); // compile(sb, name); @@ -268,6 +267,19 @@ return "vm." + className; } + @Override + protected String accessMember(String object, String mangledName, + String[] fieldInfoName) throws IOException { + final ClassData declaringClass = + classDataCache.getClassData(fieldInfoName[0]); + if (declaringClass == null) { + return object + "['" + mangledName + "']"; + } + + // TODO + return object + "." + mangledName; + } + private static final class Standalone extends VM { private Standalone(Appendable out, Bck2Brwsr.Resources resources) { super(out, resources); @@ -322,11 +334,11 @@ @Override protected String generateClass(String className) throws IOException { - InputStream is = loadClass(resources, className); - if (is == null) { + ClassData classData = classDataCache.getClassData(className); + if (classData == null) { throw new IOException("Can't find class " + className); } - return compile(is); + return compile(classData); } @Override @@ -362,8 +374,8 @@ @Override protected String generateClass(String className) throws IOException { - InputStream is = loadClass(resources, className); - if (is == null) { + ClassData classData = classDataCache.getClassData(className); + if (classData == null) { out.append("\n").append(assignClass( className.replace('/', '_'))) .append("function() {\n return link('") @@ -374,7 +386,7 @@ return null; } - return compile(is); + return compile(classData); } @Override