зеркало из https://github.com/mono/ikvm-fork.git
*** empty log message ***
This commit is contained in:
Родитель
4f63f7e13d
Коммит
1b65938abf
|
@ -72,7 +72,7 @@ namespace ikvm.awt
|
|||
// HACK I have no idea why this line is necessary...
|
||||
IntPtr p = form.Handle;
|
||||
bogusForm = form;
|
||||
// HACK to make sure we can be aborted (Thread.Abort) we need to periodically
|
||||
// FXBUG to make sure we can be aborted (Thread.Abort) we need to periodically
|
||||
// fire an event (because otherwise we'll be blocking in unmanaged code and
|
||||
// the Abort cannot be handled there).
|
||||
System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();
|
||||
|
@ -333,10 +333,16 @@ namespace ikvm.awt
|
|||
return getImage(url);
|
||||
}
|
||||
|
||||
const int ERROR = java.awt.image.ImageObserver.__Fields.ERROR;
|
||||
const int WIDTH = java.awt.image.ImageObserver.__Fields.WIDTH;
|
||||
const int HEIGHT = java.awt.image.ImageObserver.__Fields.HEIGHT;
|
||||
const int FRAMEBITS = java.awt.image.ImageObserver.__Fields.FRAMEBITS;
|
||||
const int ALLBITS = java.awt.image.ImageObserver.__Fields.ALLBITS;
|
||||
|
||||
public override bool prepareImage(java.awt.Image image, int width, int height, java.awt.image.ImageObserver observer)
|
||||
{
|
||||
// HACK for now we call checkImage to obtain the status and fire the observer
|
||||
return (checkImage(image, width, height, observer) & 32) != 0;
|
||||
return (checkImage(image, width, height, observer) & ALLBITS) != 0;
|
||||
}
|
||||
|
||||
public override int checkImage(java.awt.Image image, int width, int height, java.awt.image.ImageObserver observer)
|
||||
|
@ -345,16 +351,15 @@ namespace ikvm.awt
|
|||
{
|
||||
if(observer != null)
|
||||
{
|
||||
observer.imageUpdate(image, 64, 0, 0, -1, -1);
|
||||
observer.imageUpdate(image, ERROR, 0, 0, -1, -1);
|
||||
}
|
||||
return 64; // ERROR
|
||||
return ERROR;
|
||||
}
|
||||
if(observer != null)
|
||||
{
|
||||
observer.imageUpdate(image, 1 + 2 + 16 + 32, 0, 0, image.getWidth(null), image.getHeight(null));
|
||||
observer.imageUpdate(image, WIDTH + HEIGHT + FRAMEBITS + ALLBITS, 0, 0, image.getWidth(null), image.getHeight(null));
|
||||
}
|
||||
// HACK we cannot use the constants defined in the interface from C#, so we hardcode the flags
|
||||
return 1 + 2 + 16 + 32; // WIDTH + HEIGHT + FRAMEBITS + ALLBITS
|
||||
return WIDTH + HEIGHT + FRAMEBITS + ALLBITS;
|
||||
}
|
||||
|
||||
public override java.awt.Image createImage(java.awt.image.ImageProducer producer)
|
||||
|
|
|
@ -15,7 +15,6 @@ java/lang/VMDouble.java
|
|||
java/lang/VMFloat.java
|
||||
java/lang/VMSystem.java
|
||||
java/lang/ExceptionHelper.java
|
||||
java/lang/ObjectHelper.java
|
||||
java/lang/StringHelper.java
|
||||
java/lang/VMClassLoader.java
|
||||
java/lang/VMRuntime.java
|
||||
|
@ -57,6 +56,43 @@ sun/misc/Ref.java
|
|||
../../classpath/gnu/java/awt/peer/ClasspathTextLayoutPeer.java
|
||||
../../classpath/gnu/java/awt/peer/EmbeddedWindowPeer.java
|
||||
../../classpath/gnu/java/beans/BeanInfoEmbryo.java
|
||||
../../classpath/gnu/java/beans/decoder/AbstractContext.java
|
||||
../../classpath/gnu/java/beans/decoder/AbstractCreatableObjectContext.java
|
||||
../../classpath/gnu/java/beans/decoder/AbstractElementHandler.java
|
||||
../../classpath/gnu/java/beans/decoder/AbstractObjectContext.java
|
||||
../../classpath/gnu/java/beans/decoder/ArrayContext.java
|
||||
../../classpath/gnu/java/beans/decoder/ArrayHandler.java
|
||||
../../classpath/gnu/java/beans/decoder/AssemblyException.java
|
||||
../../classpath/gnu/java/beans/decoder/BooleanHandler.java
|
||||
../../classpath/gnu/java/beans/decoder/ByteHandler.java
|
||||
../../classpath/gnu/java/beans/decoder/CharHandler.java
|
||||
../../classpath/gnu/java/beans/decoder/ClassHandler.java
|
||||
../../classpath/gnu/java/beans/decoder/ConstructorContext.java
|
||||
../../classpath/gnu/java/beans/decoder/Context.java
|
||||
../../classpath/gnu/java/beans/decoder/DecoderContext.java
|
||||
../../classpath/gnu/java/beans/decoder/DefaultExceptionListener.java
|
||||
../../classpath/gnu/java/beans/decoder/DoubleHandler.java
|
||||
../../classpath/gnu/java/beans/decoder/DummyContext.java
|
||||
../../classpath/gnu/java/beans/decoder/DummyHandler.java
|
||||
../../classpath/gnu/java/beans/decoder/ElementHandler.java
|
||||
../../classpath/gnu/java/beans/decoder/FloatHandler.java
|
||||
../../classpath/gnu/java/beans/decoder/GrowableArrayContext.java
|
||||
../../classpath/gnu/java/beans/decoder/IndexContext.java
|
||||
../../classpath/gnu/java/beans/decoder/IntHandler.java
|
||||
../../classpath/gnu/java/beans/decoder/JavaHandler.java
|
||||
../../classpath/gnu/java/beans/decoder/LongHandler.java
|
||||
../../classpath/gnu/java/beans/decoder/MethodContext.java
|
||||
../../classpath/gnu/java/beans/decoder/MethodFinder.java
|
||||
../../classpath/gnu/java/beans/decoder/NullHandler.java
|
||||
../../classpath/gnu/java/beans/decoder/ObjectContext.java
|
||||
../../classpath/gnu/java/beans/decoder/ObjectHandler.java
|
||||
../../classpath/gnu/java/beans/decoder/PersistenceParser.java
|
||||
../../classpath/gnu/java/beans/decoder/PropertyContext.java
|
||||
../../classpath/gnu/java/beans/decoder/ShortHandler.java
|
||||
../../classpath/gnu/java/beans/decoder/SimpleHandler.java
|
||||
../../classpath/gnu/java/beans/decoder/StaticMethodContext.java
|
||||
../../classpath/gnu/java/beans/decoder/StringHandler.java
|
||||
../../classpath/gnu/java/beans/decoder/VoidHandler.java
|
||||
../../classpath/gnu/java/beans/editors/ColorEditor.java
|
||||
../../classpath/gnu/java/beans/editors/FontEditor.java
|
||||
../../classpath/gnu/java/beans/editors/NativeBooleanEditor.java
|
||||
|
@ -964,6 +1000,7 @@ sun/misc/Ref.java
|
|||
../../classpath/java/beans/VetoableChangeListenerProxy.java
|
||||
../../classpath/java/beans/VetoableChangeSupport.java
|
||||
../../classpath/java/beans/Visibility.java
|
||||
../../classpath/java/beans/XMLDecoder.java
|
||||
../../classpath/java/io/BufferedInputStream.java
|
||||
../../classpath/java/io/BufferedOutputStream.java
|
||||
../../classpath/java/io/BufferedReader.java
|
||||
|
@ -1564,6 +1601,7 @@ sun/misc/Ref.java
|
|||
../../classpath/java/util/ListIterator.java
|
||||
../../classpath/java/util/ListResourceBundle.java
|
||||
../../classpath/java/util/Locale.java
|
||||
../../classpath/java/util/LocaleData.java
|
||||
../../classpath/java/util/logging/ConsoleHandler.java
|
||||
../../classpath/java/util/logging/ErrorManager.java
|
||||
../../classpath/java/util/logging/FileHandler.java
|
||||
|
@ -2162,6 +2200,7 @@ sun/misc/Ref.java
|
|||
../../classpath/javax/swing/ImageIcon.java
|
||||
../../classpath/javax/swing/InputMap.java
|
||||
../../classpath/javax/swing/InputVerifier.java
|
||||
../../classpath/javax/swing/InternalFrameFocusTraversalPolicy.java
|
||||
../../classpath/javax/swing/JApplet.java
|
||||
../../classpath/javax/swing/JButton.java
|
||||
../../classpath/javax/swing/JCheckBox.java
|
||||
|
@ -2230,6 +2269,7 @@ sun/misc/Ref.java
|
|||
../../classpath/javax/swing/plaf/basic/BasicComboPopup.java
|
||||
../../classpath/javax/swing/plaf/basic/BasicDesktopIconUI.java
|
||||
../../classpath/javax/swing/plaf/basic/BasicDesktopPaneUI.java
|
||||
../../classpath/javax/swing/plaf/basic/BasicEditorPaneUI.java
|
||||
../../classpath/javax/swing/plaf/basic/BasicFormattedTextFieldUI.java
|
||||
../../classpath/javax/swing/plaf/basic/BasicGraphicsUtils.java
|
||||
../../classpath/javax/swing/plaf/basic/BasicIconFactory.java
|
||||
|
@ -2290,7 +2330,9 @@ sun/misc/Ref.java
|
|||
../../classpath/javax/swing/plaf/ListUI.java
|
||||
../../classpath/javax/swing/plaf/MenuBarUI.java
|
||||
../../classpath/javax/swing/plaf/MenuItemUI.java
|
||||
../../classpath/javax/swing/plaf/metal/DefaultMetalTheme.java
|
||||
../../classpath/javax/swing/plaf/metal/MetalLookAndFeel.java
|
||||
../../classpath/javax/swing/plaf/metal/MetalTheme.java
|
||||
../../classpath/javax/swing/plaf/OptionPaneUI.java
|
||||
../../classpath/javax/swing/plaf/PanelUI.java
|
||||
../../classpath/javax/swing/plaf/PopupMenuUI.java
|
||||
|
@ -2449,3 +2491,411 @@ sun/misc/Ref.java
|
|||
../../classpath/vm/reference/java/lang/VMSecurityManager.java
|
||||
../../classpath/vm/reference/java/lang/VMString.java
|
||||
../../classpath/vm/reference/java/lang/VMThrowable.java
|
||||
../../classpath/external/sax/org/xml/sax/AttributeList.java
|
||||
../../classpath/external/sax/org/xml/sax/Attributes.java
|
||||
../../classpath/external/sax/org/xml/sax/ContentHandler.java
|
||||
../../classpath/external/sax/org/xml/sax/DocumentHandler.java
|
||||
../../classpath/external/sax/org/xml/sax/DTDHandler.java
|
||||
../../classpath/external/sax/org/xml/sax/EntityResolver.java
|
||||
../../classpath/external/sax/org/xml/sax/ErrorHandler.java
|
||||
../../classpath/external/sax/org/xml/sax/HandlerBase.java
|
||||
../../classpath/external/sax/org/xml/sax/InputSource.java
|
||||
../../classpath/external/sax/org/xml/sax/Locator.java
|
||||
../../classpath/external/sax/org/xml/sax/Parser.java
|
||||
../../classpath/external/sax/org/xml/sax/SAXException.java
|
||||
../../classpath/external/sax/org/xml/sax/SAXNotRecognizedException.java
|
||||
../../classpath/external/sax/org/xml/sax/SAXNotSupportedException.java
|
||||
../../classpath/external/sax/org/xml/sax/SAXParseException.java
|
||||
../../classpath/external/sax/org/xml/sax/XMLFilter.java
|
||||
../../classpath/external/sax/org/xml/sax/XMLReader.java
|
||||
../../classpath/external/sax/org/xml/sax/ext/Attributes2.java
|
||||
../../classpath/external/sax/org/xml/sax/ext/Attributes2Impl.java
|
||||
../../classpath/external/sax/org/xml/sax/ext/DeclHandler.java
|
||||
../../classpath/external/sax/org/xml/sax/ext/DefaultHandler2.java
|
||||
../../classpath/external/sax/org/xml/sax/ext/EntityResolver2.java
|
||||
../../classpath/external/sax/org/xml/sax/ext/LexicalHandler.java
|
||||
../../classpath/external/sax/org/xml/sax/ext/Locator2.java
|
||||
../../classpath/external/sax/org/xml/sax/ext/Locator2Impl.java
|
||||
../../classpath/external/sax/org/xml/sax/helpers/AttributeListImpl.java
|
||||
../../classpath/external/sax/org/xml/sax/helpers/AttributesImpl.java
|
||||
../../classpath/external/sax/org/xml/sax/helpers/DefaultHandler.java
|
||||
../../classpath/external/sax/org/xml/sax/helpers/LocatorImpl.java
|
||||
../../classpath/external/sax/org/xml/sax/helpers/NamespaceSupport.java
|
||||
../../classpath/external/sax/org/xml/sax/helpers/NewInstance.java
|
||||
../../classpath/external/sax/org/xml/sax/helpers/ParserAdapter.java
|
||||
../../classpath/external/sax/org/xml/sax/helpers/ParserFactory.java
|
||||
../../classpath/external/sax/org/xml/sax/helpers/XMLFilterImpl.java
|
||||
../../classpath/external/sax/org/xml/sax/helpers/XMLReaderAdapter.java
|
||||
../../classpath/external/sax/org/xml/sax/helpers/XMLReaderFactory.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/Attr.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/CDATASection.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/CharacterData.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/Comment.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/Document.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/DocumentFragment.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/DocumentType.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/DOMConfiguration.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/DOMError.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/DOMErrorHandler.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/DOMException.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/DOMImplementation.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/DOMImplementationList.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/DOMImplementationSource.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/DOMLocator.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/DOMStringList.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/Element.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/Entity.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/EntityReference.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/NamedNodeMap.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/NameList.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/Node.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/NodeList.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/Notation.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/ProcessingInstruction.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/Text.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/TypeInfo.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/UserDataHandler.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/bootstrap/DOMImplementationRegistry.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/Counter.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/CSS2Properties.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/CSSCharsetRule.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/CSSFontFaceRule.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/CSSImportRule.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/CSSMediaRule.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/CSSPageRule.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/CSSPrimitiveValue.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/CSSRule.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/CSSRuleList.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/CSSStyleDeclaration.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/CSSStyleRule.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/CSSStyleSheet.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/CSSUnknownRule.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/CSSValue.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/CSSValueList.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/DocumentCSS.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/DOMImplementationCSS.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/ElementCSSInlineStyle.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/Rect.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/RGBColor.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/css/ViewCSS.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/events/DocumentEvent.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/events/Event.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/events/EventException.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/events/EventListener.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/events/EventTarget.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/events/MouseEvent.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/events/MutationEvent.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/events/UIEvent.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLAnchorElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLAppletElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLAreaElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLBaseElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLBaseFontElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLBodyElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLBRElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLButtonElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLCollection.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLDirectoryElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLDivElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLDListElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLDocument.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLFieldSetElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLFontElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLFormElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLFrameElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLFrameSetElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLHeadElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLHeadingElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLHRElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLHtmlElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLIFrameElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLImageElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLInputElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLIsIndexElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLLabelElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLLegendElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLLIElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLLinkElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLMapElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLMenuElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLMetaElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLModElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLObjectElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLOListElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLOptGroupElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLOptionElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLOptionsCollection.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLParagraphElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLParamElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLPreElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLQuoteElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLScriptElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLSelectElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLStyleElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableCaptionElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableCellElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableColElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableRowElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTableSectionElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTextAreaElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLTitleElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/html2/HTMLUListElement.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/ls/DOMImplementationLS.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/ls/LSException.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/ls/LSInput.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/ls/LSLoadEvent.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/ls/LSOutput.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/ls/LSParser.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/ls/LSParserFilter.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/ls/LSProgressEvent.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/ls/LSResourceResolver.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/ls/LSSerializer.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/ls/LSSerializerFilter.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/ranges/DocumentRange.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/ranges/Range.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/ranges/RangeException.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/stylesheets/DocumentStyle.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/stylesheets/LinkStyle.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/stylesheets/MediaList.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/stylesheets/StyleSheet.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/stylesheets/StyleSheetList.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/traversal/DocumentTraversal.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/traversal/NodeFilter.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/traversal/NodeIterator.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/traversal/TreeWalker.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/views/AbstractView.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/views/DocumentView.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/xpath/XPathEvaluator.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/xpath/XPathException.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/xpath/XPathExpression.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/xpath/XPathNamespace.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/xpath/XPathNSResolver.java
|
||||
../../classpath/external/w3c_dom/org/w3c/dom/xpath/XPathResult.java
|
||||
../../classpath/gnu/xml/aelfred2/ContentHandler2.java
|
||||
../../classpath/gnu/xml/aelfred2/JAXPFactory.java
|
||||
../../classpath/gnu/xml/aelfred2/SAXDriver.java
|
||||
../../classpath/gnu/xml/aelfred2/XmlParser.java
|
||||
../../classpath/gnu/xml/aelfred2/XmlReader.java
|
||||
../../classpath/gnu/xml/dom/Consumer.java
|
||||
../../classpath/gnu/xml/dom/DomAttr.java
|
||||
../../classpath/gnu/xml/dom/DomCDATA.java
|
||||
../../classpath/gnu/xml/dom/DomCharacterData.java
|
||||
../../classpath/gnu/xml/dom/DomComment.java
|
||||
../../classpath/gnu/xml/dom/DomDoctype.java
|
||||
../../classpath/gnu/xml/dom/DomDocument.java
|
||||
../../classpath/gnu/xml/dom/DomDocumentBuilder.java
|
||||
../../classpath/gnu/xml/dom/DomDocumentBuilderFactory.java
|
||||
../../classpath/gnu/xml/dom/DomDocumentConfiguration.java
|
||||
../../classpath/gnu/xml/dom/DomElement.java
|
||||
../../classpath/gnu/xml/dom/DomEntity.java
|
||||
../../classpath/gnu/xml/dom/DomEntityReference.java
|
||||
../../classpath/gnu/xml/dom/DomEvent.java
|
||||
../../classpath/gnu/xml/dom/DomEx.java
|
||||
../../classpath/gnu/xml/dom/DomExtern.java
|
||||
../../classpath/gnu/xml/dom/DomFragment.java
|
||||
../../classpath/gnu/xml/dom/DomImpl.java
|
||||
../../classpath/gnu/xml/dom/DomIterator.java
|
||||
../../classpath/gnu/xml/dom/DomNamedNodeMap.java
|
||||
../../classpath/gnu/xml/dom/DomNode.java
|
||||
../../classpath/gnu/xml/dom/DomNodeIterator.java
|
||||
../../classpath/gnu/xml/dom/DomNotation.java
|
||||
../../classpath/gnu/xml/dom/DomNsNode.java
|
||||
../../classpath/gnu/xml/dom/DomNSResolverContext.java
|
||||
../../classpath/gnu/xml/dom/DomPI.java
|
||||
../../classpath/gnu/xml/dom/DomText.java
|
||||
../../classpath/gnu/xml/dom/DomXPathExpression.java
|
||||
../../classpath/gnu/xml/dom/DomXPathNSResolver.java
|
||||
../../classpath/gnu/xml/dom/DomXPathResult.java
|
||||
../../classpath/gnu/xml/dom/DTDAttributeTypeInfo.java
|
||||
../../classpath/gnu/xml/dom/DTDElementTypeInfo.java
|
||||
../../classpath/gnu/xml/dom/ImplementationList.java
|
||||
../../classpath/gnu/xml/dom/ImplementationSource.java
|
||||
../../classpath/gnu/xml/dom/JAXPFactory.java
|
||||
../../classpath/gnu/xml/dom/ls/DomLSEx.java
|
||||
../../classpath/gnu/xml/dom/ls/DomLSInput.java
|
||||
../../classpath/gnu/xml/dom/ls/DomLSOutput.java
|
||||
../../classpath/gnu/xml/dom/ls/DomLSParser.java
|
||||
../../classpath/gnu/xml/dom/ls/DomLSSerializer.java
|
||||
../../classpath/gnu/xml/dom/ls/FilteredSAXEventSink.java
|
||||
../../classpath/gnu/xml/dom/ls/ReaderInputStream.java
|
||||
../../classpath/gnu/xml/dom/ls/SAXEventSink.java
|
||||
../../classpath/gnu/xml/dom/ls/WriterOutputStream.java
|
||||
../../classpath/gnu/xml/pipeline/CallFilter.java
|
||||
../../classpath/gnu/xml/pipeline/DomConsumer.java
|
||||
../../classpath/gnu/xml/pipeline/EventConsumer.java
|
||||
../../classpath/gnu/xml/pipeline/EventFilter.java
|
||||
../../classpath/gnu/xml/pipeline/LinkFilter.java
|
||||
../../classpath/gnu/xml/pipeline/NSFilter.java
|
||||
../../classpath/gnu/xml/pipeline/PipelineFactory.java
|
||||
../../classpath/gnu/xml/pipeline/TeeConsumer.java
|
||||
../../classpath/gnu/xml/pipeline/TextConsumer.java
|
||||
../../classpath/gnu/xml/pipeline/ValidationConsumer.java
|
||||
../../classpath/gnu/xml/pipeline/WellFormednessFilter.java
|
||||
../../classpath/gnu/xml/pipeline/XIncludeFilter.java
|
||||
../../classpath/gnu/xml/pipeline/XsltFilter.java
|
||||
../../classpath/gnu/xml/transform/AbstractNumberNode.java
|
||||
../../classpath/gnu/xml/transform/ApplyImportsNode.java
|
||||
../../classpath/gnu/xml/transform/ApplyTemplatesNode.java
|
||||
../../classpath/gnu/xml/transform/AttributeNode.java
|
||||
../../classpath/gnu/xml/transform/AttributeSet.java
|
||||
../../classpath/gnu/xml/transform/Bindings.java
|
||||
../../classpath/gnu/xml/transform/CallTemplateNode.java
|
||||
../../classpath/gnu/xml/transform/ChooseNode.java
|
||||
../../classpath/gnu/xml/transform/CommentNode.java
|
||||
../../classpath/gnu/xml/transform/CopyNode.java
|
||||
../../classpath/gnu/xml/transform/CopyOfNode.java
|
||||
../../classpath/gnu/xml/transform/CurrentFunction.java
|
||||
../../classpath/gnu/xml/transform/DocumentFunction.java
|
||||
../../classpath/gnu/xml/transform/DOMSourceLocator.java
|
||||
../../classpath/gnu/xml/transform/ElementAvailableFunction.java
|
||||
../../classpath/gnu/xml/transform/ElementNode.java
|
||||
../../classpath/gnu/xml/transform/ErrorListenerErrorHandler.java
|
||||
../../classpath/gnu/xml/transform/ForEachNode.java
|
||||
../../classpath/gnu/xml/transform/FormatNumberFunction.java
|
||||
../../classpath/gnu/xml/transform/FunctionAvailableFunction.java
|
||||
../../classpath/gnu/xml/transform/GenerateIdFunction.java
|
||||
../../classpath/gnu/xml/transform/IfNode.java
|
||||
../../classpath/gnu/xml/transform/Key.java
|
||||
../../classpath/gnu/xml/transform/KeyFunction.java
|
||||
../../classpath/gnu/xml/transform/LiteralNode.java
|
||||
../../classpath/gnu/xml/transform/MessageNode.java
|
||||
../../classpath/gnu/xml/transform/NodeNumberNode.java
|
||||
../../classpath/gnu/xml/transform/NumberNode.java
|
||||
../../classpath/gnu/xml/transform/OtherwiseNode.java
|
||||
../../classpath/gnu/xml/transform/ParameterNode.java
|
||||
../../classpath/gnu/xml/transform/ProcessingInstructionNode.java
|
||||
../../classpath/gnu/xml/transform/SAXSerializer.java
|
||||
../../classpath/gnu/xml/transform/SortKey.java
|
||||
../../classpath/gnu/xml/transform/StreamSerializer.java
|
||||
../../classpath/gnu/xml/transform/Stylesheet.java
|
||||
../../classpath/gnu/xml/transform/SystemPropertyFunction.java
|
||||
../../classpath/gnu/xml/transform/Template.java
|
||||
../../classpath/gnu/xml/transform/TemplateNode.java
|
||||
../../classpath/gnu/xml/transform/TemplatesImpl.java
|
||||
../../classpath/gnu/xml/transform/TextNode.java
|
||||
../../classpath/gnu/xml/transform/TransformerFactoryImpl.java
|
||||
../../classpath/gnu/xml/transform/TransformerImpl.java
|
||||
../../classpath/gnu/xml/transform/TransformerOutputProperties.java
|
||||
../../classpath/gnu/xml/transform/UnparsedEntityUriFunction.java
|
||||
../../classpath/gnu/xml/transform/URIResolverEntityResolver.java
|
||||
../../classpath/gnu/xml/transform/ValueOfNode.java
|
||||
../../classpath/gnu/xml/transform/WhenNode.java
|
||||
../../classpath/gnu/xml/transform/WithParam.java
|
||||
../../classpath/gnu/xml/transform/XSLComparator.java
|
||||
../../classpath/gnu/xml/transform/XSLURIResolver.java
|
||||
../../classpath/gnu/xml/util/DomParser.java
|
||||
../../classpath/gnu/xml/util/DoParse.java
|
||||
../../classpath/gnu/xml/util/Resolver.java
|
||||
../../classpath/gnu/xml/util/SAXNullTransformerFactory.java
|
||||
../../classpath/gnu/xml/util/XCat.java
|
||||
../../classpath/gnu/xml/util/XHTMLWriter.java
|
||||
../../classpath/gnu/xml/util/XMLWriter.java
|
||||
../../classpath/gnu/xml/xpath/AndExpr.java
|
||||
../../classpath/gnu/xml/xpath/ArithmeticExpr.java
|
||||
../../classpath/gnu/xml/xpath/BooleanFunction.java
|
||||
../../classpath/gnu/xml/xpath/CeilingFunction.java
|
||||
../../classpath/gnu/xml/xpath/ConcatFunction.java
|
||||
../../classpath/gnu/xml/xpath/Constant.java
|
||||
../../classpath/gnu/xml/xpath/ContainsFunction.java
|
||||
../../classpath/gnu/xml/xpath/CountFunction.java
|
||||
../../classpath/gnu/xml/xpath/DocumentOrderComparator.java
|
||||
../../classpath/gnu/xml/xpath/EqualityExpr.java
|
||||
../../classpath/gnu/xml/xpath/Expr.java
|
||||
../../classpath/gnu/xml/xpath/FalseFunction.java
|
||||
../../classpath/gnu/xml/xpath/FloorFunction.java
|
||||
../../classpath/gnu/xml/xpath/Function.java
|
||||
../../classpath/gnu/xml/xpath/FunctionCall.java
|
||||
../../classpath/gnu/xml/xpath/IdFunction.java
|
||||
../../classpath/gnu/xml/xpath/LangFunction.java
|
||||
../../classpath/gnu/xml/xpath/LastFunction.java
|
||||
../../classpath/gnu/xml/xpath/LocalNameFunction.java
|
||||
../../classpath/gnu/xml/xpath/NameFunction.java
|
||||
../../classpath/gnu/xml/xpath/NamespaceTest.java
|
||||
../../classpath/gnu/xml/xpath/NamespaceUriFunction.java
|
||||
../../classpath/gnu/xml/xpath/NameTest.java
|
||||
../../classpath/gnu/xml/xpath/NegativeExpr.java
|
||||
../../classpath/gnu/xml/xpath/NodeTypeTest.java
|
||||
../../classpath/gnu/xml/xpath/NormalizeSpaceFunction.java
|
||||
../../classpath/gnu/xml/xpath/NotFunction.java
|
||||
../../classpath/gnu/xml/xpath/NumberFunction.java
|
||||
../../classpath/gnu/xml/xpath/OrExpr.java
|
||||
../../classpath/gnu/xml/xpath/ParenthesizedExpr.java
|
||||
../../classpath/gnu/xml/xpath/Path.java
|
||||
../../classpath/gnu/xml/xpath/Pattern.java
|
||||
../../classpath/gnu/xml/xpath/PositionFunction.java
|
||||
../../classpath/gnu/xml/xpath/Predicate.java
|
||||
../../classpath/gnu/xml/xpath/RelationalExpr.java
|
||||
../../classpath/gnu/xml/xpath/Root.java
|
||||
../../classpath/gnu/xml/xpath/RoundFunction.java
|
||||
../../classpath/gnu/xml/xpath/Selector.java
|
||||
../../classpath/gnu/xml/xpath/StartsWithFunction.java
|
||||
../../classpath/gnu/xml/xpath/Steps.java
|
||||
../../classpath/gnu/xml/xpath/StringFunction.java
|
||||
../../classpath/gnu/xml/xpath/StringLengthFunction.java
|
||||
../../classpath/gnu/xml/xpath/SubstringAfterFunction.java
|
||||
../../classpath/gnu/xml/xpath/SubstringBeforeFunction.java
|
||||
../../classpath/gnu/xml/xpath/SubstringFunction.java
|
||||
../../classpath/gnu/xml/xpath/SumFunction.java
|
||||
../../classpath/gnu/xml/xpath/Test.java
|
||||
../../classpath/gnu/xml/xpath/TranslateFunction.java
|
||||
../../classpath/gnu/xml/xpath/TrueFunction.java
|
||||
../../classpath/gnu/xml/xpath/UnionExpr.java
|
||||
../../classpath/gnu/xml/xpath/VariableReference.java
|
||||
../../classpath/gnu/xml/xpath/XPathFactoryImpl.java
|
||||
../../classpath/gnu/xml/xpath/XPathImpl.java
|
||||
../../classpath/gnu/xml/xpath/XPathParser.java
|
||||
../../classpath/gnu/xml/xpath/XPathTokenizer.java
|
||||
../../classpath/javax/xml/XMLConstants.java
|
||||
../../classpath/javax/xml/datatype/DatatypeConfigurationException.java
|
||||
../../classpath/javax/xml/datatype/DatatypeConstants.java
|
||||
../../classpath/javax/xml/datatype/DatatypeFactory.java
|
||||
../../classpath/javax/xml/datatype/Duration.java
|
||||
../../classpath/javax/xml/datatype/XMLGregorianCalendar.java
|
||||
../../classpath/javax/xml/namespace/NamespaceContext.java
|
||||
../../classpath/javax/xml/namespace/QName.java
|
||||
../../classpath/javax/xml/parsers/DocumentBuilder.java
|
||||
../../classpath/javax/xml/parsers/DocumentBuilderFactory.java
|
||||
../../classpath/javax/xml/parsers/FactoryConfigurationError.java
|
||||
../../classpath/javax/xml/parsers/ParserConfigurationException.java
|
||||
../../classpath/javax/xml/parsers/SAXParser.java
|
||||
../../classpath/javax/xml/parsers/SAXParserFactory.java
|
||||
../../classpath/javax/xml/transform/ErrorListener.java
|
||||
../../classpath/javax/xml/transform/OutputKeys.java
|
||||
../../classpath/javax/xml/transform/Result.java
|
||||
../../classpath/javax/xml/transform/Source.java
|
||||
../../classpath/javax/xml/transform/SourceLocator.java
|
||||
../../classpath/javax/xml/transform/Templates.java
|
||||
../../classpath/javax/xml/transform/Transformer.java
|
||||
../../classpath/javax/xml/transform/TransformerConfigurationException.java
|
||||
../../classpath/javax/xml/transform/TransformerException.java
|
||||
../../classpath/javax/xml/transform/TransformerFactory.java
|
||||
../../classpath/javax/xml/transform/TransformerFactoryConfigurationError.java
|
||||
../../classpath/javax/xml/transform/URIResolver.java
|
||||
../../classpath/javax/xml/transform/dom/DOMLocator.java
|
||||
../../classpath/javax/xml/transform/dom/DOMResult.java
|
||||
../../classpath/javax/xml/transform/dom/DOMSource.java
|
||||
../../classpath/javax/xml/transform/sax/SAXResult.java
|
||||
../../classpath/javax/xml/transform/sax/SAXSource.java
|
||||
../../classpath/javax/xml/transform/sax/SAXTransformerFactory.java
|
||||
../../classpath/javax/xml/transform/sax/TemplatesHandler.java
|
||||
../../classpath/javax/xml/transform/sax/TransformerHandler.java
|
||||
../../classpath/javax/xml/transform/stream/StreamResult.java
|
||||
../../classpath/javax/xml/transform/stream/StreamSource.java
|
||||
../../classpath/javax/xml/validation/Schema.java
|
||||
../../classpath/javax/xml/validation/SchemaFactory.java
|
||||
../../classpath/javax/xml/validation/TypeInfoProvider.java
|
||||
../../classpath/javax/xml/validation/Validator.java
|
||||
../../classpath/javax/xml/validation/ValidatorHandler.java
|
||||
../../classpath/javax/xml/xpath/XPath.java
|
||||
../../classpath/javax/xml/xpath/XPathConstants.java
|
||||
../../classpath/javax/xml/xpath/XPathException.java
|
||||
../../classpath/javax/xml/xpath/XPathExpression.java
|
||||
../../classpath/javax/xml/xpath/XPathExpressionException.java
|
||||
../../classpath/javax/xml/xpath/XPathFactory.java
|
||||
../../classpath/javax/xml/xpath/XPathFactoryConfigurationException.java
|
||||
../../classpath/javax/xml/xpath/XPathFunction.java
|
||||
../../classpath/javax/xml/xpath/XPathFunctionException.java
|
||||
../../classpath/javax/xml/xpath/XPathFunctionResolver.java
|
||||
../../classpath/javax/xml/xpath/XPathVariableResolver.java
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<includes name="**.class"/>
|
||||
</fileset>
|
||||
</delete>
|
||||
<property name="classpath" value=".${pathsep}${Classpath.dir}${pathsep}${Classpath.dir}/vm/reference${pathsep}mscorlib.jar${pathsep}System.jar" />
|
||||
<property name="classpath" value=".${pathsep}${Classpath.dir}${pathsep}${Classpath.dir}/external/w3c_dom${pathsep}${Classpath.dir}/external/sax${pathsep}${Classpath.dir}/vm/reference${pathsep}mscorlib.jar${pathsep}System.jar" />
|
||||
<exec program="jikes" commandline="-g -nowarn -classpath ${classpath} @allsources.lst"/>
|
||||
</target>
|
||||
|
||||
|
|
|
@ -10,6 +10,10 @@ public class VMSystemProperties
|
|||
|
||||
static void preInit(Properties p)
|
||||
{
|
||||
String[] culture = ((cli.System.String)(Object)cli.System.Globalization.CultureInfo.get_CurrentCulture().get_Name()).Split(new char[] { '-' });
|
||||
p.setProperty("user.language", culture[0]);
|
||||
p.setProperty("user.region", culture.length > 1 ? culture[1] : "");
|
||||
p.setProperty("user.variant", culture.length > 2 ? culture[2] : "");
|
||||
p.setProperty("java.version", "1.4");
|
||||
p.setProperty("java.vendor", "Jeroen Frijters");
|
||||
p.setProperty("java.vendor.url", "http://ikvm.net/");
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2003 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
|
||||
|
||||
*/
|
||||
package java.lang;
|
||||
|
||||
class ObjectHelper
|
||||
{
|
||||
private ObjectHelper() {}
|
||||
|
||||
static void wait(Object o, long timeout, int nanos)
|
||||
{
|
||||
if(o == null)
|
||||
{
|
||||
throw new NullPointerException();
|
||||
}
|
||||
if(timeout < 0 || nanos < 0 || nanos > 999999)
|
||||
{
|
||||
throw new IllegalArgumentException("argument out of range");
|
||||
}
|
||||
if(timeout == 0 && nanos == 0)
|
||||
{
|
||||
cli.System.Threading.Monitor.Wait(o);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO handle time span calculation overflow
|
||||
cli.System.Threading.Monitor.Wait(o, new cli.System.TimeSpan(timeout * 10000 + (nanos + 99) / 100));
|
||||
}
|
||||
}
|
||||
|
||||
static String toStringSpecial(Object o)
|
||||
{
|
||||
return o.getClass().getName() + '@' + Integer.toHexString(o.hashCode());
|
||||
}
|
||||
}
|
|
@ -39,9 +39,6 @@ import cli.System.Diagnostics.ProcessStartInfo;
|
|||
*/
|
||||
final class VMRuntime
|
||||
{
|
||||
// HACK ikvm.exe sets this field to pass the properties set on the command line
|
||||
private static cli.System.Collections.Hashtable props;
|
||||
|
||||
/**
|
||||
* No instance is ever created.
|
||||
*/
|
||||
|
@ -49,7 +46,7 @@ final class VMRuntime
|
|||
{
|
||||
}
|
||||
|
||||
static
|
||||
static void enableShutdownHooks()
|
||||
{
|
||||
cli.System.AppDomain.get_CurrentDomain().add_ProcessExit(new cli.System.EventHandler(new cli.System.EventHandler.Method() {
|
||||
public void Invoke(Object sender, cli.System.EventArgs e) {
|
||||
|
@ -311,8 +308,18 @@ final class VMRuntime
|
|||
|
||||
public int waitFor() throws InterruptedException
|
||||
{
|
||||
proc.WaitForExit();
|
||||
return proc.get_ExitCode();
|
||||
// to be interruptable we have to use polling
|
||||
for(;;)
|
||||
{
|
||||
if(Thread.interrupted())
|
||||
{
|
||||
throw new InterruptedException();
|
||||
}
|
||||
if(proc.WaitForExit(100))
|
||||
{
|
||||
return proc.get_ExitCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int exitValue()
|
||||
|
|
|
@ -12,7 +12,10 @@ final class VMThread
|
|||
// Note: when this thread dies, this reference is *not* cleared
|
||||
volatile Thread thread;
|
||||
private volatile boolean running;
|
||||
private volatile cli.System.Threading.Thread joinThread;
|
||||
private volatile boolean interruptableWait;
|
||||
private volatile boolean interruptPending;
|
||||
private VMThread firstJoinWaiter;
|
||||
private VMThread nextJoinWaiter;
|
||||
|
||||
private VMThread(Thread thread)
|
||||
{
|
||||
|
@ -75,6 +78,44 @@ final class VMThread
|
|||
}
|
||||
}
|
||||
|
||||
private synchronized void addJoinWaiter(VMThread waiter)
|
||||
{
|
||||
if(waiter != this)
|
||||
{
|
||||
waiter.nextJoinWaiter = firstJoinWaiter;
|
||||
firstJoinWaiter = waiter;
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void removeJoinWaiter(VMThread waiter)
|
||||
{
|
||||
if(waiter == this)
|
||||
{
|
||||
// we never link ourself
|
||||
}
|
||||
else if(firstJoinWaiter == waiter)
|
||||
{
|
||||
firstJoinWaiter = waiter.nextJoinWaiter;
|
||||
waiter.nextJoinWaiter = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
VMThread prev = firstJoinWaiter;
|
||||
VMThread curr = prev.nextJoinWaiter;
|
||||
while(curr != null)
|
||||
{
|
||||
if(curr == waiter)
|
||||
{
|
||||
prev.nextJoinWaiter = waiter.nextJoinWaiter;
|
||||
waiter.nextJoinWaiter = null;
|
||||
break;
|
||||
}
|
||||
prev = curr;
|
||||
curr = curr.nextJoinWaiter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void jniDetach()
|
||||
{
|
||||
VMThread vmthread = Thread.currentThread().vmThread;
|
||||
|
@ -82,10 +123,13 @@ final class VMThread
|
|||
{
|
||||
vmthread.cleanup();
|
||||
cli.System.Threading.Thread.SetData(localDataStoreSlot, null);
|
||||
if(vmthread.joinThread != null)
|
||||
{
|
||||
vmthread.joinThread.Interrupt();
|
||||
}
|
||||
VMThread joinWaiter = vmthread.firstJoinWaiter;
|
||||
while(joinWaiter != null)
|
||||
{
|
||||
VMThread next = joinWaiter.nextJoinWaiter;
|
||||
joinWaiter.interrupt();
|
||||
joinWaiter = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,47 +201,43 @@ final class VMThread
|
|||
|
||||
void join(long ms, int ns) throws InterruptedException
|
||||
{
|
||||
cli.System.Threading.Thread nativeThread;
|
||||
synchronized(this)
|
||||
cli.System.Threading.Thread nativeThread = (cli.System.Threading.Thread)nativeThreadReference.get_Target();
|
||||
if(nativeThread == null)
|
||||
{
|
||||
nativeThread = (cli.System.Threading.Thread)nativeThreadReference.get_Target();
|
||||
if(nativeThread == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
joinThread = cli.System.Threading.Thread.get_CurrentThread();
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
if(false) throw new InterruptedException();
|
||||
VMThread current = currentThread().vmThread;
|
||||
enterInterruptableWait();
|
||||
try
|
||||
{
|
||||
if(ms == 0 && ns == 0)
|
||||
{
|
||||
nativeThread.Join();
|
||||
}
|
||||
else
|
||||
{
|
||||
// if nanoseconds are specified, round up to one millisecond
|
||||
if(ns != 0)
|
||||
addJoinWaiter(current);
|
||||
if(thread.vmThread != null)
|
||||
{
|
||||
if(ms == 0 && ns == 0)
|
||||
{
|
||||
nativeThread.Join(1);
|
||||
nativeThread.Join();
|
||||
}
|
||||
for(long iter = ms / Integer.MAX_VALUE; iter != 0; iter--)
|
||||
else
|
||||
{
|
||||
nativeThread.Join(Integer.MAX_VALUE);
|
||||
// if nanoseconds are specified, round up to one millisecond
|
||||
if(ns != 0)
|
||||
{
|
||||
nativeThread.Join(1);
|
||||
}
|
||||
for(long iter = ms / Integer.MAX_VALUE; iter != 0; iter--)
|
||||
{
|
||||
nativeThread.Join(Integer.MAX_VALUE);
|
||||
}
|
||||
nativeThread.Join((int)(ms % Integer.MAX_VALUE));
|
||||
}
|
||||
nativeThread.Join((int)(ms % Integer.MAX_VALUE));
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
synchronized(this)
|
||||
{
|
||||
joinThread = null;
|
||||
// make sure that any pending interrupts (caused by the thread dying) are handled
|
||||
cli.System.Threading.Thread.Sleep(0);
|
||||
}
|
||||
removeJoinWaiter(current);
|
||||
leaveInterruptableWait();
|
||||
}
|
||||
}
|
||||
catch(InterruptedException x)
|
||||
|
@ -253,41 +293,78 @@ final class VMThread
|
|||
}
|
||||
}
|
||||
|
||||
void interrupt()
|
||||
private static void enterInterruptableWait() throws InterruptedException
|
||||
{
|
||||
cli.System.Threading.Thread nativeThread = (cli.System.Threading.Thread)nativeThreadReference.get_Target();
|
||||
if(nativeThread != null)
|
||||
{
|
||||
nativeThread.Interrupt();
|
||||
}
|
||||
VMThread vmthread = currentThread().vmThread;
|
||||
synchronized(vmthread)
|
||||
{
|
||||
if(vmthread.interruptPending)
|
||||
{
|
||||
vmthread.interruptPending = false;
|
||||
throw new InterruptedException();
|
||||
}
|
||||
vmthread.interruptableWait = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static void leaveInterruptableWait() throws InterruptedException
|
||||
{
|
||||
cli.System.Threading.ThreadInterruptedException dotnetInterrupt = null;
|
||||
for(;;)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(false) throw new cli.System.Threading.ThreadInterruptedException();
|
||||
VMThread vmthread = currentThread().vmThread;
|
||||
synchronized(vmthread)
|
||||
{
|
||||
vmthread.interruptableWait = false;
|
||||
if(vmthread.interruptPending)
|
||||
{
|
||||
vmthread.interruptPending = false;
|
||||
throw new InterruptedException();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
catch(cli.System.Threading.ThreadInterruptedException x)
|
||||
{
|
||||
dotnetInterrupt = x;
|
||||
}
|
||||
}
|
||||
if(dotnetInterrupt != null)
|
||||
{
|
||||
VMClass.throwException(dotnetInterrupt);
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void interrupt()
|
||||
{
|
||||
interruptPending = true;
|
||||
if(interruptableWait)
|
||||
{
|
||||
cli.System.Threading.Thread nativeThread = (cli.System.Threading.Thread)nativeThreadReference.get_Target();
|
||||
if(nativeThread != null)
|
||||
{
|
||||
nativeThread.Interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static boolean interrupted()
|
||||
{
|
||||
VMThread thread = currentThread().vmThread;
|
||||
synchronized(thread)
|
||||
{
|
||||
boolean state = thread.interruptPending;
|
||||
thread.interruptPending = false;
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
boolean isInterrupted()
|
||||
{
|
||||
// NOTE special case for current thread, because then we can use the .NET interrupted status
|
||||
if(thread == currentThread())
|
||||
{
|
||||
try
|
||||
{
|
||||
if(false) throw new InterruptedException();
|
||||
cli.System.Threading.Thread.Sleep(0);
|
||||
return false;
|
||||
}
|
||||
catch(InterruptedException x)
|
||||
{
|
||||
// because we "consumed" the interrupt, we need to interrupt ourself again
|
||||
cli.System.Threading.Thread nativeThread = (cli.System.Threading.Thread)nativeThreadReference.get_Target();
|
||||
if(nativeThread != null)
|
||||
{
|
||||
nativeThread.Interrupt();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// HACK since quering the interrupted state of another thread is inherently racy, I hope
|
||||
// we can get away with always returning false, because I have no idea how to obtain this
|
||||
// information from the .NET runtime
|
||||
return false;
|
||||
return interruptPending;
|
||||
}
|
||||
|
||||
void suspend()
|
||||
|
@ -436,16 +513,7 @@ final class VMThread
|
|||
|
||||
static void yield()
|
||||
{
|
||||
try
|
||||
{
|
||||
if(false) throw new InterruptedException();
|
||||
cli.System.Threading.Thread.Sleep(0);
|
||||
}
|
||||
catch(InterruptedException x)
|
||||
{
|
||||
// since we "consumed" the interrupt, we have to interrupt ourself again
|
||||
cli.System.Threading.Thread.get_CurrentThread().Interrupt();
|
||||
}
|
||||
cli.System.Threading.Thread.Sleep(0);
|
||||
}
|
||||
|
||||
static void sleep(long ms, int ns) throws InterruptedException
|
||||
|
@ -458,30 +526,24 @@ final class VMThread
|
|||
}
|
||||
else
|
||||
{
|
||||
// if nanoseconds are specified, round up to one millisecond
|
||||
if(ns != 0)
|
||||
{
|
||||
cli.System.Threading.Thread.Sleep(1);
|
||||
}
|
||||
for(long iter = ms / Integer.MAX_VALUE; iter != 0; iter--)
|
||||
{
|
||||
cli.System.Threading.Thread.Sleep(Integer.MAX_VALUE);
|
||||
}
|
||||
cli.System.Threading.Thread.Sleep((int)(ms % Integer.MAX_VALUE));
|
||||
}
|
||||
}
|
||||
|
||||
static boolean interrupted()
|
||||
{
|
||||
try
|
||||
{
|
||||
if(false) throw new InterruptedException();
|
||||
cli.System.Threading.Thread.Sleep(0);
|
||||
return false;
|
||||
}
|
||||
catch(InterruptedException x)
|
||||
{
|
||||
return true;
|
||||
enterInterruptableWait();
|
||||
try
|
||||
{
|
||||
// if nanoseconds are specified, round up to one millisecond
|
||||
if(ns != 0)
|
||||
{
|
||||
cli.System.Threading.Thread.Sleep(1);
|
||||
}
|
||||
for(long iter = ms / Integer.MAX_VALUE; iter != 0; iter--)
|
||||
{
|
||||
cli.System.Threading.Thread.Sleep(Integer.MAX_VALUE);
|
||||
}
|
||||
cli.System.Threading.Thread.Sleep((int)(ms % Integer.MAX_VALUE));
|
||||
}
|
||||
finally
|
||||
{
|
||||
leaveInterruptableWait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -504,4 +566,33 @@ final class VMThread
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// this implements java.lang.Object.wait(long timeout, int nanos) (via map.xml)
|
||||
static void objectWait(Object o, long timeout, int nanos) throws InterruptedException
|
||||
{
|
||||
if(o == null)
|
||||
{
|
||||
throw new NullPointerException();
|
||||
}
|
||||
if(timeout < 0 || nanos < 0 || nanos > 999999)
|
||||
{
|
||||
throw new IllegalArgumentException("argument out of range");
|
||||
}
|
||||
enterInterruptableWait();
|
||||
try
|
||||
{
|
||||
if((timeout == 0 && nanos == 0) || timeout > 922337203685476L)
|
||||
{
|
||||
cli.System.Threading.Monitor.Wait(o);
|
||||
}
|
||||
else
|
||||
{
|
||||
cli.System.Threading.Monitor.Wait(o, new cli.System.TimeSpan(timeout * 10000 + (nanos + 99) / 100));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
leaveInterruptableWait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,9 +44,10 @@
|
|||
<throws class="java.lang.InterruptedException" />
|
||||
<body>
|
||||
<ldarg_0 />
|
||||
<call type="System.Threading.Monitor, mscorlib" name="Wait" sig="(Ljava.lang.Object;)Z" />
|
||||
<!-- For some reason, Wait returns a boolean -->
|
||||
<pop />
|
||||
<ldc_i4_0 />
|
||||
<conv_i8 />
|
||||
<ldc_i4_0 />
|
||||
<call class="java.lang.VMThread" name="objectWait" sig="(Ljava.lang.Object;JI)V" />
|
||||
<ret />
|
||||
</body>
|
||||
</method>
|
||||
|
@ -56,7 +57,7 @@
|
|||
<ldarg_0 />
|
||||
<ldarg_1 />
|
||||
<ldc_i4_0 />
|
||||
<call class="java.lang.ObjectHelper" name="wait" sig="(Ljava.lang.Object;JI)V" />
|
||||
<call class="java.lang.VMThread" name="objectWait" sig="(Ljava.lang.Object;JI)V" />
|
||||
<ret />
|
||||
</body>
|
||||
</method>
|
||||
|
@ -66,7 +67,7 @@
|
|||
<ldarg_0 />
|
||||
<ldarg_1 />
|
||||
<ldarg_2 />
|
||||
<call class="java.lang.ObjectHelper" name="wait" sig="(Ljava.lang.Object;JI)V" />
|
||||
<call class="java.lang.VMThread" name="objectWait" sig="(Ljava.lang.Object;JI)V" />
|
||||
<ret />
|
||||
</body>
|
||||
</method>
|
||||
|
@ -103,11 +104,24 @@
|
|||
<ret />
|
||||
</alternateBody>
|
||||
</method>
|
||||
<method name="toStringImpl" sig="(Ljava.lang.Object;)Ljava.lang.String;" modifiers="private static">
|
||||
<body>
|
||||
<ldarg_0 />
|
||||
<callvirt class="java.lang.Object" name="getClass" sig="()Ljava.lang.Class;" />
|
||||
<call class="java.lang.Class" name="getName" sig="()Ljava.lang.String;" />
|
||||
<ldstr value="@" />
|
||||
<ldarg_0 />
|
||||
<callvirt class="java.lang.Object" name="hashCode" sig="()I" />
|
||||
<call class="java.lang.Integer" name="toHexString" sig="(I)Ljava.lang.String;" />
|
||||
<call type="System.String, mscorlib" name="Concat" sig="(Ljava.lang.String;Ljava.lang.String;Ljava.lang.String;)Ljava.lang.String;" />
|
||||
<ret />
|
||||
</body>
|
||||
</method>
|
||||
<method name="toString" sig="()Ljava.lang.String;" modifiers="public">
|
||||
<override name="ToString" />
|
||||
<body>
|
||||
<ldarg_0 />
|
||||
<call class="java.lang.ObjectHelper" name="toStringSpecial" sig="(Ljava.lang.Object;)Ljava.lang.String;" />
|
||||
<call class="java.lang.Object" name="toStringImpl" sig="(Ljava.lang.Object;)Ljava.lang.String;" />
|
||||
<ret />
|
||||
</body>
|
||||
<alternateBody>
|
||||
|
@ -115,7 +129,7 @@
|
|||
<isinst type="System.Array, mscorlib" />
|
||||
<brfalse name="skip" />
|
||||
<ldarg_0 />
|
||||
<call class="java.lang.ObjectHelper" name="toStringSpecial" sig="(Ljava.lang.Object;)Ljava.lang.String;" />
|
||||
<call class="java.lang.Object" name="toStringImpl" sig="(Ljava.lang.Object;)Ljava.lang.String;" />
|
||||
<br name="end" />
|
||||
<label name="skip" />
|
||||
<ldarg_0 />
|
||||
|
@ -125,7 +139,7 @@
|
|||
</alternateBody>
|
||||
<nonvirtualAlternateBody>
|
||||
<ldarg_0 />
|
||||
<call class="java.lang.ObjectHelper" name="toStringSpecial" sig="(Ljava.lang.Object;)Ljava.lang.String;" />
|
||||
<call class="java.lang.Object" name="toStringImpl" sig="(Ljava.lang.Object;)Ljava.lang.String;" />
|
||||
<ret />
|
||||
</nonvirtualAlternateBody>
|
||||
</method>
|
||||
|
@ -934,7 +948,7 @@
|
|||
<ldloc name="result" />
|
||||
<ret />
|
||||
<label name="err" />
|
||||
<newobj class="java.nio.BufferOverflowException" name="<init>" sig="()V" />
|
||||
<newobj class="java.nio.BufferUnderflowException" name="<init>" sig="()V" />
|
||||
<throw />
|
||||
</body>
|
||||
</method>
|
||||
|
@ -1027,7 +1041,6 @@
|
|||
</code>
|
||||
</exception>
|
||||
<exception src="System.Threading.SynchronizationLockException, mscorlib" dst="java.lang.IllegalMonitorStateException" />
|
||||
<exception src="System.Threading.ThreadInterruptedException, mscorlib" dst="java.lang.InterruptedException" />
|
||||
<exception src="System.OutOfMemoryException, mscorlib" dst="java.lang.OutOfMemoryError" />
|
||||
<exception src="System.DivideByZeroException, mscorlib" dst="java.lang.ArithmeticException">
|
||||
<code>
|
||||
|
|
|
@ -278,7 +278,7 @@ public class NetExp
|
|||
((mods & (Modifiers.Static | Modifiers.Final)) == (Modifiers.Static | Modifiers.Final) &&
|
||||
fields[i].getName() == "serialVersionUID" && fields[i].getType() == java.lang.Long.TYPE))
|
||||
{
|
||||
// HACK we use the IKVM runtime API to get constant value
|
||||
// we use the IKVM runtime API to get constant value
|
||||
// NOTE we can't use Field.get() because that will run the static initializer and
|
||||
// also won't allow us to see the difference between constants and blank final fields.
|
||||
object constantValue = IKVM.Runtime.Util.GetFieldConstantValue(fields[i]);
|
||||
|
|
|
@ -227,7 +227,7 @@ namespace IKVM.Runtime
|
|||
{
|
||||
TypeWrapper caller = ClassLoaderWrapper.GetWrapperFromType(Type.GetTypeFromHandle(type));
|
||||
TypeWrapper wrapper = LoadTypeWrapper(type, clazz);
|
||||
MethodWrapper mw = wrapper.GetMethodWrapper(new MethodDescriptor(name, sig), false);
|
||||
MethodWrapper mw = wrapper.GetMethodWrapper(name, sig, false);
|
||||
if(mw == null)
|
||||
{
|
||||
throw JavaException.NoSuchMethodError(clazz + "." + name + sig);
|
||||
|
@ -344,28 +344,6 @@ namespace IKVM.Runtime
|
|||
return (long)d;
|
||||
}
|
||||
|
||||
[DebuggerStepThroughAttribute]
|
||||
public static void monitorenter(object obj)
|
||||
{
|
||||
bool interruptPending = false;
|
||||
for(;;)
|
||||
{
|
||||
try
|
||||
{
|
||||
System.Threading.Monitor.Enter(obj);
|
||||
if(interruptPending)
|
||||
{
|
||||
System.Threading.Thread.CurrentThread.Interrupt();
|
||||
}
|
||||
return;
|
||||
}
|
||||
catch(System.Threading.ThreadInterruptedException)
|
||||
{
|
||||
interruptPending = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is used by static JNI and synchronized methods that need a class object
|
||||
[DebuggerStepThroughAttribute]
|
||||
public static object GetClassFromTypeHandle(RuntimeTypeHandle typeHandle)
|
||||
|
|
|
@ -770,7 +770,7 @@ class ClassFile
|
|||
}
|
||||
prev = c;
|
||||
}
|
||||
name = name.Replace('/', '.');
|
||||
name = String.Intern(name.Replace('/', '.'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -995,10 +995,10 @@ class ClassFile
|
|||
{
|
||||
throw new ClassFormatError("Bad index in constant pool");
|
||||
}
|
||||
name = classFile.GetConstantPoolUtf8String(name_and_type.name_index);
|
||||
name = String.Intern(classFile.GetConstantPoolUtf8String(name_and_type.name_index));
|
||||
descriptor = classFile.GetConstantPoolUtf8String(name_and_type.descriptor_index);
|
||||
Validate(name, descriptor);
|
||||
descriptor = descriptor.Replace('/', '.');
|
||||
descriptor = String.Intern(descriptor.Replace('/', '.'));
|
||||
}
|
||||
|
||||
protected abstract void Validate(string name, string descriptor);
|
||||
|
@ -1163,8 +1163,7 @@ class ClassFile
|
|||
TypeWrapper wrapper = GetClassType();
|
||||
if(!wrapper.IsUnloadable)
|
||||
{
|
||||
MethodDescriptor md = new MethodDescriptor(Name, Signature);
|
||||
method = wrapper.GetMethodWrapper(md, Name != "<init>");
|
||||
method = wrapper.GetMethodWrapper(Name, Signature, Name != "<init>");
|
||||
if(method != null)
|
||||
{
|
||||
method.Link();
|
||||
|
@ -1173,7 +1172,7 @@ class ClassFile
|
|||
(thisType.Modifiers & (__Modifiers.Interface | __Modifiers.Super)) == __Modifiers.Super &&
|
||||
thisType != wrapper && thisType.IsSubTypeOf(wrapper))
|
||||
{
|
||||
invokespecialMethod = thisType.BaseTypeWrapper.GetMethodWrapper(md, true);
|
||||
invokespecialMethod = thisType.BaseTypeWrapper.GetMethodWrapper(Name, Signature, true);
|
||||
if(invokespecialMethod != null)
|
||||
{
|
||||
invokespecialMethod.Link();
|
||||
|
@ -1189,9 +1188,9 @@ class ClassFile
|
|||
{
|
||||
}
|
||||
|
||||
private static MethodWrapper GetInterfaceMethod(TypeWrapper wrapper, MethodDescriptor md)
|
||||
private static MethodWrapper GetInterfaceMethod(TypeWrapper wrapper, string name, string sig)
|
||||
{
|
||||
MethodWrapper method = wrapper.GetMethodWrapper(md, false);
|
||||
MethodWrapper method = wrapper.GetMethodWrapper(name, sig, false);
|
||||
if(method != null)
|
||||
{
|
||||
return method;
|
||||
|
@ -1199,7 +1198,7 @@ class ClassFile
|
|||
TypeWrapper[] interfaces = wrapper.Interfaces;
|
||||
for(int i = 0; i < interfaces.Length; i++)
|
||||
{
|
||||
method = GetInterfaceMethod(interfaces[i], md);
|
||||
method = GetInterfaceMethod(interfaces[i], name, sig);
|
||||
if(method != null)
|
||||
{
|
||||
return method;
|
||||
|
@ -1214,12 +1213,11 @@ class ClassFile
|
|||
TypeWrapper wrapper = GetClassType();
|
||||
if(!wrapper.IsUnloadable)
|
||||
{
|
||||
MethodDescriptor md = new MethodDescriptor(Name, Signature);
|
||||
method = GetInterfaceMethod(wrapper, md);
|
||||
method = GetInterfaceMethod(wrapper, Name, Signature);
|
||||
if(method == null)
|
||||
{
|
||||
// NOTE vmspec 5.4.3.4 clearly states that an interfacemethod may also refer to a method in Object
|
||||
method = CoreClasses.java.lang.Object.Wrapper.GetMethodWrapper(md, false);
|
||||
method = CoreClasses.java.lang.Object.Wrapper.GetMethodWrapper(Name, Signature, false);
|
||||
}
|
||||
if(method != null)
|
||||
{
|
||||
|
@ -1364,10 +1362,10 @@ class ClassFile
|
|||
internal FieldOrMethod(ClassFile classFile, BigEndianBinaryReader br)
|
||||
{
|
||||
access_flags = (Modifiers)br.ReadUInt16();
|
||||
name = classFile.GetConstantPoolUtf8String(br.ReadUInt16());
|
||||
name = String.Intern(classFile.GetConstantPoolUtf8String(br.ReadUInt16()));
|
||||
descriptor = classFile.GetConstantPoolUtf8String(br.ReadUInt16());
|
||||
ValidateSig(classFile, descriptor);
|
||||
descriptor = descriptor.Replace('/', '.');
|
||||
descriptor = String.Intern(descriptor.Replace('/', '.'));
|
||||
}
|
||||
|
||||
protected abstract void ValidateSig(ClassFile classFile, string descriptor);
|
||||
|
|
|
@ -216,6 +216,11 @@ class ClassLoaderWrapper
|
|||
{
|
||||
throw new NullReferenceException();
|
||||
}
|
||||
// .NET 1.1 has a limit of 1024 characters for type names
|
||||
if(name.Length >= 1024)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
Profiler.Enter("LoadClassByDottedName");
|
||||
try
|
||||
{
|
||||
|
@ -407,44 +412,51 @@ class ClassLoaderWrapper
|
|||
Debug.Assert(!(type.Assembly is AssemblyBuilder), "!(type.Assembly is AssemblyBuilder)", type.FullName);
|
||||
// only the bootstrap classloader can own compiled types
|
||||
Debug.Assert(this == GetBootstrapClassLoader(), "this == GetBootstrapClassLoader()", type.FullName);
|
||||
TypeWrapper wrapper = null;
|
||||
if(type.Module.IsDefined(typeof(JavaModuleAttribute), false))
|
||||
bool javaType = type.Module.IsDefined(typeof(JavaModuleAttribute), false);
|
||||
string name;
|
||||
if(javaType)
|
||||
{
|
||||
lock(types.SyncRoot)
|
||||
{
|
||||
string name = CompiledTypeWrapper.GetName(type);
|
||||
wrapper = (TypeWrapper)types[name];
|
||||
if(wrapper == null)
|
||||
{
|
||||
// since this type was compiled from Java source, we have to look for our
|
||||
// attributes
|
||||
wrapper = new CompiledTypeWrapper(name, type);
|
||||
Debug.Assert(wrapper.Name == name, "wrapper.Name == name", type.FullName);
|
||||
Debug.Assert(!types.ContainsKey(wrapper.Name), wrapper.Name, type.FullName);
|
||||
types.Add(wrapper.Name, wrapper);
|
||||
Debug.Assert(!typeToTypeWrapper.ContainsKey(type), "!typeToTypeWrapper.ContainsKey(type)", type.FullName);
|
||||
typeToTypeWrapper.Add(type, wrapper);
|
||||
}
|
||||
}
|
||||
name = CompiledTypeWrapper.GetName(type);
|
||||
}
|
||||
else
|
||||
{
|
||||
name = DotNetTypeWrapper.GetName(type);
|
||||
}
|
||||
TypeWrapper wrapper;
|
||||
lock(types.SyncRoot)
|
||||
{
|
||||
wrapper = (TypeWrapper)types[name];
|
||||
}
|
||||
if(wrapper == null)
|
||||
{
|
||||
if(javaType)
|
||||
{
|
||||
// since this type was compiled from Java source, we have to look for our
|
||||
// attributes
|
||||
wrapper = new CompiledTypeWrapper(name, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
// since this type was not compiled from Java source, we don't need to
|
||||
// look for our attributes, but we do need to filter unrepresentable
|
||||
// stuff (and transform some other stuff)
|
||||
wrapper = new DotNetTypeWrapper(type);
|
||||
}
|
||||
Debug.Assert(wrapper.Name == name, "wrapper.Name == name", type.FullName);
|
||||
lock(types.SyncRoot)
|
||||
{
|
||||
string name = DotNetTypeWrapper.GetName(type);
|
||||
wrapper = (TypeWrapper)types[name];
|
||||
if(wrapper == null)
|
||||
// another thread may have beaten us to it and in that
|
||||
// case we don't want to overwrite the previous one
|
||||
TypeWrapper race = (TypeWrapper)types[name];
|
||||
if(race == null)
|
||||
{
|
||||
// since this type was not compiled from Java source, we don't need to
|
||||
// look for our attributes, but we do need to filter unrepresentable
|
||||
// stuff (and transform some other stuff)
|
||||
wrapper = new DotNetTypeWrapper(type);
|
||||
Debug.Assert(wrapper.Name == name, "wrapper.Name == name", type.FullName);
|
||||
Debug.Assert(!types.ContainsKey(wrapper.Name), wrapper.Name, type.FullName);
|
||||
types.Add(wrapper.Name, wrapper);
|
||||
Debug.Assert(!typeToTypeWrapper.ContainsKey(type), "!typeToTypeWrapper.ContainsKey(type)", type.FullName);
|
||||
types.Add(name, wrapper);
|
||||
typeToTypeWrapper.Add(type, wrapper);
|
||||
}
|
||||
else
|
||||
{
|
||||
wrapper = race;
|
||||
}
|
||||
}
|
||||
}
|
||||
return wrapper;
|
||||
|
@ -488,59 +500,79 @@ class ClassLoaderWrapper
|
|||
return null;
|
||||
}
|
||||
|
||||
// NOTE this method can actually return null if the resulting array type name would be too long
|
||||
// for .NET to handle.
|
||||
private TypeWrapper CreateArrayType(string name, TypeWrapper elementTypeWrapper, int dims)
|
||||
{
|
||||
Type elementType = elementTypeWrapper.TypeAsArrayType;
|
||||
Debug.Assert(!elementType.IsArray);
|
||||
TypeWrapper wrapper;
|
||||
lock(types.SyncRoot)
|
||||
{
|
||||
TypeWrapper wrapper = (TypeWrapper)types[name];
|
||||
if(wrapper == null)
|
||||
wrapper = (TypeWrapper)types[name];
|
||||
}
|
||||
if(wrapper == null)
|
||||
{
|
||||
String netname = elementType.FullName + "[]";
|
||||
for(int i = 1; i < dims; i++)
|
||||
{
|
||||
String netname = "[]";
|
||||
for(int i = 1; i < dims; i++)
|
||||
netname += "[]";
|
||||
}
|
||||
// .NET 1.1 has a limit of 1024 characters for type names
|
||||
if(netname.Length >= 1024)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
Type array;
|
||||
if(elementType.Module is ModuleBuilder)
|
||||
{
|
||||
// FXBUG ModuleBuilder.GetType() is broken (I think), it fires a TypeResolveEvent when
|
||||
// you try to construct an array type from an unfinished type. I don't think it should
|
||||
// do that. We have to work around that by setting a global flag (yuck) to prevent us
|
||||
// from responding to the TypeResolveEvent.
|
||||
lock(arrayConstructionLock)
|
||||
{
|
||||
netname += "[]";
|
||||
}
|
||||
Type array;
|
||||
if(elementType.Module is ModuleBuilder)
|
||||
{
|
||||
// FXBUG ModuleBuilder.GetType() is broken (I think), it fires a TypeResolveEvent when
|
||||
// you try to construct an array type from an unfinished type. I don't think it should
|
||||
// do that. We have to work around that by setting a global flag (yuck) to prevent us
|
||||
// from responding to the TypeResolveEvent.
|
||||
lock(arrayConstructionLock)
|
||||
arrayConstructionHack = true;
|
||||
try
|
||||
{
|
||||
arrayConstructionHack = true;
|
||||
try
|
||||
{
|
||||
array = ((ModuleBuilder)elementType.Module).GetType(elementType.FullName + netname);
|
||||
}
|
||||
finally
|
||||
{
|
||||
arrayConstructionHack = false;
|
||||
}
|
||||
array = ((ModuleBuilder)elementType.Module).GetType(netname);
|
||||
}
|
||||
finally
|
||||
{
|
||||
arrayConstructionHack = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
array = elementType.Assembly.GetType(netname, true);
|
||||
}
|
||||
Modifiers modifiers = Modifiers.Final | Modifiers.Abstract;
|
||||
Modifiers reflectiveModifiers = modifiers;
|
||||
modifiers |= elementTypeWrapper.Modifiers & Modifiers.Public;
|
||||
reflectiveModifiers |= elementTypeWrapper.ReflectiveModifiers & Modifiers.AccessMask;
|
||||
wrapper = new ArrayTypeWrapper(array, modifiers, reflectiveModifiers, name, this);
|
||||
lock(types.SyncRoot)
|
||||
{
|
||||
// another thread may have beaten us to it and in that
|
||||
// case we don't want to overwrite the previous one
|
||||
TypeWrapper race = (TypeWrapper)types[name];
|
||||
if(race == null)
|
||||
{
|
||||
types.Add(name, wrapper);
|
||||
if(!(elementType is TypeBuilder) && !wrapper.IsGhostArray)
|
||||
{
|
||||
Debug.Assert(!typeToTypeWrapper.ContainsKey(array), name);
|
||||
typeToTypeWrapper.Add(array, wrapper);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
array = elementType.Assembly.GetType(elementType.FullName + netname, true);
|
||||
}
|
||||
Modifiers modifiers = Modifiers.Final | Modifiers.Abstract;
|
||||
Modifiers reflectiveModifiers = modifiers;
|
||||
modifiers |= elementTypeWrapper.Modifiers & Modifiers.Public;
|
||||
reflectiveModifiers |= elementTypeWrapper.ReflectiveModifiers & Modifiers.AccessMask;
|
||||
wrapper = new ArrayTypeWrapper(array, modifiers, reflectiveModifiers, name, this);
|
||||
Debug.Assert(!types.ContainsKey(name));
|
||||
types.Add(name, wrapper);
|
||||
if(!(elementType is TypeBuilder) && !wrapper.IsGhostArray)
|
||||
{
|
||||
Debug.Assert(!typeToTypeWrapper.ContainsKey(array), name);
|
||||
typeToTypeWrapper.Add(array, wrapper);
|
||||
wrapper = race;
|
||||
}
|
||||
}
|
||||
return wrapper;
|
||||
}
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
internal TypeWrapper DefineClass(ClassFile f, object protectionDomain)
|
||||
|
@ -561,16 +593,33 @@ class ClassLoaderWrapper
|
|||
}
|
||||
// mark the type as "loading in progress", so that we can detect circular dependencies.
|
||||
types.Add(f.Name, null);
|
||||
try
|
||||
}
|
||||
try
|
||||
{
|
||||
TypeWrapper type = new DynamicTypeWrapper(f, this, protectionDomain);
|
||||
lock(types.SyncRoot)
|
||||
{
|
||||
TypeWrapper type = new DynamicTypeWrapper(f, this, protectionDomain);
|
||||
Debug.Assert(!dynamicTypes.ContainsKey(type.TypeAsTBD.FullName));
|
||||
dynamicTypes.Add(type.TypeAsTBD.FullName, type);
|
||||
Debug.Assert(types[f.Name] == null);
|
||||
types[f.Name] = type;
|
||||
return type;
|
||||
// in very extreme conditions another thread may have beaten us to it
|
||||
// and loaded a class with the same name, in that case we'll leak
|
||||
// the defined DynamicTypeWrapper (or rather the Reflection.Emit
|
||||
// defined type).
|
||||
TypeWrapper race = (TypeWrapper)types[f.Name];
|
||||
if(race == null)
|
||||
{
|
||||
Debug.Assert(!dynamicTypes.ContainsKey(type.TypeAsTBD.FullName));
|
||||
dynamicTypes.Add(type.TypeAsTBD.FullName, type);
|
||||
types[f.Name] = type;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = race;
|
||||
}
|
||||
}
|
||||
catch
|
||||
return type;
|
||||
}
|
||||
catch
|
||||
{
|
||||
lock(types.SyncRoot)
|
||||
{
|
||||
if(types[f.Name] == null)
|
||||
{
|
||||
|
@ -578,51 +627,63 @@ class ClassLoaderWrapper
|
|||
// because otherwise we get a ClassCircularityError if we try to load the class again.
|
||||
types.Remove(f.Name);
|
||||
}
|
||||
throw;
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private TypeWrapper DefineNetExpType(string name, string assemblyName)
|
||||
{
|
||||
Debug.Assert(this == GetBootstrapClassLoader());
|
||||
TypeWrapper type;
|
||||
lock(types.SyncRoot)
|
||||
{
|
||||
// we need to check if we've already got it, because other classloaders than the bootstrap classloader may
|
||||
// "define" NetExp types, there is a potential race condition if multiple classloaders try to define the
|
||||
// same type simultaneously.
|
||||
TypeWrapper type = (TypeWrapper)types[name];
|
||||
type = (TypeWrapper)types[name];
|
||||
if(type != null)
|
||||
{
|
||||
return type;
|
||||
}
|
||||
// The sole purpose of the netexp class is to let us load the assembly that the class lives in,
|
||||
// once we've done that, all types in it become visible.
|
||||
Assembly asm;
|
||||
try
|
||||
{
|
||||
asm = Assembly.Load(assemblyName);
|
||||
}
|
||||
catch(Exception x)
|
||||
{
|
||||
throw new NoClassDefFoundError(name + " (" + x.Message + ")");
|
||||
}
|
||||
// pre-compiled Java types can also live in a netexp referenced assembly,
|
||||
// so we have to explicitly check for those
|
||||
// (DotNetTypeWrapper.CreateDotNetTypeWrapper will refuse to return Java types).
|
||||
Type t = GetJavaTypeFromAssembly(asm, name);
|
||||
if(t != null)
|
||||
{
|
||||
return GetWrapperFromBootstrapType(t);
|
||||
}
|
||||
type = DotNetTypeWrapper.CreateDotNetTypeWrapper(name);
|
||||
if(type == null)
|
||||
{
|
||||
throw new NoClassDefFoundError(name + " not found in " + assemblyName);
|
||||
}
|
||||
types.Add(name, type);
|
||||
return type;
|
||||
}
|
||||
// The sole purpose of the netexp class is to let us load the assembly that the class lives in,
|
||||
// once we've done that, all types in it become visible.
|
||||
Assembly asm;
|
||||
try
|
||||
{
|
||||
asm = Assembly.Load(assemblyName);
|
||||
}
|
||||
catch(Exception x)
|
||||
{
|
||||
throw new NoClassDefFoundError(name + " (" + x.Message + ")");
|
||||
}
|
||||
// pre-compiled Java types can also live in a netexp referenced assembly,
|
||||
// so we have to explicitly check for those
|
||||
// (DotNetTypeWrapper.CreateDotNetTypeWrapper will refuse to return Java types).
|
||||
Type t = GetJavaTypeFromAssembly(asm, name);
|
||||
if(t != null)
|
||||
{
|
||||
return GetWrapperFromBootstrapType(t);
|
||||
}
|
||||
type = DotNetTypeWrapper.CreateDotNetTypeWrapper(name);
|
||||
if(type == null)
|
||||
{
|
||||
throw new NoClassDefFoundError(name + " not found in " + assemblyName);
|
||||
}
|
||||
lock(types.SyncRoot)
|
||||
{
|
||||
TypeWrapper race = (TypeWrapper)types[name];
|
||||
if(race == null)
|
||||
{
|
||||
types.Add(name, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
type = race;
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
internal object GetJavaClassLoader()
|
||||
|
|
|
@ -175,9 +175,8 @@ class CountingILGenerator
|
|||
|
||||
internal void Emit(OpCode opcode, Label[] labels)
|
||||
{
|
||||
offset += opcode.Size;
|
||||
offset += 5 + labels.Length * 4;
|
||||
ilgen.Emit(opcode, labels);
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
internal void Emit(OpCode opcode, LocalBuilder local)
|
||||
|
|
|
@ -103,12 +103,12 @@ namespace IKVM.NativeCode.java.lang
|
|||
{
|
||||
if(cause == throwable)
|
||||
{
|
||||
MethodWrapper mw = CoreClasses.java.lang.Throwable.Wrapper.GetMethodWrapper(new MethodDescriptor("<init>", "(Ljava.lang.String;)V"), false);
|
||||
MethodWrapper mw = CoreClasses.java.lang.Throwable.Wrapper.GetMethodWrapper("<init>", "(Ljava.lang.String;)V", false);
|
||||
mw.Invoke(throwable, new object[] { detailMessage }, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
MethodWrapper mw = CoreClasses.java.lang.Throwable.Wrapper.GetMethodWrapper(new MethodDescriptor("<init>", "(Ljava.lang.String;Ljava.lang.Throwable;)V"), false);
|
||||
MethodWrapper mw = CoreClasses.java.lang.Throwable.Wrapper.GetMethodWrapper("<init>", "(Ljava.lang.String;Ljava.lang.Throwable;)V", false);
|
||||
mw.Invoke(throwable, new object[] { detailMessage, cause }, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1317,7 +1317,7 @@ namespace IKVM.Runtime
|
|||
internal static jint ThrowNew(JNIEnv* pEnv, jclass clazz, byte* msg)
|
||||
{
|
||||
TypeWrapper wrapper = IKVM.NativeCode.java.lang.VMClass.getWrapperFromClass(pEnv->UnwrapRef(clazz));
|
||||
MethodWrapper mw = wrapper.GetMethodWrapper(new MethodDescriptor("<init>", "(Ljava.lang.String;)V"), false);
|
||||
MethodWrapper mw = wrapper.GetMethodWrapper("<init>", "(Ljava.lang.String;)V", false);
|
||||
if(mw != null)
|
||||
{
|
||||
jint rc;
|
||||
|
@ -1613,8 +1613,7 @@ namespace IKVM.Runtime
|
|||
{
|
||||
TypeWrapper wrapper = IKVM.NativeCode.java.lang.VMClass.getWrapperFromClass(pEnv->UnwrapRef(clazz));
|
||||
wrapper.Finish();
|
||||
MethodDescriptor md = new MethodDescriptor(StringFromUTF8(name), StringFromUTF8(sig).Replace('/', '.'));
|
||||
MethodWrapper mw = wrapper.GetMethodWrapper(md, true);
|
||||
MethodWrapper mw = wrapper.GetMethodWrapper(StringFromUTF8(name), StringFromUTF8(sig).Replace('/', '.'), true);
|
||||
if(mw != null)
|
||||
{
|
||||
if(mw.IsStatic == isstatic)
|
||||
|
@ -1623,7 +1622,7 @@ namespace IKVM.Runtime
|
|||
return mw.Cookie;
|
||||
}
|
||||
}
|
||||
SetPendingException(pEnv, JavaException.NoSuchMethodError("{0}{1}", md.Name, md.Signature));
|
||||
SetPendingException(pEnv, JavaException.NoSuchMethodError("{0}{1}", StringFromUTF8(name), StringFromUTF8(sig).Replace('/', '.')));
|
||||
}
|
||||
catch(RetargetableJavaException x)
|
||||
{
|
||||
|
@ -2903,7 +2902,7 @@ namespace IKVM.Runtime
|
|||
{
|
||||
try
|
||||
{
|
||||
ByteCodeHelper.monitorenter(pEnv->UnwrapRef(obj));
|
||||
System.Threading.Monitor.Enter(pEnv->UnwrapRef(obj));
|
||||
return JNI_OK;
|
||||
}
|
||||
catch(Exception x)
|
||||
|
|
|
@ -171,7 +171,9 @@ class MemberWrapper
|
|||
|
||||
abstract class MethodWrapper : MemberWrapper
|
||||
{
|
||||
private MethodDescriptor md;
|
||||
internal static readonly MethodWrapper[] EmptyArray = new MethodWrapper[0];
|
||||
private string name;
|
||||
private string sig;
|
||||
private MethodBase method;
|
||||
private string[] declaredExceptions;
|
||||
private TypeWrapper returnTypeWrapper;
|
||||
|
@ -196,8 +198,8 @@ abstract class MethodWrapper : MemberWrapper
|
|||
{
|
||||
private MethodInfo ghostMethod;
|
||||
|
||||
internal GhostMethodWrapper(TypeWrapper declaringType, MethodDescriptor md, MethodBase method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags)
|
||||
: base(declaringType, md, method, returnType, parameterTypes, modifiers, flags)
|
||||
internal GhostMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodBase method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags)
|
||||
: base(declaringType, name, sig, method, returnType, parameterTypes, modifiers, flags)
|
||||
{
|
||||
// make sure we weren't handed the ghostMethod in the wrapper value type
|
||||
Debug.Assert(method == null || method.DeclaringType.IsInterface);
|
||||
|
@ -231,9 +233,9 @@ abstract class MethodWrapper : MemberWrapper
|
|||
}
|
||||
}
|
||||
|
||||
internal static MethodWrapper Create(TypeWrapper declaringType, MethodDescriptor md, MethodBase method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, bool hideFromReflection)
|
||||
internal static MethodWrapper Create(TypeWrapper declaringType, string name, string sig, MethodBase method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, bool hideFromReflection)
|
||||
{
|
||||
Debug.Assert(declaringType != null && md != null && method != null);
|
||||
Debug.Assert(declaringType != null && name!= null && sig != null && method != null);
|
||||
|
||||
if(declaringType.IsGhost)
|
||||
{
|
||||
|
@ -247,23 +249,24 @@ abstract class MethodWrapper : MemberWrapper
|
|||
}
|
||||
method = declaringType.TypeAsBaseType.GetMethod(method.Name, types);
|
||||
}
|
||||
return new GhostMethodWrapper(declaringType, md, method, returnType, parameterTypes, modifiers, hideFromReflection ? MemberFlags.HideFromReflection : MemberFlags.None);
|
||||
return new GhostMethodWrapper(declaringType, name, sig, method, returnType, parameterTypes, modifiers, hideFromReflection ? MemberFlags.HideFromReflection : MemberFlags.None);
|
||||
}
|
||||
else if(method is ConstructorInfo)
|
||||
{
|
||||
return new SmartConstructorMethodWrapper(declaringType, md, (ConstructorInfo)method, parameterTypes, modifiers, hideFromReflection);
|
||||
return new SmartConstructorMethodWrapper(declaringType, name, sig, (ConstructorInfo)method, parameterTypes, modifiers, hideFromReflection);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new SmartCallMethodWrapper(declaringType, md, (MethodInfo)method, returnType, parameterTypes, modifiers, hideFromReflection, OpCodes.Call, method.IsStatic ? OpCodes.Call : OpCodes.Callvirt);
|
||||
return new SmartCallMethodWrapper(declaringType, name, sig, (MethodInfo)method, returnType, parameterTypes, modifiers, hideFromReflection, SimpleOpCode.Call, method.IsStatic ? SimpleOpCode.Call : SimpleOpCode.Callvirt);
|
||||
}
|
||||
}
|
||||
|
||||
internal MethodWrapper(TypeWrapper declaringType, MethodDescriptor md, MethodBase method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags)
|
||||
internal MethodWrapper(TypeWrapper declaringType, string name, string sig, MethodBase method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags)
|
||||
: base(declaringType, modifiers, flags)
|
||||
{
|
||||
Profiler.Count("MethodWrapper");
|
||||
this.md = md;
|
||||
this.name = name;
|
||||
this.sig = sig;
|
||||
this.method = method;
|
||||
Debug.Assert(((returnType == null) == (parameterTypes == null)) || (returnType == PrimitiveTypeWrapper.VOID));
|
||||
this.returnTypeWrapper = returnType;
|
||||
|
@ -296,19 +299,11 @@ abstract class MethodWrapper : MemberWrapper
|
|||
return (MethodWrapper)FromCookieImpl(cookie);
|
||||
}
|
||||
|
||||
internal MethodDescriptor Descriptor
|
||||
{
|
||||
get
|
||||
{
|
||||
return md;
|
||||
}
|
||||
}
|
||||
|
||||
internal string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return md.Name;
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -316,7 +311,7 @@ abstract class MethodWrapper : MemberWrapper
|
|||
{
|
||||
get
|
||||
{
|
||||
return md.Signature;
|
||||
return sig;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,7 +331,6 @@ abstract class MethodWrapper : MemberWrapper
|
|||
{
|
||||
Debug.Assert(returnTypeWrapper == null || returnTypeWrapper == PrimitiveTypeWrapper.VOID);
|
||||
ClassLoaderWrapper loader = this.DeclaringType.GetClassLoader();
|
||||
string sig = md.Signature;
|
||||
// TODO we need to use the actual classCache here
|
||||
System.Collections.Hashtable classCache = new System.Collections.Hashtable();
|
||||
returnTypeWrapper = ClassFile.RetTypeWrapperFromSig(loader, classCache, sig);
|
||||
|
@ -469,7 +463,7 @@ abstract class MethodWrapper : MemberWrapper
|
|||
attribs |= MethodAttributes.Family;
|
||||
}
|
||||
// constructors aren't virtual
|
||||
if(!IsStatic && !IsPrivate && md.Name != "<init>")
|
||||
if(!IsStatic && !IsPrivate && name != "<init>")
|
||||
{
|
||||
attribs |= MethodAttributes.Virtual;
|
||||
}
|
||||
|
@ -552,7 +546,7 @@ abstract class MethodWrapper : MemberWrapper
|
|||
}
|
||||
else
|
||||
{
|
||||
if(md.Name == "<init>")
|
||||
if(name == "<init>")
|
||||
{
|
||||
if(method is MethodInfo)
|
||||
{
|
||||
|
@ -774,7 +768,7 @@ abstract class MethodWrapper : MemberWrapper
|
|||
{
|
||||
TypeWrapper[] argTypes = mw.GetParameters();
|
||||
|
||||
if(!mw.IsStatic && method.IsStatic && mw.md.Name != "<init>")
|
||||
if(!mw.IsStatic && method.IsStatic && mw.Name != "<init>")
|
||||
{
|
||||
// we've been redirected to a static method, so we have to copy the 'obj' into the args
|
||||
args = new object[original_args.Length + 1];
|
||||
|
@ -822,12 +816,27 @@ abstract class MethodWrapper : MemberWrapper
|
|||
return args;
|
||||
}
|
||||
}
|
||||
|
||||
internal static OpCode SimpleOpCodeToOpCode(SimpleOpCode opc)
|
||||
{
|
||||
switch(opc)
|
||||
{
|
||||
case SimpleOpCode.Call:
|
||||
return OpCodes.Call;
|
||||
case SimpleOpCode.Callvirt:
|
||||
return OpCodes.Callvirt;
|
||||
case SimpleOpCode.Newobj:
|
||||
return OpCodes.Newobj;
|
||||
default:
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SmartMethodWrapper : MethodWrapper
|
||||
{
|
||||
internal SmartMethodWrapper(TypeWrapper declaringType, MethodDescriptor md, MethodBase method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags)
|
||||
: base(declaringType, md, method, returnType, parameterTypes, modifiers, flags)
|
||||
internal SmartMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodBase method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags)
|
||||
: base(declaringType, name, sig, method, returnType, parameterTypes, modifiers, flags)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -895,9 +904,7 @@ class SmartMethodWrapper : MethodWrapper
|
|||
NewobjImpl(ilgen);
|
||||
if(DeclaringType.IsNonPrimitiveValueType)
|
||||
{
|
||||
// HACK after constructing a new object, we don't want the custom boxing rule to run
|
||||
// (because that would turn "new IntPtr" into a null reference)
|
||||
ilgen.Emit(OpCodes.Box, DeclaringType.TypeAsTBD);
|
||||
DeclaringType.EmitBox(ilgen);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -907,13 +914,20 @@ class SmartMethodWrapper : MethodWrapper
|
|||
}
|
||||
}
|
||||
|
||||
enum SimpleOpCode : byte
|
||||
{
|
||||
Call,
|
||||
Callvirt,
|
||||
Newobj
|
||||
}
|
||||
|
||||
sealed class SimpleCallMethodWrapper : MethodWrapper
|
||||
{
|
||||
private OpCode call;
|
||||
private OpCode callvirt;
|
||||
private SimpleOpCode call;
|
||||
private SimpleOpCode callvirt;
|
||||
|
||||
internal SimpleCallMethodWrapper(TypeWrapper declaringType, MethodDescriptor md, MethodInfo method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, bool hideFromReflection, OpCode call, OpCode callvirt)
|
||||
: base(declaringType, md, method, returnType, parameterTypes, modifiers, hideFromReflection ? MemberFlags.HideFromReflection : MemberFlags.None)
|
||||
internal SimpleCallMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodInfo method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, bool hideFromReflection, SimpleOpCode call, SimpleOpCode callvirt)
|
||||
: base(declaringType, name, sig, method, returnType, parameterTypes, modifiers, hideFromReflection ? MemberFlags.HideFromReflection : MemberFlags.None)
|
||||
{
|
||||
this.call = call;
|
||||
this.callvirt = callvirt;
|
||||
|
@ -921,27 +935,27 @@ sealed class SimpleCallMethodWrapper : MethodWrapper
|
|||
|
||||
internal override void EmitCall(ILGenerator ilgen)
|
||||
{
|
||||
ilgen.Emit(call, (MethodInfo)GetMethod());
|
||||
ilgen.Emit(SimpleOpCodeToOpCode(call), (MethodInfo)GetMethod());
|
||||
}
|
||||
|
||||
internal override void EmitCallvirt(ILGenerator ilgen)
|
||||
{
|
||||
ilgen.Emit(callvirt, (MethodInfo)GetMethod());
|
||||
ilgen.Emit(SimpleOpCodeToOpCode(callvirt), (MethodInfo)GetMethod());
|
||||
}
|
||||
}
|
||||
|
||||
sealed class SmartCallMethodWrapper : SmartMethodWrapper
|
||||
{
|
||||
private OpCode call;
|
||||
private OpCode callvirt;
|
||||
private SimpleOpCode call;
|
||||
private SimpleOpCode callvirt;
|
||||
|
||||
internal SmartCallMethodWrapper(TypeWrapper declaringType, MethodDescriptor md, MethodInfo method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, bool hideFromReflection, OpCode call, OpCode callvirt)
|
||||
: this(declaringType, md, method, returnType, parameterTypes, modifiers, hideFromReflection ? MemberFlags.HideFromReflection : MemberFlags.None, call, callvirt)
|
||||
internal SmartCallMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodInfo method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, bool hideFromReflection, SimpleOpCode call, SimpleOpCode callvirt)
|
||||
: this(declaringType, name, sig, method, returnType, parameterTypes, modifiers, hideFromReflection ? MemberFlags.HideFromReflection : MemberFlags.None, call, callvirt)
|
||||
{
|
||||
}
|
||||
|
||||
internal SmartCallMethodWrapper(TypeWrapper declaringType, MethodDescriptor md, MethodInfo method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags, OpCode call, OpCode callvirt)
|
||||
: base(declaringType, md, method, returnType, parameterTypes, modifiers, flags)
|
||||
internal SmartCallMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodInfo method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags, SimpleOpCode call, SimpleOpCode callvirt)
|
||||
: base(declaringType, name, sig, method, returnType, parameterTypes, modifiers, flags)
|
||||
{
|
||||
this.call = call;
|
||||
this.callvirt = callvirt;
|
||||
|
@ -949,24 +963,24 @@ sealed class SmartCallMethodWrapper : SmartMethodWrapper
|
|||
|
||||
protected override void CallImpl(ILGenerator ilgen)
|
||||
{
|
||||
ilgen.Emit(call, (MethodInfo)GetMethod());
|
||||
ilgen.Emit(SimpleOpCodeToOpCode(call), (MethodInfo)GetMethod());
|
||||
}
|
||||
|
||||
protected override void CallvirtImpl(ILGenerator ilgen)
|
||||
{
|
||||
ilgen.Emit(callvirt, (MethodInfo)GetMethod());
|
||||
ilgen.Emit(SimpleOpCodeToOpCode(callvirt), (MethodInfo)GetMethod());
|
||||
}
|
||||
}
|
||||
|
||||
sealed class SmartConstructorMethodWrapper : SmartMethodWrapper
|
||||
{
|
||||
internal SmartConstructorMethodWrapper(TypeWrapper declaringType, MethodDescriptor md, ConstructorInfo method, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags)
|
||||
: base(declaringType, md, method, PrimitiveTypeWrapper.VOID, parameterTypes, modifiers, flags)
|
||||
internal SmartConstructorMethodWrapper(TypeWrapper declaringType, string name, string sig, ConstructorInfo method, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags)
|
||||
: base(declaringType, name, sig, method, PrimitiveTypeWrapper.VOID, parameterTypes, modifiers, flags)
|
||||
{
|
||||
}
|
||||
|
||||
internal SmartConstructorMethodWrapper(TypeWrapper declaringType, MethodDescriptor md, ConstructorInfo method, TypeWrapper[] parameterTypes, Modifiers modifiers, bool hideFromReflection)
|
||||
: base(declaringType, md, method, PrimitiveTypeWrapper.VOID, parameterTypes, modifiers, hideFromReflection ? MemberFlags.HideFromReflection : MemberFlags.None)
|
||||
internal SmartConstructorMethodWrapper(TypeWrapper declaringType, string name, string sig, ConstructorInfo method, TypeWrapper[] parameterTypes, Modifiers modifiers, bool hideFromReflection)
|
||||
: base(declaringType, name, sig, method, PrimitiveTypeWrapper.VOID, parameterTypes, modifiers, hideFromReflection ? MemberFlags.HideFromReflection : MemberFlags.None)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1037,6 +1051,7 @@ sealed class ReflectionOnConstant
|
|||
|
||||
abstract class FieldWrapper : MemberWrapper
|
||||
{
|
||||
internal static readonly FieldWrapper[] EmptyArray = new FieldWrapper[0];
|
||||
private string name;
|
||||
private string sig;
|
||||
private FieldInfo field;
|
||||
|
@ -1045,7 +1060,6 @@ abstract class FieldWrapper : MemberWrapper
|
|||
internal FieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, string name, string sig, Modifiers modifiers, FieldInfo field)
|
||||
: base(declaringType, modifiers, false)
|
||||
{
|
||||
Debug.Assert(fieldType != null);
|
||||
Debug.Assert(name != null);
|
||||
Debug.Assert(sig != null);
|
||||
this.name = name;
|
||||
|
@ -1070,12 +1084,12 @@ abstract class FieldWrapper : MemberWrapper
|
|||
Debug.Assert(fieldType != null, this.DeclaringType.Name + "::" + this.name + " (" + this.sig+ ")");
|
||||
}
|
||||
|
||||
// HACK used (thru IKVM.Runtime.Util.GetFieldConstantValue) by ikvmstub to find out if the
|
||||
// NOTE used (thru IKVM.Runtime.Util.GetFieldConstantValue) by ikvmstub to find out if the
|
||||
// field is a constant (and if it is, to get its value)
|
||||
internal object GetConstant()
|
||||
{
|
||||
AssertLinked();
|
||||
// NOTE only pritimives and string can be literals in Java (because the other "primitives" (like uint),
|
||||
// only pritimives and string can be literals in Java (because the other "primitives" (like uint),
|
||||
// are treated as NonPrimitiveValueTypes)
|
||||
if(field != null && (fieldType.IsPrimitive || fieldType == CoreClasses.java.lang.String.Wrapper))
|
||||
{
|
||||
|
@ -1121,6 +1135,14 @@ abstract class FieldWrapper : MemberWrapper
|
|||
}
|
||||
}
|
||||
|
||||
internal string Signature
|
||||
{
|
||||
get
|
||||
{
|
||||
return sig;
|
||||
}
|
||||
}
|
||||
|
||||
internal TypeWrapper FieldTypeWrapper
|
||||
{
|
||||
get
|
||||
|
@ -1157,7 +1179,7 @@ abstract class FieldWrapper : MemberWrapper
|
|||
fieldType = ClassFile.FieldTypeWrapperFromSig(this.DeclaringType.GetClassLoader(), classCache, sig);
|
||||
try
|
||||
{
|
||||
this.DeclaringType.LinkField(this);
|
||||
field = this.DeclaringType.LinkField(this);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -1180,35 +1202,12 @@ abstract class FieldWrapper : MemberWrapper
|
|||
|
||||
internal static FieldWrapper Create(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string name, string sig, Modifiers modifiers)
|
||||
{
|
||||
if(fieldType.IsUnloadable)
|
||||
// volatile long & double field accesses must be made atomic
|
||||
if((modifiers & Modifiers.Volatile) != 0 && (sig == "J" || sig == "D"))
|
||||
{
|
||||
// TODO we might need to emit code to check the type dynamically
|
||||
// TODO the fact that the type is unloadable now, doesn't mean it will be unloadable when a method
|
||||
// that accesses this field is compiled, that means that that method may need to emit a cast
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fieldType.IsGhost)
|
||||
{
|
||||
return new GhostFieldWrapper(declaringType, fieldType, fi, name, sig, modifiers);
|
||||
}
|
||||
if((modifiers & Modifiers.Volatile) != 0)
|
||||
{
|
||||
// long & double field accesses must be made atomic
|
||||
if(fi.FieldType == typeof(long) || fi.FieldType == typeof(double))
|
||||
{
|
||||
return new VolatileLongDoubleFieldWrapper(declaringType, fieldType, fi, name, sig, modifiers);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(declaringType.IsNonPrimitiveValueType)
|
||||
{
|
||||
return new NonPrimitiveValueTypeFieldWrapper(declaringType, fieldType, fi, name, sig, modifiers);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new SimpleFieldWrapper(declaringType, fieldType, fi, name, sig, modifiers);
|
||||
return new VolatileLongDoubleFieldWrapper(declaringType, fieldType, fi, name, sig, modifiers);
|
||||
}
|
||||
return new SimpleFieldWrapper(declaringType, fieldType, fi, name, sig, modifiers);
|
||||
}
|
||||
|
||||
private void LookupField()
|
||||
|
@ -1278,35 +1277,96 @@ sealed class SimpleFieldWrapper : FieldWrapper
|
|||
internal SimpleFieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string name, string sig, Modifiers modifiers)
|
||||
: base(declaringType, fieldType, name, sig, modifiers, fi)
|
||||
{
|
||||
Debug.Assert(!declaringType.IsNonPrimitiveValueType);
|
||||
Debug.Assert(!fieldType.IsGhost);
|
||||
Debug.Assert(fieldType != PrimitiveTypeWrapper.DOUBLE || fieldType != PrimitiveTypeWrapper.LONG || !IsVolatile);
|
||||
Debug.Assert(!(fieldType == PrimitiveTypeWrapper.DOUBLE || fieldType == PrimitiveTypeWrapper.LONG) || !IsVolatile);
|
||||
}
|
||||
|
||||
protected override void EmitGetImpl(ILGenerator ilgen)
|
||||
{
|
||||
if(IsVolatile)
|
||||
if(FieldTypeWrapper.IsGhost)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Volatile);
|
||||
FieldInfo fi = GetField();
|
||||
if(fi.IsStatic)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Ldsflda, fi);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(DeclaringType.IsNonPrimitiveValueType)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
||||
}
|
||||
ilgen.Emit(OpCodes.Ldflda, fi);
|
||||
}
|
||||
if(IsVolatile)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Volatile);
|
||||
}
|
||||
ilgen.Emit(OpCodes.Ldfld, FieldTypeWrapper.GhostRefField);
|
||||
}
|
||||
ilgen.Emit(IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld, GetField());
|
||||
if(!FieldTypeWrapper.IsUnloadable && FieldTypeWrapper.IsNonPrimitiveValueType)
|
||||
else
|
||||
{
|
||||
FieldTypeWrapper.EmitBox(ilgen);
|
||||
if(!IsStatic && DeclaringType.IsNonPrimitiveValueType)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
||||
}
|
||||
if(IsVolatile)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Volatile);
|
||||
}
|
||||
ilgen.Emit(IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld, GetField());
|
||||
if(!FieldTypeWrapper.IsUnloadable && FieldTypeWrapper.IsNonPrimitiveValueType)
|
||||
{
|
||||
FieldTypeWrapper.EmitBox(ilgen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void EmitSetImpl(ILGenerator ilgen)
|
||||
{
|
||||
if(!FieldTypeWrapper.IsUnloadable && FieldTypeWrapper.IsNonPrimitiveValueType)
|
||||
if(FieldTypeWrapper.IsGhost)
|
||||
{
|
||||
FieldTypeWrapper.EmitUnbox(ilgen);
|
||||
FieldInfo fi = GetField();
|
||||
LocalBuilder temp = ilgen.DeclareLocal(FieldTypeWrapper.TypeAsLocalOrStackType);
|
||||
ilgen.Emit(OpCodes.Stloc, temp);
|
||||
if(fi.IsStatic)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Ldsflda, fi);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(DeclaringType.IsNonPrimitiveValueType)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
||||
}
|
||||
ilgen.Emit(OpCodes.Ldflda, fi);
|
||||
}
|
||||
ilgen.Emit(OpCodes.Ldloc, temp);
|
||||
if(IsVolatile)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Volatile);
|
||||
}
|
||||
ilgen.Emit(OpCodes.Stfld, FieldTypeWrapper.GhostRefField);
|
||||
}
|
||||
if(IsVolatile)
|
||||
else
|
||||
{
|
||||
ilgen.Emit(OpCodes.Volatile);
|
||||
if(!IsStatic && DeclaringType.IsNonPrimitiveValueType)
|
||||
{
|
||||
FieldInfo fi = GetField();
|
||||
LocalBuilder temp = ilgen.DeclareLocal(FieldTypeWrapper.TypeAsLocalOrStackType);
|
||||
ilgen.Emit(OpCodes.Stloc, temp);
|
||||
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
||||
ilgen.Emit(OpCodes.Ldloc, temp);
|
||||
}
|
||||
if(!FieldTypeWrapper.IsUnloadable && FieldTypeWrapper.IsNonPrimitiveValueType)
|
||||
{
|
||||
FieldTypeWrapper.EmitUnbox(ilgen);
|
||||
}
|
||||
if(IsVolatile)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Volatile);
|
||||
}
|
||||
ilgen.Emit(IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, GetField());
|
||||
}
|
||||
ilgen.Emit(IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, GetField());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1380,111 +1440,6 @@ sealed class VolatileLongDoubleFieldWrapper : FieldWrapper
|
|||
}
|
||||
}
|
||||
|
||||
sealed class GhostFieldWrapper : FieldWrapper
|
||||
{
|
||||
internal GhostFieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string name, string sig, Modifiers modifiers)
|
||||
: base(declaringType, fieldType, name, sig, modifiers, fi)
|
||||
{
|
||||
Debug.Assert(fieldType.IsGhost);
|
||||
}
|
||||
|
||||
protected override void EmitGetImpl(ILGenerator ilgen)
|
||||
{
|
||||
FieldInfo fi = GetField();
|
||||
if(fi.IsStatic)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Ldsflda, fi);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(DeclaringType.IsNonPrimitiveValueType)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
||||
}
|
||||
ilgen.Emit(OpCodes.Ldflda, fi);
|
||||
}
|
||||
if(IsVolatile)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Volatile);
|
||||
}
|
||||
ilgen.Emit(OpCodes.Ldfld, FieldTypeWrapper.GhostRefField);
|
||||
}
|
||||
|
||||
protected override void EmitSetImpl(ILGenerator ilgen)
|
||||
{
|
||||
FieldInfo fi = GetField();
|
||||
LocalBuilder temp = ilgen.DeclareLocal(FieldTypeWrapper.TypeAsLocalOrStackType);
|
||||
ilgen.Emit(OpCodes.Stloc, temp);
|
||||
if(fi.IsStatic)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Ldsflda, fi);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(DeclaringType.IsNonPrimitiveValueType)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
||||
}
|
||||
ilgen.Emit(OpCodes.Ldflda, fi);
|
||||
}
|
||||
ilgen.Emit(OpCodes.Ldloc, temp);
|
||||
if(IsVolatile)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Volatile);
|
||||
}
|
||||
ilgen.Emit(OpCodes.Stfld, FieldTypeWrapper.GhostRefField);
|
||||
}
|
||||
}
|
||||
|
||||
sealed class NonPrimitiveValueTypeFieldWrapper : FieldWrapper
|
||||
{
|
||||
internal NonPrimitiveValueTypeFieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string name, string sig, Modifiers modifiers)
|
||||
: base(declaringType, fieldType, name, sig, modifiers, fi)
|
||||
{
|
||||
Debug.Assert(declaringType.IsNonPrimitiveValueType);
|
||||
Debug.Assert(!fieldType.IsGhost);
|
||||
Debug.Assert(fieldType != PrimitiveTypeWrapper.DOUBLE || fieldType != PrimitiveTypeWrapper.LONG || !IsVolatile);
|
||||
}
|
||||
|
||||
protected override void EmitGetImpl(ILGenerator ilgen)
|
||||
{
|
||||
if(!IsStatic)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
||||
}
|
||||
if(IsVolatile)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Volatile);
|
||||
}
|
||||
ilgen.Emit(IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld, GetField());
|
||||
if(!FieldTypeWrapper.IsUnloadable && FieldTypeWrapper.IsNonPrimitiveValueType)
|
||||
{
|
||||
FieldTypeWrapper.EmitBox(ilgen);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void EmitSetImpl(ILGenerator ilgen)
|
||||
{
|
||||
if(!IsStatic)
|
||||
{
|
||||
FieldInfo fi = GetField();
|
||||
LocalBuilder temp = ilgen.DeclareLocal(FieldTypeWrapper.TypeAsLocalOrStackType);
|
||||
ilgen.Emit(OpCodes.Stloc, temp);
|
||||
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
||||
ilgen.Emit(OpCodes.Ldloc, temp);
|
||||
}
|
||||
if(!FieldTypeWrapper.IsUnloadable && FieldTypeWrapper.IsNonPrimitiveValueType)
|
||||
{
|
||||
FieldTypeWrapper.EmitUnbox(ilgen);
|
||||
}
|
||||
if(IsVolatile)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Volatile);
|
||||
}
|
||||
ilgen.Emit(IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, GetField());
|
||||
}
|
||||
}
|
||||
|
||||
sealed class GetterFieldWrapper : FieldWrapper
|
||||
{
|
||||
private MethodInfo getter;
|
||||
|
@ -1498,6 +1453,11 @@ sealed class GetterFieldWrapper : FieldWrapper
|
|||
this.getter = getter;
|
||||
}
|
||||
|
||||
internal void SetGetter(MethodInfo getter)
|
||||
{
|
||||
this.getter = getter;
|
||||
}
|
||||
|
||||
protected override void EmitGetImpl(ILGenerator ilgen)
|
||||
{
|
||||
if(IsStatic)
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -792,6 +792,11 @@ namespace IKVM.NativeCode.java
|
|||
|
||||
public static object getClassLoaderFromType(Type type)
|
||||
{
|
||||
// global methods have no type
|
||||
if(type == null)
|
||||
{
|
||||
return JVM.Library.getSystemClassLoader();
|
||||
}
|
||||
return ClassLoaderWrapper.GetWrapperFromType(type).GetClassLoader().GetJavaClassLoader();
|
||||
}
|
||||
|
||||
|
|
|
@ -74,11 +74,11 @@ class Compiler
|
|||
|
||||
static Compiler()
|
||||
{
|
||||
getTypeFromHandleMethod = typeof(Type).GetMethod("GetTypeFromHandle");
|
||||
getTypeFromHandleMethod = typeof(Type).GetMethod("GetTypeFromHandle", BindingFlags.Static | BindingFlags.Public, null, new Type[] { typeof(RuntimeTypeHandle) }, null);
|
||||
getClassFromTypeHandleMethod = typeof(ByteCodeHelper).GetMethod("GetClassFromTypeHandle");
|
||||
multiANewArrayMethod = typeof(ByteCodeHelper).GetMethod("multianewarray");
|
||||
monitorEnterMethod = typeof(ByteCodeHelper).GetMethod("monitorenter");
|
||||
monitorExitMethod = typeof(System.Threading.Monitor).GetMethod("Exit");
|
||||
monitorEnterMethod = typeof(System.Threading.Monitor).GetMethod("Enter", BindingFlags.Static | BindingFlags.Public, null, new Type[] { typeof(object) }, null);
|
||||
monitorExitMethod = typeof(System.Threading.Monitor).GetMethod("Exit", BindingFlags.Static | BindingFlags.Public, null, new Type[] { typeof(object) }, null);
|
||||
objectToStringMethod = typeof(object).GetMethod("ToString");
|
||||
f2iMethod = typeof(ByteCodeHelper).GetMethod("f2i");
|
||||
d2iMethod = typeof(ByteCodeHelper).GetMethod("d2i");
|
||||
|
@ -90,11 +90,11 @@ class Compiler
|
|||
arraycopy_primitive_1Method = typeof(ByteCodeHelper).GetMethod("arraycopy_primitive_1");
|
||||
arraycopyMethod = typeof(ByteCodeHelper).GetMethod("arraycopy");
|
||||
TypeWrapper exceptionHelper = ClassLoaderWrapper.LoadClassCritical("java.lang.ExceptionHelper");
|
||||
mapExceptionMethod = exceptionHelper.GetMethodWrapper(new MethodDescriptor("MapException", "(Ljava.lang.Throwable;Lcli.System.Type;)Ljava.lang.Throwable;"), false);
|
||||
mapExceptionMethod = exceptionHelper.GetMethodWrapper("MapException", "(Ljava.lang.Throwable;Lcli.System.Type;)Ljava.lang.Throwable;", false);
|
||||
mapExceptionMethod.Link();
|
||||
mapExceptionFastMethod = exceptionHelper.GetMethodWrapper(new MethodDescriptor("MapExceptionFast", "(Ljava.lang.Throwable;)Ljava.lang.Throwable;"), false);
|
||||
mapExceptionFastMethod = exceptionHelper.GetMethodWrapper("MapExceptionFast", "(Ljava.lang.Throwable;)Ljava.lang.Throwable;", false);
|
||||
mapExceptionFastMethod.Link();
|
||||
fillInStackTraceMethod = exceptionHelper.GetMethodWrapper(new MethodDescriptor("fillInStackTrace", "(Ljava.lang.Throwable;)Ljava.lang.Throwable;"), false);
|
||||
fillInStackTraceMethod = exceptionHelper.GetMethodWrapper("fillInStackTrace", "(Ljava.lang.Throwable;)Ljava.lang.Throwable;", false);
|
||||
fillInStackTraceMethod.Link();
|
||||
java_lang_Throwable = CoreClasses.java.lang.Throwable.Wrapper;
|
||||
java_lang_Object = CoreClasses.java.lang.Object.Wrapper;
|
||||
|
@ -476,7 +476,7 @@ class Compiler
|
|||
{
|
||||
Tracer.Error(Tracer.Compiler, "{0}: {1}\n\tat {2}.{3}{4}", type.Name, Message, classFile.Name, m.Name, m.Signature);
|
||||
ilgen.Emit(OpCodes.Ldstr, Message);
|
||||
MethodWrapper method = type.GetMethodWrapper(new MethodDescriptor("<init>", "(Ljava.lang.String;)V"), false);
|
||||
MethodWrapper method = type.GetMethodWrapper("<init>", "(Ljava.lang.String;)V", false);
|
||||
method.Link();
|
||||
method.EmitNewobj(ilgen);
|
||||
ilgen.Emit(OpCodes.Throw);
|
||||
|
@ -756,24 +756,17 @@ class Compiler
|
|||
Profiler.Enter("Compile");
|
||||
try
|
||||
{
|
||||
if(m.IsSynchronized)
|
||||
if(m.IsSynchronized && m.IsStatic)
|
||||
{
|
||||
ArrayList exits = new ArrayList();
|
||||
if(m.IsStatic)
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Ldsfld, clazz.ClassObjectField);
|
||||
Label label = ilGenerator.DefineLabel();
|
||||
ilGenerator.Emit(OpCodes.Brtrue_S, label);
|
||||
ilGenerator.Emit(OpCodes.Ldtoken, clazz.TypeAsTBD);
|
||||
ilGenerator.Emit(OpCodes.Call, getClassFromTypeHandleMethod);
|
||||
ilGenerator.Emit(OpCodes.Stsfld, clazz.ClassObjectField);
|
||||
ilGenerator.MarkLabel(label);
|
||||
ilGenerator.Emit(OpCodes.Ldsfld, clazz.ClassObjectField);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Ldarg_0);
|
||||
}
|
||||
ilGenerator.Emit(OpCodes.Ldsfld, clazz.ClassObjectField);
|
||||
Label label = ilGenerator.DefineLabel();
|
||||
ilGenerator.Emit(OpCodes.Brtrue_S, label);
|
||||
ilGenerator.Emit(OpCodes.Ldtoken, clazz.TypeAsTBD);
|
||||
ilGenerator.Emit(OpCodes.Call, getClassFromTypeHandleMethod);
|
||||
ilGenerator.Emit(OpCodes.Stsfld, clazz.ClassObjectField);
|
||||
ilGenerator.MarkLabel(label);
|
||||
ilGenerator.Emit(OpCodes.Ldsfld, clazz.ClassObjectField);
|
||||
ilGenerator.Emit(OpCodes.Dup);
|
||||
LocalBuilder monitor = ilGenerator.DeclareLocal(typeof(object));
|
||||
ilGenerator.Emit(OpCodes.Stloc, monitor);
|
||||
|
@ -1503,7 +1496,7 @@ class Compiler
|
|||
method.EmitNewobj(ilGenerator);
|
||||
if(!thisType.IsUnloadable && thisType.IsSubTypeOf(java_lang_Throwable))
|
||||
{
|
||||
// HACK if the next instruction isn't an athrow, we need to
|
||||
// if the next instruction isn't an athrow, we need to
|
||||
// call fillInStackTrace, because the object might be used
|
||||
// to print out a stack trace without ever being thrown
|
||||
if(code[i + 1].NormalizedOpCode != NormalizedByteCode.__athrow)
|
||||
|
@ -1530,8 +1523,9 @@ class Compiler
|
|||
// instruction)
|
||||
if(stacktype == VerifierTypeWrapper.Null)
|
||||
{
|
||||
// TODO handle null stack entries
|
||||
throw new NotImplementedException();
|
||||
// NOTE we abuse the newobj local as a cookie to signal null!
|
||||
tempstack[j] = newobj;
|
||||
ilGenerator.Emit(OpCodes.Pop);
|
||||
}
|
||||
else if(!VerifierTypeWrapper.IsNew(stacktype))
|
||||
{
|
||||
|
@ -1549,7 +1543,15 @@ class Compiler
|
|||
}
|
||||
else if(tempstack[j] != null)
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Ldloc, tempstack[j]);
|
||||
// NOTE we abuse the newobj local as a cookie to signal null!
|
||||
if(tempstack[j] == newobj)
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Ldnull);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Ldloc, tempstack[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
LocalVar[] locals = ma.GetLocalVarsForInvokeSpecial(i);
|
||||
|
@ -2514,19 +2516,40 @@ class Compiler
|
|||
ilGenerator.Emit(OpCodes.Throw);
|
||||
break;
|
||||
case NormalizedByteCode.__lookupswitch:
|
||||
// TODO use OpCodes.Switch
|
||||
for(int j = 0; j < instr.SwitchEntryCount; j++)
|
||||
// for tableswitch we can use the CIL switch opcode, which is more
|
||||
// compact (and could theoretically be faster)
|
||||
if(instr.OpCode == ByteCode.__tableswitch)
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Dup);
|
||||
EmitLdc_I4(instr.GetSwitchValue(j));
|
||||
Label label = ilGenerator.DefineLabel();
|
||||
ilGenerator.Emit(OpCodes.Bne_Un_S, label);
|
||||
ilGenerator.Emit(OpCodes.Pop);
|
||||
ilGenerator.Emit(OpCodes.Br, block.GetLabel(instr.PC + instr.GetSwitchTargetOffset(j)));
|
||||
ilGenerator.MarkLabel(label);
|
||||
// note that a tableswitch always has at least one entry
|
||||
// (otherwise it would have failed verification)
|
||||
Label[] labels = new Label[instr.SwitchEntryCount];
|
||||
for(int j = 0; j < labels.Length; j++)
|
||||
{
|
||||
labels[j] = block.GetLabel(instr.PC + instr.GetSwitchTargetOffset(j));
|
||||
}
|
||||
if(instr.GetSwitchValue(0) != 0)
|
||||
{
|
||||
EmitLdc_I4(instr.GetSwitchValue(0));
|
||||
ilGenerator.Emit(OpCodes.Sub);
|
||||
}
|
||||
ilGenerator.Emit(OpCodes.Switch, labels);
|
||||
ilGenerator.Emit(OpCodes.Br, block.GetLabel(instr.PC + instr.DefaultOffset));
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int j = 0; j < instr.SwitchEntryCount; j++)
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Dup);
|
||||
EmitLdc_I4(instr.GetSwitchValue(j));
|
||||
Label label = ilGenerator.DefineLabel();
|
||||
ilGenerator.Emit(OpCodes.Bne_Un_S, label);
|
||||
ilGenerator.Emit(OpCodes.Pop);
|
||||
ilGenerator.Emit(OpCodes.Br, block.GetLabel(instr.PC + instr.GetSwitchTargetOffset(j)));
|
||||
ilGenerator.MarkLabel(label);
|
||||
}
|
||||
ilGenerator.Emit(OpCodes.Pop);
|
||||
ilGenerator.Emit(OpCodes.Br, block.GetLabel(instr.PC + instr.DefaultOffset));
|
||||
}
|
||||
ilGenerator.Emit(OpCodes.Pop);
|
||||
ilGenerator.Emit(OpCodes.Br, block.GetLabel(instr.PC + instr.DefaultOffset));
|
||||
break;
|
||||
case NormalizedByteCode.__iinc:
|
||||
LoadLocal(instr);
|
||||
|
@ -2966,7 +2989,7 @@ class Compiler
|
|||
private ClassFile.ConstantPoolItemMI cpi;
|
||||
|
||||
internal DynamicMethodWrapper(ClassLoaderWrapper classLoader, TypeWrapper wrapper, ClassFile.ConstantPoolItemMI cpi)
|
||||
: base(wrapper, null, null, null, null, Modifiers.Public, MemberFlags.None)
|
||||
: base(wrapper, null, null, null, null, null, Modifiers.Public, MemberFlags.None)
|
||||
{
|
||||
this.classLoader = classLoader;
|
||||
this.wrapper = wrapper;
|
||||
|
@ -3054,13 +3077,13 @@ class Compiler
|
|||
}
|
||||
else
|
||||
{
|
||||
// HACK special case for incorrect invocation of Object.clone(), because this could mean
|
||||
// NOTE special case for incorrect invocation of Object.clone(), because this could mean
|
||||
// we're calling clone() on an array
|
||||
// (bug in javac, see http://developer.java.sun.com/developer/bugParade/bugs/4329886.html)
|
||||
if(wrapper == java_lang_Object && thisType.IsArray && cpi.Name == "clone")
|
||||
{
|
||||
// NOTE since thisType is an array, we can be sure that the method is already linked
|
||||
method = thisType.GetMethodWrapper(new MethodDescriptor(cpi.Name, cpi.Signature), false);
|
||||
method = thisType.GetMethodWrapper(cpi.Name, cpi.Signature, false);
|
||||
if(method != null && method.IsPublic)
|
||||
{
|
||||
return method;
|
||||
|
|
|
@ -111,7 +111,7 @@ namespace IKVM.Internal.MapXml
|
|||
if(Class != null)
|
||||
{
|
||||
Debug.Assert(Sig != null);
|
||||
MethodWrapper method = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(Class).GetMethodWrapper(new MethodDescriptor(Name, Sig), false);
|
||||
MethodWrapper method = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(Class).GetMethodWrapper(Name, Sig, false);
|
||||
if(method == null)
|
||||
{
|
||||
throw new InvalidOperationException("method not found: " + Class + "." + Name + Sig);
|
||||
|
@ -759,6 +759,14 @@ namespace IKVM.Internal.MapXml
|
|||
}
|
||||
}
|
||||
|
||||
[XmlType("conv_i1")]
|
||||
public sealed class Conv_I1 : Simple
|
||||
{
|
||||
public Conv_I1() : base(OpCodes.Conv_I1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[XmlType("conv_u1")]
|
||||
public sealed class Conv_U1 : Simple
|
||||
{
|
||||
|
@ -767,6 +775,14 @@ namespace IKVM.Internal.MapXml
|
|||
}
|
||||
}
|
||||
|
||||
[XmlType("conv_i2")]
|
||||
public sealed class Conv_I2 : Simple
|
||||
{
|
||||
public Conv_I2() : base(OpCodes.Conv_I2)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[XmlType("conv_u2")]
|
||||
public sealed class Conv_U2 : Simple
|
||||
{
|
||||
|
@ -775,6 +791,14 @@ namespace IKVM.Internal.MapXml
|
|||
}
|
||||
}
|
||||
|
||||
[XmlType("conv_i4")]
|
||||
public sealed class Conv_I4 : Simple
|
||||
{
|
||||
public Conv_I4() : base(OpCodes.Conv_I4)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[XmlType("conv_u4")]
|
||||
public sealed class Conv_U4 : Simple
|
||||
{
|
||||
|
@ -783,6 +807,14 @@ namespace IKVM.Internal.MapXml
|
|||
}
|
||||
}
|
||||
|
||||
[XmlType("conv_i8")]
|
||||
public sealed class Conv_I8 : Simple
|
||||
{
|
||||
public Conv_I8() : base(OpCodes.Conv_I8)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[XmlType("conv_u8")]
|
||||
public sealed class Conv_U8 : Simple
|
||||
{
|
||||
|
@ -913,9 +945,13 @@ namespace IKVM.Internal.MapXml
|
|||
[XmlElement(typeof(Ldc_I4_1))]
|
||||
[XmlElement(typeof(Ldc_I4_M1))]
|
||||
[XmlElement(typeof(Conv_I))]
|
||||
[XmlElement(typeof(Conv_I1))]
|
||||
[XmlElement(typeof(Conv_U1))]
|
||||
[XmlElement(typeof(Conv_I2))]
|
||||
[XmlElement(typeof(Conv_U2))]
|
||||
[XmlElement(typeof(Conv_I4))]
|
||||
[XmlElement(typeof(Conv_U4))]
|
||||
[XmlElement(typeof(Conv_I8))]
|
||||
[XmlElement(typeof(Conv_U8))]
|
||||
[XmlElement(typeof(Ldlen))]
|
||||
[XmlElement(typeof(ExceptionBlock))]
|
||||
|
|
|
@ -1018,14 +1018,9 @@ class VerifierTypeWrapper : TypeWrapper
|
|||
this.underlyingType = underlyingType;
|
||||
}
|
||||
|
||||
protected override FieldWrapper GetFieldImpl(string fieldName, string fieldSig)
|
||||
protected override void LazyPublishMembers()
|
||||
{
|
||||
throw new InvalidOperationException("GetFieldImpl called on " + this);
|
||||
}
|
||||
|
||||
internal override MethodWrapper GetMethodWrapper(MethodDescriptor md, bool inherit)
|
||||
{
|
||||
throw new InvalidOperationException("GetMethodWrapper called on " + this);
|
||||
throw new InvalidOperationException("LazyPublishMembers called on " + this);
|
||||
}
|
||||
|
||||
internal override Type TypeAsTBD
|
||||
|
|
|
@ -547,13 +547,13 @@ namespace IKVM.Internal
|
|||
ilgen.Emit(OpCodes.Stloc, exceptionLocal);
|
||||
TypeWrapper threadTypeWrapper = ClassLoaderWrapper.LoadClassCritical("java.lang.Thread");
|
||||
LocalBuilder threadLocal = ilgen.DeclareLocal(threadTypeWrapper.TypeAsLocalOrStackType);
|
||||
threadTypeWrapper.GetMethodWrapper(new MethodDescriptor("currentThread", "()Ljava.lang.Thread;"), false).EmitCall(ilgen);
|
||||
threadTypeWrapper.GetMethodWrapper("currentThread", "()Ljava.lang.Thread;", false).EmitCall(ilgen);
|
||||
ilgen.Emit(OpCodes.Stloc, threadLocal);
|
||||
ilgen.Emit(OpCodes.Ldloc, threadLocal);
|
||||
threadTypeWrapper.GetMethodWrapper(new MethodDescriptor("getThreadGroup", "()Ljava.lang.ThreadGroup;"), false).EmitCallvirt(ilgen);
|
||||
threadTypeWrapper.GetMethodWrapper("getThreadGroup", "()Ljava.lang.ThreadGroup;", false).EmitCallvirt(ilgen);
|
||||
ilgen.Emit(OpCodes.Ldloc, threadLocal);
|
||||
ilgen.Emit(OpCodes.Ldloc, exceptionLocal);
|
||||
ClassLoaderWrapper.LoadClassCritical("java.lang.ThreadGroup").GetMethodWrapper(new MethodDescriptor("uncaughtException", "(Ljava.lang.Thread;Ljava.lang.Throwable;)V"), false).EmitCall(ilgen);
|
||||
ClassLoaderWrapper.LoadClassCritical("java.lang.ThreadGroup").GetMethodWrapper("uncaughtException", "(Ljava.lang.Thread;Ljava.lang.Throwable;)V", false).EmitCall(ilgen);
|
||||
ilgen.Emit(OpCodes.Ldc_I4_1);
|
||||
ilgen.Emit(OpCodes.Stloc, rc);
|
||||
ilgen.BeginFinallyBlock();
|
||||
|
@ -752,11 +752,13 @@ namespace IKVM.Internal
|
|||
ilgen.Emit(OpCodes.Throw);
|
||||
}
|
||||
|
||||
ArrayList methods = new ArrayList();
|
||||
|
||||
if(c.Constructors != null)
|
||||
{
|
||||
foreach(IKVM.Internal.MapXml.Constructor m in c.Constructors)
|
||||
{
|
||||
AddMethod(new RemappedConstructorWrapper(this, m));
|
||||
methods.Add(new RemappedConstructorWrapper(this, m));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -765,15 +767,17 @@ namespace IKVM.Internal
|
|||
// TODO we should also add methods from our super classes (e.g. Throwable should have Object's methods)
|
||||
foreach(IKVM.Internal.MapXml.Method m in c.Methods)
|
||||
{
|
||||
AddMethod(new RemappedMethodWrapper(this, m, map));
|
||||
methods.Add(new RemappedMethodWrapper(this, m, map));
|
||||
}
|
||||
}
|
||||
|
||||
SetMethods((MethodWrapper[])methods.ToArray(typeof(MethodWrapper)));
|
||||
}
|
||||
|
||||
abstract class RemappedMethodBaseWrapper : MethodWrapper
|
||||
{
|
||||
internal RemappedMethodBaseWrapper(RemapperTypeWrapper typeWrapper, MethodDescriptor md, Modifiers modifiers)
|
||||
: base(typeWrapper, md, null, null, null, modifiers, MemberFlags.None)
|
||||
internal RemappedMethodBaseWrapper(RemapperTypeWrapper typeWrapper, string name, string sig, Modifiers modifiers)
|
||||
: base(typeWrapper, name, sig, null, null, null, modifiers, MemberFlags.None)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -801,7 +805,7 @@ namespace IKVM.Internal
|
|||
private MethodBuilder mbHelper;
|
||||
|
||||
internal RemappedConstructorWrapper(RemapperTypeWrapper typeWrapper, IKVM.Internal.MapXml.Constructor m)
|
||||
: base(typeWrapper, new MethodDescriptor("<init>", m.Sig), (Modifiers)m.Modifiers)
|
||||
: base(typeWrapper, "<init>", m.Sig, (Modifiers)m.Modifiers)
|
||||
{
|
||||
this.m = m;
|
||||
}
|
||||
|
@ -826,7 +830,6 @@ namespace IKVM.Internal
|
|||
internal override MethodBase DoLink()
|
||||
{
|
||||
MethodAttributes attr = MapMethodAccessModifiers(m.Modifiers);
|
||||
MethodDescriptor md = new MethodDescriptor("<init>", m.Sig);
|
||||
RemapperTypeWrapper typeWrapper = (RemapperTypeWrapper)DeclaringType;
|
||||
Type[] paramTypes = typeWrapper.GetClassLoader().ArgTypeListFromSig(m.Sig);
|
||||
|
||||
|
@ -907,7 +910,6 @@ namespace IKVM.Internal
|
|||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
MethodDescriptor redir = new MethodDescriptor(m.redirect.Name, m.redirect.Sig);
|
||||
Type[] redirParamTypes = ClassLoaderWrapper.GetBootstrapClassLoader().ArgTypeListFromSig(m.redirect.Sig);
|
||||
for(int i = 0; i < redirParamTypes.Length; i++)
|
||||
{
|
||||
|
@ -927,7 +929,7 @@ namespace IKVM.Internal
|
|||
else
|
||||
{
|
||||
TypeWrapper tw = ClassLoaderWrapper.LoadClassCritical(m.redirect.Class);
|
||||
MethodWrapper mw = tw.GetMethodWrapper(redir, false);
|
||||
MethodWrapper mw = tw.GetMethodWrapper(m.redirect.Name, m.redirect.Sig, false);
|
||||
if(mw == null)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
|
@ -975,7 +977,7 @@ namespace IKVM.Internal
|
|||
private ArrayList overriders = new ArrayList();
|
||||
|
||||
internal RemappedMethodWrapper(RemapperTypeWrapper typeWrapper, IKVM.Internal.MapXml.Method m, IKVM.Internal.MapXml.Root map)
|
||||
: base(typeWrapper, new MethodDescriptor(m.Name, m.Sig), (Modifiers)m.Modifiers)
|
||||
: base(typeWrapper, m.Name, m.Sig, (Modifiers)m.Modifiers)
|
||||
{
|
||||
this.m = m;
|
||||
this.map = map;
|
||||
|
@ -1001,7 +1003,6 @@ namespace IKVM.Internal
|
|||
internal override MethodBase DoLink()
|
||||
{
|
||||
RemapperTypeWrapper typeWrapper = (RemapperTypeWrapper)DeclaringType;
|
||||
MethodDescriptor md = new MethodDescriptor(m.Name, m.Sig);
|
||||
|
||||
if(typeWrapper.IsInterface)
|
||||
{
|
||||
|
@ -1069,7 +1070,7 @@ namespace IKVM.Internal
|
|||
{
|
||||
ilgen.Emit(OpCodes.Ldarg, (short)i);
|
||||
}
|
||||
MethodWrapper mw = tw.GetMethodWrapper(md, false);
|
||||
MethodWrapper mw = tw.GetMethodWrapper(m.Name, m.Sig, false);
|
||||
mw.Link();
|
||||
mw.EmitCallvirt(ilgen);
|
||||
ilgen.Emit(OpCodes.Ret);
|
||||
|
@ -1097,7 +1098,7 @@ namespace IKVM.Internal
|
|||
// skip instance methods in sealed types, but we do need to add them to the overriders
|
||||
if(typeWrapper.BaseTypeWrapper != null && (m.Modifiers & IKVM.Internal.MapXml.MapModifiers.Private) == 0)
|
||||
{
|
||||
RemappedMethodWrapper baseMethod = typeWrapper.BaseTypeWrapper.GetMethodWrapper(md, true) as RemappedMethodWrapper;
|
||||
RemappedMethodWrapper baseMethod = typeWrapper.BaseTypeWrapper.GetMethodWrapper(m.Name, m.Sig, true) as RemappedMethodWrapper;
|
||||
if(baseMethod != null &&
|
||||
!baseMethod.IsFinal &&
|
||||
!baseMethod.IsPrivate &&
|
||||
|
@ -1123,7 +1124,7 @@ namespace IKVM.Internal
|
|||
attr |= MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.CheckAccessOnOverride;
|
||||
if(typeWrapper.BaseTypeWrapper != null)
|
||||
{
|
||||
RemappedMethodWrapper baseMethod = typeWrapper.BaseTypeWrapper.GetMethodWrapper(md, true) as RemappedMethodWrapper;
|
||||
RemappedMethodWrapper baseMethod = typeWrapper.BaseTypeWrapper.GetMethodWrapper(m.Name, m.Sig, true) as RemappedMethodWrapper;
|
||||
if(baseMethod != null)
|
||||
{
|
||||
baseMethod.overriders.Add(typeWrapper);
|
||||
|
@ -1183,7 +1184,6 @@ namespace IKVM.Internal
|
|||
internal override void Finish()
|
||||
{
|
||||
// TODO we should insert method tracing (if enabled)
|
||||
MethodDescriptor md = this.Descriptor;
|
||||
Type[] paramTypes = this.GetParametersForDefineMethod();
|
||||
|
||||
MethodBuilder mbCore = GetMethod() as MethodBuilder;
|
||||
|
@ -1286,7 +1286,7 @@ namespace IKVM.Internal
|
|||
}
|
||||
foreach(RemapperTypeWrapper overrider in overriders)
|
||||
{
|
||||
RemappedMethodWrapper mw = (RemappedMethodWrapper)overrider.GetMethodWrapper(md, false);
|
||||
RemappedMethodWrapper mw = (RemappedMethodWrapper)overrider.GetMethodWrapper(Name, Signature, false);
|
||||
if(mw.m.redirect == null && mw.m.body == null && mw.m.alternateBody == null)
|
||||
{
|
||||
// the overridden method doesn't actually do anything special (that means it will end
|
||||
|
@ -1351,7 +1351,7 @@ namespace IKVM.Internal
|
|||
}
|
||||
else
|
||||
{
|
||||
RemappedMethodWrapper baseMethod = DeclaringType.BaseTypeWrapper.GetMethodWrapper(md, true) as RemappedMethodWrapper;
|
||||
RemappedMethodWrapper baseMethod = DeclaringType.BaseTypeWrapper.GetMethodWrapper(Name, Signature, true) as RemappedMethodWrapper;
|
||||
if(baseMethod == null || baseMethod.m.@override == null)
|
||||
{
|
||||
throw new InvalidOperationException(DeclaringType.Name + "." + m.Name + m.Sig);
|
||||
|
@ -1415,7 +1415,6 @@ namespace IKVM.Internal
|
|||
redirSig = m.Sig;
|
||||
}
|
||||
ClassLoaderWrapper classLoader = ClassLoaderWrapper.GetBootstrapClassLoader();
|
||||
MethodDescriptor redir = new MethodDescriptor(redirName, redirSig);
|
||||
// HACK if the class name contains a comma, we assume it is a .NET type
|
||||
if(m.redirect.Class == null || m.redirect.Class.IndexOf(',') >= 0)
|
||||
{
|
||||
|
@ -1432,10 +1431,10 @@ namespace IKVM.Internal
|
|||
else
|
||||
{
|
||||
TypeWrapper tw = ClassLoaderWrapper.LoadClassCritical(m.redirect.Class);
|
||||
MethodWrapper mw = tw.GetMethodWrapper(redir, false);
|
||||
MethodWrapper mw = tw.GetMethodWrapper(redirName, redirSig, false);
|
||||
if(mw == null)
|
||||
{
|
||||
throw new InvalidOperationException("Missing redirect method: " + tw.Name + "." + redir.Name + redir.Signature);
|
||||
throw new InvalidOperationException("Missing redirect method: " + tw.Name + "." + redirName + redirSig);
|
||||
}
|
||||
mw.Link();
|
||||
mw.EmitCall(ilgen);
|
||||
|
@ -1475,6 +1474,8 @@ namespace IKVM.Internal
|
|||
interfaceWrappers = TypeWrapper.EmptyArray;
|
||||
}
|
||||
|
||||
ArrayList fields = new ArrayList();
|
||||
|
||||
// TODO fields should be moved to the RemapperTypeWrapper constructor as well
|
||||
if(c.Fields != null)
|
||||
{
|
||||
|
@ -1483,8 +1484,7 @@ namespace IKVM.Internal
|
|||
if(f.redirect != null)
|
||||
{
|
||||
TypeWrapper tw = ClassLoaderWrapper.LoadClassCritical(f.redirect.Class);
|
||||
MethodDescriptor redir = new MethodDescriptor(f.redirect.Name, f.redirect.Sig);
|
||||
MethodWrapper method = tw.GetMethodWrapper(redir, false);
|
||||
MethodWrapper method = tw.GetMethodWrapper(f.redirect.Name, f.redirect.Sig, false);
|
||||
if(method == null || !method.IsStatic)
|
||||
{
|
||||
// TODO better error handling
|
||||
|
@ -1492,7 +1492,7 @@ namespace IKVM.Internal
|
|||
}
|
||||
// TODO emit an static helper method that enables access to the field at runtime
|
||||
method.Link();
|
||||
AddField(new GetterFieldWrapper(this, GetClassLoader().FieldTypeWrapperFromSig(f.Sig), null, f.Name, f.Sig, (Modifiers)f.Modifiers, (MethodInfo)method.GetMethod()));
|
||||
fields.Add(new GetterFieldWrapper(this, GetClassLoader().FieldTypeWrapperFromSig(f.Sig), null, f.Name, f.Sig, (Modifiers)f.Modifiers, (MethodInfo)method.GetMethod()));
|
||||
}
|
||||
else if((f.Modifiers & IKVM.Internal.MapXml.MapModifiers.Static) != 0)
|
||||
{
|
||||
|
@ -1519,11 +1519,11 @@ namespace IKVM.Internal
|
|||
throw new NotImplementedException("remapped constant field of type: " + f.Sig);
|
||||
}
|
||||
fb.SetConstant(constant);
|
||||
AddField(new ConstantFieldWrapper(this, GetClassLoader().FieldTypeWrapperFromSig(f.Sig), f.Name, f.Sig, (Modifiers)f.Modifiers, fb, constant));
|
||||
fields.Add(new ConstantFieldWrapper(this, GetClassLoader().FieldTypeWrapperFromSig(f.Sig), f.Name, f.Sig, (Modifiers)f.Modifiers, fb, constant));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddField(FieldWrapper.Create(this, GetClassLoader().FieldTypeWrapperFromSig(f.Sig), fb, f.Name, f.Sig, (Modifiers)f.Modifiers));
|
||||
fields.Add(FieldWrapper.Create(this, GetClassLoader().FieldTypeWrapperFromSig(f.Sig), fb, f.Name, f.Sig, (Modifiers)f.Modifiers));
|
||||
}
|
||||
if(f.Deprecated)
|
||||
{
|
||||
|
@ -1538,6 +1538,7 @@ namespace IKVM.Internal
|
|||
}
|
||||
}
|
||||
}
|
||||
SetFields((FieldWrapper[])fields.ToArray(typeof(FieldWrapper)));
|
||||
}
|
||||
|
||||
internal void Process3rdPass()
|
||||
|
@ -1754,12 +1755,6 @@ namespace IKVM.Internal
|
|||
{
|
||||
}
|
||||
|
||||
protected override FieldWrapper GetFieldImpl(string fieldName, string fieldSig)
|
||||
{
|
||||
// we don't resolve fields lazily
|
||||
return null;
|
||||
}
|
||||
|
||||
internal override TypeWrapper[] InnerClasses
|
||||
{
|
||||
get
|
||||
|
@ -2096,7 +2091,7 @@ namespace IKVM.Internal
|
|||
Console.Error.WriteLine("Error: main class not found");
|
||||
return 1;
|
||||
}
|
||||
MethodWrapper mw = wrapper.GetMethodWrapper(new MethodDescriptor("main", "([Ljava.lang.String;)V"), false);
|
||||
MethodWrapper mw = wrapper.GetMethodWrapper("main", "([Ljava.lang.String;)V", false);
|
||||
if(mw == null)
|
||||
{
|
||||
Console.Error.WriteLine("Error: main method not found");
|
||||
|
|
Загрузка…
Ссылка в новой задаче