Imported Upstream version 3.10.0

Former-commit-id: 172c8e3c300b39d5785c7a3e8dfb08ebdbc1a99b
This commit is contained in:
Jo Shields
2014-10-04 11:27:48 +01:00
parent fe777c5c82
commit 8b9b85e7f5
970 changed files with 20242 additions and 31308 deletions

View File

@ -150,6 +150,11 @@ namespace Mono.Cecil.PE {
PointerToRawData = buffer.ReadInt32 (),
};
if (directory.SizeOfData == 0 || directory.PointerToRawData == 0) {
header = Empty<byte>.Array;
return directory;
}
buffer.position = (int) (directory.PointerToRawData - section.PointerToRawData);
header = new byte [directory.SizeOfData];

View File

@ -3099,9 +3099,29 @@ namespace Mono.Cecil {
}
}
string UnescapeTypeName (string name)
{
StringBuilder sb = new StringBuilder (name.Length);
for (int i = 0; i < name.Length; i++) {
char c = name [i];
if (name [i] == '\\') {
if ((i < name.Length - 1) && (name [i + 1] == '\\')) {
sb.Append (c);
i++;
}
} else {
sb.Append (c);
}
}
return sb.ToString ();
}
public TypeReference ReadTypeReference ()
{
return TypeParser.ParseType (reader.module, ReadUTF8String ());
string s = ReadUTF8String ();
if (s != null && s.IndexOf ('\\') != -1)
s = UnescapeTypeName (s);
return TypeParser.ParseType (reader.module, s);
}
object ReadCustomAttributeEnum (TypeReference enum_type)

View File

