001: /*
002: * RuntimeClass.java
003: *
004: * Copyright (C) 2004 Peter Graves
005: * $Id: RuntimeClass.java,v 1.7 2004/08/24 18:22:36 asimon Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.lisp;
023:
024: import java.io.File;
025: import java.util.Map;
026: import java.util.HashMap;
027:
028: public class RuntimeClass extends Lisp {
029: private static Map classes = new HashMap();
030:
031: private Map methods = new HashMap();
032:
033: // ### %jnew-runtime-class
034: // %jnew-runtime-class class-name &rest method-names-and-defs
035: private static final Primitive _JNEW_RUNTIME_CLASS = new Primitive(
036: "%jnew-runtime-class", PACKAGE_JAVA, false,
037: "class-name &rest method-names-and-defs") {
038: public LispObject execute(LispObject[] args)
039: throws ConditionThrowable {
040: int length = args.length;
041: if (length < 3 || length % 2 != 1)
042: return signal(new WrongNumberOfArgumentsException(this ));
043: RuntimeClass rc = new RuntimeClass();
044: String className = args[0].getStringValue();
045: for (int i = 1; i < length; i = i + 2) {
046: String methodName = args[i].getStringValue();
047: rc.addLispMethod(methodName, (Function) args[i + 1]);
048: }
049: classes.put(className, rc);
050: return T;
051: }
052: };
053:
054: // ### jredefine-method
055: // %jredefine-method class-name method-name method-def
056: private static final Primitive3 _JREDEFINE_METHOD = new Primitive3(
057: "%jredefine-method", PACKAGE_JAVA, false,
058: "class-name method-name method-def") {
059: public LispObject execute(LispObject className,
060: LispObject methodName, LispObject methodDef)
061: throws ConditionThrowable {
062:
063: String cn = className.getStringValue();
064: String mn = methodName.getStringValue();
065: Function def = (Function) methodDef;
066: RuntimeClass rc = null;
067: if (classes.containsKey(cn)) {
068: rc = (RuntimeClass) classes.get(cn);
069: rc.addLispMethod(mn, def);
070: return T;
071: } else {
072: signal(new LispError("undefined Java class: " + cn));
073: return NIL;
074: }
075: }
076: };
077:
078: // ### %load-java-class-from-byte-array
079: private static final Primitive2 _LOAD_JAVA_CLASS_FROM_BYTE_ARRAY = new Primitive2(
080: "%load-java-class-from-byte-array", PACKAGE_JAVA, false,
081: "classname bytearray") {
082: public LispObject execute(LispObject className,
083: LispObject classBytes) throws ConditionThrowable {
084: String cn = className.getStringValue();
085: String pn = cn.substring(0, cn.lastIndexOf('.'));
086: byte[] cb = (byte[]) classBytes.javaInstance();
087: try {
088: JavaClassLoader loader = JavaClassLoader
089: .getPersistentInstance(pn);
090: Class c = loader.loadClassFromByteArray(cn, cb);
091: if (c != null) {
092: return T;
093: }
094: } catch (VerifyError e) {
095: return signal(new LispError(
096: "class verification failed: " + e.getMessage()));
097: } catch (LinkageError e) {
098: return signal(new LispError(
099: "class could not be linked: " + e.getMessage()));
100: } catch (Throwable t) {
101: Debug.trace(t);
102: }
103: return signal(new LispError("unable to load ".concat(cn)));
104: }
105: };
106:
107: public static RuntimeClass getRuntimeClass(String className) {
108: return (RuntimeClass) classes.get(className);
109: }
110:
111: public Function getLispMethod(String methodName) {
112: return (Function) methods.get(methodName);
113: }
114:
115: private void addLispMethod(String methodName, Function def) {
116: methods.put(methodName, def);
117: }
118:
119: public static final LispObject makeLispObject(Object obj)
120: throws ConditionThrowable {
121: return new JavaObject(obj);
122: }
123:
124: public static final Fixnum makeLispObject(byte i)
125: throws ConditionThrowable {
126: return new Fixnum(i);
127: }
128:
129: public static final Fixnum makeLispObject(short i)
130: throws ConditionThrowable {
131: return new Fixnum(i);
132: }
133:
134: public static final Fixnum makeLispObject(int i)
135: throws ConditionThrowable {
136: return new Fixnum(i);
137: }
138:
139: public static final Bignum makeLispObject(long i)
140: throws ConditionThrowable {
141: return new Bignum(i);
142: }
143:
144: public static final LispFloat makeLispObject(float i)
145: throws ConditionThrowable {
146: return new LispFloat(i);
147: }
148:
149: public static final LispFloat makeLispObject(double i)
150: throws ConditionThrowable {
151: return new LispFloat(i);
152: }
153:
154: public static final LispCharacter makeLispObject(char i)
155: throws ConditionThrowable {
156: return LispCharacter.getInstance(i);
157: }
158:
159: public static final LispObject makeLispObject(boolean i)
160: throws ConditionThrowable {
161: return i ? T : NIL;
162: }
163: }
|