mirror of
https://github.com/corda/corda.git
synced 2025-01-14 08:49:47 +00:00
Squashed commit of the following: (#15)
commit fabf4dd0cca19118c59c925f572a655d1d9c4092
Author: Joel Dice <joel.dice@gmail.com>
Date: Sun Jul 9 17:36:06 2017 -0600
reserve a little more stack space for worst-case lambda expressions
commit 24b95016dd6f62fa4a82312310fcb5c55cc22f93
Author: Joel Dice <joel.dice@gmail.com>
Date: Sun Jul 9 17:33:39 2017 -0600
support constructor references
commit a329416f4f37840d2a5d7976874585413cd4c6af
Author: Joel Dice <joel.dice@gmail.com>
Date: Sun Jul 9 17:11:19 2017 -0600
normalize class name in Classes.forName
This fixes a Tomcat classloading issue when using the OpenJDK class library.
commit ecafdf40baf2f3cde4835620e9af4380b1081fe7
Author: Joel Dice <joel.dice@gmail.com>
Date: Sun Jul 9 16:58:04 2017 -0600
fix some lambda bugs
commit 552dfd779baf077cc6445b4042588e4b6e34f3d2
Merge: 63dda56 aa2f25d
Author: Joel Dice <joel.dice@gmail.com>
Date: Sat Jul 8 10:57:59 2017 -0600
Merge remote-tracking branch 'corda/chrisr3-invoking-extension'
commit 63dda560f8648a793bdb609879076ab729b17e19
Merge: 3ec983d e589f10
Author: Joel Dice <joel.dice@gmail.com>
Date: Sat Jul 8 10:54:53 2017 -0600
Merge pull request #538 from dicej/master
avoid definePackage infinite recursion with OpenJDK class library
commit aa2f25da404b2fc168a672392df939b52ea250ab
Author: Chris Rankin <chris.rankin@r3.com>
Date: Mon Jul 3 17:26:41 2017 +0100
Add support for "invokevirtual" and "invokeinterface".
The "invokeinterface" support seems to be broken for lambdas that require native types to be boxed/unboxed.
commit e589f105741ea36d07bba1e300c7ed69c33a22d1
Author: Joel Dice <joel.dice@gmail.com>
Date: Sun Jul 2 19:43:36 2017 -0600
avoid definePackage infinite recursion with OpenJDK class library
commit 3ec983dd82e01b36fb96411df345a54119a68181
Merge: 6f6bdd7 78881d4
Author: Joel Dice <joel.dice@gmail.com>
Date: Tue Jun 13 09:50:49 2017 -0600
Merge pull request #534 from lwahlmeier/fileGetParentFile
fixed File.getParent when getting parent returns root
commit 78881d427cd474c14f5ce94484f5253de564074b
Author: Luke Wahlmeier <lwahlmeier@gmail.com>
Date: Tue May 30 13:42:56 2017 -0600
fixed File.getParent when getting parent returns root
commit 6f6bdd7d5c171e0c4c807d0a4f3aa676461307de
Merge: 8b694f9 b22343e
Author: Joel Dice <joel.dice@gmail.com>
Date: Mon May 22 12:58:09 2017 -0600
Merge pull request #529 from mikehearn/proguard-fixes
Some fixes to the ProGuard files
commit 8b694f961496f2d47a377254f61153b0338335fd
Merge: dfae414 61c82e1
Author: Joel Dice <joel.dice@gmail.com>
Date: Mon May 22 12:57:54 2017 -0600
Merge pull request #531 from mikehearn/fileinputstream-compat
FileInputStream has wrapped some more native methods
commit dfae414da8da57049076c16c43472cc32bdeb07c
Merge: 16dd804 d7a6f68
Author: Joel Dice <joel.dice@gmail.com>
Date: Mon May 22 12:57:38 2017 -0600
Merge pull request #532 from mikehearn/use-symlinks
Symlink OpenJDK files rather than hardlink
commit d7a6f68235b2d42c03aba36f1bb48d173adb4fa6
Author: Mike Hearn <mike@plan99.net>
Date: Sun May 14 21:42:06 2017 +0200
Symlink OpenJDK files rather than hardlink
commit 61c82e1070d857bcdc7a4f086d13836d9608da00
Author: Mike Hearn <mike@plan99.net>
Date: Sun May 14 21:40:52 2017 +0200
FileInputStream has wrapped some more native methods in recent OpenJDK releases
commit b22343eb6731f1df2631635e2fcf9d51817273fe
Author: Mike Hearn <mike@plan99.net>
Date: Sun May 14 21:38:09 2017 +0200
Some fixes to the ProGuard files
commit 16dd804f392168497fa17ab682978f938e291bfb
Merge: e2d3270 19deadd
Author: Joel Dice <joel.dice@gmail.com>
Date: Wed Mar 22 16:00:30 2017 -0600
Merge pull request #526 from MaartenR/arrays-binsearch
Added integer array binary search methods to Arrays class
commit e2d3270fe8e92203b6107b95f862ff5bd245c37a
Merge: dee99d6 545b9c8
Author: Joel Dice <joel.dice@gmail.com>
Date: Wed Mar 22 16:00:20 2017 -0600
Merge pull request #527 from MaartenR/integer-nolz
Added numberOfLeadingZeros method to Integer class
commit 545b9c8732a6ea026285b1edf976a79eb541ef2e
Author: Maarten Raaphorst <mwraaphorst@gmail.com>
Date: Tue Mar 14 11:23:36 2017 +0100
Tested more negative numbers
commit b45bcf09535daef99ed31451ae55db8bec83164c
Author: Maarten Raaphorst <mwraaphorst@gmail.com>
Date: Tue Mar 14 10:47:27 2017 +0100
Added unit test for numberOfLeadingZeros method of the Integer class
commit 19deadd36bbfc02a8c13e6d91963e41f5125057f
Author: Maarten Raaphorst <mwraaphorst@gmail.com>
Date: Mon Mar 13 12:19:17 2017 +0100
Fixed mistake with end index being exclusive
commit 7271c0b7077ae3bef473e036aa0f0298a9eb0601
Author: Maarten Raaphorst <mwraaphorst@gmail.com>
Date: Fri Mar 10 11:17:13 2017 +0100
Added numberOfLeadingZeros method to Integer class
commit 023bb69acd071348f29cd43ff954d3dcf2856c7c
Author: Maarten Raaphorst <mwraaphorst@gmail.com>
Date: Thu Mar 9 13:43:03 2017 +0100
Added integer array binary search methods to Arrays class
commit dee99d6dd60b743a870d1a2c58183649c8a6449c
Merge: f7a651d
6c90953
Author: Joel Dice <joel.dice@gmail.com>
Date: Wed Mar 1 08:39:32 2017 -0700
Merge pull request #525 from MaartenR/master
Added functionality to HttpURLConnection for obtaining content length
commit 6c90953745be5451ac9a028639f94e3fcc43d7f3
Author: Maarten Raaphorst <raaphorst@serviceplanet.nl>
Date: Wed Mar 1 14:19:51 2017 +0100
Made http headers case insensitive
commit 2c3a82d2b387251a8932ddb6575e718c2c1785a7
Author: Maarten Raaphorst <mwraaphorst@gmail.com>
Date: Fri Feb 3 05:42:56 2017 -0800
Added functionality to HttpURLConnection for obtaining content length
This commit is contained in:
parent
b40533a14f
commit
9411c223af
1
sgx-jvm/avian/.gitignore
vendored
1
sgx-jvm/avian/.gitignore
vendored
@ -15,3 +15,4 @@ workspace/
|
|||||||
src/.cproject
|
src/.cproject
|
||||||
/cmake-build
|
/cmake-build
|
||||||
/cmake-build
|
/cmake-build
|
||||||
|
.idea/*
|
||||||
|
@ -46,7 +46,7 @@ public class Classes {
|
|||||||
public static native VMClass toVMClass(Class c);
|
public static native VMClass toVMClass(Class c);
|
||||||
|
|
||||||
public static native VMMethod toVMMethod(Method m);
|
public static native VMMethod toVMMethod(Method m);
|
||||||
|
|
||||||
private static native VMClass resolveVMClass(ClassLoader loader, byte[] spec)
|
private static native VMClass resolveVMClass(ClassLoader loader, byte[] spec)
|
||||||
throws ClassNotFoundException;
|
throws ClassNotFoundException;
|
||||||
|
|
||||||
@ -295,7 +295,7 @@ public class Classes {
|
|||||||
if (loader == null) {
|
if (loader == null) {
|
||||||
loader = Class.class.getClassLoader();
|
loader = Class.class.getClassLoader();
|
||||||
}
|
}
|
||||||
Class c = loader.loadClass(name);
|
Class c = loader.loadClass(name.replace('/', '.'));
|
||||||
VMClass vmc = SystemClassLoader.vmClass(c);
|
VMClass vmc = SystemClassLoader.vmClass(c);
|
||||||
link(vmc, loader);
|
link(vmc, loader);
|
||||||
if (initialize) {
|
if (initialize) {
|
||||||
@ -443,7 +443,7 @@ public class Classes {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int findMethod(VMClass vmClass, String name,
|
public static int findMethod(VMClass vmClass, String name,
|
||||||
Class[] parameterTypes)
|
Class[] parameterTypes)
|
||||||
{
|
{
|
||||||
@ -599,6 +599,6 @@ public class Classes {
|
|||||||
private static native void acquireClassLock();
|
private static native void acquireClassLock();
|
||||||
|
|
||||||
private static native void releaseClassLock();
|
private static native void releaseClassLock();
|
||||||
|
|
||||||
public static native String makeString(byte[] array, int offset, int length);
|
public static native String makeString(byte[] array, int offset, int length);
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ public class ConstantPool {
|
|||||||
private static final int CONSTANT_NameAndType = 12;
|
private static final int CONSTANT_NameAndType = 12;
|
||||||
private static final int CONSTANT_Fieldref = 9;
|
private static final int CONSTANT_Fieldref = 9;
|
||||||
private static final int CONSTANT_Methodref = 10;
|
private static final int CONSTANT_Methodref = 10;
|
||||||
|
private static final int CONSTANT_InterfaceMethodref = 11;
|
||||||
|
|
||||||
public static int add(List<PoolEntry> pool, PoolEntry e) {
|
public static int add(List<PoolEntry> pool, PoolEntry e) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -85,6 +86,16 @@ public class ConstantPool {
|
|||||||
addNameAndType(pool, name, spec)));
|
addNameAndType(pool, name, spec)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int addInterfaceMethodRef(List<PoolEntry> pool,
|
||||||
|
String interfaceName,
|
||||||
|
String name,
|
||||||
|
String spec)
|
||||||
|
{
|
||||||
|
return add(pool, new InterfaceMethodRefPoolEntry
|
||||||
|
(addClass(pool, interfaceName),
|
||||||
|
addNameAndType(pool, name, spec)));
|
||||||
|
}
|
||||||
|
|
||||||
public interface PoolEntry {
|
public interface PoolEntry {
|
||||||
public void writeTo(OutputStream out) throws IOException;
|
public void writeTo(OutputStream out) throws IOException;
|
||||||
}
|
}
|
||||||
@ -239,4 +250,30 @@ public class ConstantPool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class InterfaceMethodRefPoolEntry implements PoolEntry {
|
||||||
|
private final int classIndex;
|
||||||
|
private final int nameAndTypeIndex;
|
||||||
|
|
||||||
|
public InterfaceMethodRefPoolEntry(int classIndex, int nameAndTypeIndex) {
|
||||||
|
this.classIndex = classIndex;
|
||||||
|
this.nameAndTypeIndex = nameAndTypeIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeTo(OutputStream out) throws IOException {
|
||||||
|
write1(out, CONSTANT_InterfaceMethodref);
|
||||||
|
write2(out, classIndex + 1);
|
||||||
|
write2(out, nameAndTypeIndex + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o instanceof InterfaceMethodRefPoolEntry) {
|
||||||
|
InterfaceMethodRefPoolEntry other = (InterfaceMethodRefPoolEntry) o;
|
||||||
|
return other.classIndex == classIndex
|
||||||
|
&& other.nameAndTypeIndex == nameAndTypeIndex;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,21 +76,6 @@ public class SystemClassLoader extends ClassLoader {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Package getPackage(String name) {
|
|
||||||
Package p = super.getPackage(name);
|
|
||||||
if (p == null) {
|
|
||||||
String source = getPackageSource(name);
|
|
||||||
if (source != null) {
|
|
||||||
// todo: load attributes from JAR manifest
|
|
||||||
definePackage(name, null, null, null, null, null, null, null);
|
|
||||||
} else {
|
|
||||||
definePackage(name, null, null, null, null, null, null, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.getPackage(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static native String getPackageSource(String name);
|
protected static native String getPackageSource(String name);
|
||||||
|
|
||||||
// OpenJDK's java.lang.ClassLoader.getResource makes use of
|
// OpenJDK's java.lang.ClassLoader.getResource makes use of
|
||||||
|
@ -23,8 +23,11 @@ import java.net.Socket;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLConnection;
|
import java.net.URLConnection;
|
||||||
import java.net.URLStreamHandler;
|
import java.net.URLStreamHandler;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class Handler extends URLStreamHandler
|
public class Handler extends URLStreamHandler
|
||||||
{
|
{
|
||||||
@ -35,10 +38,12 @@ public class Handler extends URLStreamHandler
|
|||||||
|
|
||||||
class HttpURLConnection extends URLConnection
|
class HttpURLConnection extends URLConnection
|
||||||
{
|
{
|
||||||
|
private static final String HKEY_CONTENT_LENGTH = "content-length";
|
||||||
|
|
||||||
Socket socket;
|
Socket socket;
|
||||||
private BufferedWriter writer;
|
private BufferedWriter writer;
|
||||||
private InputStream bin;
|
private InputStream bin;
|
||||||
private Map<String,String> header = new HashMap<String, String>();
|
private Map<String, List<String>> header = new HashMap<String, List<String>>();
|
||||||
private int status;
|
private int status;
|
||||||
|
|
||||||
protected HttpURLConnection(URL url)
|
protected HttpURLConnection(URL url)
|
||||||
@ -97,7 +102,12 @@ public class Handler extends URLStreamHandler
|
|||||||
int i = line.indexOf(':');
|
int i = line.indexOf(':');
|
||||||
if(i > 0)
|
if(i > 0)
|
||||||
{
|
{
|
||||||
header.put(line.substring(0, i), line.substring(i + 1) .trim());
|
String key = line.substring(0, i).toLowerCase();
|
||||||
|
String value = line.substring(i + 1).trim();
|
||||||
|
|
||||||
|
List<String> valueList = new ArrayList<String>();
|
||||||
|
valueList.add(value);
|
||||||
|
header.put(key, Collections.unmodifiableList(valueList));
|
||||||
}
|
}
|
||||||
line = reader.readLine();
|
line = reader.readLine();
|
||||||
}
|
}
|
||||||
@ -116,5 +126,23 @@ public class Handler extends URLStreamHandler
|
|||||||
{
|
{
|
||||||
throw new UnsupportedOperationException("Can' write to HTTP Connection");
|
throw new UnsupportedOperationException("Can' write to HTTP Connection");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContentLength()
|
||||||
|
{
|
||||||
|
return getHeaderFieldInt(HKEY_CONTENT_LENGTH, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getContentLengthLong()
|
||||||
|
{
|
||||||
|
return getHeaderFieldLong(HKEY_CONTENT_LENGTH, -1l);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String,List<String>> getHeaderFields()
|
||||||
|
{
|
||||||
|
return Collections.unmodifiableMap(header);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ public class File implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static String stripSeparators(String p) {
|
private static String stripSeparators(String p) {
|
||||||
while (p.endsWith(FileSeparator)) {
|
while (p.length() > 1 && p.endsWith(FileSeparator)) {
|
||||||
p = p.substring(0, p.length() - 1);
|
p = p.substring(0, p.length() - 1);
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
@ -173,8 +173,10 @@ public class File implements Serializable {
|
|||||||
|
|
||||||
public String getParent() {
|
public String getParent() {
|
||||||
int index = path.lastIndexOf(FileSeparator);
|
int index = path.lastIndexOf(FileSeparator);
|
||||||
if (index >= 0) {
|
if (index > 0) {
|
||||||
return normalize(path.substring(0, index));
|
return normalize(path.substring(0, index));
|
||||||
|
} else if (index == 0) {
|
||||||
|
return normalize(path.substring(0, FileSeparator.length()));
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -45,9 +45,31 @@ public abstract class ClassLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Package getPackage(String name) {
|
protected Package getPackage(String name) {
|
||||||
|
Package p;
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
return packages().get(name);
|
p = packages().get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parent != null) {
|
||||||
|
p = parent.getPackage(name);
|
||||||
|
} else {
|
||||||
|
// todo: load attributes from JAR manifest if available
|
||||||
|
p = definePackage(name, null, null, null, null, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p != null) {
|
||||||
|
synchronized (this) {
|
||||||
|
Package p2 = packages().get(name);
|
||||||
|
if (p2 != null) {
|
||||||
|
p = p2;
|
||||||
|
} else {
|
||||||
|
packages().put(name, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Package[] getPackages() {
|
protected Package[] getPackages() {
|
||||||
@ -145,7 +167,7 @@ public abstract class ClassLoader {
|
|||||||
public final ClassLoader getParent() {
|
public final ClassLoader getParent() {
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected URL findResource(String path) {
|
protected URL findResource(String path) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -183,11 +205,11 @@ public abstract class ClassLoader {
|
|||||||
public static InputStream getSystemResourceAsStream(String path) {
|
public static InputStream getSystemResourceAsStream(String path) {
|
||||||
return getSystemClassLoader().getResourceAsStream(path);
|
return getSystemClassLoader().getResourceAsStream(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Enumeration<URL> getSystemResources(String name) throws IOException {
|
public static Enumeration<URL> getSystemResources(String name) throws IOException {
|
||||||
return getSystemClassLoader().getResources(name);
|
return getSystemClassLoader().getResources(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Enumeration<URL> getResources(String name)
|
public Enumeration<URL> getResources(String name)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
Collection<URL> resources = collectResources(name);
|
Collection<URL> resources = collectResources(name);
|
||||||
@ -209,5 +231,5 @@ public abstract class ClassLoader {
|
|||||||
|
|
||||||
static native Class getCaller();
|
static native Class getCaller();
|
||||||
|
|
||||||
static native void load(String name, Class caller, boolean mapName);
|
static native void load(String name, Class caller, boolean mapName);
|
||||||
}
|
}
|
||||||
|
@ -139,4 +139,14 @@ public final class Integer extends Number implements Comparable<Integer> {
|
|||||||
}
|
}
|
||||||
return new Integer(parseInt(string, 10));
|
return new Integer(parseInt(string, 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int numberOfLeadingZeros(int i) {
|
||||||
|
// See nlz5 at http://www.hackersdelight.org/hdcodetxt/nlz.c.txt
|
||||||
|
i |= i >> 1;
|
||||||
|
i |= i >> 2;
|
||||||
|
i |= i >> 4;
|
||||||
|
i |= i >> 8;
|
||||||
|
i |= i >> 16;
|
||||||
|
return bitCount(~i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,9 @@ import java.lang.reflect.Modifier;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import avian.Classes;
|
import avian.Classes;
|
||||||
@ -145,6 +147,127 @@ public class LambdaMetafactory {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void maybeBoxOrUnbox(ByteArrayOutputStream out,
|
||||||
|
List<PoolEntry> pool,
|
||||||
|
MethodType.TypeSpec from,
|
||||||
|
MethodType.TypeSpec to)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
if (to.type().isPrimitive()) {
|
||||||
|
if (! from.type().isPrimitive()) {
|
||||||
|
write1(out, invokevirtual);
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch (to.spec()) {
|
||||||
|
case "Z":
|
||||||
|
writeMethodReference(out, pool, Classes.toVMMethod
|
||||||
|
(Boolean.class.getMethod("booleanValue")));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "B":
|
||||||
|
writeMethodReference(out, pool, Classes.toVMMethod
|
||||||
|
(Byte.class.getMethod("byteValue")));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "S":
|
||||||
|
writeMethodReference(out, pool, Classes.toVMMethod
|
||||||
|
(Short.class.getMethod("shortValue")));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "C":
|
||||||
|
writeMethodReference(out, pool, Classes.toVMMethod
|
||||||
|
(Character.class.getMethod("charValue")));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "I":
|
||||||
|
writeMethodReference(out, pool, Classes.toVMMethod
|
||||||
|
(Integer.class.getMethod("intValue")));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "F":
|
||||||
|
writeMethodReference(out, pool, Classes.toVMMethod
|
||||||
|
(Float.class.getMethod("floatValue")));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "J":
|
||||||
|
writeMethodReference(out, pool, Classes.toVMMethod
|
||||||
|
(Long.class.getMethod("longValue")));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "D":
|
||||||
|
writeMethodReference(out, pool, Classes.toVMMethod
|
||||||
|
(Double.class.getMethod("doubleValue")));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new AssertionError("don't know how to auto-unbox to " + to.spec());
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (from.type().isPrimitive()) {
|
||||||
|
write1(out, invokestatic);
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch (from.spec()) {
|
||||||
|
case "Z":
|
||||||
|
writeMethodReference(out, pool, Classes.toVMMethod
|
||||||
|
(Boolean.class.getMethod
|
||||||
|
("valueOf", Boolean.TYPE)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "B":
|
||||||
|
writeMethodReference(out, pool, Classes.toVMMethod
|
||||||
|
(Byte.class.getMethod
|
||||||
|
("valueOf", Byte.TYPE)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "S":
|
||||||
|
writeMethodReference(out, pool, Classes.toVMMethod
|
||||||
|
(Short.class.getMethod
|
||||||
|
("valueOf", Short.TYPE)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "C":
|
||||||
|
writeMethodReference(out, pool, Classes.toVMMethod
|
||||||
|
(Character.class.getMethod
|
||||||
|
("valueOf", Character.TYPE)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "I":
|
||||||
|
writeMethodReference(out, pool, Classes.toVMMethod
|
||||||
|
(Integer.class.getMethod
|
||||||
|
("valueOf", Integer.TYPE)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "F":
|
||||||
|
writeMethodReference(out, pool, Classes.toVMMethod
|
||||||
|
(Float.class.getMethod
|
||||||
|
("valueOf", Float.TYPE)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "J":
|
||||||
|
writeMethodReference(out, pool, Classes.toVMMethod
|
||||||
|
(Long.class.getMethod
|
||||||
|
("valueOf", Long.TYPE)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "D":
|
||||||
|
writeMethodReference(out, pool, Classes.toVMMethod
|
||||||
|
(Double.class.getMethod
|
||||||
|
("valueOf", Double.TYPE)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new AssertionError("don't know how to autobox from " + from.spec());
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static byte[] makeInvocationCode(List<PoolEntry> pool,
|
private static byte[] makeInvocationCode(List<PoolEntry> pool,
|
||||||
String className,
|
String className,
|
||||||
String constructorSpec,
|
String constructorSpec,
|
||||||
@ -155,47 +278,81 @@ public class LambdaMetafactory {
|
|||||||
{
|
{
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
write2(out, fieldType.footprint()
|
write2(out, fieldType.footprint()
|
||||||
+ localType.footprint() + 2); // max stack
|
+ localType.footprint() + 4); // max stack
|
||||||
write2(out, localType.footprint() + 1); // max locals
|
write2(out, localType.footprint() + 1); // max locals
|
||||||
write4(out, 0); // length (we'll set the real value later)
|
write4(out, 0); // length (we'll set the real value later)
|
||||||
|
|
||||||
write1(out, aload_0);
|
write1(out, aload_0);
|
||||||
|
|
||||||
|
Iterator<MethodType.Parameter> dst = implementation.type().parameters().iterator();
|
||||||
|
|
||||||
|
boolean skip = implementation.kind != MethodHandle.REF_invokeStatic;
|
||||||
|
|
||||||
for (MethodType.Parameter p: fieldType.parameters()) {
|
for (MethodType.Parameter p: fieldType.parameters()) {
|
||||||
write1(out, aload_0);
|
write1(out, aload_0);
|
||||||
write1(out, getfield);
|
write1(out, getfield);
|
||||||
write2(out, ConstantPool.addFieldRef
|
write2(out, ConstantPool.addFieldRef
|
||||||
(pool, className, "field" + p.index(), p.spec()) + 1);
|
(pool, className, "field" + p.index(), p.spec()) + 1);
|
||||||
|
if (skip) {
|
||||||
|
skip = false;
|
||||||
|
} else {
|
||||||
|
maybeBoxOrUnbox(out, pool, p, dst.next());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (MethodType.Parameter p: localType.parameters()) {
|
for (MethodType.Parameter p: localType.parameters()) {
|
||||||
write1(out, p.load());
|
write1(out, p.load());
|
||||||
write1(out, p.position() + 1);
|
write1(out, p.position() + 1);
|
||||||
|
if (skip) {
|
||||||
|
skip = false;
|
||||||
|
} else {
|
||||||
|
maybeBoxOrUnbox(out, pool, p, dst.next());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (implementation.kind) {
|
switch (implementation.kind) {
|
||||||
|
case MethodHandle.REF_invokeVirtual:
|
||||||
|
write1(out, invokevirtual);
|
||||||
|
writeMethodReference(out, pool, implementation.method);
|
||||||
|
break;
|
||||||
|
|
||||||
case MethodHandle.REF_invokeStatic:
|
case MethodHandle.REF_invokeStatic:
|
||||||
write1(out, invokestatic);
|
write1(out, invokestatic);
|
||||||
|
writeMethodReference(out, pool, implementation.method);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MethodHandle.REF_invokeSpecial:
|
case MethodHandle.REF_invokeSpecial:
|
||||||
write1(out, invokespecial);
|
write1(out, invokespecial);
|
||||||
|
writeMethodReference(out, pool, implementation.method);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MethodHandle.REF_newInvokeSpecial:
|
||||||
|
write1(out, new_);
|
||||||
|
write2(out, ConstantPool.addClass
|
||||||
|
(pool,
|
||||||
|
Classes.makeString
|
||||||
|
(implementation.method.class_.name, 0,
|
||||||
|
implementation.method.class_.name.length - 1)) + 1);
|
||||||
|
write1(out, dup);
|
||||||
|
write1(out, invokespecial);
|
||||||
|
writeMethodReference(out, pool, implementation.method);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MethodHandle.REF_invokeInterface:
|
||||||
|
write1(out, invokeinterface);
|
||||||
|
writeInterfaceMethodReference(out, pool, implementation.method);
|
||||||
|
write1(out, implementation.method.parameterFootprint);
|
||||||
|
write1(out, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: throw new AssertionError
|
default: throw new AssertionError
|
||||||
("todo: implement per http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.4.3.5");
|
("todo: implement '" + implementation.kind + "' per http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.4.3.5");
|
||||||
}
|
}
|
||||||
|
|
||||||
write2(out, ConstantPool.addMethodRef
|
if (implementation.kind != MethodHandle.REF_newInvokeSpecial) {
|
||||||
(pool,
|
maybeBoxOrUnbox(out, pool, implementation.type().result(), localType.result());
|
||||||
Classes.makeString(implementation.method.class_.name, 0,
|
}
|
||||||
implementation.method.class_.name.length - 1),
|
write1(out, localType.result().return_());
|
||||||
Classes.makeString(implementation.method.name, 0,
|
|
||||||
implementation.method.name.length - 1),
|
|
||||||
Classes.makeString(implementation.method.spec, 0,
|
|
||||||
implementation.method.spec.length - 1)) + 1);
|
|
||||||
|
|
||||||
write1(out, implementation.type().result().return_());
|
|
||||||
|
|
||||||
write2(out, 0); // exception handler table length
|
write2(out, 0); // exception handler table length
|
||||||
write2(out, 0); // attribute count
|
write2(out, 0); // attribute count
|
||||||
@ -206,6 +363,36 @@ public class LambdaMetafactory {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void writeMethodReference(OutputStream out,
|
||||||
|
List<PoolEntry> pool,
|
||||||
|
avian.VMMethod method)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
write2(out, ConstantPool.addMethodRef
|
||||||
|
(pool,
|
||||||
|
Classes.makeString(method.class_.name, 0,
|
||||||
|
method.class_.name.length - 1),
|
||||||
|
Classes.makeString(method.name, 0,
|
||||||
|
method.name.length - 1),
|
||||||
|
Classes.makeString(method.spec, 0,
|
||||||
|
method.spec.length - 1)) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void writeInterfaceMethodReference(OutputStream out,
|
||||||
|
List<PoolEntry> pool,
|
||||||
|
avian.VMMethod method)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
write2(out, ConstantPool.addInterfaceMethodRef
|
||||||
|
(pool,
|
||||||
|
Classes.makeString(method.class_.name, 0,
|
||||||
|
method.class_.name.length - 1),
|
||||||
|
Classes.makeString(method.name, 0,
|
||||||
|
method.name.length - 1),
|
||||||
|
Classes.makeString(method.spec, 0,
|
||||||
|
method.spec.length - 1)) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
public static byte[] makeLambda(String invokedName,
|
public static byte[] makeLambda(String invokedName,
|
||||||
String invokedType,
|
String invokedType,
|
||||||
String methodType,
|
String methodType,
|
||||||
|
@ -14,8 +14,11 @@ import avian.Classes;
|
|||||||
import avian.SystemClassLoader;
|
import avian.SystemClassLoader;
|
||||||
|
|
||||||
public class MethodHandle {
|
public class MethodHandle {
|
||||||
|
static final int REF_invokeVirtual = 5;
|
||||||
static final int REF_invokeStatic = 6;
|
static final int REF_invokeStatic = 6;
|
||||||
static final int REF_invokeSpecial = 7;
|
static final int REF_invokeSpecial = 7;
|
||||||
|
static final int REF_newInvokeSpecial = 8;
|
||||||
|
static final int REF_invokeInterface = 9;
|
||||||
|
|
||||||
final int kind;
|
final int kind;
|
||||||
private final ClassLoader loader;
|
private final ClassLoader loader;
|
||||||
|
@ -267,7 +267,13 @@ public final class MethodType implements java.io.Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Parameter {
|
public interface TypeSpec {
|
||||||
|
public Class type();
|
||||||
|
|
||||||
|
public String spec();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Parameter implements TypeSpec {
|
||||||
private final int index;
|
private final int index;
|
||||||
private final int position;
|
private final int position;
|
||||||
private final String spec;
|
private final String spec;
|
||||||
@ -299,12 +305,16 @@ public final class MethodType implements java.io.Serializable {
|
|||||||
return spec;
|
return spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Class type() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
public int load() {
|
public int load() {
|
||||||
return load;
|
return load;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Result {
|
public static class Result implements TypeSpec {
|
||||||
private final String spec;
|
private final String spec;
|
||||||
private final Class type;
|
private final Class type;
|
||||||
private final int return_;
|
private final int return_;
|
||||||
@ -318,5 +328,13 @@ public final class MethodType implements java.io.Serializable {
|
|||||||
public int return_() {
|
public int return_() {
|
||||||
return return_; // :)
|
return return_; // :)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String spec() {
|
||||||
|
return spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class type() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,9 @@ package java.net;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public abstract class URLConnection {
|
public abstract class URLConnection {
|
||||||
protected final URL url;
|
protected final URL url;
|
||||||
@ -32,6 +35,10 @@ public abstract class URLConnection {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getContentLengthLong() {
|
||||||
|
return -1l;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract void connect() throws IOException;
|
public abstract void connect() throws IOException;
|
||||||
|
|
||||||
public InputStream getInputStream() throws IOException {
|
public InputStream getInputStream() throws IOException {
|
||||||
@ -61,4 +68,35 @@ public abstract class URLConnection {
|
|||||||
public void setUseCaches(boolean v) {
|
public void setUseCaches(boolean v) {
|
||||||
useCaches = v;
|
useCaches = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getHeaderField(String name) {
|
||||||
|
String result = null;
|
||||||
|
if(name != null) {
|
||||||
|
List<String> values = getHeaderFields().get(name.toLowerCase());
|
||||||
|
if (values != null && values.size() > 0) {
|
||||||
|
result = values.get(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeaderFieldInt(String name, int Default) {
|
||||||
|
return (int) getHeaderFieldLong(name, Default);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getHeaderFieldLong(String name, long Default) {
|
||||||
|
long result = Default;
|
||||||
|
try {
|
||||||
|
result = Long.parseLong(getHeaderField(name));
|
||||||
|
} catch(Exception e) {
|
||||||
|
// Do nothing, default will be returned
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String,List<String>> getHeaderFields() {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -686,4 +686,30 @@ public class Arrays {
|
|||||||
System.arraycopy(array, 0, result, 0, length);
|
System.arraycopy(array, 0, result, 0, length);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int binarySearch(int[] a, int key) {
|
||||||
|
return binarySearch(a, 0, a.length - 1, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int binarySearch(int[] a, int fromIndex, int toIndex, int key) {
|
||||||
|
checkRange(a.length, fromIndex, toIndex);
|
||||||
|
|
||||||
|
// Assume array is already sorted
|
||||||
|
int left = fromIndex;
|
||||||
|
int right = toIndex - 1;
|
||||||
|
int mid;
|
||||||
|
while(left <= right) {
|
||||||
|
mid = (left + right) / 2;
|
||||||
|
if(a[mid] < key) {
|
||||||
|
left = mid + 1;
|
||||||
|
} else if(a[mid] > key) {
|
||||||
|
right = mid - 1;
|
||||||
|
} else {
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -left - 1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2345,21 +2345,21 @@ ifeq ($(kernel),darwin)
|
|||||||
$(header-sysroot)/usr/include/netinet/icmp6.h \
|
$(header-sysroot)/usr/include/netinet/icmp6.h \
|
||||||
$(header-sysroot)/usr/include/netinet/ip_var.h; do \
|
$(header-sysroot)/usr/include/netinet/ip_var.h; do \
|
||||||
if [ ! -f "$(build)/openjdk/netinet/$$(basename $${file})" ]; then \
|
if [ ! -f "$(build)/openjdk/netinet/$$(basename $${file})" ]; then \
|
||||||
ln "$${file}" "$(build)/openjdk/netinet/$$(basename $${file})"; \
|
ln -s "$${file}" "$(build)/openjdk/netinet/$$(basename $${file})"; \
|
||||||
fi; \
|
fi; \
|
||||||
done
|
done
|
||||||
mkdir -p $(build)/openjdk/netinet6
|
mkdir -p $(build)/openjdk/netinet6
|
||||||
for file in \
|
for file in \
|
||||||
$(header-sysroot)/usr/include/netinet6/in6_var.h; do \
|
$(header-sysroot)/usr/include/netinet6/in6_var.h; do \
|
||||||
if [ ! -f "$(build)/openjdk/netinet6/$$(basename $${file})" ]; then \
|
if [ ! -f "$(build)/openjdk/netinet6/$$(basename $${file})" ]; then \
|
||||||
ln "$${file}" "$(build)/openjdk/netinet6/$$(basename $${file})"; \
|
ln -s "$${file}" "$(build)/openjdk/netinet6/$$(basename $${file})"; \
|
||||||
fi; \
|
fi; \
|
||||||
done
|
done
|
||||||
mkdir -p $(build)/openjdk/net
|
mkdir -p $(build)/openjdk/net
|
||||||
for file in \
|
for file in \
|
||||||
$(header-sysroot)/usr/include/net/if_arp.h; do \
|
$(header-sysroot)/usr/include/net/if_arp.h; do \
|
||||||
if [ ! -f "$(build)/openjdk/net/$$(basename $${file})" ]; then \
|
if [ ! -f "$(build)/openjdk/net/$$(basename $${file})" ]; then \
|
||||||
ln "$${file}" "$(build)/openjdk/net/$$(basename $${file})"; \
|
ln -s "$${file}" "$(build)/openjdk/net/$$(basename $${file})"; \
|
||||||
fi; \
|
fi; \
|
||||||
done
|
done
|
||||||
mkdir -p $(build)/openjdk/sys
|
mkdir -p $(build)/openjdk/sys
|
||||||
@ -2367,7 +2367,7 @@ ifeq ($(kernel),darwin)
|
|||||||
$(header-sysroot)/usr/include/sys/kern_event.h \
|
$(header-sysroot)/usr/include/sys/kern_event.h \
|
||||||
$(header-sysroot)/usr/include/sys/sys_domain.h; do \
|
$(header-sysroot)/usr/include/sys/sys_domain.h; do \
|
||||||
if [ ! -f "$(build)/openjdk/sys/$$(basename $${file})" ]; then \
|
if [ ! -f "$(build)/openjdk/sys/$$(basename $${file})" ]; then \
|
||||||
ln "$${file}" "$(build)/openjdk/sys/$$(basename $${file})"; \
|
ln -s "$${file}" "$(build)/openjdk/sys/$$(basename $${file})"; \
|
||||||
fi; \
|
fi; \
|
||||||
done
|
done
|
||||||
endif
|
endif
|
||||||
|
@ -332,3 +332,19 @@
|
|||||||
<methods>;
|
<methods>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Needed to create temporary file paths, amongst other things.
|
||||||
|
-keep class sun.security.provider.NativePRNG
|
||||||
|
-keep class sun.security.provider.SHA
|
||||||
|
|
||||||
|
# Character set codecs
|
||||||
|
-keep class sun.nio.cs.ISO_8859_1
|
||||||
|
-keep class sun.nio.cs.UTF_8
|
||||||
|
-keep class sun.nio.cs.UTF_16
|
||||||
|
-keep class sun.nio.cs.UTF_16BE
|
||||||
|
-keep class sun.nio.cs.UTF_16LE
|
||||||
|
-keep class sun.nio.cs.US_ASCII
|
||||||
|
|
||||||
|
# Accessed from native code
|
||||||
|
-keep class java.util.zip.Deflater {
|
||||||
|
<fields>;
|
||||||
|
}
|
@ -3455,6 +3455,7 @@ inline object resolve(
|
|||||||
loadMemoryBarrier();
|
loadMemoryBarrier();
|
||||||
|
|
||||||
if (objectClass(t, o) == type(t, GcReference::Type)) {
|
if (objectClass(t, o) == type(t, GcReference::Type)) {
|
||||||
|
PROTECT(t, loader);
|
||||||
PROTECT(t, pool);
|
PROTECT(t, pool);
|
||||||
|
|
||||||
GcReference* reference = cast<GcReference>(t, o);
|
GcReference* reference = cast<GcReference>(t, o);
|
||||||
@ -3475,6 +3476,10 @@ inline object resolve(
|
|||||||
if (o) {
|
if (o) {
|
||||||
storeStoreMemoryBarrier();
|
storeStoreMemoryBarrier();
|
||||||
|
|
||||||
|
if (objectClass(t, o) == type(t, GcMethod::Type)) {
|
||||||
|
o = makeMethodHandle(t, reference->kind(), loader, cast<GcMethod>(t, o), 0);
|
||||||
|
}
|
||||||
|
|
||||||
pool->setBodyElement(t, index, reinterpret_cast<uintptr_t>(o));
|
pool->setBodyElement(t, index, reinterpret_cast<uintptr_t>(o));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -3594,7 +3599,7 @@ inline GcMethod* resolveMethod(Thread* t,
|
|||||||
unsigned index,
|
unsigned index,
|
||||||
bool throw_ = true)
|
bool throw_ = true)
|
||||||
{
|
{
|
||||||
return cast<GcMethod>(t,
|
GcMethodHandle* handle = cast<GcMethodHandle>(t,
|
||||||
resolve(t,
|
resolve(t,
|
||||||
loader,
|
loader,
|
||||||
method->code()->pool(),
|
method->code()->pool(),
|
||||||
@ -3602,6 +3607,8 @@ inline GcMethod* resolveMethod(Thread* t,
|
|||||||
findMethodInClass,
|
findMethodInClass,
|
||||||
GcNoSuchMethodError::Type,
|
GcNoSuchMethodError::Type,
|
||||||
throw_));
|
throw_));
|
||||||
|
|
||||||
|
return handle ? handle->method() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline GcMethod* resolveMethod(Thread* t,
|
inline GcMethod* resolveMethod(Thread* t,
|
||||||
|
@ -2102,6 +2102,8 @@ void interceptFileOperations(Thread* t, bool updateRuntimeData)
|
|||||||
if (fileInputStreamFdField) {
|
if (fileInputStreamFdField) {
|
||||||
cp->fileInputStreamFdField = fileInputStreamFdField->offset();
|
cp->fileInputStreamFdField = fileInputStreamFdField->offset();
|
||||||
|
|
||||||
|
// Some OpenJDK versions wrap the native call in a simple forwarder method, others don't.
|
||||||
|
|
||||||
if (findMethodOrNull(t, fileInputStreamClass, "open0", "(Ljava/lang/String;)V") != 0) {
|
if (findMethodOrNull(t, fileInputStreamClass, "open0", "(Ljava/lang/String;)V") != 0) {
|
||||||
intercept(t,
|
intercept(t,
|
||||||
fileInputStreamClass,
|
fileInputStreamClass,
|
||||||
@ -2141,19 +2143,37 @@ void interceptFileOperations(Thread* t, bool updateRuntimeData)
|
|||||||
voidPointer(readBytesFromFile),
|
voidPointer(readBytesFromFile),
|
||||||
updateRuntimeData);
|
updateRuntimeData);
|
||||||
|
|
||||||
intercept(t,
|
if (findMethodOrNull(t, fileInputStreamClass, "skip0", "()I") != 0) {
|
||||||
fileInputStreamClass,
|
intercept(t,
|
||||||
"skip",
|
fileInputStreamClass,
|
||||||
"(J)J",
|
"skip0",
|
||||||
voidPointer(skipBytesInFile),
|
"(J)J",
|
||||||
updateRuntimeData);
|
voidPointer(skipBytesInFile),
|
||||||
|
updateRuntimeData);
|
||||||
|
} else {
|
||||||
|
intercept(t,
|
||||||
|
fileInputStreamClass,
|
||||||
|
"skip",
|
||||||
|
"(J)J",
|
||||||
|
voidPointer(skipBytesInFile),
|
||||||
|
updateRuntimeData);
|
||||||
|
}
|
||||||
|
|
||||||
intercept(t,
|
if (findMethodOrNull(t, fileInputStreamClass, "available0", "()I") != 0) {
|
||||||
fileInputStreamClass,
|
intercept(t,
|
||||||
"available",
|
fileInputStreamClass,
|
||||||
"()I",
|
"available0",
|
||||||
voidPointer(availableBytesInFile),
|
"()I",
|
||||||
updateRuntimeData);
|
voidPointer(availableBytesInFile),
|
||||||
|
updateRuntimeData);
|
||||||
|
} else {
|
||||||
|
intercept(t,
|
||||||
|
fileInputStreamClass,
|
||||||
|
"available",
|
||||||
|
"()I",
|
||||||
|
voidPointer(availableBytesInFile),
|
||||||
|
updateRuntimeData);
|
||||||
|
}
|
||||||
|
|
||||||
intercept(t,
|
intercept(t,
|
||||||
fileInputStreamClass,
|
fileInputStreamClass,
|
||||||
|
@ -6094,13 +6094,13 @@ GcCallSite* resolveDynamic(Thread* t, GcInvocation* invocation)
|
|||||||
PROTECT(t, bootstrapArray);
|
PROTECT(t, bootstrapArray);
|
||||||
|
|
||||||
// Resolve the bootstrap method itself.
|
// Resolve the bootstrap method itself.
|
||||||
GcMethod* bootstrap = cast<GcMethod>(t,
|
GcMethod* bootstrap = cast<GcMethodHandle>(t,
|
||||||
resolve(t,
|
resolve(t,
|
||||||
c->loader(),
|
c->loader(),
|
||||||
invocation->pool(),
|
invocation->pool(),
|
||||||
bootstrapArray->body()[0],
|
bootstrapArray->body()[0],
|
||||||
findMethodInClass,
|
findMethodInClass,
|
||||||
GcNoSuchMethodError::Type));
|
GcNoSuchMethodError::Type))->method();
|
||||||
PROTECT(t, bootstrap);
|
PROTECT(t, bootstrap);
|
||||||
|
|
||||||
// Caller context info to be passed to the bootstrap method.
|
// Caller context info to be passed to the bootstrap method.
|
||||||
@ -6219,13 +6219,7 @@ GcCallSite* resolveDynamic(Thread* t, GcInvocation* invocation)
|
|||||||
|
|
||||||
array->setBodyElement(t, i + argument, type);
|
array->setBodyElement(t, i + argument, type);
|
||||||
} else if (strncmp(p, methodHandle, strlen(methodHandle)) == 0) {
|
} else if (strncmp(p, methodHandle, strlen(methodHandle)) == 0) {
|
||||||
GcReference* reference = cast<GcReference>(
|
GcMethodHandle* handle = cast<GcMethodHandle>(t,
|
||||||
t,
|
|
||||||
singletonObject(
|
|
||||||
t, invocation->pool(), bootstrapArray->body()[i + 1]));
|
|
||||||
int kind = reference->kind();
|
|
||||||
|
|
||||||
GcMethod* method = cast<GcMethod>(t,
|
|
||||||
resolve(t,
|
resolve(t,
|
||||||
c->loader(),
|
c->loader(),
|
||||||
invocation->pool(),
|
invocation->pool(),
|
||||||
@ -6233,9 +6227,6 @@ GcCallSite* resolveDynamic(Thread* t, GcInvocation* invocation)
|
|||||||
findMethodInClass,
|
findMethodInClass,
|
||||||
GcNoSuchMethodError::Type));
|
GcNoSuchMethodError::Type));
|
||||||
|
|
||||||
GcMethodHandle* handle
|
|
||||||
= makeMethodHandle(t, kind, c->loader(), method, 0);
|
|
||||||
|
|
||||||
array->setBodyElement(t, i + argument, handle);
|
array->setBodyElement(t, i + argument, handle);
|
||||||
} else {
|
} else {
|
||||||
abort(t);
|
abort(t);
|
||||||
@ -6265,6 +6256,7 @@ GcCallSite* resolveDynamic(Thread* t, GcInvocation* invocation)
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
fprintf(stderr, "todo: unsupported bootstrap argument type: %s", p);
|
||||||
abort(t);
|
abort(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,6 +40,37 @@ public class ArraysTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void testBinarySearch() {
|
||||||
|
int[] a = new int[]{ 1, 5, 7, 8, 10, 13, 17, 18, 21, 26 };
|
||||||
|
|
||||||
|
int i = Arrays.binarySearch(a, 5);
|
||||||
|
expect(i == 1);
|
||||||
|
i = Arrays.binarySearch(a, 17);
|
||||||
|
expect(i == 6);
|
||||||
|
i = Arrays.binarySearch(a, 6);
|
||||||
|
expect(i == -3);
|
||||||
|
i = Arrays.binarySearch(a, 1, 4, 8);
|
||||||
|
expect(i == 3);
|
||||||
|
i = Arrays.binarySearch(a, 1, 4, 10);
|
||||||
|
expect(i == -5);
|
||||||
|
|
||||||
|
Exception exception = null;
|
||||||
|
try {
|
||||||
|
Arrays.binarySearch(a, -1, a.length, 4);
|
||||||
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
|
exception = e;
|
||||||
|
}
|
||||||
|
expect(exception != null);
|
||||||
|
|
||||||
|
exception = null;
|
||||||
|
try {
|
||||||
|
Arrays.binarySearch(a, 0, a.length + 1, 4);
|
||||||
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
|
exception = e;
|
||||||
|
}
|
||||||
|
expect(exception != null);
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
{ int[] array = new int[0];
|
{ int[] array = new int[0];
|
||||||
Exception exception = null;
|
Exception exception = null;
|
||||||
@ -170,5 +201,6 @@ public class ArraysTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
testSort();
|
testSort();
|
||||||
|
testBinarySearch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,15 @@ public class Files {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void isRootParent() {
|
||||||
|
if(!IsWindows) {
|
||||||
|
File f = new File("/root");
|
||||||
|
File f2 = f.getParentFile();
|
||||||
|
System.out.println("------------"+f2);
|
||||||
|
expect(f2.getPath().equals("/"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void setExecutableTestWithPermissions(boolean executable)
|
private static void setExecutableTestWithPermissions(boolean executable)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
@ -49,6 +58,7 @@ public class Files {
|
|||||||
isAbsoluteTest(false);
|
isAbsoluteTest(false);
|
||||||
setExecutableTestWithPermissions(true);
|
setExecutableTestWithPermissions(true);
|
||||||
setExecutableTestWithPermissions(false);
|
setExecutableTestWithPermissions(false);
|
||||||
|
isRootParent();
|
||||||
|
|
||||||
{ File f = new File("test.txt");
|
{ File f = new File("test.txt");
|
||||||
f.createNewFile();
|
f.createNewFile();
|
||||||
|
@ -20,6 +20,50 @@ public class Integers {
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void testNumberOfLeadingZeros() {
|
||||||
|
expect(Integer.numberOfLeadingZeros(Integer.MAX_VALUE) == 1);
|
||||||
|
expect(Integer.numberOfLeadingZeros(0) == 32);
|
||||||
|
|
||||||
|
int positive = 1;
|
||||||
|
int negative = Integer.MIN_VALUE;
|
||||||
|
for(int i = 0; i < 32; i++) {
|
||||||
|
expect(Integer.numberOfLeadingZeros(positive) == 32 - i - 1);
|
||||||
|
positive <<= 1;
|
||||||
|
|
||||||
|
expect(Integer.numberOfLeadingZeros(negative) == 0);
|
||||||
|
negative += ((int)Math.pow(2, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 99999; i++) {
|
||||||
|
String binary = "";
|
||||||
|
int nolz = 0;
|
||||||
|
boolean nolzFound = false;
|
||||||
|
for(int j = 0; j < 31; j++) {
|
||||||
|
double r = Math.random();
|
||||||
|
if(r < 0.5) {
|
||||||
|
binary += "0";
|
||||||
|
if(!nolzFound) {
|
||||||
|
nolz++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
binary += "1";
|
||||||
|
nolzFound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double r = Math.random();
|
||||||
|
if(r < 0.5) {
|
||||||
|
// positive
|
||||||
|
binary = "0" + binary;
|
||||||
|
nolz++;
|
||||||
|
expect(Integer.numberOfLeadingZeros(Integer.parseInt(binary, 2)) == nolz);
|
||||||
|
} else {
|
||||||
|
// negative
|
||||||
|
expect(Integer.numberOfLeadingZeros(-Integer.parseInt(binary, 2)) == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
{ int foo = 1028;
|
{ int foo = 1028;
|
||||||
foo -= 1023;
|
foo -= 1023;
|
||||||
@ -320,5 +364,7 @@ public class Integers {
|
|||||||
expect(-83 == Integer.decode("-0123").intValue());
|
expect(-83 == Integer.decode("-0123").intValue());
|
||||||
expect(-291 == Integer.decode("-0x123").intValue());
|
expect(-291 == Integer.decode("-0x123").intValue());
|
||||||
expect(291 == Integer.decode("#123").intValue());
|
expect(291 == Integer.decode("#123").intValue());
|
||||||
|
|
||||||
|
testNumberOfLeadingZeros();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import java.util.*;
|
||||||
|
|
||||||
public class InvokeDynamic {
|
public class InvokeDynamic {
|
||||||
private final int foo;
|
private final int foo;
|
||||||
|
|
||||||
@ -27,6 +29,40 @@ public class InvokeDynamic {
|
|||||||
T get();
|
T get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private interface Consumer<T> {
|
||||||
|
void accept(T obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface Function<T, R> {
|
||||||
|
R apply(T obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface BiFunction<T, U, R> {
|
||||||
|
R apply(T t, U u);
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface GetLong {
|
||||||
|
long get(long l);
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface GetDouble {
|
||||||
|
double get(double d);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class LongHolder implements GetLong {
|
||||||
|
@Override
|
||||||
|
public long get(long l) {
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DoubleHolder implements GetDouble {
|
||||||
|
@Override
|
||||||
|
public double get(double d) {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void expect(boolean v) {
|
private static void expect(boolean v) {
|
||||||
if (! v) throw new RuntimeException();
|
if (! v) throw new RuntimeException();
|
||||||
}
|
}
|
||||||
@ -93,19 +129,56 @@ public class InvokeDynamic {
|
|||||||
s.someFunction(1, 2, "");
|
s.someFunction(1, 2, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ Consumer<String> c = System.out::println;
|
||||||
|
c.accept("invoke virtual");
|
||||||
|
}
|
||||||
|
|
||||||
|
{ Function<CharSequence, String> f = CharSequence::toString;
|
||||||
|
expect(f.apply("invoke interface") == "invoke interface");
|
||||||
|
}
|
||||||
|
|
||||||
|
{ Function<CharSequence, Integer> f = CharSequence::length;
|
||||||
|
expect(f.apply("invoke interface") == 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ BiFunction<CharSequence, Integer, Character> f = CharSequence::charAt;
|
||||||
|
String data = "0123456789";
|
||||||
|
for (int i = 0; i < data.length(); ++i) {
|
||||||
|
expect(f.apply(data, i) == data.charAt(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{ Function<java.util.List<String>, Iterator<String>> f = java.util.List<String>::iterator;
|
||||||
|
Iterator<String> iter = f.apply(Arrays.asList("1", "22", "333"));
|
||||||
|
expect(iter.next() == "1");
|
||||||
|
expect(iter.next() == "22");
|
||||||
|
expect(iter.next() == "333");
|
||||||
|
expect(! iter.hasNext());
|
||||||
|
}
|
||||||
|
|
||||||
|
{ BiFunction<GetLong, Long, Long> f = GetLong::get;
|
||||||
|
expect(f.apply(new LongHolder(), 20L) == 20L);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ BiFunction<GetDouble, Double, Double> f = GetDouble::get;
|
||||||
|
expect(f.apply(new DoubleHolder(), 20d) == 20d);
|
||||||
|
}
|
||||||
|
|
||||||
// This abort()s in machine.cpp
|
// This abort()s in machine.cpp
|
||||||
// { Foo s = (Foo & Marker) this::requiresBridge;
|
// { Foo s = (Foo & Marker) this::requiresBridge;
|
||||||
// s.someFunction(1, 2, "");
|
// s.someFunction(1, 2, "");
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// NPE
|
{ UnboxedSerializable s = InvokeDynamic::addBoxed;
|
||||||
// { UnboxedSerializable s = InvokeDynamic::addBoxed;
|
expect(s.add(1, 2) == 3);
|
||||||
// expect(s.add(1, 2) == 3);
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// NPE
|
{ Unboxed s = InvokeDynamic::addBoxed;
|
||||||
// { Unboxed s = InvokeDynamic::addBoxed;
|
expect(s.add(1, 2) == 3);
|
||||||
// expect(s.add(1, 2) == 3);
|
}
|
||||||
// }
|
|
||||||
|
{ Supplier<java.util.List<String>> s = java.util.ArrayList<String>::new;
|
||||||
|
java.util.List<String> list = s.get();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,9 +49,10 @@ public class Reflection {
|
|||||||
private static void innerClasses() throws Exception {
|
private static void innerClasses() throws Exception {
|
||||||
Class c = Reflection.class;
|
Class c = Reflection.class;
|
||||||
Class[] inner = c.getDeclaredClasses();
|
Class[] inner = c.getDeclaredClasses();
|
||||||
expect(2 == inner.length);
|
expect(3 == inner.length);
|
||||||
expect(Hello.class == inner[0]
|
expect(Hello.class == inner[0]
|
||||||
|| Hello.class == inner[1]);
|
|| Hello.class == inner[1]
|
||||||
|
|| Hello.class == inner[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int egads;
|
private int egads;
|
||||||
@ -98,7 +99,7 @@ public class Reflection {
|
|||||||
expect(1 == args.length);
|
expect(1 == args.length);
|
||||||
expect(args[0] == String.class);
|
expect(args[0] == String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void throwOOME() {
|
public static void throwOOME() {
|
||||||
throw new OutOfMemoryError();
|
throw new OutOfMemoryError();
|
||||||
}
|
}
|
||||||
@ -110,15 +111,23 @@ public class Reflection {
|
|||||||
expect(!Reflection.class.isMemberClass());
|
expect(!Reflection.class.isMemberClass());
|
||||||
|
|
||||||
expect(Reflection.Hello.class.isMemberClass());
|
expect(Reflection.Hello.class.isMemberClass());
|
||||||
|
|
||||||
Cloneable anonymousLocal = new Cloneable() {};
|
Cloneable anonymousLocal = new Cloneable() {};
|
||||||
expect(anonymousLocal.getClass().isAnonymousClass());
|
expect(anonymousLocal.getClass().isAnonymousClass());
|
||||||
|
|
||||||
class NamedLocal {}
|
class NamedLocal {}
|
||||||
expect(NamedLocal.class.isLocalClass());
|
expect(NamedLocal.class.isLocalClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class MyClassLoader extends ClassLoader {
|
||||||
|
public Package definePackage1(String name) {
|
||||||
|
return definePackage(name, null, null, null, null, null, null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
expect(new MyClassLoader().definePackage1("foo").getName().equals("foo"));
|
||||||
|
|
||||||
innerClasses();
|
innerClasses();
|
||||||
annotations();
|
annotations();
|
||||||
genericType();
|
genericType();
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
# proguard include file (http://proguard.sourceforge.net)
|
# proguard include file (http://proguard.sourceforge.net)
|
||||||
|
|
||||||
# we call the values method reflectively in Enum.valueOf():
|
# Enums have methods and members that are called reflectively in both Avian and OpenJDK.
|
||||||
|
-keepclassmembers enum * {
|
||||||
-keepclassmembers public class * extends java.lang.Enum {
|
**[] $VALUES;
|
||||||
public static *** values();
|
public *;
|
||||||
}
|
public static **[] values();
|
||||||
|
}
|
||||||
|
|
||||||
# the VM depends on the fixed layout of the following classes:
|
# the VM depends on the fixed layout of the following classes:
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user