@ -1164,9 +1164,14 @@ namespace Mono.Cecil {
MetadataToken GetTypeRefToken (TypeReference type)
{
MetadataToken token;
if (module.CustomMetadataWriter != null) {
if (module.CustomMetadataWriter.CreateTypeRefToken (ref type, out token))
return token;
}
var row = CreateTypeRefRow (type);
MetadataToken token;
if (type_ref_map.TryGetValue (row, out token))
return token;

View File

@ -437,7 +437,7 @@ namespace Mono.Cecil {
}
#endif
public TypeReference ImportType (TypeReference type, ImportGenericContext context)
public virtual TypeReference ImportType (TypeReference type, ImportGenericContext context)
{
if (type.IsTypeSpecification ())
return ImportTypeSpecification (type, context);
@ -466,6 +466,7 @@ namespace Mono.Cecil {
case MetadataScopeType.AssemblyNameReference:
return ImportAssemblyName ((AssemblyNameReference) scope);
case MetadataScopeType.ModuleDefinition:
if (scope == module) return scope;
return ImportAssemblyName (((ModuleDefinition) scope).Assembly.Name);
case MetadataScopeType.ModuleReference:
throw new NotImplementedException ();
@ -474,7 +475,7 @@ namespace Mono.Cecil {
throw new NotSupportedException ();
}
AssemblyNameReference ImportAssemblyName (AssemblyNameReference name)
protected virtual AssemblyNameReference ImportAssemblyName (AssemblyNameReference name)
{
AssemblyNameReference reference;
if (TryGetAssemblyNameReference (name, out reference))

View File

@ -157,6 +157,22 @@ namespace Mono.Cecil {
}
}
interface ICustomMetadataWriter
{
/*
* Remap TypeReference or create custom TypeRef token.
*
* Return true to use the returned custom 'token'.
*
* Return false to create a TypeRef token for 'type'
* (which may have been replaced with a different TypeReference).
*
* This is necessary when types are moved from one assembly to another
* to either adjust the scope or replace a TypeRef with a TypeDef token.
*/
bool CreateTypeRefToken (ref TypeReference type, out MetadataToken token);
}
public sealed class WriterParameters {
Stream symbol_stream;
@ -216,6 +232,7 @@ namespace Mono.Cecil {
#if !READ_ONLY
MetadataImporter importer;
ICustomMetadataWriter custom_writer;
#endif
Collection<CustomAttribute> custom_attributes;
Collection<AssemblyNameReference> references;
@ -286,6 +303,18 @@ namespace Mono.Cecil {
internal MetadataImporter MetadataImporter {
get { return importer ?? (importer = new MetadataImporter (this)); }
}
internal void SetMetadataImporter (MetadataImporter importer)
{
if (this.importer != null)
throw new InvalidOperationException ();
this.importer = importer;
}
internal ICustomMetadataWriter CustomMetadataWriter {
get { return custom_writer; }
set { custom_writer = value; }
}
#endif
public IAssemblyResolver AssemblyResolver {

View File

@ -1,7 +1,7 @@
/*
Copyright (C) 2002, 2004, 2005, 2006, 2007 Jeroen Frijters
Copyright (C) 2006 Active Endpoints, Inc.
Copyright (C) 2006 - 2013 Volker Berlin (i-net software)
Copyright (C) 2006 - 2014 Volker Berlin (i-net software)
Copyright (C) 2011 Karsten Heinrich (i-net software)
This software is provided 'as-is', without any express or implied
@ -40,17 +40,29 @@ namespace ikvm.awt
internal class BitmapGraphics : NetGraphics
{
private readonly Bitmap bitmap;
private readonly BufferedImage image;
internal BitmapGraphics(Bitmap bitmap, java.awt.Font font, Color fgcolor, Color bgcolor)
: base(createGraphics(bitmap), font, fgcolor, bgcolor)
internal BitmapGraphics(Bitmap bitmap, Object destination, java.awt.Font font, Color fgcolor, Color bgcolor)
: base(createGraphics(bitmap), destination, font, fgcolor, bgcolor)
{
this.bitmap = bitmap;
image = destination as BufferedImage;
}
internal BitmapGraphics(Bitmap bitmap)
: base(createGraphics(bitmap), null, Color.White, Color.Black)
internal BitmapGraphics(Bitmap bitmap, Object destination)
: this(bitmap, destination, null, Color.White, Color.Black)
{
this.bitmap = bitmap;
}
internal override Graphics g
{
get {
if (image != null)
{
image.toBitmap();
}
return base.g;
}
}
protected override SizeF GetSize() {
@ -89,8 +101,8 @@ namespace ikvm.awt
{
private readonly Control control;
internal ComponentGraphics(Control control, java.awt.Color fgColor, java.awt.Color bgColor, java.awt.Font font)
: base(control.CreateGraphics(), font, J2C.ConvertColor(fgColor), J2C.ConvertColor(bgColor))
internal ComponentGraphics(Control control, java.awt.Component target, java.awt.Color fgColor, java.awt.Color bgColor, java.awt.Font font)
: base(control.CreateGraphics(), target, font, J2C.ConvertColor(fgColor), J2C.ConvertColor(bgColor))
{
this.control = control;
}
@ -116,12 +128,17 @@ namespace ikvm.awt
return (Point)this.control.Invoke(new Converter<Point,Point>(getPointToScreenImpl),point);
}
public override void copyArea(int x, int y, int width, int height, int dx, int dy)
{
Point src = getPointToScreen(new Point(x + (int)this.g.Transform.OffsetX, y + (int)this.g.Transform.OffsetY));
Point dest = new Point(x + (int)this.g.Transform.OffsetX + dx, y + (int)this.g.Transform.OffsetY + dy);
this.g.CopyFromScreen(src, dest, new Size(width, height));
}
public override void copyArea(int x, int y, int width, int height, int dx, int dy)
{
Matrix t = g.Transform;
Point src = getPointToScreen(new Point(x + (int)t.OffsetX, y + (int)t.OffsetY));
Bitmap copy = new Bitmap(width, height);
using (Graphics gCopy = Graphics.FromImage(copy))
{
gCopy.CopyFromScreen(src, new Point(0, 0), new Size(width, height));
}
g.DrawImageUnscaled(copy, x + dx, y + dy);
}
public override void clip(java.awt.Shape shape)
{
@ -150,7 +167,7 @@ namespace ikvm.awt
private bool isBase = true;
internal PrintGraphics(Graphics g)
: base(g, null, Color.White, Color.Black)
: base(g, null, null, Color.White, Color.Black)
{
baseContext = new PrintGraphicsContext();
baseContext.Current = this;
@ -744,7 +761,7 @@ namespace ikvm.awt
netG.g.Clip = Clip;
netG.g.SmoothingMode = SmoothingMode;
netG.g.PixelOffsetMode = PixelOffsetMode;
netG.g.TextRenderingHint = TextRenderingHint;
netG.setTextRenderingHint(TextRenderingHint);
netG.g.InterpolationMode = InterpolationMode;
netG.g.CompositingMode = CompositingMode;
}
@ -768,10 +785,9 @@ namespace ikvm.awt
}
}
internal abstract class NetGraphics : java.awt.Graphics2D
internal abstract class NetGraphics : java.awt.Graphics2D//sun.java2d.SunGraphics2D
{
internal Graphics g;
internal Graphics JGraphics { get { return g; } }
private Graphics graphics;
private java.awt.Color javaColor;
private java.awt.Paint javaPaint;
internal Color color;
@ -780,6 +796,7 @@ namespace ikvm.awt
private java.awt.Stroke stroke;
private static java.awt.BasicStroke defaultStroke = new java.awt.BasicStroke();
private Font netfont;
private int baseline;
internal Brush brush;
internal Pen pen;
private CompositeHelper composite;
@ -787,7 +804,16 @@ namespace ikvm.awt
private Object textAntialiasHint;
private Object fractionalHint = java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT;
protected NetGraphics(Graphics g, java.awt.Font font, Color fgcolor, Color bgcolor)
private static System.Collections.Generic.Dictionary<String, Int32> baselines = new System.Collections.Generic.Dictionary<String, Int32>();
internal static readonly StringFormat FORMAT = new StringFormat(StringFormat.GenericTypographic);
static NetGraphics()
{
FORMAT.FormatFlags = StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoWrap | StringFormatFlags.FitBlackBox;
FORMAT.Trimming = StringTrimming.None;
}
protected NetGraphics(Graphics g, Object destination, java.awt.Font font, Color fgcolor, Color bgcolor) //: base( new sun.java2d.SurfaceData(destination) )
{
if (font == null)
{
@ -801,12 +827,21 @@ namespace ikvm.awt
init(g);
}
/// <summary>
/// The current C# Graphics
/// </summary>
internal virtual Graphics g
{
get { return graphics; }
set { graphics = value; }
}
protected void init(Graphics graphics)
{
NetGraphicsState state = new NetGraphicsState();
state.saveGraphics(this);
g = graphics;
state.restoreGraphics(this);
state.restoreGraphics(this);
}
/// <summary>
@ -850,7 +885,7 @@ namespace ikvm.awt
{
if (pen!=null) pen.Dispose();
if (brush!=null) brush.Dispose();
g.Dispose();
graphics.Dispose(); //for dispose we does not need to synchronize the buffer of a bitmap
}
public override void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)
@ -1190,6 +1225,7 @@ namespace ikvm.awt
{
netfont = f.getNetFont();
font = f;
baseline = getBaseline( netfont, g.TextRenderingHint );
}
}
@ -1278,30 +1314,33 @@ namespace ikvm.awt
drawString(str, (float)x, (float)y);
}
public override void drawString(String text, float x, float y)
{
if (text.Length == 0)
{
public override void drawString(String text, float x, float y) {
if (text.Length == 0) {
return;
}
bool fractional = isFractionalMetrics();
StringFormat format = new StringFormat(StringFormat.GenericTypographic);
format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoWrap | StringFormatFlags.FitBlackBox;
format.Trimming = StringTrimming.None;
if (fractional || !sun.font.StandardGlyphVector.isSimpleString(font, text))
{
g.DrawString(text, netfont, brush, x, y - font.getSize(), format);
}
else
{
// fixed metric for simple text, we position every character to simulate the Java behaviour
java.awt.font.FontRenderContext frc = new java.awt.font.FontRenderContext(null, isAntiAlias(), fractional);
sun.font.FontDesignMetrics metrics = sun.font.FontDesignMetrics.getMetrics(font, frc);
y -= font.getSize();
for (int i = 0; i < text.Length; i++)
{
g.DrawString(text.Substring(i, 1), netfont, brush, x, y, format);
x += metrics.charWidth(text[i]);
CompositingMode origCM = g.CompositingMode;
try {
if (origCM != CompositingMode.SourceOver) {
// Java has a different behaviar for AlphaComposite and Text Antialiasing
g.CompositingMode = CompositingMode.SourceOver;
}
bool fractional = isFractionalMetrics();
if (fractional || !sun.font.StandardGlyphVector.isSimpleString(font, text)) {
g.DrawString(text, netfont, brush, x, y - baseline, FORMAT);
} else {
// fixed metric for simple text, we position every character to simulate the Java behaviour
java.awt.font.FontRenderContext frc = new java.awt.font.FontRenderContext(null, isAntiAlias(), fractional);
sun.font.FontDesignMetrics metrics = sun.font.FontDesignMetrics.getMetrics(font, frc);
y -= baseline;
for (int i = 0; i < text.Length; i++) {
g.DrawString(text.Substring(i, 1), netfont, brush, x, y, FORMAT);
x += metrics.charWidth(text[i]);
}
}
} finally {
if (origCM != CompositingMode.SourceOver) {
g.CompositingMode = origCM;
}
}
}
@ -1345,6 +1384,9 @@ namespace ikvm.awt
public override void setComposite(java.awt.Composite comp)
{
if (javaComposite == comp) {
return;
}
if (comp == null)
{
throw new java.lang.IllegalArgumentException("null Composite");
@ -1750,13 +1792,13 @@ namespace ikvm.awt
if (hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT ||
hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_OFF)
{
g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;
setTextRenderingHint(TextRenderingHint.SingleBitPerPixelGridFit);
textAntialiasHint = hintValue;
return;
}
if (hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON)
{
g.TextRenderingHint = TextRenderingHint.AntiAlias;
setTextRenderingHint(TextRenderingHint.AntiAlias);
textAntialiasHint = hintValue;
return;
}
@ -1933,6 +1975,71 @@ namespace ikvm.awt
return stroke;
}
internal void setTextRenderingHint(TextRenderingHint hint)
{
g.TextRenderingHint = hint;
baseline = getBaseline(netfont, hint);
}
/// <summary>
/// Caclulate the baseline from a font and a TextRenderingHint
/// </summary>
/// <param name="font">the font</param>
/// <param name="hint">the used TextRenderingHint</param>
/// <returns></returns>
private static int getBaseline(Font font, TextRenderingHint hint)
{
lock (baselines)
{
String key = font.ToString() + hint.ToString();
int baseline;
if (!baselines.TryGetValue(key, out baseline))
{
FontFamily family = font.FontFamily;
FontStyle style = font.Style;
float ascent = family.GetCellAscent(style);
float lineSpace = family.GetLineSpacing(style);
baseline = (int)Math.Round(font.GetHeight() * ascent / lineSpace);
// Until this point the calulation use only the Font. But with different TextRenderingHint there are smal differences.
// There is no API that calulate the offset from TextRenderingHint that we messure it.
const int w = 3;
const int h = 3;
Bitmap bitmap = new Bitmap(w, h);
Graphics g = Graphics.FromImage(bitmap);
g.TextRenderingHint = hint;
g.FillRectangle(new SolidBrush(Color.White), 0, 0, w, h);
g.DrawString("A", font, new SolidBrush(Color.Black), 0, -baseline, FORMAT);
g.DrawString("X", font, new SolidBrush(Color.Black), 0, -baseline, FORMAT);
g.Dispose();
int y = 0;
LINE:
while (y < h)
{
for (int x = 0; x < w; x++)
{
Color color = bitmap.GetPixel(x, y);
if (color.GetBrightness() < 0.5)
{
//there is a black pixel, we continue in the next line.
baseline++;
y++;
goto LINE;
}
}
break; // there was a line without black pixel
}
baselines[key] = baseline;
}
return baseline;
}
}
private bool isAntiAlias()
{
switch (g.TextRenderingHint)
@ -1962,6 +2069,7 @@ namespace ikvm.awt
Matrix currentMatrix = null;
Font currentFont = netfont;
TextRenderingHint currentHint = g.TextRenderingHint;
int currentBaseline = baseline;
try
{
java.awt.Font javaFont = gv.getFont();
@ -1969,19 +2077,22 @@ namespace ikvm.awt
{
netfont = javaFont.getNetFont();
}
TextRenderingHint hint;
if (frc.isAntiAliased()) {
if( frc.usesFractionalMetrics() ){
g.TextRenderingHint = TextRenderingHint.AntiAlias;
hint = TextRenderingHint.AntiAlias;
} else {
g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
hint = TextRenderingHint.AntiAliasGridFit;
}
} else {
if (frc.usesFractionalMetrics()) {
g.TextRenderingHint = TextRenderingHint.SingleBitPerPixel;
hint = TextRenderingHint.SingleBitPerPixel;
} else {
g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;
hint = TextRenderingHint.SingleBitPerPixelGridFit;
}
}
g.TextRenderingHint = hint;
baseline = getBaseline(netfont, hint);
if (!frc.getTransform().equals(getTransform()))
{
// save the old context and use the transformation from the renderContext
@ -1994,6 +2105,7 @@ namespace ikvm.awt
{
// Restore the old context if needed
g.TextRenderingHint = currentHint;
baseline = currentBaseline;
netfont = currentFont;
if (currentMatrix != null)
{
@ -2144,14 +2256,20 @@ namespace ikvm.awt
}
}
public class NetGraphicsEnvironment : java.awt.GraphicsEnvironment
public class NetGraphicsEnvironment : sun.java2d.SunGraphicsEnvironment
{
public override bool isDisplayLocal()
{
return true;
}
// Create a bitmap with the dimensions of the argument image. Then
// create a graphics objects from the bitmap. All paint operations will
// then paint the bitmap.
public override java.awt.Graphics2D createGraphics(BufferedImage bi)
{
return new BitmapGraphics(bi.getBitmap());
return new BitmapGraphics(bi.getBitmap(), bi );
}
public override java.awt.Font[] getAllFonts()

View File

@ -1 +1 @@
4341b9c30b528a9c448533ed715fc437369b3561
474cfafc92a8fad74e36e71fb612ebd44209bce8

15
external/ikvm/bin/ikvm.exe.manifest vendored Normal file
View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!--The ID below indicates application support for Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!--The ID below indicates application support for Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
</application>
</compatibility>
</assembly>

View File

@ -0,0 +1,380 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
* http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.atomic;
import java.util.function.LongBinaryOperator;
import java.util.function.DoubleBinaryOperator;
import java.util.concurrent.ThreadLocalRandom;
/**
* A package-local class holding common representation and mechanics
* for classes supporting dynamic striping on 64bit values. The class
* extends Number so that concrete subclasses must publicly do so.
*/
@SuppressWarnings("serial")
abstract class Striped64 extends Number {
/*
* This class maintains a lazily-initialized table of atomically
* updated variables, plus an extra "base" field. The table size
* is a power of two. Indexing uses masked per-thread hash codes.
* Nearly all declarations in this class are package-private,
* accessed directly by subclasses.
*
* Table entries are of class Cell; a variant of AtomicLong padded
* (via @sun.misc.Contended) to reduce cache contention. Padding
* is overkill for most Atomics because they are usually
* irregularly scattered in memory and thus don't interfere much
* with each other. But Atomic objects residing in arrays will
* tend to be placed adjacent to each other, and so will most
* often share cache lines (with a huge negative performance
* impact) without this precaution.
*
* In part because Cells are relatively large, we avoid creating
* them until they are needed. When there is no contention, all
* updates are made to the base field. Upon first contention (a
* failed CAS on base update), the table is initialized to size 2.
* The table size is doubled upon further contention until
* reaching the nearest power of two greater than or equal to the
* number of CPUS. Table slots remain empty (null) until they are
* needed.
*
* A single spinlock ("cellsBusy") is used for initializing and
* resizing the table, as well as populating slots with new Cells.
* There is no need for a blocking lock; when the lock is not
* available, threads try other slots (or the base). During these
* retries, there is increased contention and reduced locality,
* which is still better than alternatives.
*
* The Thread probe fields maintained via ThreadLocalRandom serve
* as per-thread hash codes. We let them remain uninitialized as
* zero (if they come in this way) until they contend at slot
* 0. They are then initialized to values that typically do not
* often conflict with others. Contention and/or table collisions
* are indicated by failed CASes when performing an update
* operation. Upon a collision, if the table size is less than
* the capacity, it is doubled in size unless some other thread
* holds the lock. If a hashed slot is empty, and lock is
* available, a new Cell is created. Otherwise, if the slot
* exists, a CAS is tried. Retries proceed by "double hashing",
* using a secondary hash (Marsaglia XorShift) to try to find a
* free slot.
*
* The table size is capped because, when there are more threads
* than CPUs, supposing that each thread were bound to a CPU,
* there would exist a perfect hash function mapping threads to
* slots that eliminates collisions. When we reach capacity, we
* search for this mapping by randomly varying the hash codes of
* colliding threads. Because search is random, and collisions
* only become known via CAS failures, convergence can be slow,
* and because threads are typically not bound to CPUS forever,
* may not occur at all. However, despite these limitations,
* observed contention rates are typically low in these cases.
*
* It is possible for a Cell to become unused when threads that
* once hashed to it terminate, as well as in the case where
* doubling the table causes no thread to hash to it under
* expanded mask. We do not try to detect or remove such cells,
* under the assumption that for long-running instances, observed
* contention levels will recur, so the cells will eventually be
* needed again; and for short-lived ones, it does not matter.
*/
/**
* Padded variant of AtomicLong supporting only raw accesses plus CAS.
*
* JVM intrinsics note: It would be possible to use a release-only
* form of CAS here, if it were provided.
*/
@sun.misc.Contended static final class Cell {
volatile long value;
Cell(long x) { value = x; }
@ikvm.internal.InterlockedCompareAndSet("value")
final native boolean cas(long cmp, long val);
}
/** Number of CPUS, to place bound on table size */
static final int NCPU = Runtime.getRuntime().availableProcessors();
/**
* Table of cells. When non-null, size is a power of 2.
*/
transient volatile Cell[] cells;
/**
* Base value, used mainly when there is no contention, but also as
* a fallback during table initialization races. Updated via CAS.
*/
transient volatile long base;
/**
* Spinlock (locked via CAS) used when resizing and/or creating Cells.
*/
transient volatile int cellsBusy;
/**
* Package-private default constructor
*/
Striped64() {
}
/**
* CASes the base field.
*/
@ikvm.internal.InterlockedCompareAndSet("base")
final native boolean casBase(long cmp, long val);
/**
* CASes the cellsBusy field from 0 to 1 to acquire lock.
*/
final boolean casCellsBusy() {
return casCellsBusy(0, 1);
}
@ikvm.internal.InterlockedCompareAndSet("cellsBusy")
private native boolean casCellsBusy(int cmp, int newVal);
/**
* Returns the probe value for the current thread.
* Duplicated from ThreadLocalRandom because of packaging restrictions.
*/
static final int getProbe() {
return Thread.currentThread().threadLocalRandomProbe;
}
/**
* Pseudo-randomly advances and records the given probe value for the
* given thread.
* Duplicated from ThreadLocalRandom because of packaging restrictions.
*/
static final int advanceProbe(int probe) {
probe ^= probe << 13; // xorshift
probe ^= probe >>> 17;
probe ^= probe << 5;
Thread.currentThread().threadLocalRandomProbe = probe;
return probe;
}
/**
* Handles cases of updates involving initialization, resizing,
* creating new Cells, and/or contention. See above for
* explanation. This method suffers the usual non-modularity
* problems of optimistic retry code, relying on rechecked sets of
* reads.
*
* @param x the value
* @param fn the update function, or null for add (this convention
* avoids the need for an extra field or function in LongAdder).
* @param wasUncontended false if CAS failed before call
*/
final void longAccumulate(long x, LongBinaryOperator fn,
boolean wasUncontended) {
int h;
if ((h = getProbe()) == 0) {
ThreadLocalRandom.current(); // force initialization
h = getProbe();
wasUncontended = true;
}
boolean collide = false; // True if last slot nonempty
for (;;) {
Cell[] as; Cell a; int n; long v;
if ((as = cells) != null && (n = as.length) > 0) {
if ((a = as[(n - 1) & h]) == null) {
if (cellsBusy == 0) { // Try to attach new Cell
Cell r = new Cell(x); // Optimistically create
if (cellsBusy == 0 && casCellsBusy()) {
boolean created = false;
try { // Recheck under lock
Cell[] rs; int m, j;
if ((rs = cells) != null &&
(m = rs.length) > 0 &&
rs[j = (m - 1) & h] == null) {
rs[j] = r;
created = true;
}
} finally {
cellsBusy = 0;
}
if (created)
break;
continue; // Slot is now non-empty
}
}
collide = false;
}
else if (!wasUncontended) // CAS already known to fail
wasUncontended = true; // Continue after rehash
else if (a.cas(v = a.value, ((fn == null) ? v + x :
fn.applyAsLong(v, x))))
break;
else if (n >= NCPU || cells != as)
collide = false; // At max size or stale
else if (!collide)
collide = true;
else if (cellsBusy == 0 && casCellsBusy()) {
try {
if (cells == as) { // Expand table unless stale
Cell[] rs = new Cell[n << 1];
for (int i = 0; i < n; ++i)
rs[i] = as[i];
cells = rs;
}
} finally {
cellsBusy = 0;
}
collide = false;
continue; // Retry with expanded table
}
h = advanceProbe(h);
}
else if (cellsBusy == 0 && cells == as && casCellsBusy()) {
boolean init = false;
try { // Initialize table
if (cells == as) {
Cell[] rs = new Cell[2];
rs[h & 1] = new Cell(x);
cells = rs;
init = true;
}
} finally {
cellsBusy = 0;
}
if (init)
break;
}
else if (casBase(v = base, ((fn == null) ? v + x :
fn.applyAsLong(v, x))))
break; // Fall back on using base
}
}
/**
* Same as longAccumulate, but injecting long/double conversions
* in too many places to sensibly merge with long version, given
* the low-overhead requirements of this class. So must instead be
* maintained by copy/paste/adapt.
*/
final void doubleAccumulate(double x, DoubleBinaryOperator fn,
boolean wasUncontended) {
int h;
if ((h = getProbe()) == 0) {
ThreadLocalRandom.current(); // force initialization
h = getProbe();
wasUncontended = true;
}
boolean collide = false; // True if last slot nonempty
for (;;) {
Cell[] as; Cell a; int n; long v;
if ((as = cells) != null && (n = as.length) > 0) {
if ((a = as[(n - 1) & h]) == null) {
if (cellsBusy == 0) { // Try to attach new Cell
Cell r = new Cell(Double.doubleToRawLongBits(x));
if (cellsBusy == 0 && casCellsBusy()) {
boolean created = false;
try { // Recheck under lock
Cell[] rs; int m, j;
if ((rs = cells) != null &&
(m = rs.length) > 0 &&
rs[j = (m - 1) & h] == null) {
rs[j] = r;
created = true;
}
} finally {
cellsBusy = 0;
}
if (created)
break;
continue; // Slot is now non-empty
}
}
collide = false;
}
else if (!wasUncontended) // CAS already known to fail
wasUncontended = true; // Continue after rehash
else if (a.cas(v = a.value,
((fn == null) ?
Double.doubleToRawLongBits
(Double.longBitsToDouble(v) + x) :
Double.doubleToRawLongBits
(fn.applyAsDouble
(Double.longBitsToDouble(v), x)))))
break;
else if (n >= NCPU || cells != as)
collide = false; // At max size or stale
else if (!collide)
collide = true;
else if (cellsBusy == 0 && casCellsBusy()) {
try {
if (cells == as) { // Expand table unless stale
Cell[] rs = new Cell[n << 1];
for (int i = 0; i < n; ++i)
rs[i] = as[i];
cells = rs;
}
} finally {
cellsBusy = 0;
}
collide = false;
continue; // Retry with expanded table
}
h = advanceProbe(h);
}
else if (cellsBusy == 0 && cells == as && casCellsBusy()) {
boolean init = false;
try { // Initialize table
if (cells == as) {
Cell[] rs = new Cell[2];
rs[h & 1] = new Cell(Double.doubleToRawLongBits(x));
cells = rs;
init = true;
}
} finally {
cellsBusy = 0;
}
if (init)
break;
}
else if (casBase(v = base,
((fn == null) ?
Double.doubleToRawLongBits
(Double.longBitsToDouble(v) + x) :
Double.doubleToRawLongBits
(fn.applyAsDouble
(Double.longBitsToDouble(v), x)))))
break; // Fall back on using base
}
}
}

View File

@ -35,7 +35,7 @@
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
<DefineConstants>TRACE;DEBUG;STATIC_COMPILER;IKVM_REF_EMIT</DefineConstants>
<DefineConstants>TRACE;DEBUG;STATIC_COMPILER;EMITTERS</DefineConstants>
<DocumentationFile>
</DocumentationFile>
<DebugSymbols>true</DebugSymbols>
@ -91,6 +91,7 @@
<Compile Include="runtime\BigEndianBinaryReader.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="runtime\Boxer.cs" />
<Compile Include="runtime\ByteCode.cs">
<SubType>Code</SubType>
</Compile>
@ -119,10 +120,12 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="runtime\JsrInliner.cs" />
<Compile Include="runtime\LambdaMetafactory.cs" />
<Compile Include="runtime\LocalVars.cs" />
<Compile Include="runtime\MemberWrapper.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="runtime\MethodHandleUtil.cs" />
<Compile Include="runtime\profiler.cs">
<SubType>Code</SubType>
</Compile>

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2002-2009 Jeroen Frijters
Copyright (C) 2002-2014 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -48,14 +48,14 @@ namespace IKVM.Internal
private WorkaroundBaseClass workaroundBaseClass;
internal AotTypeWrapper(ClassFile f, CompilerClassLoader loader)
: base(f, loader, null)
: base(null, f, loader, null)
{
}
protected override Type GetBaseTypeForDefineType()
{
TypeWrapper baseTypeWrapper = BaseTypeWrapper;
if (this.IsPublic && this.IsAbstract && baseTypeWrapper.IsPublic && baseTypeWrapper.IsAbstract)
if (this.IsPublic && this.IsAbstract && baseTypeWrapper.IsPublic && baseTypeWrapper.IsAbstract && classLoader.WorkaroundAbstractMethodWidening)
{
// FXBUG
// if the current class widens access on an abstract base class method,
@ -78,7 +78,7 @@ namespace IKVM.Internal
}
if (methods != null)
{
string name = "__WorkaroundBaseClass__." + Name;
string name = "__WorkaroundBaseClass__." + UnicodeUtil.EscapeInvalidSurrogates(Name);
while (!classLoader.ReserveName(name))
{
name = "_" + name;
@ -297,10 +297,7 @@ namespace IKVM.Internal
}
if(!found)
{
FieldWrapper[] newFields = new FieldWrapper[fields.Length + 1];
Array.Copy(fields, newFields, fields.Length);
fields = newFields;
fields[fields.Length - 1] = FieldWrapper.Create(this, null, null, field.Name, field.Sig, new ExModifiers((Modifiers)field.Modifiers, false));
fields = ArrayUtil.Concat(fields, FieldWrapper.Create(this, null, null, field.Name, field.Sig, new ExModifiers((Modifiers)field.Modifiers, false)));
}
}
}
@ -471,9 +468,7 @@ namespace IKVM.Internal
if(setter != null)
{
MethodWrapper mw = setter;
Type[] args = new Type[indexer.Length + 1];
indexer.CopyTo(args, 0);
args[args.Length - 1] = typeWrapper.TypeAsSignatureType;
Type[] args = ArrayUtil.Concat(indexer, typeWrapper.TypeAsSignatureType);
if(!CheckPropertyArgs(args, mw.GetParametersForDefineMethod()))
{
Console.Error.WriteLine("Warning: ignoring invalid property setter for {0}::{1}", clazz.Name, prop.Name);
@ -512,36 +507,6 @@ namespace IKVM.Internal
}
}
protected override bool IsPInvokeMethod(ClassFile.Method m)
{
Dictionary<string, IKVM.Internal.MapXml.Class> mapxml = classLoader.GetMapXmlClasses();
if(mapxml != null)
{
IKVM.Internal.MapXml.Class clazz;
if(mapxml.TryGetValue(this.Name, out clazz) && clazz.Methods != null)
{
foreach(IKVM.Internal.MapXml.Method method in clazz.Methods)
{
if(method.Name == m.Name && method.Sig == m.Signature)
{
if(method.Attributes != null)
{
foreach(IKVM.Internal.MapXml.Attribute attr in method.Attributes)
{
if(StaticCompiler.GetType(classLoader, attr.Type) == JVM.Import(typeof(System.Runtime.InteropServices.DllImportAttribute)))
{
return true;
}
}
}
break;
}
}
}
}
return base.IsPInvokeMethod(m);
}
private static void MapModifiers(MapXml.MapModifiers mapmods, bool isConstructor, out bool setmodifiers, ref MethodAttributes attribs)
{
setmodifiers = false;
@ -716,14 +681,14 @@ namespace IKVM.Internal
// are we adding a new method?
if(GetMethodWrapper(method.Name, method.Sig, false) == null)
{
if(method.body == null)
bool setmodifiers = false;
MethodAttributes attribs = method.MethodAttributes;
MapModifiers(method.Modifiers, false, out setmodifiers, ref attribs);
if(method.body == null && (attribs & MethodAttributes.Abstract) == 0)
{
Console.Error.WriteLine("Error: Method {0}.{1}{2} in xml remap file doesn't have a body.", clazz.Name, method.Name, method.Sig);
continue;
}
bool setmodifiers = false;
MethodAttributes attribs = method.MethodAttributes;
MapModifiers(method.Modifiers, false, out setmodifiers, ref attribs);
Type returnType;
Type[] parameterTypes;
MapSignature(method.Sig, out returnType, out parameterTypes);
@ -739,9 +704,12 @@ namespace IKVM.Internal
typeBuilder.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod());
}
CompilerClassLoader.AddDeclaredExceptions(mb, method.throws);
CodeEmitter ilgen = CodeEmitter.Create(mb);
method.Emit(classLoader, ilgen);
ilgen.DoEmit();
if(method.body != null)
{
CodeEmitter ilgen = CodeEmitter.Create(mb);
method.Emit(classLoader, ilgen);
ilgen.DoEmit();
}
if(method.Attributes != null)
{
foreach(IKVM.Internal.MapXml.Attribute attr in method.Attributes)
@ -804,11 +772,14 @@ namespace IKVM.Internal
}
}
protected override MethodBuilder DefineGhostMethod(string name, MethodAttributes attribs, MethodWrapper mw)
protected override MethodBuilder DefineGhostMethod(TypeBuilder typeBuilder, string name, MethodAttributes attribs, MethodWrapper mw)
{
if(typeBuilderGhostInterface != null)
if(typeBuilderGhostInterface != null && mw.IsVirtual)
{
return mw.GetDefineMethodHelper().DefineMethod(this, typeBuilderGhostInterface, name, attribs);
DefineMethodHelper helper = mw.GetDefineMethodHelper();
MethodBuilder stub = helper.DefineMethod(this, typeBuilder, name, MethodAttributes.Public);
((GhostMethodWrapper)mw).SetGhostMethod(stub);
return helper.DefineMethod(this, typeBuilderGhostInterface, name, attribs);
}
return null;
}
@ -820,11 +791,12 @@ namespace IKVM.Internal
// TODO consider adding methods from base interface and java.lang.Object as well
for(int i = 0; i < methods.Length; i++)
{
// skip <clinit>
if(!methods[i].IsStatic)
// skip <clinit> and non-virtual interface methods introduced in Java 8
GhostMethodWrapper gmw = methods[i] as GhostMethodWrapper;
if(gmw != null)
{
TypeWrapper[] args = methods[i].GetParameters();
MethodBuilder stub = methods[i].GetDefineMethodHelper().DefineMethod(this, typeBuilder, methods[i].Name, MethodAttributes.Public);
MethodBuilder stub = gmw.GetGhostMethod();
AddParameterMetadata(stub, methods[i]);
AttributeHelper.SetModifiers(stub, methods[i].Modifiers, methods[i].IsInternal);
CodeEmitter ilgen = CodeEmitter.Create(stub);
@ -850,13 +822,32 @@ namespace IKVM.Internal
ilgen.Emit(OpCodes.Isinst, implementers[j].TypeAsTBD);
label = ilgen.DefineLabel();
ilgen.EmitBrfalse(label);
ilgen.Emit(OpCodes.Castclass, implementers[j].TypeAsTBD);
for(int k = 0; k < args.Length; k++)
{
ilgen.EmitLdarg(k + 1);
}
MethodWrapper mw = implementers[j].GetMethodWrapper(methods[i].Name, methods[i].Signature, true);
mw.EmitCallvirt(ilgen);
if(mw == null)
{
if(methods[i].IsAbstract)
{
// This should only happen for remapped types (defined in map.xml), because normally you'd get a miranda method.
throw new FatalCompilerErrorException(Message.GhostInterfaceMethodMissing, implementers[j].Name, Name, methods[i].Name, methods[i].Signature);
}
// We're inheriting a default method
ilgen.Emit(OpCodes.Pop);
ilgen.Emit(OpCodes.Ldarg_0);
for (int k = 0; k < args.Length; k++)
{
ilgen.EmitLdarg(k + 1);
}
ilgen.Emit(OpCodes.Call, DefaultInterfaceMethodWrapper.GetImpl(methods[i]));
}
else
{
ilgen.Emit(OpCodes.Castclass, implementers[j].TypeAsTBD);
for (int k = 0; k < args.Length; k++)
{
ilgen.EmitLdarg(k + 1);
}
mw.EmitCallvirt(ilgen);
}
ilgen.EmitBr(end);
ilgen.MarkLabel(label);
}

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2002-2013 Jeroen Frijters
Copyright (C) 2002-2014 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -156,6 +156,13 @@ sealed class FatalCompilerErrorException : Exception
return "The type '{0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{1}'";
case IKVM.Internal.Message.FileNotFound:
return "File not found: {0}";
case IKVM.Internal.Message.RuntimeMethodMissing:
return "Runtime method '{0}' not found";
case IKVM.Internal.Message.MapFileFieldNotFound:
return "Field '{0}' referenced in remap file was not found in class '{1}'";
case IKVM.Internal.Message.GhostInterfaceMethodMissing:
return "Remapped class '{0}' does not implement ghost interface method\n" +
"\t({1}.{2}{3})";
default:
return "Missing Error Message. Please file a bug.";
}
@ -167,7 +174,6 @@ sealed class IkvmcCompiler
private bool nonleaf;
private string manifestMainClass;
private string defaultAssemblyName;
private List<string> classesToExclude = new List<string>();
private static bool time;
private static string runtimeAssembly;
private static bool nostdlib;
@ -515,6 +521,8 @@ sealed class IkvmcCompiler
Console.Error.WriteLine("-lib:<dir> Additional directories to search for references");
Console.Error.WriteLine("-highentropyva Enable high entropy ASLR");
Console.Error.WriteLine("-static Disable dynamic binding");
Console.Error.WriteLine("-assemblyattributes:<file> Read assembly custom attributes from specified");
Console.Error.WriteLine(" class file.");
}
void ParseCommandLine(IEnumerator<string> arglist, List<CompilerOptions> targets, CompilerOptions options)
@ -543,7 +551,6 @@ sealed class IkvmcCompiler
IkvmcCompiler nestedLevel = new IkvmcCompiler();
nestedLevel.manifestMainClass = manifestMainClass;
nestedLevel.defaultAssemblyName = defaultAssemblyName;
nestedLevel.classesToExclude = new List<string>(classesToExclude);
nestedLevel.ContinueParseCommandLine(arglist, targets, options.Copy());
}
else if(s == "}")
@ -775,7 +782,7 @@ sealed class IkvmcCompiler
}
else if(s.StartsWith("-exclude:"))
{
ProcessExclusionFile(classesToExclude, s.Substring(9));
ProcessExclusionFile(ref options.classesToExclude, s.Substring(9));
}
else if(s.StartsWith("-version:"))
{
@ -977,12 +984,25 @@ sealed class IkvmcCompiler
}
else if(s == "-static")
{
options.codegenoptions |= CodeGenOptions.DisableDynamicBinding;
// we abuse -static to also enable support for NoRefEmit scenarios
options.codegenoptions |= CodeGenOptions.DisableDynamicBinding | CodeGenOptions.NoRefEmitHelpers;
}
else if(s == "-nojarstubs") // undocumented temporary option to mitigate risk
{
options.nojarstubs = true;
}
else if(s.StartsWith("-assemblyattributes:", StringComparison.Ordinal))
{
ProcessAttributeAnnotationsClass(ref options.assemblyAttributeAnnotations, s.Substring(20));
}
else if(s == "-w4") // undocumented option to always warn if a class isn't found
{
options.warningLevelHigh = true;
}
else if(s == "-noparameterreflection") // undocumented option to compile core class libraries with, to disable MethodParameter attribute
{
options.noParameterReflection = true;
}
else
{
throw new FatalCompilerErrorException(Message.UnrecognizedOption, s);
@ -1032,7 +1052,6 @@ sealed class IkvmcCompiler
StaticCompiler.IssueMessage(options, Message.MainMethodFromManifest, manifestMainClass);
options.mainClass = manifestMainClass;
}
options.classesToExclude = classesToExclude.ToArray();
targets.Add(options);
}
@ -1180,7 +1199,7 @@ sealed class IkvmcCompiler
{
foreach (CompilerOptions peer in targets)
{
if (peer.assembly.Equals(reference, StringComparison.InvariantCultureIgnoreCase))
if (peer.assembly.Equals(reference, StringComparison.OrdinalIgnoreCase))
{
ArrayAppend(ref target.peerReferences, peer.assembly);
goto next_reference;
@ -1238,10 +1257,22 @@ sealed class IkvmcCompiler
}
else
{
T[] temp = new T[array.Length + 1];
Array.Copy(array, 0, temp, 0, array.Length);
temp[temp.Length - 1] = element;
array = temp;
array = ArrayUtil.Concat(array, element);
}
}
private static void ArrayAppend<T>(ref T[] array, T[] append)
{
if (array == null)
{
array = append;
}
else if (append != null)
{
T[] tmp = new T[array.Length + append.Length];
Array.Copy(array, tmp, array.Length);
Array.Copy(append, 0, tmp, array.Length, append.Length);
array = tmp;
}
}
@ -1262,7 +1293,7 @@ sealed class IkvmcCompiler
ClassFile cf;
try
{
cf = new ClassFile(buf, 0, buf.Length, "<unknown>", ClassFileParseOptions.None);
cf = new ClassFile(buf, 0, buf.Length, "<unknown>", ClassFileParseOptions.None, null);
}
catch (ClassFormatError)
{
@ -1290,7 +1321,7 @@ sealed class IkvmcCompiler
return true;
}
private static bool IsStubLegacy(CompilerOptions options, ZipEntry ze, byte[] data)
private static bool IsExcludedOrStubLegacy(CompilerOptions options, ZipEntry ze, byte[] data)
{
if (ze.Name.EndsWith(".class", StringComparison.OrdinalIgnoreCase))
{
@ -1298,7 +1329,7 @@ sealed class IkvmcCompiler
{
bool stub;
string name = ClassFile.GetClassName(data, 0, data.Length, out stub);
if (stub && EmitStubWarning(options, data))
if (options.IsExcludedClass(name) || (stub && EmitStubWarning(options, data)))
{
// we use stubs to add references, but otherwise ignore them
return true;
@ -1356,7 +1387,7 @@ sealed class IkvmcCompiler
{
found = true;
byte[] data = ReadFromZip(zf, ze);
if (IsStubLegacy(options, ze, data))
if (IsExcludedOrStubLegacy(options, ze, data))
{
continue;
}
@ -1405,6 +1436,10 @@ sealed class IkvmcCompiler
{
bool stub;
string name = ClassFile.GetClassName(data, 0, data.Length, out stub);
if (options.IsExcludedClass(name))
{
return;
}
if (stub && EmitStubWarning(options, data))
{
// we use stubs to add references, but otherwise ignore them
@ -1474,10 +1509,11 @@ sealed class IkvmcCompiler
}
//This processes an exclusion file with a single regular expression per line
private static void ProcessExclusionFile(List<string> classesToExclude, String filename)
private static void ProcessExclusionFile(ref string[] classesToExclude, string filename)
{
try
{
List<string> list = classesToExclude == null ? new List<string>() : new List<string>(classesToExclude);
using(StreamReader file = new StreamReader(filename))
{
String line;
@ -1486,14 +1522,29 @@ sealed class IkvmcCompiler
line = line.Trim();
if(!line.StartsWith("//") && line.Length != 0)
{
classesToExclude.Add(line);
list.Add(line);
}
}
}
classesToExclude = list.ToArray();
}
catch(Exception x)
{
throw new FatalCompilerErrorException(Message.ErrorReadingFile, filename, x.Message);
}
}
private static void ProcessAttributeAnnotationsClass(ref object[] annotations, string filename)
{
try
{
byte[] buf = File.ReadAllBytes(filename);
ClassFile cf = new ClassFile(buf, 0, buf.Length, null, ClassFileParseOptions.None, null);
ArrayAppend(ref annotations, cf.Annotations);
}
catch (Exception x)
{
throw new FatalCompilerErrorException(Message.ErrorReadingFile, filename, x.Message);
}
}
}

View File

@ -1 +1 @@
e7247c17ca6a6a7139699d9fdb9ddf15796f40b4
b71e0f94bba2f37126b0c66cbd774ef9d76cd588

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2011 Jeroen Frijters
Copyright (C) 2011-2014 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -23,6 +23,7 @@
*/
using System;
using System.Collections.Generic;
using IKVM.Attributes;
using IKVM.Reflection;
using IKVM.Reflection.Emit;
using Type = IKVM.Reflection.Type;
@ -143,6 +144,7 @@ namespace IKVM.Internal
// Check for duplicates
if (!MethodExists(methods, mw))
{
mw.Link();
methods.Add(mw);
}
}
@ -220,9 +222,20 @@ namespace IKVM.Internal
private static void CreateNoFail(CompilerClassLoader loader, TypeWrapper[] interfaces, List<ProxyMethod> methods)
{
bool ispublic = true;
Type[] interfaceTypes = new Type[interfaces.Length];
for (int i = 0; i < interfaceTypes.Length; i++)
{
ispublic &= interfaces[i].IsPublic;
interfaceTypes[i] = interfaces[i].TypeAsBaseType;
}
TypeAttributes attr = TypeAttributes.Class | TypeAttributes.Sealed;
attr |= ispublic ? TypeAttributes.NestedPublic : TypeAttributes.NestedAssembly;
DynamicClassLoader factory = (DynamicClassLoader)loader.GetTypeWrapperFactory();
TypeBuilder tb = factory.DefineProxy(proxyClass, interfaces);
TypeBuilder tb = factory.DefineProxy(TypeNameUtil.GetProxyNestedName(interfaces), attr, proxyClass.TypeAsBaseType, interfaceTypes);
AttributeHelper.SetImplementsAttribute(tb, interfaces);
// we apply an InnerClass attribute to avoid the CompiledTypeWrapper heuristics for figuring out the modifiers
AttributeHelper.SetInnerClass(tb, null, ispublic ? Modifiers.Public | Modifiers.Final : Modifiers.Final);
CreateConstructor(tb);
for (int i = 0; i < methods.Count; i++)
{
@ -232,7 +245,7 @@ namespace IKVM.Internal
{
CreateMethod(loader, tb, method);
}
CreateStaticInitializer(tb, methods);
CreateStaticInitializer(tb, methods, loader);
}
private static void CreateConstructor(TypeBuilder tb)
@ -297,7 +310,7 @@ namespace IKVM.Internal
}
else if (returnType.IsPrimitive)
{
Boxer.EmitUnbox(ilgen, returnType);
Boxer.EmitUnbox(ilgen, returnType, true);
}
else if (returnType != CoreClasses.java.lang.Object.Wrapper)
{
@ -341,9 +354,9 @@ namespace IKVM.Internal
ilgen.DoEmit();
}
private static void CreateStaticInitializer(TypeBuilder tb, List<ProxyMethod> methods)
private static void CreateStaticInitializer(TypeBuilder tb, List<ProxyMethod> methods, CompilerClassLoader loader)
{
CodeEmitter ilgen = CodeEmitter.Create(ReflectUtil.DefineTypeInitializer(tb));
CodeEmitter ilgen = CodeEmitter.Create(ReflectUtil.DefineTypeInitializer(tb, loader));
CodeEmitterLocal callerID = ilgen.DeclareLocal(CoreClasses.ikvm.@internal.CallerID.Wrapper.TypeAsSignatureType);
TypeBuilder tbCallerID = DynamicTypeWrapper.FinishContext.EmitCreateCallerID(tb, ilgen);
ilgen.Emit(OpCodes.Stloc, callerID);
@ -401,7 +414,10 @@ namespace IKVM.Internal
Dictionary<string, MethodWrapper> methods = new Dictionary<string, MethodWrapper>();
foreach (MethodWrapper mw in tw.GetMethods())
{
methods.Add(mw.Name + mw.Signature, mw);
if (mw.IsVirtual)
{
methods.Add(mw.Name + mw.Signature, mw);
}
}
foreach (TypeWrapper iface in tw.Interfaces)
{
@ -438,165 +454,4 @@ namespace IKVM.Internal
}
}
}
static class Boxer
{
private static readonly TypeWrapper javaLangByte;
private static readonly MethodWrapper byteValue;
private static readonly MethodWrapper valueOfByte;
private static readonly TypeWrapper javaLangBoolean;
private static readonly MethodWrapper booleanValue;
private static readonly MethodWrapper valueOfBoolean;
private static readonly TypeWrapper javaLangShort;
private static readonly MethodWrapper shortValue;
private static readonly MethodWrapper valueOfShort;
private static readonly TypeWrapper javaLangCharacter;
private static readonly MethodWrapper charValue;
private static readonly MethodWrapper valueOfCharacter;
private static readonly TypeWrapper javaLangInteger;
private static readonly MethodWrapper intValue;
private static readonly MethodWrapper valueOfInteger;
private static readonly TypeWrapper javaLangFloat;
private static readonly MethodWrapper floatValue;
private static readonly MethodWrapper valueOfFloat;
private static readonly TypeWrapper javaLangLong;
private static readonly MethodWrapper longValue;
private static readonly MethodWrapper valueOfLong;
private static readonly TypeWrapper javaLangDouble;
private static readonly MethodWrapper doubleValue;
private static readonly MethodWrapper valueOfDouble;
static Boxer()
{
ClassLoaderWrapper bootClassLoader = ClassLoaderWrapper.GetBootstrapClassLoader();
javaLangByte = bootClassLoader.LoadClassByDottedNameFast("java.lang.Byte");
byteValue = javaLangByte.GetMethodWrapper("byteValue", "()B", false);
byteValue.Link();
valueOfByte = javaLangByte.GetMethodWrapper("valueOf", "(B)Ljava.lang.Byte;", false);
valueOfByte.Link();
javaLangBoolean = bootClassLoader.LoadClassByDottedNameFast("java.lang.Boolean");
booleanValue = javaLangBoolean.GetMethodWrapper("booleanValue", "()Z", false);
booleanValue.Link();
valueOfBoolean = javaLangBoolean.GetMethodWrapper("valueOf", "(Z)Ljava.lang.Boolean;", false);
valueOfBoolean.Link();
javaLangShort = bootClassLoader.LoadClassByDottedNameFast("java.lang.Short");
shortValue = javaLangShort.GetMethodWrapper("shortValue", "()S", false);
shortValue.Link();
valueOfShort = javaLangShort.GetMethodWrapper("valueOf", "(S)Ljava.lang.Short;", false);
valueOfShort.Link();
javaLangCharacter = bootClassLoader.LoadClassByDottedNameFast("java.lang.Character");
charValue = javaLangCharacter.GetMethodWrapper("charValue", "()C", false);
charValue.Link();
valueOfCharacter = javaLangCharacter.GetMethodWrapper("valueOf", "(C)Ljava.lang.Character;", false);
valueOfCharacter.Link();
javaLangInteger = bootClassLoader.LoadClassByDottedNameFast("java.lang.Integer");
intValue = javaLangInteger.GetMethodWrapper("intValue", "()I", false);
intValue.Link();
valueOfInteger = javaLangInteger.GetMethodWrapper("valueOf", "(I)Ljava.lang.Integer;", false);
valueOfInteger.Link();
javaLangFloat = bootClassLoader.LoadClassByDottedNameFast("java.lang.Float");
floatValue = javaLangFloat.GetMethodWrapper("floatValue", "()F", false);
floatValue.Link();
valueOfFloat = javaLangFloat.GetMethodWrapper("valueOf", "(F)Ljava.lang.Float;", false);
valueOfFloat.Link();
javaLangLong = bootClassLoader.LoadClassByDottedNameFast("java.lang.Long");
longValue = javaLangLong.GetMethodWrapper("longValue", "()J", false);
longValue.Link();
valueOfLong = javaLangLong.GetMethodWrapper("valueOf", "(J)Ljava.lang.Long;", false);
valueOfLong.Link();
javaLangDouble = bootClassLoader.LoadClassByDottedNameFast("java.lang.Double");
doubleValue = javaLangDouble.GetMethodWrapper("doubleValue", "()D", false);
doubleValue.Link();
valueOfDouble = javaLangDouble.GetMethodWrapper("valueOf", "(D)Ljava.lang.Double;", false);
valueOfDouble.Link();
}
internal static void EmitUnbox(CodeEmitter ilgen, TypeWrapper tw)
{
if (tw == PrimitiveTypeWrapper.BYTE)
{
javaLangByte.EmitCheckcast(ilgen);
byteValue.EmitCall(ilgen);
}
else if (tw == PrimitiveTypeWrapper.BOOLEAN)
{
javaLangBoolean.EmitCheckcast(ilgen);
booleanValue.EmitCall(ilgen);
}
else if (tw == PrimitiveTypeWrapper.SHORT)
{
javaLangShort.EmitCheckcast(ilgen);
shortValue.EmitCall(ilgen);
}
else if (tw == PrimitiveTypeWrapper.CHAR)
{
javaLangCharacter.EmitCheckcast(ilgen);
charValue.EmitCall(ilgen);
}
else if (tw == PrimitiveTypeWrapper.INT)
{
javaLangInteger.EmitCheckcast(ilgen);
intValue.EmitCall(ilgen);
}
else if (tw == PrimitiveTypeWrapper.FLOAT)
{
javaLangFloat.EmitCheckcast(ilgen);
floatValue.EmitCall(ilgen);
}
else if (tw == PrimitiveTypeWrapper.LONG)
{
javaLangLong.EmitCheckcast(ilgen);
longValue.EmitCall(ilgen);
}
else if (tw == PrimitiveTypeWrapper.DOUBLE)
{
javaLangDouble.EmitCheckcast(ilgen);
doubleValue.EmitCall(ilgen);
}
else
{
throw new InvalidOperationException();
}
}
internal static void EmitBox(CodeEmitter ilgen, TypeWrapper tw)
{
if (tw == PrimitiveTypeWrapper.BYTE)
{
valueOfByte.EmitCall(ilgen);
}
else if (tw == PrimitiveTypeWrapper.BOOLEAN)
{
valueOfBoolean.EmitCall(ilgen);
}
else if (tw == PrimitiveTypeWrapper.SHORT)
{
valueOfShort.EmitCall(ilgen);
}
else if (tw == PrimitiveTypeWrapper.CHAR)
{
valueOfCharacter.EmitCall(ilgen);
}
else if (tw == PrimitiveTypeWrapper.INT)
{
valueOfInteger.EmitCall(ilgen);
}
else if (tw == PrimitiveTypeWrapper.FLOAT)
{
valueOfFloat.EmitCall(ilgen);
}
else if (tw == PrimitiveTypeWrapper.LONG)
{
valueOfLong.EmitCall(ilgen);
}
else if (tw == PrimitiveTypeWrapper.DOUBLE)
{
valueOfDouble.EmitCall(ilgen);
}
else
{
throw new InvalidOperationException();
}
}
}
}

View File

@ -1,9 +1,32 @@
<?xml version="1.0"?>
<!--
Copyright (C) 2002-2013 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jeroen Frijters
jeroen@frijters.net
-->
<project name="ikvmc" default="ikvmc">
<include buildfile="../ikvm.include" />
<target name="ikvmc">
<property name="defs" value="TRACE;STATIC_COMPILER" />
<property name="defs" value="TRACE;STATIC_COMPILER;EMITTERS" />
<if test="${property::exists('signed')}">
<property name="defs" value="${defs};${signed}" />
</if>
@ -25,6 +48,7 @@
<include name="../runtime/atomic.cs" />
<include name="../runtime/attributes.cs" />
<include name="../runtime/BigEndianBinaryReader.cs" />
<include name="../runtime/Boxer.cs" />
<include name="../runtime/ByteCode.cs" />
<include name="../runtime/ClassFile.cs" />
<include name="../runtime/ClassLoaderWrapper.cs" />
@ -37,8 +61,10 @@
<include name="../runtime/intrinsics.cs" />
<include name="../runtime/JavaException.cs" />
<include name="../runtime/JsrInliner.cs" />
<include name="../runtime/LambdaMetafactory.cs" />
<include name="../runtime/LocalVars.cs" />
<include name="../runtime/MemberWrapper.cs" />
<include name="../runtime/MethodHandleUtil.cs" />
<include name="../runtime/profiler.cs" />
<include name="../runtime/ReflectUtil.cs" />
<include name="../runtime/RuntimeHelperTypes.cs" />

View File

@ -30,18 +30,7 @@ jdk/src/share/classes/java/io/RandomAccessFile.java=java/io/RandomAccessFile.jav
jdk/src/share/classes/java/lang/Class.java=java/lang/Class.java
jdk/src/share/classes/java/lang/ClassLoader.java=java/lang/ClassLoader.java
jdk/src/share/classes/java/lang/Enum.java=java/lang/Enum.java
jdk/src/share/classes/java/lang/invoke/AdapterMethodHandle.java=java/lang/invoke/AdapterMethodHandle.java
jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java=java/lang/invoke/BoundMethodHandle.java
jdk/src/share/classes/java/lang/invoke/CallSite.java=java/lang/invoke/CallSite.java
jdk/src/share/classes/java/lang/invoke/ConstantCallSite.java=java/lang/invoke/ConstantCallSite.java
jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java=java/lang/invoke/DirectMethodHandle.java
jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java=java/lang/invoke/MethodHandleImpl.java
jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java=java/lang/invoke/MethodHandleNatives.java
jdk/src/share/classes/java/lang/invoke/MethodHandles.java=java/lang/invoke/MethodHandles.java
jdk/src/share/classes/java/lang/invoke/MutableCallSite.java=java/lang/invoke/MutableCallSite.java
jdk/src/share/classes/java/lang/invoke/VolatileCallSite.java=java/lang/invoke/VolatileCallSite.java
jdk/src/share/classes/java/lang/management/PlatformComponent.java=java/lang/management/PlatformComponent.java
jdk/src/share/classes/java/lang/Package.java=java/lang/Package.java
jdk/src/share/classes/java/lang/ref/SoftReference.java=java/lang/ref/SoftReference.java
jdk/src/share/classes/java/lang/reflect/Constructor.java=java/lang/reflect/Constructor.java
jdk/src/share/classes/java/lang/reflect/Field.java=java/lang/reflect/Field.java
@ -57,7 +46,6 @@ jdk/src/share/classes/java/net/SocketOutputStream.java=java/net/SocketOutputStre
jdk/src/share/classes/java/nio/Bits.java=java/nio/Bits.java
jdk/src/share/classes/java/security/AccessController.java=java/security/AccessController.java
jdk/src/share/classes/java/security/ProtectionDomain.java=java/security/ProtectionDomain.java
jdk/src/share/classes/java/sql/DriverManager.java=java/sql/DriverManager.java
jdk/src/share/classes/java/util/concurrent/atomic/AtomicBoolean.java=../classpath/java/util/concurrent/atomic/AtomicBoolean.java
jdk/src/share/classes/java/util/concurrent/atomic/AtomicInteger.java=../classpath/java/util/concurrent/atomic/AtomicInteger.java
jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java=../classpath/java/util/concurrent/atomic/AtomicIntegerArray.java
@ -67,9 +55,6 @@ jdk/src/share/classes/java/util/concurrent/atomic/AtomicReference.java=../classp
jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java=../classpath/java/util/concurrent/atomic/AtomicReferenceArray.java
jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java=java/util/concurrent/locks/AbstractQueuedSynchronizer.java
jdk/src/share/classes/java/util/concurrent/locks/LockSupport.java=java/util/concurrent/locks/LockSupport.java
jdk/src/share/classes/java/util/ResourceBundle.java=java/util/ResourceBundle.java
jdk/src/share/classes/java/util/TimeZone.java=java/util/TimeZone.java
jdk/src/share/classes/sun/awt/AppContext.java=sun/awt/AppContext.java
jdk/src/share/classes/sun/awt/EmbeddedFrame.java=sun/awt/EmbeddedFrame.java
jdk/src/share/classes/sun/awt/image/ByteInterleavedRaster.java=sun/awt/image/ByteInterleavedRaster.java
jdk/src/share/classes/sun/awt/image/ImagingLib.java=sun/awt/image/ImagingLib.java
@ -79,11 +64,8 @@ jdk/src/share/classes/sun/awt/image/ToolkitImage.java=sun/awt/image/ToolkitImage
jdk/src/share/classes/sun/awt/SunToolkit.java=sun/awt/SunToolkit.java
jdk/src/share/classes/sun/font/FontManager.java=sun/font/FontManager.java
jdk/src/share/classes/sun/font/StrikeCache.java=sun/font/StrikeCache.java
jdk/src/share/classes/sun/management/GcInfoBuilder.java=sun/management/GcInfoBuilder.java
jdk/src/share/classes/sun/management/ManagementFactoryHelper.java=sun/management/ManagementFactoryHelper.java
jdk/src/share/classes/sun/management/VMManagementImpl.java=sun/management/VMManagementImpl.java
jdk/src/share/classes/sun/misc/IoTrace.java=sun/misc/IoTrace.java
jdk/src/share/classes/sun/misc/JavaAWTAccess.java=sun/misc/JavaAWTAccess.java
jdk/src/share/classes/sun/misc/SharedSecrets.java=sun/misc/SharedSecrets.java
jdk/src/share/classes/sun/misc/VM.java=sun/misc/VM.java
jdk/src/share/classes/sun/net/sdp/SdpSupport.java=sun/net/sdp/SdpSupport.java
@ -94,9 +76,8 @@ jdk/src/share/classes/sun/nio/ch/IOUtil.java=sun/nio/ch/IOUtil.java
jdk/src/share/classes/sun/nio/ch/NativeDispatcher.java=sun/nio/ch/NativeDispatcher.java
jdk/src/share/classes/sun/nio/ch/Net.java=sun/nio/ch/Net.java
jdk/src/share/classes/sun/nio/ch/Util.java=sun/nio/ch/Util.java
jdk/src/share/classes/sun/reflect/CallerSensitive.java=sun/reflect/CallerSensitive.java
jdk/src/share/classes/sun/reflect/annotation/AnnotationType.java=sun/reflect/annotation/AnnotationType.java
jdk/src/share/classes/sun/reflect/MethodAccessor.java=sun/reflect/MethodAccessor.java
jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java=sun/reflect/misc/ReflectUtil.java
jdk/src/share/classes/sun/reflect/Reflection.java=sun/reflect/Reflection.java
jdk/src/share/classes/sun/reflect/ReflectionFactory.java=sun/reflect/ReflectionFactory.java
jdk/src/solaris/classes/sun/nio/fs/UnixUriUtils.java=sun/nio/fs/UnixUriUtils.java

View File

@ -1 +1 @@
533d7645e2bb496cbbac8996759c133993dcc1bb
4911d54d998b7a044246f97683fb62901e9dc052

View File

@ -236,12 +236,14 @@ public abstract class AnnotationAttributeBase
{
// TODO consider checking that the type matches
// (or better yet (?), remove the first two redundant elements from the array)
decodeValues(values, annotationType, annotationType.getClassLoader(), definition);
decodeValues(values, annotationType, annotationType.getClassLoader(), unescapeInvalidSurrogates(definition));
definition = null;
}
}
}
private static native Object[] unescapeInvalidSurrogates(Object[] definition);
private static void decodeValues(HashMap map, Class annotationClass, ClassLoader loader, Object[] array)
{
for (int i = 2; i < array.length; i += 2)

View File

@ -1 +1 @@
bbc1d241f632078e8ecf146e9398406c5719dd2f
07fd7bd567e5b0ae8b3ae9c32741b56f6f363b0a

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2007-2011 Jeroen Frijters
Copyright (C) 2007-2014 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -24,80 +24,40 @@
package java.lang;
import ikvm.runtime.AssemblyClassLoader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AccessController;
import java.util.Enumeration;
import java.lang.annotation.Annotation;
import java.lang.reflect.Executable;
import java.security.AccessControlContext;
import java.util.Map;
import sun.nio.ch.Interruptible;
import sun.reflect.annotation.AnnotationType;
import sun.security.action.GetPropertyAction;
@ikvm.lang.Internal
public class LangHelper
{
private static boolean addedSystemPackages;
private static void addSystemPackage(Map pkgMap)
{
// NOTE caller must have acquired lock on pkgMap
if (!addedSystemPackages)
{
addedSystemPackages = true;
String[] pkgs = getBootClassPackages();
for (int i = 0; i < pkgs.length; i++)
{
pkgMap.put(pkgs[i],
new Package(pkgs[i],
VMSystemProperties.SPEC_TITLE, // specTitle
VMSystemProperties.SPEC_VERSION, // specVersion
VMSystemProperties.SPEC_VENDOR, // specVendor
"IKVM.NET OpenJDK", // implTitle
PropertyConstants.openjdk_version, // implVersion
"Oracle Corporation & others", // implVendor
null, // sealBase
null)); // class loader
}
}
}
private static native String[] getBootClassPackages();
/* this method gets called by Package.getSystemPackage() via a redefined method in map.xml */
static Package getSystemPackage(Map pkgs, String name)
{
synchronized (pkgs)
{
addSystemPackage(pkgs);
return (Package)pkgs.get(name);
}
}
/* this method gets called by Package.getSystemPackages() via a redefined method in map.xml */
static Package[] getSystemPackages(Map pkgs)
{
synchronized (pkgs)
{
addSystemPackage(pkgs);
return (Package[])pkgs.values().toArray(new Package[pkgs.size()]);
}
}
public static sun.misc.JavaLangAccess getJavaLangAccess()
{
return new sun.misc.JavaLangAccess() {
public sun.reflect.ConstantPool getConstantPool(Class klass) {
return null;
return klass.getConstantPool();
}
public void setAnnotationType(Class klass, AnnotationType type) {
klass.setAnnotationType(type);
public boolean casAnnotationType(Class<?> klass, AnnotationType oldType, AnnotationType newType) {
return klass.casAnnotationType(oldType, newType);
}
public AnnotationType getAnnotationType(Class klass) {
return klass.getAnnotationType();
}
public Map<Class<? extends Annotation>, Annotation> getDeclaredAnnotationMap(Class<?> klass) {
return klass.getDeclaredAnnotationMap();
}
public byte[] getRawClassAnnotations(Class<?> klass) {
throw new InternalError();
}
public byte[] getRawClassTypeAnnotations(Class<?> klass) {
return klass.getRawTypeAnnotations();
}
public byte[] getRawExecutableTypeAnnotations(Executable executable) {
return Class.getExecutableTypeAnnotationBytes(executable);
}
public <E extends Enum<E>>
E[] getEnumConstantsShared(Class<E> klass) {
return klass.getEnumConstantsShared();
@ -114,8 +74,14 @@ public class LangHelper
public StackTraceElement getStackTraceElement(Throwable t, int i) {
return t.getStackTraceElement(i);
}
public int getStringHash32(String string) {
return StringHelper.hash32(string);
public String newStringUnsafe(char[] chars) {
return String.valueOf(chars);
}
public Thread newThreadWithAcc(Runnable target, AccessControlContext acc) {
return new Thread(target, acc);
}
public void invokeFinalize(Object o) throws Throwable {
// we don't actually support invoking the finalize method explicitly
}
};
}

Some files were not shown because too many files have changed in this diff Show More