Merge pull request #93 from dscho/misc

Miscellaneous enhancements and a fix
This commit is contained in:
Joshua Warner 2013-11-06 07:35:06 -08:00
commit 513f02ebd3
12 changed files with 119 additions and 8 deletions

View File

@ -12,7 +12,7 @@ package avian;
public class ClassAddendum extends Addendum { public class ClassAddendum extends Addendum {
public Object[] interfaceTable; public Object[] interfaceTable;
public Object[] innerClassTable; public InnerClassReference[] innerClassTable;
public Object[] methodTable; public Object[] methodTable;
public Object enclosingClass; public Object enclosingClass;
public Object enclosingMethod; public Object enclosingMethod;

View File

@ -0,0 +1,18 @@
/* Copyright (c) 2008-2013, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package avian;
public class InnerClassReference {
public byte[] inner;
public byte[] outer;
public byte[] name;
public short flags;
}

View File

@ -653,6 +653,8 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
r = e->NewStringUTF("\r\n"); r = e->NewStringUTF("\r\n");
} else if (strcmp(chars, "file.separator") == 0) { } else if (strcmp(chars, "file.separator") == 0) {
r = e->NewStringUTF("\\"); r = e->NewStringUTF("\\");
} else if (strcmp(chars, "path.separator") == 0) {
r = e->NewStringUTF(";");
} else if (strcmp(chars, "os.name") == 0) { } else if (strcmp(chars, "os.name") == 0) {
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) # if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
r = e->NewStringUTF("Windows"); r = e->NewStringUTF("Windows");
@ -726,6 +728,8 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
r = e->NewStringUTF("\n"); r = e->NewStringUTF("\n");
} else if (strcmp(chars, "file.separator") == 0) { } else if (strcmp(chars, "file.separator") == 0) {
r = e->NewStringUTF("/"); r = e->NewStringUTF("/");
} else if (strcmp(chars, "path.separator") == 0) {
r = e->NewStringUTF(":");
} else if (strcmp(chars, "os.name") == 0) { } else if (strcmp(chars, "os.name") == 0) {
#ifdef __APPLE__ #ifdef __APPLE__
r = e->NewStringUTF("Mac OS X"); r = e->NewStringUTF("Mac OS X");

View File

@ -16,11 +16,15 @@ public class File implements Serializable {
public static final String separator = FileSeparator; public static final String separator = FileSeparator;
public static final char separatorChar = FileSeparator.charAt(0);
private static final String PathSeparator private static final String PathSeparator
= System.getProperty("path.separator"); = System.getProperty("path.separator");
public static final String pathSeparator = PathSeparator; public static final String pathSeparator = PathSeparator;
public static final char pathSeparatorChar = PathSeparator.charAt(0);
// static { // static {
// System.loadLibrary("natives"); // System.loadLibrary("natives");
// } // }

View File

@ -15,6 +15,7 @@ import avian.ClassAddendum;
import avian.AnnotationInvocationHandler; import avian.AnnotationInvocationHandler;
import avian.SystemClassLoader; import avian.SystemClassLoader;
import avian.Classes; import avian.Classes;
import avian.InnerClassReference;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -402,6 +403,37 @@ public final class Class <T> implements Type, AnnotatedElement {
} }
} }
public Class[] getDeclaredClasses() {
if (vmClass.addendum == null || vmClass.addendum.innerClassTable == null) {
return new Class[0];
}
InnerClassReference[] table = vmClass.addendum.innerClassTable;
Class[] result = new Class[table.length];
int counter = 0;
String prefix = getName().replace('.', '/') + "$";
for (int i = 0; i < table.length; ++i) try {
byte[] inner = table[i].inner;
if (inner != null && inner.length > 1) {
String name = new String(inner, 0, inner.length - 1);
if (name.startsWith(prefix)) {
Class innerClass = getClassLoader().loadClass(name);
result[counter++] = innerClass;
}
}
} catch (ClassNotFoundException e) {
throw new Error(e);
}
if (counter == result.length) {
return result;
}
if (counter == 0) {
return new Class[0];
}
Class[] result2 = new Class[counter];
System.arraycopy(result, 0, result2, 0, counter);
return result2;
}
public ClassLoader getClassLoader() { public ClassLoader getClassLoader() {
return vmClass.loader; return vmClass.loader;
} }

View File

@ -75,6 +75,14 @@ public final class Math {
return (int) Math.floor(v + 0.5); return (int) Math.floor(v + 0.5);
} }
public static double signum(double d) {
return d > 0 ? +1.0 : d < 0 ? -1.0 : 0;
}
public static float signum(float f) {
return f > 0 ? +1.0f : f < 0 ? -1.0f : 0;
}
public static double random() { public static double random() {
return random.nextDouble(); return random.nextDouble();
} }

View File

@ -0,0 +1,13 @@
/* Copyright (c) 2008-2013, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.util;
public class EmptyStackException extends RuntimeException {}

View File

@ -32,6 +32,7 @@ public class Logger {
if (name.equals("")) return rootLogger; if (name.equals("")) return rootLogger;
Logger logger = new Logger(name); Logger logger = new Logger(name);
logger.parent = rootLogger; logger.parent = rootLogger;
logger.setLevel(Level.INFO);
return logger; return logger;
} }
@ -79,6 +80,30 @@ public class Logger {
log(level, Method.getCaller(), message, exception); log(level, Method.getCaller(), message, exception);
} }
public void log(Level level, String message, Object param) {
log(level, Method.getCaller(), replaceParameters(message, param), null);
}
private static String replaceParameters(String message, Object... params) {
StringBuilder builder = new StringBuilder();
int offset = 0;
for (int i = 0; i < params.length; ++i) {
int curly = message.indexOf("{}", offset);
if (curly < 0) {
break;
}
if (curly > offset) {
builder.append(message, offset, curly);
}
offset = curly + 2;
builder.append(params[i]);
}
if (message.length() > offset) {
builder.append(message, offset, message.length());
}
return builder.toString();
}
public void logp(Level level, String sourceClass, String sourceMethod, String msg) { public void logp(Level level, String sourceClass, String sourceMethod, String msg) {
if (!isLoggable(level)) { if (!isLoggable(level)) {
return; return;

View File

@ -53,7 +53,7 @@ class MyClasspath : public Classpath {
return vm::makeThread return vm::makeThread
(t, 0, 0, 0, 0, NewState, NormalPriority, 0, 0, 0, (t, 0, 0, 0, 0, NewState, NormalPriority, 0, 0, 0,
root(t, Machine::BootLoader), 0, 0, group, 0); root(t, Machine::AppLoader), 0, 0, group, 0);
} }
virtual object virtual object

View File

@ -156,11 +156,7 @@
(void* value) (void* value)
(object next)) (object next))
(type innerClassReference (type innerClassReference avian/InnerClassReference)
(object inner)
(object outer)
(object name)
(int16_t flags))
(type continuationContext (type continuationContext
(object next) (object next)

View File

@ -66,7 +66,7 @@ public class Logging {
public void run() { public void run() {
log.info("Started run"); log.info("Started run");
a(); a();
log.info("Ended run"); log.log(Level.INFO, "Ended {}!", "run");
} }
private void a() { private void a() {

View File

@ -38,7 +38,18 @@ public class Reflection {
if (! v) throw new RuntimeException(); if (! v) throw new RuntimeException();
} }
private static class Hello { }
private static void innerClasses() throws Exception {
Class c = Reflection.class;
Class[] inner = c.getDeclaredClasses();
expect(1 == inner.length);
expect(Hello.class == inner[0]);
}
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
innerClasses();
Class system = Class.forName("java.lang.System"); Class system = Class.forName("java.lang.System");
Field out = system.getDeclaredField("out"); Field out = system.getDeclaredField("out");
Class output = Class.forName("java.io.PrintStream"); Class output = Class.forName("java.io.PrintStream");