1.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Thu Feb 14 12:06:16 2013 +0100
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,227 +0,0 @@
1.4 -/**
1.5 - * Back 2 Browser Bytecode Translator
1.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
1.7 - *
1.8 - * This program is free software: you can redistribute it and/or modify
1.9 - * it under the terms of the GNU General Public License as published by
1.10 - * the Free Software Foundation, version 2 of the License.
1.11 - *
1.12 - * This program is distributed in the hope that it will be useful,
1.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.15 - * GNU General Public License for more details.
1.16 - *
1.17 - * You should have received a copy of the GNU General Public License
1.18 - * along with this program. Look for COPYING file in the top folder.
1.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
1.20 - */
1.21 -package org.apidesign.vm4brwsr;
1.22 -
1.23 -import java.io.IOException;
1.24 -import java.io.InputStream;
1.25 -
1.26 -/** Generator of JavaScript from bytecode of classes on classpath of the VM.
1.27 - *
1.28 - * @author Jaroslav Tulach <jtulach@netbeans.org>
1.29 - */
1.30 -class VM extends ByteCodeToJavaScript {
1.31 - public VM(Appendable out) {
1.32 - super(out);
1.33 - }
1.34 -
1.35 - static {
1.36 - // uses VMLazy to load dynamic classes
1.37 - VMLazy.init();
1.38 - Zips.init();
1.39 - }
1.40 -
1.41 - @Override
1.42 - boolean debug(String msg) throws IOException {
1.43 - return false;
1.44 - }
1.45 -
1.46 - static void compile(Bck2Brwsr.Resources l, Appendable out, StringArray names) throws IOException {
1.47 - new VM(out).doCompile(l, names);
1.48 - }
1.49 - protected void doCompile(Bck2Brwsr.Resources l, StringArray names) throws IOException {
1.50 - out.append("(function VM(global) {");
1.51 - out.append("\n var vm = {};");
1.52 - StringArray processed = new StringArray();
1.53 - StringArray initCode = new StringArray();
1.54 - for (String baseClass : names.toArray()) {
1.55 - references.add(baseClass);
1.56 - for (;;) {
1.57 - String name = null;
1.58 - for (String n : references.toArray()) {
1.59 - if (processed.contains(n)) {
1.60 - continue;
1.61 - }
1.62 - name = n;
1.63 - }
1.64 - if (name == null) {
1.65 - break;
1.66 - }
1.67 - InputStream is = loadClass(l, name);
1.68 - if (is == null) {
1.69 - throw new IOException("Can't find class " + name);
1.70 - }
1.71 - try {
1.72 - String ic = compile(is);
1.73 - processed.add(name);
1.74 - initCode.add(ic == null ? "" : ic);
1.75 - } catch (RuntimeException ex) {
1.76 - if (out instanceof CharSequence) {
1.77 - CharSequence seq = (CharSequence)out;
1.78 - int lastBlock = seq.length();
1.79 - while (lastBlock-- > 0) {
1.80 - if (seq.charAt(lastBlock) == '{') {
1.81 - break;
1.82 - }
1.83 - }
1.84 - throw new IOException("Error while compiling " + name + "\n"
1.85 - + seq.subSequence(lastBlock + 1, seq.length()), ex
1.86 - );
1.87 - } else {
1.88 - throw new IOException("Error while compiling " + name + "\n"
1.89 - + out, ex
1.90 - );
1.91 - }
1.92 - }
1.93 - }
1.94 -
1.95 - for (String resource : scripts.toArray()) {
1.96 - while (resource.startsWith("/")) {
1.97 - resource = resource.substring(1);
1.98 - }
1.99 - InputStream emul = l.get(resource);
1.100 - if (emul == null) {
1.101 - throw new IOException("Can't find " + resource);
1.102 - }
1.103 - readResource(emul, out);
1.104 - }
1.105 - scripts = new StringArray();
1.106 -
1.107 - StringArray toInit = StringArray.asList(references.toArray());
1.108 - toInit.reverse();
1.109 -
1.110 - for (String ic : toInit.toArray()) {
1.111 - int indx = processed.indexOf(ic);
1.112 - if (indx >= 0) {
1.113 - out.append(initCode.toArray()[indx]).append("\n");
1.114 - initCode.toArray()[indx] = "";
1.115 - }
1.116 - }
1.117 - }
1.118 - out.append(
1.119 - " global.bck2brwsr = function() {\n"
1.120 - + " var args = arguments;\n"
1.121 - + " var loader = {};\n"
1.122 - + " loader.vm = vm;\n"
1.123 - + " if (args.length == 1 && typeof args[0] !== 'function') {;\n"
1.124 - + " var classpath = args[0];\n"
1.125 - + " args[0] = function(name) {\n"
1.126 - + " return vm.org_apidesign_vm4brwsr_Zips(false).loadFromCp___3B_3Ljava_lang_Object_2Ljava_lang_String_2(classpath, name);\n"
1.127 - + " };\n"
1.128 - + " };\n"
1.129 - + " loader.loadClass = function(name) {\n"
1.130 - + " var attr = name.replace__Ljava_lang_String_2CC('.','_');\n"
1.131 - + " var fn = vm[attr];\n"
1.132 - + " if (fn) return fn(false);\n"
1.133 - + " if (!args[0]) throw 'bck2brwsr initialized without loader function, cannot load ' + name;\n"
1.134 - + " return vm.org_apidesign_vm4brwsr_VMLazy(false).\n"
1.135 - + " load__Ljava_lang_Object_2Ljava_lang_Object_2Ljava_lang_String_2_3Ljava_lang_Object_2(loader, name, args);\n"
1.136 - + " }\n"
1.137 - + " if (args[0]) {\n"
1.138 - + " vm.loadClass = loader.loadClass;\n"
1.139 - + " vm.loadBytes = function(name) {\n"
1.140 - + " if (!args[0]) throw 'bck2brwsr initialized without loader function, cannot load ' + name;\n"
1.141 - + " return args[0](name);\n"
1.142 - + " }\n"
1.143 - + " }\n"
1.144 - + " return loader;\n"
1.145 - + " };\n");
1.146 - out.append("}(this));");
1.147 - }
1.148 - private static void readResource(InputStream emul, Appendable out) throws IOException {
1.149 - try {
1.150 - int state = 0;
1.151 - for (;;) {
1.152 - int ch = emul.read();
1.153 - if (ch == -1) {
1.154 - break;
1.155 - }
1.156 - if (ch < 0 || ch > 255) {
1.157 - throw new IOException("Invalid char in emulation " + ch);
1.158 - }
1.159 - switch (state) {
1.160 - case 0:
1.161 - if (ch == '/') {
1.162 - state = 1;
1.163 - } else {
1.164 - out.append((char)ch);
1.165 - }
1.166 - break;
1.167 - case 1:
1.168 - if (ch == '*') {
1.169 - state = 2;
1.170 - } else {
1.171 - out.append('/').append((char)ch);
1.172 - state = 0;
1.173 - }
1.174 - break;
1.175 - case 2:
1.176 - if (ch == '*') {
1.177 - state = 3;
1.178 - }
1.179 - break;
1.180 - case 3:
1.181 - if (ch == '/') {
1.182 - state = 0;
1.183 - } else {
1.184 - state = 2;
1.185 - }
1.186 - break;
1.187 - }
1.188 - }
1.189 - } finally {
1.190 - emul.close();
1.191 - }
1.192 - }
1.193 -
1.194 - private static InputStream loadClass(Bck2Brwsr.Resources l, String name) throws IOException {
1.195 - return l.get(name + ".class"); // NOI18N
1.196 - }
1.197 -
1.198 - static String toString(String name) throws IOException {
1.199 - StringBuilder sb = new StringBuilder();
1.200 -// compile(sb, name);
1.201 - return sb.toString().toString();
1.202 - }
1.203 -
1.204 - private StringArray scripts = new StringArray();
1.205 - private StringArray references = new StringArray();
1.206 -
1.207 - @Override
1.208 - protected boolean requireReference(String cn) {
1.209 - if (references.contains(cn)) {
1.210 - return false;
1.211 - }
1.212 - references.add(cn);
1.213 - return true;
1.214 - }
1.215 -
1.216 - @Override
1.217 - protected void requireScript(String resourcePath) {
1.218 - scripts.add(resourcePath);
1.219 - }
1.220 -
1.221 - @Override
1.222 - String assignClass(String className) {
1.223 - return "vm." + className + " = ";
1.224 - }
1.225 -
1.226 - @Override
1.227 - String accessClass(String className) {
1.228 - return "vm." + className;
1.229 - }
1.230 -}