This commit is contained in:
jfrijters 2005-01-03 08:26:21 +00:00
Родитель 4f63f7e13d
Коммит 1b65938abf
22 изменённых файлов: 1753 добавлений и 1139 удалений

Просмотреть файл

@ -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="&lt;init&gt;" sig="()V" />
<newobj class="java.nio.BufferUnderflowException" name="&lt;init&gt;" 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");