Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/ikvm-fork.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--classpath/allsources.lst161
-rw-r--r--classpath/java/lang/VMRuntime.java2
-rw-r--r--classpath/map.xml2
-rw-r--r--ikvm.build9
-rw-r--r--ikvm.sln16
-rw-r--r--jni/clr-win32/AssemblyInfo.cpp81
-rw-r--r--jni/clr-win32/Stdafx.cpp5
-rw-r--r--jni/clr-win32/Stdafx.h9
-rw-r--r--jni/clr-win32/clr-win32.build16
-rw-r--r--jni/clr-win32/jni.cpp269
-rw-r--r--jni/clr-win32/jni.h196
-rw-r--r--jni/clr-win32/jnienv.cpp1506
-rw-r--r--jni/clr-win32/jnienv.h595
-rw-r--r--jni/mono/JNI.cs567
-rw-r--r--jni/mono/mono.build14
-rw-r--r--native/jni.c500
-rw-r--r--native/jni.h401
-rw-r--r--native/native.build29
-rw-r--r--native/native.vcproj (renamed from jni/clr-win32/IKVM.JNI.CLR-Win32.vcproj)95
-rw-r--r--native/os.c73
-rw-r--r--runtime/BigEndianBinaryReader.cs75
-rw-r--r--runtime/ByteCode.cs479
-rw-r--r--runtime/ClassFile.cs1292
-rw-r--r--runtime/ClassLoaderWrapper.cs27
-rw-r--r--runtime/IKVM.Runtime.csproj2
-rw-r--r--runtime/JavaException.cs10
-rw-r--r--runtime/JniInterface.cs2586
-rw-r--r--runtime/MemberWrapper.cs1
-rw-r--r--runtime/TypeWrapper.cs126
-rw-r--r--runtime/classpath.cs47
-rw-r--r--runtime/compiler.cs121
-rw-r--r--runtime/runtime.build2
-rw-r--r--runtime/verifier.cs98
-rw-r--r--runtime/vm.cs35
34 files changed, 4783 insertions, 4664 deletions
diff --git a/classpath/allsources.lst b/classpath/allsources.lst
index 73a45b1f..cd5a38d4 100644
--- a/classpath/allsources.lst
+++ b/classpath/allsources.lst
@@ -10,6 +10,7 @@ java/lang/VMThread.java
java/lang/VMClass.java
java/lang/VMDouble.java
java/lang/VMFloat.java
+java/lang/VMSystem.java
java/lang/ExceptionHelper.java
java/lang/ObjectHelper.java
java/lang/StringHelper.java
@@ -294,6 +295,8 @@ sun/misc/Ref.java
../../classpath/gnu/java/security/Engine.java
../../classpath/gnu/java/security/OID.java
../../classpath/gnu/java/security/PolicyFile.java
+../../classpath/gnu/java/security/action/GetPropertyAction.java
+../../classpath/gnu/java/security/action/SetAccessibleAction.java
../../classpath/gnu/java/security/der/BitString.java
../../classpath/gnu/java/security/der/DER.java
../../classpath/gnu/java/security/der/DEREncodingException.java
@@ -602,6 +605,7 @@ sun/misc/Ref.java
../../classpath/java/awt/image/BufferedImage.java
../../classpath/java/awt/image/BufferedImageOp.java
../../classpath/java/awt/image/BufferStrategy.java
+../../classpath/java/awt/image/ByteLookupTable.java
../../classpath/java/awt/image/ColorModel.java
../../classpath/java/awt/image/ComponentColorModel.java
../../classpath/java/awt/image/ComponentSampleModel.java
@@ -621,6 +625,8 @@ sun/misc/Ref.java
../../classpath/java/awt/image/ImageProducer.java
../../classpath/java/awt/image/ImagingOpException.java
../../classpath/java/awt/image/IndexColorModel.java
+../../classpath/java/awt/image/Kernel.java
+../../classpath/java/awt/image/LookupTable.java
../../classpath/java/awt/image/MemoryImageSource.java
../../classpath/java/awt/image/PackedColorModel.java
../../classpath/java/awt/image/PixelGrabber.java
@@ -632,6 +638,7 @@ sun/misc/Ref.java
../../classpath/java/awt/image/ReplicateScaleFilter.java
../../classpath/java/awt/image/RGBImageFilter.java
../../classpath/java/awt/image/SampleModel.java
+../../classpath/java/awt/image/ShortLookupTable.java
../../classpath/java/awt/image/SinglePixelPackedSampleModel.java
../../classpath/java/awt/image/TileObserver.java
../../classpath/java/awt/image/VolatileImage.java
@@ -687,8 +694,10 @@ sun/misc/Ref.java
../../classpath/java/beans/Beans.java
../../classpath/java/beans/Customizer.java
../../classpath/java/beans/DesignMode.java
+../../classpath/java/beans/EventHandler.java
../../classpath/java/beans/EventSetDescriptor.java
../../classpath/java/beans/ExceptionListener.java
+../../classpath/java/beans/Expression.java
../../classpath/java/beans/FeatureDescriptor.java
../../classpath/java/beans/IndexedPropertyDescriptor.java
../../classpath/java/beans/IntrospectionException.java
@@ -705,6 +714,7 @@ sun/misc/Ref.java
../../classpath/java/beans/PropertyEditorSupport.java
../../classpath/java/beans/PropertyVetoException.java
../../classpath/java/beans/SimpleBeanInfo.java
+../../classpath/java/beans/Statement.java
../../classpath/java/beans/VetoableChangeListener.java
../../classpath/java/beans/VetoableChangeListenerProxy.java
../../classpath/java/beans/VetoableChangeSupport.java
@@ -1202,8 +1212,10 @@ sun/misc/Ref.java
../../classpath/java/security/cert/PolicyQualifierInfo.java
../../classpath/java/security/cert/TrustAnchor.java
../../classpath/java/security/cert/X509Certificate.java
+../../classpath/java/security/cert/X509CertSelector.java
../../classpath/java/security/cert/X509CRL.java
../../classpath/java/security/cert/X509CRLEntry.java
+../../classpath/java/security/cert/X509CRLSelector.java
../../classpath/java/security/cert/X509Extension.java
../../classpath/java/security/interfaces/DSAKey.java
../../classpath/java/security/interfaces/DSAKeyPairGenerator.java
@@ -1429,6 +1441,46 @@ sun/misc/Ref.java
../../classpath/javax/accessibility/AccessibleTableModelChange.java
../../classpath/javax/accessibility/AccessibleText.java
../../classpath/javax/accessibility/AccessibleValue.java
+../../classpath/javax/crypto/BadPaddingException.java
+../../classpath/javax/crypto/Cipher.java
+../../classpath/javax/crypto/CipherInputStream.java
+../../classpath/javax/crypto/CipherOutputStream.java
+../../classpath/javax/crypto/CipherSpi.java
+../../classpath/javax/crypto/EncryptedPrivateKeyInfo.java
+../../classpath/javax/crypto/ExemptionMechanism.java
+../../classpath/javax/crypto/ExemptionMechanismException.java
+../../classpath/javax/crypto/ExemptionMechanismSpi.java
+../../classpath/javax/crypto/IllegalBlockSizeException.java
+../../classpath/javax/crypto/KeyAgreement.java
+../../classpath/javax/crypto/KeyAgreementSpi.java
+../../classpath/javax/crypto/KeyGenerator.java
+../../classpath/javax/crypto/KeyGeneratorSpi.java
+../../classpath/javax/crypto/Mac.java
+../../classpath/javax/crypto/MacSpi.java
+../../classpath/javax/crypto/NoSuchPaddingException.java
+../../classpath/javax/crypto/NullCipher.java
+../../classpath/javax/crypto/NullCipherImpl.java
+../../classpath/javax/crypto/SealedObject.java
+../../classpath/javax/crypto/SecretKey.java
+../../classpath/javax/crypto/SecretKeyFactory.java
+../../classpath/javax/crypto/SecretKeyFactorySpi.java
+../../classpath/javax/crypto/ShortBufferException.java
+../../classpath/javax/crypto/interfaces/DHKey.java
+../../classpath/javax/crypto/interfaces/DHPrivateKey.java
+../../classpath/javax/crypto/interfaces/DHPublicKey.java
+../../classpath/javax/crypto/interfaces/PBEKey.java
+../../classpath/javax/crypto/spec/DESedeKeySpec.java
+../../classpath/javax/crypto/spec/DESKeySpec.java
+../../classpath/javax/crypto/spec/DHGenParameterSpec.java
+../../classpath/javax/crypto/spec/DHParameterSpec.java
+../../classpath/javax/crypto/spec/DHPrivateKeySpec.java
+../../classpath/javax/crypto/spec/DHPublicKeySpec.java
+../../classpath/javax/crypto/spec/IvParameterSpec.java
+../../classpath/javax/crypto/spec/PBEKeySpec.java
+../../classpath/javax/crypto/spec/PBEParameterSpec.java
+../../classpath/javax/crypto/spec/RC2ParameterSpec.java
+../../classpath/javax/crypto/spec/RC5ParameterSpec.java
+../../classpath/javax/crypto/spec/SecretKeySpec.java
../../classpath/javax/imageio/IIOException.java
../../classpath/javax/imageio/ImageReader.java
../../classpath/javax/imageio/ImageTranscoder.java
@@ -1536,6 +1588,40 @@ sun/misc/Ref.java
../../classpath/javax/naming/spi/Resolver.java
../../classpath/javax/naming/spi/ResolveResult.java
../../classpath/javax/naming/spi/StateFactory.java
+../../classpath/javax/net/ServerSocketFactory.java
+../../classpath/javax/net/SocketFactory.java
+../../classpath/javax/net/VanillaServerSocketFactory.java
+../../classpath/javax/net/VanillaSocketFactory.java
+../../classpath/javax/net/ssl/HandshakeCompletedEvent.java
+../../classpath/javax/net/ssl/HandshakeCompletedListener.java
+../../classpath/javax/net/ssl/HostnameVerifier.java
+../../classpath/javax/net/ssl/HttpsURLConnection.java
+../../classpath/javax/net/ssl/KeyManager.java
+../../classpath/javax/net/ssl/KeyManagerFactory.java
+../../classpath/javax/net/ssl/KeyManagerFactorySpi.java
+../../classpath/javax/net/ssl/ManagerFactoryParameters.java
+../../classpath/javax/net/ssl/SSLContext.java
+../../classpath/javax/net/ssl/SSLContextSpi.java
+../../classpath/javax/net/ssl/SSLException.java
+../../classpath/javax/net/ssl/SSLHandshakeException.java
+../../classpath/javax/net/ssl/SSLKeyException.java
+../../classpath/javax/net/ssl/SSLPeerUnverifiedException.java
+../../classpath/javax/net/ssl/SSLPermission.java
+../../classpath/javax/net/ssl/SSLProtocolException.java
+../../classpath/javax/net/ssl/SSLServerSocket.java
+../../classpath/javax/net/ssl/SSLServerSocketFactory.java
+../../classpath/javax/net/ssl/SSLSession.java
+../../classpath/javax/net/ssl/SSLSessionBindingEvent.java
+../../classpath/javax/net/ssl/SSLSessionBindingListener.java
+../../classpath/javax/net/ssl/SSLSessionContext.java
+../../classpath/javax/net/ssl/SSLSocket.java
+../../classpath/javax/net/ssl/SSLSocketFactory.java
+../../classpath/javax/net/ssl/TrivialHostnameVerifier.java
+../../classpath/javax/net/ssl/TrustManager.java
+../../classpath/javax/net/ssl/TrustManagerFactory.java
+../../classpath/javax/net/ssl/TrustManagerFactorySpi.java
+../../classpath/javax/net/ssl/X509KeyManager.java
+../../classpath/javax/net/ssl/X509TrustManager.java
../../classpath/javax/print/AttributeException.java
../../classpath/javax/print/CancelablePrintJob.java
../../classpath/javax/print/Doc.java
@@ -1661,7 +1747,53 @@ sun/misc/Ref.java
../../classpath/javax/rmi/CORBA/Util.java
../../classpath/javax/rmi/CORBA/UtilDelegate.java
../../classpath/javax/rmi/CORBA/ValueHandler.java
+../../classpath/javax/security/auth/AuthPermission.java
+../../classpath/javax/security/auth/Destroyable.java
+../../classpath/javax/security/auth/DestroyFailedException.java
+../../classpath/javax/security/auth/Policy.java
+../../classpath/javax/security/auth/PrivateCredentialPermission.java
+../../classpath/javax/security/auth/Refreshable.java
+../../classpath/javax/security/auth/RefreshFailedException.java
+../../classpath/javax/security/auth/Subject.java
+../../classpath/javax/security/auth/SubjectDomainCombiner.java
+../../classpath/javax/security/auth/callback/Callback.java
+../../classpath/javax/security/auth/callback/CallbackHandler.java
+../../classpath/javax/security/auth/callback/ChoiceCallback.java
+../../classpath/javax/security/auth/callback/ConfirmationCallback.java
+../../classpath/javax/security/auth/callback/LanguageCallback.java
+../../classpath/javax/security/auth/callback/NameCallback.java
+../../classpath/javax/security/auth/callback/PasswordCallback.java
+../../classpath/javax/security/auth/callback/TextInputCallback.java
+../../classpath/javax/security/auth/callback/TextOutputCallback.java
+../../classpath/javax/security/auth/callback/UnsupportedCallbackException.java
+../../classpath/javax/security/auth/login/AccountExpiredException.java
+../../classpath/javax/security/auth/login/AppConfigurationEntry.java
+../../classpath/javax/security/auth/login/Configuration.java
+../../classpath/javax/security/auth/login/CredentialExpiredException.java
+../../classpath/javax/security/auth/login/FailedLoginException.java
+../../classpath/javax/security/auth/login/LoginContext.java
+../../classpath/javax/security/auth/login/LoginException.java
+../../classpath/javax/security/auth/login/NullConfiguration.java
../../classpath/javax/security/auth/x500/X500Principal.java
+../../classpath/javax/security/auth/x500/X500PrivateCredential.java
+../../classpath/javax/security/cert/Certificate.java
+../../classpath/javax/security/cert/CertificateEncodingException.java
+../../classpath/javax/security/cert/CertificateException.java
+../../classpath/javax/security/cert/CertificateExpiredException.java
+../../classpath/javax/security/cert/CertificateNotYetValidException.java
+../../classpath/javax/security/cert/CertificateParsingException.java
+../../classpath/javax/security/cert/X509CertBridge.java
+../../classpath/javax/security/cert/X509Certificate.java
+../../classpath/javax/security/sasl/AuthenticationException.java
+../../classpath/javax/security/sasl/AuthorizeCallback.java
+../../classpath/javax/security/sasl/RealmCallback.java
+../../classpath/javax/security/sasl/RealmChoiceCallback.java
+../../classpath/javax/security/sasl/Sasl.java
+../../classpath/javax/security/sasl/SaslClient.java
+../../classpath/javax/security/sasl/SaslClientFactory.java
+../../classpath/javax/security/sasl/SaslException.java
+../../classpath/javax/security/sasl/SaslServer.java
+../../classpath/javax/security/sasl/SaslServerFactory.java
../../classpath/javax/sql/ConnectionEvent.java
../../classpath/javax/sql/ConnectionEventListener.java
../../classpath/javax/sql/ConnectionPoolDataSource.java
@@ -1681,6 +1813,7 @@ sun/misc/Ref.java
../../classpath/javax/swing/AbstractCellEditor.java
../../classpath/javax/swing/AbstractListModel.java
../../classpath/javax/swing/AbstractSet.java
+../../classpath/javax/swing/AbstractSpinnerModel.java
../../classpath/javax/swing/Action.java
../../classpath/javax/swing/ActionMap.java
../../classpath/javax/swing/BorderFactory.java
@@ -1745,6 +1878,7 @@ sun/misc/Ref.java
../../classpath/javax/swing/JScrollPane.java
../../classpath/javax/swing/JSeparator.java
../../classpath/javax/swing/JSlider.java
+../../classpath/javax/swing/JSpinner.java
../../classpath/javax/swing/JSplitPane.java
../../classpath/javax/swing/JTabbedPane.java
../../classpath/javax/swing/JTable.java
@@ -1779,7 +1913,11 @@ sun/misc/Ref.java
../../classpath/javax/swing/SingleSelectionModel.java
../../classpath/javax/swing/SizeRequirements.java
../../classpath/javax/swing/SizeSequence.java
+../../classpath/javax/swing/SpinnerListModel.java
../../classpath/javax/swing/SpinnerModel.java
+../../classpath/javax/swing/SpinnerNumberModel.java
+../../classpath/javax/swing/Spring.java
+../../classpath/javax/swing/SpringLayout.java
../../classpath/javax/swing/SwingConstants.java
../../classpath/javax/swing/SwingUtilities.java
../../classpath/javax/swing/Timer.java
@@ -1920,12 +2058,16 @@ sun/misc/Ref.java
../../classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java
../../classpath/javax/swing/plaf/basic/BasicSeparatorUI.java
../../classpath/javax/swing/plaf/basic/BasicSliderUI.java
+../../classpath/javax/swing/plaf/basic/BasicSpinnerUI.java
../../classpath/javax/swing/plaf/basic/BasicSplitPaneDivider.java
../../classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java
../../classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java
+../../classpath/javax/swing/plaf/basic/BasicTextFieldUI.java
../../classpath/javax/swing/plaf/basic/BasicTextUI.java
../../classpath/javax/swing/plaf/basic/BasicToggleButtonUI.java
+../../classpath/javax/swing/plaf/basic/BasicToolBarSeparatorUI.java
../../classpath/javax/swing/plaf/basic/BasicToolBarUI.java
+../../classpath/javax/swing/plaf/basic/BasicToolTipUI.java
../../classpath/javax/swing/plaf/basic/BasicTreeUI.java
../../classpath/javax/swing/plaf/basic/BasicViewportUI.java
../../classpath/javax/swing/plaf/metal/MetalLookAndFeel.java
@@ -1943,26 +2085,31 @@ sun/misc/Ref.java
../../classpath/javax/swing/text/AttributeSet.java
../../classpath/javax/swing/text/BadLocationException.java
../../classpath/javax/swing/text/Caret.java
-../../classpath/javax/swing/text/CharacterIterator.java
../../classpath/javax/swing/text/ComponentView.java
../../classpath/javax/swing/text/DefaultCaret.java
../../classpath/javax/swing/text/DefaultEditorKit.java
+../../classpath/javax/swing/text/DefaultHighlighter.java
../../classpath/javax/swing/text/Document.java
../../classpath/javax/swing/text/DocumentFilter.java
../../classpath/javax/swing/text/EditorKit.java
../../classpath/javax/swing/text/Element.java
+../../classpath/javax/swing/text/FieldView.java
../../classpath/javax/swing/text/GapContent.java
+../../classpath/javax/swing/text/Highlighter.java
../../classpath/javax/swing/text/JTextComponent.java
../../classpath/javax/swing/text/Keymap.java
+../../classpath/javax/swing/text/LayeredHighlighter.java
../../classpath/javax/swing/text/MutableAttributeSet.java
../../classpath/javax/swing/text/NavigationFilter.java
../../classpath/javax/swing/text/PlainDocument.java
-../../classpath/javax/swing/text/PlainEditorKit.java
+../../classpath/javax/swing/text/PlainView.java
../../classpath/javax/swing/text/Position.java
../../classpath/javax/swing/text/Segment.java
../../classpath/javax/swing/text/Style.java
../../classpath/javax/swing/text/StyledDocument.java
../../classpath/javax/swing/text/StyledEditorKit.java
+../../classpath/javax/swing/text/TabableView.java
+../../classpath/javax/swing/text/TabExpander.java
../../classpath/javax/swing/text/TextAction.java
../../classpath/javax/swing/text/View.java
../../classpath/javax/swing/text/ViewFactory.java
@@ -2011,11 +2158,19 @@ sun/misc/Ref.java
../../classpath/javax/transaction/xa/XAException.java
../../classpath/javax/transaction/xa/XAResource.java
../../classpath/javax/transaction/xa/Xid.java
+../../classpath/org/ietf/jgss/ChannelBinding.java
+../../classpath/org/ietf/jgss/GSSContext.java
+../../classpath/org/ietf/jgss/GSSCredential.java
+../../classpath/org/ietf/jgss/GSSException.java
+../../classpath/org/ietf/jgss/GSSManager.java
+../../classpath/org/ietf/jgss/GSSName.java
+../../classpath/org/ietf/jgss/MessageProp.java
+../../classpath/org/ietf/jgss/Oid.java
+../../classpath/vm/reference/gnu/java/nio/VMSelector.java
../../classpath/vm/reference/java/io/VMObjectStreamClass.java
../../classpath/vm/reference/java/lang/VMObject.java
../../classpath/vm/reference/java/lang/VMSecurityManager.java
../../classpath/vm/reference/java/lang/VMString.java
-../../classpath/vm/reference/java/lang/VMSystem.java
../../classpath/vm/reference/java/lang/VMThrowable.java
../../classpath/vm/reference/java/security/VMAccessController.java
../../classpath/vm/reference/gnu/java/nio/VMPipe.java
diff --git a/classpath/java/lang/VMRuntime.java b/classpath/java/lang/VMRuntime.java
index 55258bfa..d671b568 100644
--- a/classpath/java/lang/VMRuntime.java
+++ b/classpath/java/lang/VMRuntime.java
@@ -93,7 +93,7 @@ final class VMRuntime
static long totalMemory()
{
// NOTE this really is a bogus number, but we have to return something
- return cli.System.GC.GetTotalMemory(false);
+ return cli.System.GC.GetTotalMemory(false) + freeMemory();
}
/**
diff --git a/classpath/map.xml b/classpath/map.xml
index be2ee7fb..c71f6776 100644
--- a/classpath/map.xml
+++ b/classpath/map.xml
@@ -867,6 +867,8 @@
<stloc name="x" class="java.lang.ThreadDeath" />
<exceptionBlock>
<try>
+ <!-- TODO instead of catching the ThreadStateException, we should check the ThreadState
+ before calling ResetAbort -->
<call type="System.Threading.Thread, mscorlib" name="ResetAbort" sig="()V" />
</try>
<catch type="System.Threading.ThreadStateException, mscorlib">
diff --git a/ikvm.build b/ikvm.build
index 2c18dd7b..b7dd8c8e 100644
--- a/ikvm.build
+++ b/ikvm.build
@@ -2,10 +2,7 @@
<project name="ikvm" default="all">
<target name="all">
<nant buildfile="runtime/runtime.build" />
- <if propertytrue="nant.platform.win32">
- <nant buildfile="jni/clr-win32/clr-win32.build" />
- </if>
- <nant buildfile="jni/mono/mono.build" />
+ <nant buildfile="native/native.build" />
<nant buildfile="ikvmc/ikvmc.build" />
<nant buildfile="classpath/classpath.build" />
<nant buildfile="ikvm/ikvm.build" />
@@ -20,8 +17,8 @@
<includes name="bin/IKVM.AWT.WinForms.dll" />
<includes name="bin/IKVM.Runtime.dll" />
<includes name="bin/IKVM.GNU.Classpath.dll" />
- <includes name="bin/IKVM.JNI.CLR-Win32.dll" />
- <includes name="bin/IKVM.JNI.Mono.dll" />
+ <includes name="bin/ikvm-native.dll" />
+ <includes name="bin/libikvm-native.so" />
<includes name="bin/ikvm.exe" />
<includes name="bin/ikvmc.exe" />
<includes name="bin/ikvmstub.exe" />
diff --git a/ikvm.sln b/ikvm.sln
index bf67f703..d535bffa 100644
--- a/ikvm.sln
+++ b/ikvm.sln
@@ -3,10 +3,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IKVM.Runtime", "runtime\IKV
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IKVM.JNI.CLR-Win32", "jni\clr-win32\IKVM.JNI.CLR-Win32.vcproj", "{4D400F9D-68A1-4066-95F6-85AF0E58B710}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ikvm", "ikvm\ikvm.csproj", "{4FBAFF23-1E48-4977-8C50-30F87E70A8B5}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
@@ -23,6 +19,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IKVM.AWT.WinForms", "awt\IK
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ikvm-native", "native\native.vcproj", "{14EC8F2A-90C6-4CFC-AD26-04C9A3392B8E}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
@@ -33,10 +33,6 @@ Global
{F5C7B588-0403-4AF2-A4DE-5697DE21BC2C}.Debug.Build.0 = Debug|.NET
{F5C7B588-0403-4AF2-A4DE-5697DE21BC2C}.Release.ActiveCfg = Release|.NET
{F5C7B588-0403-4AF2-A4DE-5697DE21BC2C}.Release.Build.0 = Release|.NET
- {4D400F9D-68A1-4066-95F6-85AF0E58B710}.Debug.ActiveCfg = Debug|Win32
- {4D400F9D-68A1-4066-95F6-85AF0E58B710}.Debug.Build.0 = Debug|Win32
- {4D400F9D-68A1-4066-95F6-85AF0E58B710}.Release.ActiveCfg = Release|Win32
- {4D400F9D-68A1-4066-95F6-85AF0E58B710}.Release.Build.0 = Release|Win32
{4FBAFF23-1E48-4977-8C50-30F87E70A8B5}.Debug.ActiveCfg = Debug|.NET
{4FBAFF23-1E48-4977-8C50-30F87E70A8B5}.Debug.Build.0 = Debug|.NET
{4FBAFF23-1E48-4977-8C50-30F87E70A8B5}.Release.ActiveCfg = Release|.NET
@@ -53,6 +49,10 @@ Global
{E00A0FA2-1FD7-4DD9-8C06-7202CE366102}.Debug.Build.0 = Debug|.NET
{E00A0FA2-1FD7-4DD9-8C06-7202CE366102}.Release.ActiveCfg = Release|.NET
{E00A0FA2-1FD7-4DD9-8C06-7202CE366102}.Release.Build.0 = Release|.NET
+ {14EC8F2A-90C6-4CFC-AD26-04C9A3392B8E}.Debug.ActiveCfg = Debug|Win32
+ {14EC8F2A-90C6-4CFC-AD26-04C9A3392B8E}.Debug.Build.0 = Debug|Win32
+ {14EC8F2A-90C6-4CFC-AD26-04C9A3392B8E}.Release.ActiveCfg = Release|Win32
+ {14EC8F2A-90C6-4CFC-AD26-04C9A3392B8E}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
diff --git a/jni/clr-win32/AssemblyInfo.cpp b/jni/clr-win32/AssemblyInfo.cpp
deleted file mode 100644
index e93ef2a9..00000000
--- a/jni/clr-win32/AssemblyInfo.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- Copyright (C) 2002 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
-
-*/
-#include "stdafx.h"
-
-using namespace System::Reflection;
-using namespace System::Runtime::CompilerServices;
-
-//
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-//
-[assembly:AssemblyTitleAttribute("")];
-[assembly:AssemblyDescriptionAttribute("")];
-[assembly:AssemblyConfigurationAttribute("")];
-[assembly:AssemblyCompanyAttribute("")];
-[assembly:AssemblyProductAttribute("")];
-[assembly:AssemblyCopyrightAttribute("")];
-[assembly:AssemblyTrademarkAttribute("")];
-[assembly:AssemblyCultureAttribute("")];
-
-//
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the value or you can default the Revision and Build Numbers
-// by using the '*' as shown below:
-
-[assembly:AssemblyVersionAttribute("0.9.*")];
-
-//
-// In order to sign your assembly you must specify a key to use. Refer to the
-// Microsoft .NET Framework documentation for more information on assembly signing.
-//
-// Use the attributes below to control which key is used for signing.
-//
-// Notes:
-// (*) If no key is specified, the assembly is not signed.
-// (*) KeyName refers to a key that has been installed in the Crypto Service
-// Provider (CSP) on your machine. KeyFile refers to a file which contains
-// a key.
-// (*) If the KeyFile and the KeyName values are both specified, the
-// following processing occurs:
-// (1) If the KeyName can be found in the CSP, that key is used.
-// (2) If the KeyName does not exist and the KeyFile does exist, the key
-// in the KeyFile is installed into the CSP and used.
-// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
-// When specifying the KeyFile, the location of the KeyFile should be
-// relative to the project directory.
-// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
-// documentation for more information on this.
-//
-[assembly:AssemblyDelaySignAttribute(false)];
-//[assembly: AssemblyKeyFile("c:\\ikvm-key\\ikvm.snk")];
-[assembly:AssemblyKeyNameAttribute("")];
-
diff --git a/jni/clr-win32/Stdafx.cpp b/jni/clr-win32/Stdafx.cpp
deleted file mode 100644
index 42f1745b..00000000
--- a/jni/clr-win32/Stdafx.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-// stdafx.cpp : source file that includes just the standard includes
-// jni.pch will be the pre-compiled header
-// stdafx.obj will contain the pre-compiled type information
-
-#include "stdafx.h"
diff --git a/jni/clr-win32/Stdafx.h b/jni/clr-win32/Stdafx.h
deleted file mode 100644
index 91e9cc50..00000000
--- a/jni/clr-win32/Stdafx.h
+++ /dev/null
@@ -1,9 +0,0 @@
-// stdafx.h : include file for standard system include files,
-// or project specific include files that are used frequently,
-// but are changed infrequently
-
-#pragma once
-
-#using <mscorlib.dll>
-
-#include <windows.h>
diff --git a/jni/clr-win32/clr-win32.build b/jni/clr-win32/clr-win32.build
deleted file mode 100644
index f2d84e84..00000000
--- a/jni/clr-win32/clr-win32.build
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0"?>
-<project name="IKVM.JNI.CLR-Win32" default="IKVM.JNI.CLR-Win32">
- <target name="IKVM.JNI.CLR-Win32">
- <mkdir dir="release"/>
- <cl outputdir="Release" pchfile="stdafx.h" options="/O2 /D WIN32 /D NDEBUG /D _WINDLL /D _MBCS /FD /EHac /GS /Zc:wchar_t /Zc:forScope /W3 /nologo /c /Zi /clr /TP /FU ..\..\bin\IKVM.Runtime.dll">
- <sources>
- <includes name="*.cpp"/>
- </sources>
- </cl>
- <link output="../../bin/IKVM.JNI.CLR-Win32.dll" options="/DLL /FIXED:No">
- <sources>
- <includes name="Release/*.obj"/>
- </sources>
- </link>
- </target>
-</project>
diff --git a/jni/clr-win32/jni.cpp b/jni/clr-win32/jni.cpp
deleted file mode 100644
index d94bc539..00000000
--- a/jni/clr-win32/jni.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- Copyright (C) 2002, 2004 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
-
-*/
-
-#include "stdafx.h"
-#include <malloc.h>
-#include "jnienv.h"
-#include "jni.h"
-
-#pragma managed
-
-#include <stdio.h>
-
-using namespace System;
-using namespace System::Collections;
-using namespace System::Runtime::InteropServices;
-using namespace System::Reflection;
-
-typedef JNIEXPORT jint (JNICALL *PJNI_ONLOAD)(JavaVM* vm, void* reserved);
-
-int JNI::LoadNativeLibrary(String* name)
-{
- HMODULE hMod = LoadLibrary(name);
- if(!hMod)
- {
- return 0;
- }
- //void* pOnLoad = GetProcAddress(hMod, S"_JNI_OnLoad@8");
- //if(pOnLoad)
- //{
- // JavaVM* pVM;
- // ((JNIEnv*)0)->JNIEnv::GetJavaVM(&pVM);
- // LocalRefStruct loc;
- // loc.Enter();
- // jint version = ((PJNI_ONLOAD)pOnLoad)(pVM, 0);
- // try
- // {
- // loc.Leave();
- // }
- // catch(...)
- // {
- // // If the JNI_OnLoad procedure threw an exception, we have to unload the library
- // FreeLibrary(hMod);
- // throw;
- // }
- // if(version != JNI_VERSION_1_1 && version != JNI_VERSION_1_2 && version != JNI_VERSION_1_4)
- // {
- // // NOTE we don't call JNI_OnUnload when the version doesn't match!
- // FreeLibrary(hMod);
- // throw VM::UnsatisfiedLinkError(String::Format(S"Unsupported JNI version 0x{0:X} required by {1}", __box(version), name));
- // }
- //}
- libs->Add(__box((int)hMod));
- return 1;
-}
-
-Type* JNI::GetLocalRefStructType()
-{
- return 0;
- //return __typeof(LocalRefStruct);
-}
-
-MethodInfo* JNI::GetJniFuncPtrMethod()
-{
- return __typeof(JNI)->GetMethod("GetJniFuncPtr");
-}
-
-IntPtr JNI::GetJniFuncPtr(String* method, String* sig, String* clazz)
-{
- System::Text::StringBuilder* mangledSig = new System::Text::StringBuilder();
- int sp = 0;
- for(int i = 1; sig->Chars[i] != ')'; i++)
- {
- switch(sig->Chars[i])
- {
- case '[':
- mangledSig->Append(S"_3");
- sp += 4;
- while(sig->Chars[++i] == '[')
- {
- mangledSig->Append(S"_3");
- }
- mangledSig->Append(sig->Chars[i]);
- if(sig->Chars[i] == 'L')
- {
- while(sig->Chars[++i] != ';')
- {
- if(sig->Chars[i] == '/')
- {
- mangledSig->Append(S"_");
- }
- else if(sig->Chars[i] == '_')
- {
- mangledSig->Append(S"_1");
- }
- else
- {
- mangledSig->Append(sig->Chars[i]);
- }
- }
- mangledSig->Append(S"_2");
- }
- break;
- case 'L':
- sp += 4;
- mangledSig->Append(S"L");
- while(sig->Chars[++i] != ';')
- {
- if(sig->Chars[i] == '/')
- {
- mangledSig->Append(S"_");
- }
- else if(sig->Chars[i] == '_')
- {
- mangledSig->Append(S"_1");
- }
- else
- {
- mangledSig->Append(sig->Chars[i]);
- }
- }
- mangledSig->Append(S"_2");
- break;
- case 'J':
- case 'D':
- mangledSig->Append(sig->Chars[i]);
- sp += 8;
- break;
- case 'F':
- case 'I':
- case 'C':
- case 'Z':
- case 'S':
- case 'B':
- mangledSig->Append(sig->Chars[i]);
- sp += 4;
- break;
- default:
- DebugBreak();
- throw new NotImplementedException();
- }
- }
- void* func = 0;
- // TODO implement this correctly
- String* methodName = String::Format(S"_Java_{0}_{1}@{2}", clazz->Replace(S"_", S"_1")->Replace('/', '_'), method->Replace(S"_", S"_1"), __box(sp + 8));
- for(int i = 0; i < libs->Count; i++)
- {
- HMODULE hMod = (HMODULE)__unbox<int>(libs->Item[i]);
- func = GetProcAddress(hMod, methodName);
- if(func)
- {
- return (IntPtr)func;
- }
- }
- methodName = String::Concat(String::Format(S"_Java_{0}_{1}__{2}@", clazz->Replace(S"_", S"_1")->Replace('/', '_'), method->Replace(S"_", S"_1"), mangledSig), __box(sp + 8));
- for(int i = 0; i < libs->Count; i++)
- {
- HMODULE hMod = (HMODULE)__unbox<int>(libs->Item[i]);
- func = GetProcAddress(hMod, methodName);
- if(func)
- {
- return (IntPtr)func;
- }
- }
- throw VM::UnsatisfiedLinkError(methodName);
-}
-
-//// If we put the ThreadStatic in LocalRefStruct we get an ExecutionEngineException (?!)
-//__gc class TlsHack
-//{
-//public:
-// [ThreadStatic]
-// static JNIEnv* pJNIEnv;
-//};
-//
-//JNIEnv* LocalRefStruct::GetEnv()
-//{
-// return TlsHack::pJNIEnv;
-//}
-//
-//IntPtr LocalRefStruct::Enter()
-//{
-// pJNIEnv = TlsHack::pJNIEnv;
-// if(!pJNIEnv)
-// {
-// // TODO we should create a managed helper object that deletes JNIEnv when the thread dies
-// pJNIEnv = TlsHack::pJNIEnv = new JNIEnv();
-// pJNIEnv->pendingException = 0;
-// pJNIEnv->localRefSlot = 0;
-// localRefs = pJNIEnv->localRefs = new LocalRefListEntry __gc[32];
-// }
-// else
-// {
-// pPrevLocalRefCache = pJNIEnv->pActiveLocalRefCache;
-// localRefs = pJNIEnv->localRefs;
-// }
-//
-// pJNIEnv->localRefSlot++;
-// if(pJNIEnv->localRefSlot >= 32)
-// {
-// // TODO instead of bailing out, we should grow the array
-// VM::FatalError("JNI nesting too deep");
-// }
-//
-// // NOTE since this __value type can (should) only be allocated on the stack,
-// // it is "safe" to store the this pointer in a __nogc*, but the compiler
-// // doesn't know this, so we have to use a __pin* to bypass its checks.
-// LocalRefStruct __pin* pPinHack = this;
-// pJNIEnv->pActiveLocalRefCache = pPinHack;
-// localRefs[pJNIEnv->localRefSlot].static_list = &pPinHack->fastlocalrefs.loc1;
-// return (IntPtr)pJNIEnv;
-//}
-//
-//void LocalRefStruct::Leave()
-//{
-// Object* x = pJNIEnv->UnwrapRef(pJNIEnv->pendingException);
-// pJNIEnv->pendingException = 0;
-// pJNIEnv->pActiveLocalRefCache = pPrevLocalRefCache;
-// localRefs[pJNIEnv->localRefSlot].dynamic_list = 0;
-// // TODO figure out if it is legal to Leave a JNI method while PushLocalFrame is active (i.e. without the corresponding PopLocalFrame)
-// pJNIEnv->localRefSlot--;
-// if(x)
-// {
-// throw x;
-// }
-//}
-//
-//IntPtr LocalRefStruct::MakeLocalRef(Object* obj)
-//{
-// if(obj == 0)
-// {
-// return 0;
-// }
-// int i = localRefs[pJNIEnv->localRefSlot].MakeLocalRef(obj);
-// if(i >= 0)
-// {
-// return (pJNIEnv->localRefSlot << LOCAL_REF_SHIFT) + i;
-// }
-// // TODO consider allocating a new slot (if we do this, the code in
-// // PushLocalFrame/PopLocalFrame (and Leave) must be fixed to take this into account)
-// VM::FatalError("Too many JNI local references");
-// return 0;
-//}
-//
-//Object* LocalRefStruct::UnwrapLocalRef(IntPtr localref)
-//{
-// int i = (int)localref;
-// return localRefs[i >> LOCAL_REF_SHIFT].UnwrapLocalRef(i & LOCAL_REF_MASK);
-//}
diff --git a/jni/clr-win32/jni.h b/jni/clr-win32/jni.h
deleted file mode 100644
index 400cee9a..00000000
--- a/jni/clr-win32/jni.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- Copyright (C) 2002, 2004 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
-
-*/
-
-#pragma once
-
-using namespace System;
-using namespace System::Collections;
-using namespace System::Runtime::InteropServices;
-using namespace System::Reflection;
-
-class JNIEnv;
-
-#pragma managed
-
-template<class T> T __unbox(Object* o)
-{
- // HACK the MC++ compiler has a bug when unboxing, the static_cast<> is to work around that bug
- return *(static_cast<T __gc*>(__try_cast<__box T*>(o)));
-}
-
-public __gc class JNI : public IJniProvider
-{
- static ArrayList* libs = new ArrayList();
- [DllImport("kernel32")]
- [System::Security::SuppressUnmanagedCodeSecurityAttribute]
- static HMODULE LoadLibrary(String* lpLibFileName);
- [DllImport("kernel32")]
- [System::Security::SuppressUnmanagedCodeSecurityAttribute]
- static void* GetProcAddress(HMODULE hMod, String* lpProcName);
-public:
- int LoadNativeLibrary(String* name);
- Type* GetLocalRefStructType();
- MethodInfo* GetJniFuncPtrMethod();
-
- void** GetVtable()
- {
- JNIEnv p;
- return *(void***)&p;
- }
-
- IntPtr LoadLibraryFoo(String* name)
- {
- return (IntPtr)(void*)LoadLibrary(name);
- }
-
- void FreeLibraryFoo(IntPtr p)
- {
- FreeLibrary((HMODULE)(void*)p);
- }
-
- IntPtr GetProcAddress(IntPtr library, String* name, int argcount)
- {
- String* n = String::Format(S"_{0}@{1}", name, __box(argcount));
- return (IntPtr)GetProcAddress((HMODULE)(void*)library, n);
- }
-
- IntPtr GetJavaVM()
- {
- JavaVM* pvm;
- ((JNIEnv*)0)->JNIEnv::GetJavaVM(&pvm);
- return pvm;
- }
-
- typedef JNIEXPORT jint (JNICALL *PJNI_ONLOAD)(JavaVM* vm, void* reserved);
-
- int CallOnLoad(IntPtr pFunc, IntPtr javavm, IntPtr reserved)
- {
- return ((PJNI_ONLOAD)(void*)pFunc)((JavaVM*)(void*)javavm, (void*)reserved);
- }
-
- static IntPtr GetJniFuncPtr(String* name, String* sig, String* clazz);
-};
-
-public __gc class VM
-{
-public:
- static IntPtr GetMethodCookie(Object* clazz, String* name, String* sig, bool isStatic)
- {
- return JniHelper::GetMethodCookie(clazz, name, sig, isStatic);
- }
- static String* GetMethodArgList(IntPtr cookie)
- {
- return JniHelper::GetMethodArgList(cookie);
- }
- static Object* InvokeMethod(IntPtr cookie, Object* obj, Object* args[], bool nonVirtual)
- {
- return JniHelper::InvokeMethod(cookie, obj, args, nonVirtual);
- }
- static IntPtr GetFieldCookie(Object* clazz, String* name, String* sig, bool isStatic)
- {
- return JniHelper::GetFieldCookie(clazz, name, sig, isStatic);
- }
- static Object* GetFieldValue(IntPtr cookie, Object* obj)
- {
- return JniHelper::GetFieldValue(cookie, obj);
- }
- static void SetFieldValue(IntPtr cookie, Object* obj, Object* value)
- {
- JniHelper::SetFieldValue(cookie, obj, value);
- }
- static Object* FindClass(String* javaName)
- {
- return JniHelper::FindClass(javaName);
- }
- static Exception* UnsatisfiedLinkError(String* msg)
- {
- return JniHelper::UnsatisfiedLinkError(msg);
- }
- static Object* GetObjectClass(Object* o)
- {
- return JniHelper::GetObjectClass(o);
- }
- static bool IsInstanceOf(Object* o, Object* clazz)
- {
- return JniHelper::IsInstanceOf(o, clazz);
- }
- static bool IsAssignableFrom(Object* sub, Object* sup)
- {
- return JniHelper::IsAssignableFrom(sub, sup);
- }
- static Object* GetSuperclass(Object* sub)
- {
- return JniHelper::GetSuperclass(sub);
- }
- static Object* AllocObject(Object* clazz)
- {
- return JniHelper::AllocObject(clazz);
- }
- static IntPtr MethodToCookie(Object* method)
- {
- return JniHelper::MethodToCookie(method);
- }
- static IntPtr FieldToCookie(Object* field)
- {
- return JniHelper::FieldToCookie(field);
- }
- static Object* CookieToMethod(IntPtr method)
- {
- return JniHelper::CookieToMethod(method);
- }
- static Object* CookieToField(IntPtr field)
- {
- return JniHelper::CookieToField(field);
- }
- static void FatalError(String* msg)
- {
- Console::Error->WriteLine(S"Fatal Error in JNI: {0}", msg);
- JniHelper::FatalError(msg);
- }
- static Object* DefineClass(String* name, Object* loader, System::Byte array __gc[])
- {
- return JniHelper::DefineClass(name, loader, array);
- }
- static bool SetNativeMethodPointer(Object* clazz, String* name, String* signature, IntPtr methodPtr)
- {
- return JniHelper::SetNativeMethodPointer(clazz, name, signature, methodPtr);
- }
- static void ResetNativeMethodPointers(Object* clazz)
- {
- return JniHelper::ResetNativeMethodPointers(clazz);
- }
-
- static JNIEnv* GetEnv()
- {
- return (JNIEnv*)(void*)JniHelper::GetEnv();
- }
- static jobject MakeLocalRef(JNIEnv* pEnv, Object* obj)
- {
- return (jobject)(void*)JniHelper::MakeLocalRef(pEnv, obj);
- }
- static Object* UnwrapRef(JNIEnv* pEnv, jobject obj)
- {
- return JniHelper::UnwrapRef(pEnv, obj);
- }
-};
diff --git a/jni/clr-win32/jnienv.cpp b/jni/clr-win32/jnienv.cpp
deleted file mode 100644
index 147df814..00000000
--- a/jni/clr-win32/jnienv.cpp
+++ /dev/null
@@ -1,1506 +0,0 @@
-/*
- Copyright (C) 2002, 2003, 2004 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
-
-*/
-
-#include "stdafx.h"
-#include "jnienv.h"
-#include "jni.h"
-#include <malloc.h>
-#include <stdarg.h>
-#include <vcclr.h>
-
-#define DEBUG
-#undef NDEBUG
-
-#include <assert.h>
-
-using namespace System;
-using namespace System::Runtime::InteropServices;
-using namespace System::Reflection;
-
-// this struct exists to ensure the right compile switch is used, if it fails
-// to compile, you must compile with /Zc:wchar_t
-struct wchar_t_must_be_builtin
-{
- void foo(wchar_t t) {}
- void foo(unsigned short t) {}
-};
-
-#pragma managed
-
-String* StringFromUTF8(const char* psz)
-{
- // Sun's modified UTF8 encoding is not compatible with System::Text::Encoding::UTF8, so
- // we need to roll our own
- int len = 0;
- while(psz[len]) len++;
- System::Text::StringBuilder* sb = new System::Text::StringBuilder(len);
- for(int i = 0; i < len; i++)
- {
- int c = (unsigned char)*psz++;
- int char2, char3;
- switch (c >> 4)
- {
- case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
- // 0xxxxxxx
- break;
- case 12: case 13:
- // 110x xxxx 10xx xxxx
- char2 = *psz++;
- i++;
- c = (((c & 0x1F) << 6) | (char2 & 0x3F));
- break;
- case 14:
- // 1110 xxxx 10xx xxxx 10xx xxxx
- char2 = *psz++;
- char3 = *psz++;
- i++;
- i++;
- c = (((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));
- break;
- }
- sb->Append((wchar_t)c);
- }
- return sb->ToString();
-}
-
-jobject JNIEnv::MakeLocalRef(System::Object* obj)
-{
- return VM::MakeLocalRef(this, obj);
-}
-
-Object* JNIEnv::UnwrapRef(jobject o)
-{
- return VM::UnwrapRef(this, o);
-}
-
-
-JNIEnv::JNIEnv()
-{
-}
-
-JNIEnv::~JNIEnv()
-{
-}
-
-void JNIEnv::reserved0()
-{
- VM::FatalError("JNIEnv::reserved0");
-}
-
-void JNIEnv::reserved1()
-{
- VM::FatalError("JNIEnv::reserved1");
-}
-
-void JNIEnv::reserved2()
-{
- VM::FatalError("JNIEnv::reserved2");
-}
-
-void JNIEnv::reserved3()
-{
- VM::FatalError("JNIEnv::reserved3");
-}
-
-jstring JNIEnv::NewStringUTF(const char *psz)
-{
- return (jstring)MakeLocalRef(StringFromUTF8(psz));
-}
-
-jstring JNIEnv::NewString(const jchar *unicode, jsize len)
-{
- return (jstring)MakeLocalRef(new String((__wchar_t*)unicode, 0, len));
-}
-
-static jsize StringUTFLength(String* s)
-{
- jsize len = 0;
- for(int i = 0; i < s->Length; i++)
- {
- jchar ch = s->Chars[i];
- if ((ch != 0) && (ch <=0x7f))
- {
- len++;
- }
- else if (ch <= 0x7FF)
- {
- len += 2;
- }
- else
- {
- len += 3;
- }
- }
- return len;
-}
-
-jsize JNICALL JNIEnv::GetStringUTFLength(jstring str)
-{
- String* s = __try_cast<String*>(UnwrapRef(str));
- if(s)
- {
- return StringUTFLength(s);
- }
- ThrowNew(FindClass("java/lang/NullPointerException"), "");
- return 0;
-}
-
-const char* JNIEnv::GetStringUTFChars(jstring str, jboolean *isCopy)
-{
- String* s = __try_cast<String*>(UnwrapRef(str));
- if(s)
- {
- // TODO handle out of memory (what does the unmanaged new do?)
- char *buf = new char[StringUTFLength(s) + 1];
- int j = 0;
- for(int i = 0; i < s->Length; i++)
- {
- jchar ch = s->Chars[i];
- if ((ch != 0) && (ch <=0x7f))
- {
- buf[j++] = (char)ch;
- }
- else if (ch <= 0x7FF)
- {
- /* 11 bits or less. */
- unsigned char high_five = ch >> 6;
- unsigned char low_six = ch & 0x3F;
- buf[j++] = high_five | 0xC0; /* 110xxxxx */
- buf[j++] = low_six | 0x80; /* 10xxxxxx */
- }
- else
- {
- /* possibly full 16 bits. */
- char high_four = ch >> 12;
- char mid_six = (ch >> 6) & 0x3F;
- char low_six = ch & 0x3f;
- buf[j++] = high_four | 0xE0; /* 1110xxxx */
- buf[j++] = mid_six | 0x80; /* 10xxxxxx */
- buf[j++] = low_six | 0x80; /* 10xxxxxx*/
- }
- }
- buf[j] = 0;
- if(isCopy)
- {
- *isCopy = JNI_TRUE;
- }
- return buf;
- }
- else
- {
- ThrowNew(FindClass("java/lang/NullPointerException"), "");
- return 0;
- }
-}
-
-void JNICALL JNIEnv::GetStringRegion(jstring str, jsize start, jsize len, jchar *buf)
-{
- String* s = __try_cast<String*>(UnwrapRef(str));
- if(s)
- {
- if(start > s->Length || s->Length - start < len)
- {
- ThrowNew(FindClass("java/lang/StringIndexOutOfBoundsException"), "");
- return;
- }
- else
- {
- const wchar_t __pin* p = PtrToStringChars(s);
- memcpy(buf, p, len);
- return;
- }
- }
- else
- {
- ThrowNew(FindClass("java/lang/NullPointerException"), "");
- }
-}
-
-void JNICALL JNIEnv::GetStringUTFRegion(jstring str, jsize start, jsize len, char *buf)
-{
- String* s = __try_cast<String*>(UnwrapRef(str));
- if(s)
- {
- if(start > s->Length || s->Length - start < len)
- {
- ThrowNew(FindClass("java/lang/StringIndexOutOfBoundsException"), "");
- return;
- }
- else
- {
- int j = 0;
- for(jsize i = 0; i < len; i++)
- {
- jchar ch = s->Chars[start + i];
- if ((ch != 0) && (ch <=0x7f))
- {
- buf[j++] = (char)ch;
- }
- else if (ch <= 0x7FF)
- {
- /* 11 bits or less. */
- unsigned char high_five = ch >> 6;
- unsigned char low_six = ch & 0x3F;
- buf[j++] = high_five | 0xC0; /* 110xxxxx */
- buf[j++] = low_six | 0x80; /* 10xxxxxx */
- }
- else
- {
- /* possibly full 16 bits. */
- char high_four = ch >> 12;
- char mid_six = (ch >> 6) & 0x3F;
- char low_six = ch & 0x3f;
- buf[j++] = high_four | 0xE0; /* 1110xxxx */
- buf[j++] = mid_six | 0x80; /* 10xxxxxx */
- buf[j++] = low_six | 0x80; /* 10xxxxxx*/
- }
- }
- }
- }
- else
- {
- ThrowNew(FindClass("java/lang/NullPointerException"), "");
- }
-}
-
-const jchar* JNICALL JNIEnv::GetStringCritical(jstring str, jboolean *isCopy)
-{
- String* s = __try_cast<String*>(UnwrapRef(str));
- if(s)
- {
- // TODO handle out of memory (what does the unmanaged new do?)
- jchar* cstring = new jchar[s->Length];
- const wchar_t __pin* p = PtrToStringChars(s);
- memcpy(cstring, p, s->Length * 2);
- if(isCopy)
- {
- *isCopy = JNI_TRUE;
- }
- return cstring;
- }
- ThrowNew(FindClass("java/lang/NullPointerException"), "");
- return 0;
-}
-
-#pragma unmanaged
-void JNIEnv::ReleaseStringUTFChars(jstring str, const char* chars)
-{
- delete[] chars;
-}
-
-void JNICALL JNIEnv::ReleaseStringCritical(jstring string, const jchar* cstring)
-{
- delete[] cstring;
-}
-
-#pragma managed
-jint JNIEnv::ThrowNew(jclass clazz, const char *msg)
-{
- jstring str = NewStringUTF(msg);
- jmethodID constructor = GetMethodID(clazz, "<init>", "(Ljava/lang/String;)V");
- assert(constructor);
- jobject exc = NewObject(clazz, constructor, str);
- DeleteLocalRef(str);
- Throw((jthrowable)exc);
- DeleteLocalRef(exc);
- return JNI_OK;
-}
-
-jint JNICALL JNIEnv::Throw(jthrowable obj)
-{
- //// TODO once we implement PopLocalFrame, we need to make sure that pendingException isn't in the popped local frame
- //pendingException = (jthrowable)NewLocalRef(obj);
- //return JNI_OK;
- throw new InvalidOperationException();
-}
-
-jthrowable JNICALL JNIEnv::ExceptionOccurred()
-{
- //return (jthrowable)NewLocalRef(pendingException);
- throw new InvalidOperationException();
-}
-
-void JNICALL JNIEnv::ExceptionDescribe()
-{
- //if(pendingException)
- //{
- // // when calling JNI methods there cannot be an exception pending, so we clear the exception
- // // temporarily, while we print it
- // jthrowable exception = pendingException;
- // pendingException = 0;
- // jclass cls = FindClass("java/lang/Throwable");
- // if(cls)
- // {
- // jmethodID mid = GetMethodID(cls, "printStackTrace", "()V");
- // DeleteLocalRef(cls);
- // if(mid)
- // {
- // CallVoidMethod(exception, mid);
- // }
- // else
- // {
- // Console::Error->WriteLine(S"JNI internal error: printStackTrace method not found in java.lang.Throwable");
- // }
- // }
- // else
- // {
- // Console::Error->WriteLine(S"JNI internal error: java.lang.Throwable not found");
- // }
- // pendingException = exception;
- //}
- throw new InvalidOperationException();
-}
-
-void JNICALL JNIEnv::ExceptionClear()
-{
- //DeleteLocalRef(pendingException);
- //pendingException = 0;
- throw new InvalidOperationException();
-}
-
-jclass JNIEnv::FindClass(const char *utf)
-{
- try
- {
- return (jclass)MakeLocalRef(VM::FindClass(StringFromUTF8(utf)));
- }
- catch(Exception* x)
- {
- jobject o = MakeLocalRef(x);
- Throw((jthrowable)o);
- DeleteLocalRef(o);
- return 0;
- }
-}
-
-jobject JNIEnv::AllocObject(jclass cls)
-{
- return MakeLocalRef(VM::AllocObject(UnwrapRef(cls)));
-}
-
-jmethodID JNIEnv::FindMethodID(jclass cls, const char* name, const char* sig, bool isstatic)
-{
- jmethodID mid = (jmethodID)(void*)VM::GetMethodCookie(UnwrapRef(cls), StringFromUTF8(name), StringFromUTF8(sig), isstatic);
- if(!mid)
- {
- // TODO set the exception message
- ThrowNew(FindClass("java/lang/NoSuchMethodError"), "");
- return 0;
- }
- return mid;
-}
-
-jfieldID JNIEnv::FindFieldID(jclass cls, const char* name, const char* sig, bool isstatic)
-{
- jfieldID fid = (jfieldID)(void*)VM::GetFieldCookie(UnwrapRef(cls), StringFromUTF8(name), StringFromUTF8(sig), isstatic);
- if(!fid)
- {
- // TODO set the exception message
- ThrowNew(FindClass("java/lang/NoSuchFieldError"), "");
- return 0;
- }
- return fid;
-}
-
-jmethodID JNIEnv::GetStaticMethodID(jclass cls, const char *name, const char *sig)
-{
- return FindMethodID(cls, name, sig, true);
-}
-
-static int GetMethodArgs(jmethodID methodID, char* sig)
-{
- int count = 0;
- String* s = VM::GetMethodArgList(methodID);
- for(int i = 0; i < s->Length; i++)
- {
- *sig++ = (char)s->get_Chars(i);
- count++;
- }
- *sig = 0;
- return count;
-}
-
-Object* JNIEnv::InvokeHelper(jobject object, jmethodID methodID, jvalue* args, bool nonVirtual)
-{
- DebugBreak();
- return 0;
- ////assert(!pendingException);
- //assert(methodID);
-
- //char sig[257];
- //int argc = GetMethodArgs(methodID, sig);
- //Object* argarray __gc[] = new Object*[argc];
- //for(int i = 0; i < argc; i++)
- //{
- // switch(sig[i])
- // {
- // case 'Z':
- // argarray[i] = __box(args[i].z != JNI_FALSE);
- // break;
- // case 'B':
- // argarray[i] = __box((char)args[i].b);
- // break;
- // case 'C':
- // argarray[i] = __box((__wchar_t)args[i].c);
- // break;
- // case 'S':
- // argarray[i] = __box((short)args[i].s);
- // break;
- // case 'I':
- // argarray[i] = __box((int)args[i].i);
- // break;
- // case 'J':
- // argarray[i] = __box((__int64)args[i].j);
- // break;
- // case 'F':
- // argarray[i] = __box((float)args[i].f);
- // break;
- // case 'D':
- // argarray[i] = __box((double)args[i].d);
- // break;
- // case 'L':
- // argarray[i] = UnwrapRef(args[i].l);
- // break;
- // }
- //}
- //try
- //{
- // return VM::InvokeMethod(methodID, UnwrapRef(object), argarray, nonVirtual);
- //}
- //catch(Exception* x)
- //{
- // jobject o = MakeLocalRef(x);
- // Throw((jthrowable)o);
- // DeleteLocalRef(o);
- // return 0;
- //}
-}
-
-void JNICALL JNIEnv::CallStaticVoidMethodA(jclass cls, jmethodID methodID, jvalue* args)
-{
- InvokeHelper(0, methodID, args, false);
-}
-#pragma unmanaged
-
-void JNICALL JNIEnv::CallStaticVoidMethodV(jclass clazz, jmethodID methodID, va_list args)
-{
- char arglist[257];
- int argc = GetMethodArgs(methodID, arglist);
- jvalue* argarray = (jvalue*)_alloca(argc * sizeof(jvalue));
- for(int i = 0; i < argc; i++)
- {
- switch(arglist[i])
- {
- case 'Z':
- case 'B':
- case 'S':
- case 'C':
- case 'I':
- argarray[i].i = va_arg(args, int);
- break;
- case 'J':
- argarray[i].j = va_arg(args, __int64);
- break;
- case 'L':
- argarray[i].l = va_arg(args, jobject);
- break;
- case 'D':
- argarray[i].d = va_arg(args, double);
- break;
- case 'F':
- argarray[i].f = (float)va_arg(args, double);
- break;
- }
- }
- CallStaticVoidMethodA(clazz, methodID, argarray);
-}
-
-void JNIEnv::CallStaticVoidMethod(jclass clazz, jmethodID methodID, ...)
-{
- va_list args;
- va_start(args, methodID);
- CallStaticVoidMethodV(clazz, methodID, args);
- va_end(args);
-}
-
-#define STATIC_METHOD_IMPL(Type,type) \
-type JNICALL JNIEnv::CallStatic##Type##MethodV(jclass clazz, jmethodID methodID, va_list args)\
-{\
- char sig[257];\
- int argc = GetMethodArgs(methodID, sig);\
- jvalue* argarray = (jvalue*)_alloca(argc * sizeof(jvalue));\
- for(int i = 0; i < argc; i++)\
- {\
- switch(sig[i])\
- {\
- case 'Z':\
- case 'B':\
- case 'S':\
- case 'C':\
- case 'I':\
- argarray[i].i = va_arg(args, int);\
- break;\
- case 'J':\
- argarray[i].j = va_arg(args, __int64);\
- break;\
- case 'L':\
- argarray[i].l = va_arg(args, jobject);\
- break;\
- case 'D':\
- argarray[i].d = va_arg(args, double);\
- break;\
- case 'F':\
- argarray[i].f = (float)va_arg(args, double);\
- break;\
- }\
- }\
- return CallStatic##Type##MethodA(clazz, methodID, argarray);\
-}\
-type JNIEnv::CallStatic##Type##Method(jclass clazz, jmethodID methodID, ...)\
-{\
- va_list args;\
- va_start(args, methodID);\
- type ret = CallStatic##Type##MethodV(clazz, methodID, args);\
- va_end(args);\
- return ret;\
-}
-#define STATIC_METHOD_IMPL_MANAGED(Type,type,cpptype) \
-type JNICALL JNIEnv::CallStatic##Type##MethodA(jclass cls, jmethodID methodID, jvalue* args)\
-{\
- Object* ret = InvokeHelper(0, methodID, args, false);\
- if(ret) return __unbox<cpptype>(ret);\
- return 0;\
-}
-
-STATIC_METHOD_IMPL(Object,jobject)
-STATIC_METHOD_IMPL(Boolean,jboolean)
-STATIC_METHOD_IMPL(Byte,jbyte)
-STATIC_METHOD_IMPL(Char,jchar)
-STATIC_METHOD_IMPL(Short,jshort)
-STATIC_METHOD_IMPL(Int,jint)
-STATIC_METHOD_IMPL(Long,jlong)
-STATIC_METHOD_IMPL(Float,jfloat)
-STATIC_METHOD_IMPL(Double,jdouble)
-#pragma managed
-STATIC_METHOD_IMPL_MANAGED(Boolean,jboolean,bool)
-STATIC_METHOD_IMPL_MANAGED(Byte,jbyte,System::SByte)
-STATIC_METHOD_IMPL_MANAGED(Char,jchar,wchar_t)
-STATIC_METHOD_IMPL_MANAGED(Short,jshort,short)
-STATIC_METHOD_IMPL_MANAGED(Int,jint,int)
-STATIC_METHOD_IMPL_MANAGED(Long,jlong,__int64)
-STATIC_METHOD_IMPL_MANAGED(Float,jfloat,float)
-STATIC_METHOD_IMPL_MANAGED(Double,jdouble,double)
-
-// special case for Object
-jobject JNICALL JNIEnv::CallStaticObjectMethodA(jclass cls, jmethodID methodID, jvalue* args)
-{
- return MakeLocalRef(InvokeHelper(0, methodID, args, false));
-}
-
-#pragma unmanaged
-jmethodID JNIEnv::GetMethodID(jclass cls, const char *name, const char *sig)
-{
- return FindMethodID(cls, name, sig, false);
-}
-
-jfieldID JNICALL JNIEnv::GetFieldID(jclass cls, const char *name, const char *sig)
-{
- return FindFieldID(cls, name, sig, false);
-}
-
-jfieldID JNICALL JNIEnv::GetStaticFieldID(jclass cls, const char *name, const char *sig)
-{
- return FindFieldID(cls, name, sig, true);
-}
-
-#pragma managed
-#define GET_SET_FIELD(Type,type,cpptype) \
-void JNICALL JNIEnv::Set##Type##Field(jobject obj, jfieldID fieldID, type val)\
-{\
- VM::SetFieldValue((IntPtr)fieldID, UnwrapRef(obj), __box((cpptype)val));\
-}\
-type JNICALL JNIEnv::Get##Type##Field(jobject obj, jfieldID fieldID)\
-{\
- return __unbox<cpptype>(VM::GetFieldValue((IntPtr)fieldID, UnwrapRef(obj)));\
-}\
-void JNICALL JNIEnv::SetStatic##Type##Field(jclass clazz, jfieldID fieldID, type val)\
-{\
- /* // TODO consider checking that clazz is the right object */ \
- VM::SetFieldValue((IntPtr)fieldID, 0, __box((cpptype)val));\
-}\
-type JNICALL JNIEnv::GetStatic##Type##Field(jclass clazz, jfieldID fieldID)\
-{\
- /* // TODO consider checking that clazz is the right object */ \
- return __unbox<cpptype>(VM::GetFieldValue((IntPtr)fieldID, 0));\
-}
-
-#pragma warning (push)
-// stop the compiler from wanking about "forcing value to bool 'true' or 'false' (performance warning)"
-#pragma warning (disable : 4800)
-GET_SET_FIELD(Boolean,jboolean,bool)
-#pragma warning (pop)
-GET_SET_FIELD(Byte,jbyte,System::SByte)
-GET_SET_FIELD(Char,jchar,wchar_t)
-GET_SET_FIELD(Short,jshort,short)
-GET_SET_FIELD(Int,jint,int)
-GET_SET_FIELD(Long,jlong,__int64)
-GET_SET_FIELD(Float,jfloat,float)
-GET_SET_FIELD(Double,jdouble,double)
-
-void JNICALL JNIEnv::SetObjectField(jobject obj, jfieldID fieldID, jobject val)
-{
- VM::SetFieldValue((IntPtr)fieldID, UnwrapRef(obj), UnwrapRef(val));
-}
-
-jobject JNICALL JNIEnv::GetObjectField(jobject obj, jfieldID fieldID)
-{
- return MakeLocalRef(VM::GetFieldValue((IntPtr)fieldID, UnwrapRef(obj)));
-}
-
-void JNICALL JNIEnv::SetStaticObjectField(jclass clazz, jfieldID fieldID, jobject val)
-{
- VM::SetFieldValue((IntPtr)fieldID, 0, UnwrapRef(val));
-}
-
-jobject JNICALL JNIEnv::GetStaticObjectField(jclass clazz, jfieldID fieldID)
-{
- return MakeLocalRef(VM::GetFieldValue((IntPtr)fieldID, 0));
-}
-
-#pragma unmanaged
-
-#define METHOD_IMPL(Type,type) \
-type JNIEnv::Call##Type##Method(jobject obj, jmethodID methodID, ...) \
-{\
- va_list args;\
- va_start(args, methodID);\
- type ret = Call##Type##MethodV(obj, methodID, args);\
- va_end(args);\
- return ret;\
-}\
-type JNIEnv::CallNonvirtual##Type##Method(jobject obj, jclass clazz, jmethodID methodID, ...) \
-{\
- va_list args;\
- va_start(args, methodID);\
- type ret = CallNonvirtual##Type##MethodV(obj, clazz, methodID, args);\
- va_end(args);\
- return ret;\
-}\
-type JNICALL JNIEnv::Call##Type##MethodV(jobject obj, jmethodID methodID, va_list args)\
-{\
- char sig[257];\
- int argc = GetMethodArgs(methodID, sig);\
- jvalue* argarray = (jvalue*)_alloca(argc * sizeof(jvalue));\
- for(int i = 0; i < argc; i++)\
- {\
- switch(sig[i])\
- {\
- case 'Z':\
- case 'B':\
- case 'S':\
- case 'C':\
- case 'I':\
- argarray[i].i = va_arg(args, int);\
- break;\
- case 'J':\
- argarray[i].j = va_arg(args, __int64);\
- break;\
- case 'L':\
- argarray[i].l = va_arg(args, jobject);\
- break;\
- case 'D':\
- argarray[i].d = va_arg(args, double);\
- break;\
- case 'F':\
- argarray[i].f = (float)va_arg(args, double);\
- break;\
- }\
- }\
- return Call##Type##MethodA(obj, methodID, argarray);\
-}\
-type JNICALL JNIEnv::CallNonvirtual##Type##MethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args)\
-{\
- char sig[257];\
- int argc = GetMethodArgs(methodID, sig);\
- jvalue* argarray = (jvalue*)_alloca(argc * sizeof(jvalue));\
- for(int i = 0; i < argc; i++)\
- {\
- switch(sig[i])\
- {\
- case 'Z':\
- case 'B':\
- case 'S':\
- case 'C':\
- case 'I':\
- argarray[i].i = va_arg(args, int);\
- break;\
- case 'J':\
- argarray[i].j = va_arg(args, __int64);\
- break;\
- case 'L':\
- argarray[i].l = va_arg(args, jobject);\
- break;\
- case 'D':\
- argarray[i].d = va_arg(args, double);\
- break;\
- case 'F':\
- argarray[i].f = (float)va_arg(args, double);\
- break;\
- }\
- }\
- return CallNonvirtual##Type##MethodA(obj, clazz, methodID, argarray);\
-}
-
-#define METHOD_IMPL_MANAGED(Type,type,cpptype) \
-type JNICALL JNIEnv::Call##Type##MethodA(jobject obj, jmethodID methodID, jvalue* args)\
-{\
- Object* ret = InvokeHelper(obj, methodID, args, false);\
- if(ret) return __unbox<cpptype>(ret);\
- return 0;\
-}\
-type JNICALL JNIEnv::CallNonvirtual##Type##MethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue* args)\
-{\
- Object* ret = InvokeHelper(obj, methodID, args, true);\
- if(ret) return __unbox<cpptype>(ret);\
- return 0;\
-}
-
-#pragma unmanaged
-METHOD_IMPL(Object,jobject)
-METHOD_IMPL(Boolean,jboolean)
-METHOD_IMPL(Byte,jbyte)
-METHOD_IMPL(Char,jchar)
-METHOD_IMPL(Short,jshort)
-METHOD_IMPL(Int,jint)
-METHOD_IMPL(Long,jlong)
-METHOD_IMPL(Float,jfloat)
-METHOD_IMPL(Double,jdouble)
-#pragma managed
-METHOD_IMPL_MANAGED(Boolean,jboolean,bool)
-METHOD_IMPL_MANAGED(Byte,jbyte,System::SByte)
-METHOD_IMPL_MANAGED(Char,jchar,wchar_t)
-METHOD_IMPL_MANAGED(Short,jshort,short)
-METHOD_IMPL_MANAGED(Int,jint,int)
-METHOD_IMPL_MANAGED(Long,jlong,__int64)
-METHOD_IMPL_MANAGED(Float,jfloat,float)
-METHOD_IMPL_MANAGED(Double,jdouble,double)
-
-// special case for Object, because we need to convert the reference to a localref
-jobject JNICALL JNIEnv::CallObjectMethodA(jobject obj, jmethodID methodID, jvalue* args)
-{
- return MakeLocalRef(InvokeHelper(obj, methodID, args, false));
-}
-jobject JNICALL JNIEnv::CallNonvirtualObjectMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue* args)
-{
- return MakeLocalRef(InvokeHelper(obj, methodID, args, true));
-}
-#pragma unmanaged
-
-void JNIEnv::CallVoidMethod(jobject obj, jmethodID methodID, ...)
-{
- va_list args;
- va_start(args, methodID);
- CallVoidMethodV(obj, methodID, args);
- va_end(args);
-}
-
-void JNIEnv::CallNonvirtualVoidMethod(jobject obj, jclass clazz, jmethodID methodID, ...)
-{
- va_list args;
- va_start(args, methodID);
- CallNonvirtualVoidMethodV(obj, clazz, methodID, args);
- va_end(args);
-}
-
-void JNICALL JNIEnv::CallVoidMethodV(jobject obj, jmethodID methodID, va_list args)
-{
- char sig[257];
- int argc = GetMethodArgs(methodID, sig);
- jvalue* argarray = (jvalue*)_alloca(argc * sizeof(jvalue));
- for(int i = 0; i < argc; i++)
- {
- switch(sig[i])
- {
- case 'Z':
- case 'B':
- case 'S':
- case 'C':
- case 'I':
- argarray[i].i = va_arg(args, int);
- break;
- case 'J':
- argarray[i].j = va_arg(args, __int64);
- break;
- case 'L':
- argarray[i].l = va_arg(args, jobject);
- break;
- case 'D':
- argarray[i].d = va_arg(args, double);
- break;
- case 'F':
- argarray[i].f = (float)va_arg(args, double);
- break;
- }
- }
- CallVoidMethodA(obj, methodID, argarray);
-}
-
-void JNICALL JNIEnv::CallNonvirtualVoidMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args)
-{
- char sig[257];
- int argc = GetMethodArgs(methodID, sig);
- jvalue* argarray = (jvalue*)_alloca(argc * sizeof(jvalue));
- for(int i = 0; i < argc; i++)
- {
- switch(sig[i])
- {
- case 'Z':
- case 'B':
- case 'S':
- case 'C':
- case 'I':
- argarray[i].i = va_arg(args, int);
- break;
- case 'J':
- argarray[i].j = va_arg(args, __int64);
- break;
- case 'L':
- argarray[i].l = va_arg(args, jobject);
- break;
- case 'D':
- argarray[i].d = va_arg(args, double);
- break;
- case 'F':
- argarray[i].f = (float)va_arg(args, double);
- break;
- }
- }
- CallNonvirtualVoidMethodA(obj, clazz, methodID, argarray);
-}
-
-#pragma managed
-void JNICALL JNIEnv::CallVoidMethodA(jobject obj, jmethodID methodID, jvalue* args)
-{
- InvokeHelper(obj, methodID, args, false);
-}
-
-void JNICALL JNIEnv::CallNonvirtualVoidMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue* args)
-{
- InvokeHelper(obj, methodID, args, true);
-}
-
-jsize JNIEnv::GetStringLength(jstring str)
-{
- String* s = __try_cast<String*>(UnwrapRef(str));
- return s->Length;
-}
-
-const jchar* JNIEnv::GetStringChars(jstring str, jboolean *isCopy)
-{
- String* s = __try_cast<String*>(UnwrapRef(str));
- jchar* p = new jchar[s->Length];
- for(int i = 0; i < s->Length; i++)
- {
- p[i] = s->Chars[i];
- }
- if(isCopy)
- {
- *isCopy = JNI_TRUE;
- }
- return p;
-}
-
-void JNIEnv::ReleaseStringChars(jstring str, const jchar *chars)
-{
- delete[] chars;
-}
-
-jsize JNIEnv::GetArrayLength(jarray array)
-{
- Array* ar = __try_cast<Array*>(UnwrapRef(array));
- return ar->Length;
-}
-
-#define NEW_ARRAY(Type,type,cpptype) \
-type##Array JNIEnv::New##Type##Array(jsize len)\
-{\
- try\
- {\
- return (type##Array)MakeLocalRef(new cpptype __gc[len]);\
- }\
- catch(OutOfMemoryException*)\
- {\
- ThrowNew(FindClass("java/lang/OutOfMemoryError"), "");\
- return 0;\
- }\
-}
-
-#pragma warning (push)
-// stop the compiler from wanking about "forcing value to bool 'true' or 'false' (performance warning)"
-#pragma warning (disable : 4800)
-NEW_ARRAY(Boolean, jboolean, bool)
-#pragma warning (pop)
-NEW_ARRAY(Byte, jbyte, System::SByte)
-NEW_ARRAY(Char, jchar, wchar_t)
-NEW_ARRAY(Short, jshort, short)
-NEW_ARRAY(Int, jint, int)
-NEW_ARRAY(Long, jlong, __int64)
-NEW_ARRAY(Float, jfloat, float)
-NEW_ARRAY(Double, jdouble, double)
-
-jobjectArray JNIEnv::NewObjectArray(jsize len, jclass clazz, jobject init)
-{
- try
- {
- Object* ar __gc[] = new Object* __gc[len];
- Object* o = UnwrapRef(init);
- if(o)
- {
- for(jsize i = 0; i < len; i++)
- {
- ar[i] = o;
- }
- }
- return (jobjectArray)MakeLocalRef(ar);
- }
- catch(OutOfMemoryException*)
- {
- ThrowNew(FindClass("java/lang/OutOfMemoryError"), "");
- return 0;
- }
-}
-
-void JNIEnv::SetObjectArrayElement(jobjectArray array, jsize index, jobject val)
-{
- Object* ar __gc[] = __try_cast<Object* __gc[]>(UnwrapRef(array));
- if(index >= ar->Length)
- {
- // TODO handle error
- assert(false);
- }
- ar[index] = UnwrapRef(val);
-}
-
-jobject JNIEnv::GetObjectArrayElement(jobjectArray array, jsize index)
-{
- Object* ar __gc[] = __try_cast<Object* __gc[]>(UnwrapRef(array));
- if(index >= ar->Length)
- {
- // TODO handle error
- assert(false);
- }
- return MakeLocalRef(ar[index]);
-}
-
-#define GET_SET_ARRAY_REGION(Name, JavaType, ClrType) \
-void JNICALL JNIEnv::Get##Name##ArrayRegion(JavaType##Array array, jsize start, jsize l, JavaType *buf) \
-{ \
- ClrType ar __gc[] = __try_cast<ClrType __gc[]>(UnwrapRef(array)); \
- for(; l != 0; l--) \
- { \
- *buf++ = ar[start++]; \
- } \
-} \
-void JNICALL JNIEnv::Set##Name##ArrayRegion(JavaType##Array array, jsize start, jsize l, JavaType *buf) \
-{ \
- ClrType ar __gc[] = __try_cast<ClrType __gc[]>(UnwrapRef(array)); \
- for(; l != 0; l--) \
- { \
- ar[start++] = *buf++; \
- } \
-}
-
-#pragma warning (push)
-// stop the compiler from wanking about "forcing value to bool 'true' or 'false' (performance warning)"
-#pragma warning (disable : 4800)
-GET_SET_ARRAY_REGION(Boolean, jboolean, bool)
-#pragma warning (pop)
-GET_SET_ARRAY_REGION(Byte, jbyte, System::SByte)
-GET_SET_ARRAY_REGION(Char, jchar, wchar_t)
-GET_SET_ARRAY_REGION(Short, jshort, short)
-GET_SET_ARRAY_REGION(Int, jint, int)
-GET_SET_ARRAY_REGION(Long, jlong, __int64)
-GET_SET_ARRAY_REGION(Float, jfloat, float)
-GET_SET_ARRAY_REGION(Double, jdouble, double)
-
-#define GET_SET_ARRAY_ELEMENTS(Type,type,cpptype) \
-type* JNIEnv::Get##Type##ArrayElements(type##Array array, jboolean *isCopy)\
-{\
- cpptype ar __gc[] = __try_cast<cpptype __gc[]>(UnwrapRef(array));\
- type* p = new type[ar->Length];\
- if(ar->Length)\
- {\
- cpptype __pin* par = &ar[0];\
- memcpy(p, par, ar->Length * sizeof(cpptype));\
- }\
- if(isCopy)\
- {\
- *isCopy = JNI_TRUE;\
- }\
- return p;\
-}\
-void JNIEnv::Release##Type##ArrayElements(type##Array array, type *elems, jint mode)\
-{\
- if(mode == 0 || mode == JNI_COMMIT)\
- {\
- cpptype ar __gc[] = __try_cast<cpptype __gc[]>(UnwrapRef(array));\
- if(ar->Length)\
- {\
- cpptype __pin* p = &ar[0];\
- memcpy(p, elems, ar->Length * sizeof(cpptype));\
- }\
- }\
- if(mode == 0 || mode == JNI_ABORT)\
- {\
- delete[] elems;\
- }\
-}
-
-#pragma warning (push)
-// stop the compiler from wanking about "forcing value to bool 'true' or 'false' (performance warning)"
-#pragma warning (disable : 4800)
-GET_SET_ARRAY_ELEMENTS(Boolean,jboolean,bool)
-#pragma warning (pop)
-GET_SET_ARRAY_ELEMENTS(Byte,jbyte,System::SByte)
-GET_SET_ARRAY_ELEMENTS(Char,jchar,wchar_t)
-GET_SET_ARRAY_ELEMENTS(Short,jshort,short)
-GET_SET_ARRAY_ELEMENTS(Int,jint,int)
-GET_SET_ARRAY_ELEMENTS(Long,jlong,__int64)
-GET_SET_ARRAY_ELEMENTS(Float,jfloat,float)
-GET_SET_ARRAY_ELEMENTS(Double,jdouble,double)
-
-#pragma unmanaged
-jobject JNICALL JNIEnv::NewObject(jclass clazz, jmethodID methodID, ...)
-{
- va_list args;
- va_start(args, methodID);
- jobject o = NewObjectV(clazz, methodID, args);
- va_end(args);
- return o;
-}
-
-jobject JNICALL JNIEnv::NewObjectV(jclass clazz, jmethodID methodID, va_list args)
-{
- char sig[257];
- int argc = GetMethodArgs(methodID, sig);
- jvalue* argarray = (jvalue*)_alloca(argc * sizeof(jvalue));
- for(int i = 0; i < argc; i++)
- {
- switch(sig[i])
- {
- case 'Z':
- case 'B':
- case 'S':
- case 'C':
- case 'I':
- argarray[i].i = va_arg(args, int);
- break;
- case 'J':
- argarray[i].j = va_arg(args, __int64);
- break;
- case 'L':
- argarray[i].l = va_arg(args, jobject);
- break;
- case 'D':
- argarray[i].d = va_arg(args, double);
- break;
- case 'F':
- argarray[i].f = (float)va_arg(args, double);
- break;
- }
- }
- return NewObjectA(clazz, methodID, argarray);
-}
-
-#pragma managed
-jobject JNICALL JNIEnv::NewObjectA(jclass clazz, jmethodID methodID, jvalue *args)
-{
- return MakeLocalRef(InvokeHelper(0, methodID, args, false));
-}
-
-jclass JNICALL JNIEnv::GetObjectClass(jobject obj)
-{
- if(obj)
- {
- return (jclass)MakeLocalRef(VM::GetObjectClass(UnwrapRef(obj)));
- }
- ThrowNew(FindClass("java/lang/NullPointerException"), "");
- return 0;
-}
-
-jboolean JNICALL JNIEnv::IsInstanceOf(jobject obj, jclass clazz)
-{
- if(clazz)
- {
- return obj && VM::IsInstanceOf(UnwrapRef(obj), UnwrapRef(clazz));
- }
- ThrowNew(FindClass("java/lang/NullPointerException"), "");
- return JNI_FALSE;
-}
-
-jboolean JNICALL JNIEnv::IsAssignableFrom(jclass sub, jclass sup)
-{
- if(sub && sup)
- {
- return VM::IsAssignableFrom(UnwrapRef(sub), UnwrapRef(sup));
- }
- ThrowNew(FindClass("java/lang/NullPointerException"), "");
- return JNI_FALSE;
-}
-
-jclass JNICALL JNIEnv::GetSuperclass(jclass sub)
-{
- if(sub)
- {
- return (jclass)MakeLocalRef(VM::GetSuperclass(UnwrapRef(sub)));
- }
- ThrowNew(FindClass("java/lang/NullPointerException"), "");
- return 0;
-}
-
-jobject JNICALL JNIEnv::NewLocalRef(jobject ref)
-{
- return MakeLocalRef(UnwrapRef(ref));
-}
-
-jobject JNICALL JNIEnv::NewGlobalRef(jobject obj)
-{
- //if(!obj)
- //{
- // return 0;
- //}
- //// TODO search for an empty slot before adding it to the end...
- //return (jobject)-(GlobalRefs::globalRefs->Add(UnwrapRef(obj)) + 1);
- throw new InvalidOperationException();
-}
-
-void JNICALL JNIEnv::DeleteGlobalRef(jobject gref)
-{
- //int i = int(gref);
- //if(i < 0)
- //{
- // GlobalRefs::globalRefs->Item[(-i) - 1] = 0;
- // return;
- //}
- //if(i > 0)
- //{
- // DebugBreak();
- //}
- throw new InvalidOperationException();
-}
-
-void JNICALL JNIEnv::DeleteLocalRef(jobject obj)
-{
- //int i = (int)obj;
- //if(i > 0)
- //{
- // localRefs[i >> LOCAL_REF_SHIFT].DeleteLocalRef(i & LOCAL_REF_MASK);
- // return;
- //}
- //if(i < 0)
- //{
- // Console::WriteLine("bogus localref in DeleteLocalRef");
- // DebugBreak();
- //}
- throw new InvalidOperationException();
-}
-
-jboolean JNICALL JNIEnv::IsSameObject(jobject obj1, jobject obj2)
-{
- return UnwrapRef(obj1) == UnwrapRef(obj2);
-}
-
-jint JNICALL JNIEnv::MonitorEnter(jobject obj)
-{
- Object* o = UnwrapRef(obj);
- if(o)
- {
- try
- {
- System::Threading::Monitor::Enter(o);
- return JNI_OK;
- }
- catch(System::Threading::ThreadInterruptedException*)
- {
- ThrowNew(FindClass("java/lang/InterruptedException"), "");
- return JNI_ERR;
- }
- }
- ThrowNew(FindClass("java/lang/NullPointerException"), "");
- return JNI_ERR;
-}
-
-jint JNICALL JNIEnv::MonitorExit(jobject obj)
-{
- Object* o = UnwrapRef(obj);
- if(o)
- {
- try
- {
- System::Threading::Monitor::Exit(o);
- return JNI_OK;
- }
- catch(System::Threading::SynchronizationLockException*)
- {
- ThrowNew(FindClass("java/lang/IllegalMonitorStateException"), "");
- return JNI_ERR;
- }
- }
- ThrowNew(FindClass("java/lang/NullPointerException"), "");
- return JNI_ERR;
-}
-
-#pragma unmanaged
-jint JNICALL JNIEnv::GetJavaVM(JavaVM **vm)
-{
- static JavaVM theVM;
- *vm = &theVM;
- return 0;
-}
-
-#pragma managed
-static jsize GetPrimitiveArrayElementSize(Array* ar)
-{
- Type* type = ar->GetType()->GetElementType();
- if(type == __typeof(System::SByte) || type == __typeof(System::Boolean))
- {
- return 1;
- }
- else if(type == __typeof(System::Int16) || type == __typeof(System::Char))
- {
- return 2;
- }
- else if(type == __typeof(System::Int32) || type == __typeof(System::Single))
- {
- return 4;
- }
- else if(type == __typeof(System::Int64) || type == __typeof(System::Double))
- {
- return 8;
- }
- else
- {
- assert(false);
- return 1;
- }
-}
-
-void* JNICALL JNIEnv::GetPrimitiveArrayCritical(jarray array, jboolean *isCopy)
-{
- Array* ar = __try_cast<Array*>(UnwrapRef(array));
- int len = ar->Length * GetPrimitiveArrayElementSize(ar);
- GCHandle h = GCHandle::Alloc(ar, GCHandleType::Pinned);
- try
- {
- char* buf = new char[len];
- if(!buf)
- {
- // TODO throw OutOfMemoryError
- assert(false);
- return 0;
- }
- memcpy(buf, (void*)h.AddrOfPinnedObject(), len);
- if(isCopy)
- {
- *isCopy = JNI_TRUE;
- }
- return buf;
- }
- __finally
- {
- h.Free();
- }
-}
-
-void JNICALL JNIEnv::ReleasePrimitiveArrayCritical(jarray array, void *carray, jint mode)
-{
- if(mode == 0 || mode == JNI_COMMIT)
- {
- Array* ar = __try_cast<Array*>(UnwrapRef(array));
- int len = ar->Length * GetPrimitiveArrayElementSize(ar);
- GCHandle h = GCHandle::Alloc(ar, GCHandleType::Pinned);
- try
- {
- memcpy((void*)h.AddrOfPinnedObject(), carray, len);
- }
- __finally
- {
- h.Free();
- }
- }
- if(mode == 0 || mode == JNI_ABORT)
- {
- delete[] (char*)carray;
- }
-}
-
-jint JNICALL JNIEnv::GetVersion()
-{
- // We implement (part of) JNI version 1.4
- return JNI_VERSION_1_4;
-}
-
-jboolean JNICALL JNIEnv::ExceptionCheck()
-{
- //return pendingException != 0;
- throw new InvalidOperationException();
-}
-
-jmethodID JNICALL JNIEnv::FromReflectedMethod(jobject method)
-{
- return (jmethodID)(void*)VM::MethodToCookie(UnwrapRef(method));
-}
-
-jfieldID JNICALL JNIEnv::FromReflectedField(jobject field)
-{
- return (jfieldID)(void*)VM::FieldToCookie(UnwrapRef(field));
-}
-
-jobject JNICALL JNIEnv::ToReflectedMethod(jclass clazz, jmethodID methodID)
-{
- return MakeLocalRef(VM::CookieToMethod(methodID));
-}
-
-jobject JNICALL JNIEnv::ToReflectedField(jclass clazz, jfieldID fieldID)
-{
- return MakeLocalRef(VM::CookieToField(fieldID));
-}
-
-void JNICALL JNIEnv::FatalError(const char *msg)
-{
- VM::FatalError(StringFromUTF8(msg));
-}
-
-jclass JNICALL JNIEnv::DefineClass(const char *name, jobject loader, const jbyte *buf, jsize len)
-{
- System::Byte array __gc[] = new System::Byte __gc[len];
- Marshal::Copy((void*)buf, array, 0, len);
- return (jclass)MakeLocalRef(VM::DefineClass(StringFromUTF8(name), UnwrapRef(loader), array));
-}
-
-void JavaVM::reserved0()
-{
- VM::FatalError("JavaVM::reserved0");
-}
-
-void JavaVM::reserved1()
-{
- VM::FatalError("JavaVM::reserved1");
-}
-
-void JavaVM::reserved2()
-{
- VM::FatalError("JavaVM::reserved2");
-}
-
-jint JavaVM::DestroyJavaVM()
-{
- return JNI_ERR;
-}
-
-#pragma unmanaged
-static void AttachCurrentThread_NotImplemented()
-{
- assert(false);
- _asm int 3
-}
-
-#pragma managed
-jint JavaVM::AttachCurrentThread(void **penv, void *args)
-{
- // TODO do we need a new local ref frame?
- // TODO for now we only support attaching to an existing thread
- // TODO support args (JavaVMAttachArgs)
- JNIEnv* p = VM::GetEnv();
- if(p)
- {
- *penv = p;
- return JNI_OK;
- }
- AttachCurrentThread_NotImplemented();
- return JNI_ERR;
-}
-#pragma unmanaged
-
-jint JavaVM::DetachCurrentThread()
-{
- assert(false);
- _asm int 3
-}
-
-#pragma managed
-jint JavaVM::GetEnv(void **penv, jint version)
-{
- // TODO we should check the version
- JNIEnv* p = VM::GetEnv();
- if(p)
- {
- *penv = p;
- return JNI_OK;
- }
- return JNI_EDETACHED;
-}
-
-jint JNICALL JNIEnv::RegisterNatives(jclass clazz, const JNINativeMethod *methods, jint nMethods)
-{
- Object* pclass = UnwrapRef(clazz);
- for(int i = 0; i < nMethods; i++)
- {
- if(!VM::SetNativeMethodPointer(pclass, StringFromUTF8(methods[i].name), StringFromUTF8(methods[i].signature), methods[i].fnPtr))
- {
- // TODO set the exception message
- ThrowNew(FindClass("java/lang/NoSuchMethodError"), "");
- return JNI_ERR;
- }
- }
- return JNI_OK;
-}
-
-jint JNICALL JNIEnv::UnregisterNatives(jclass clazz)
-{
- VM::ResetNativeMethodPointers(UnwrapRef(clazz));
- return JNI_OK;
-}
-
-#pragma unmanaged
-
-jint JavaVM::AttachCurrentThreadAsDaemon(void **penv, void *args)
-{
- assert(false);
- _asm int 3
-}
-
-////////////////////////////////////////////////////////////////////////////
-#pragma warning (disable : 4035)
-
-jint JNICALL JNIEnv::PushLocalFrame(jint capacity) { assert(false); _asm int 3}
-jobject JNICALL JNIEnv::PopLocalFrame(jobject result) { assert(false); _asm int 3}
-jint JNICALL JNIEnv::EnsureLocalCapacity(jint capacity) { assert(false); _asm int 3}
-
-jweak JNICALL JNIEnv::NewWeakGlobalRef(jobject obj) { assert(false); _asm int 3}
-void JNICALL JNIEnv::DeleteWeakGlobalRef(jweak ref) { assert(false); _asm int 3}
-
-jobject JNICALL JNIEnv::NewDirectByteBuffer(void* address, jlong capacity) { assert(false); _asm int 3}
-void* JNICALL JNIEnv::GetDirectBufferAddress(jobject buf) { assert(false); _asm int 3}
-jlong JNICALL JNIEnv::GetDirectBufferCapacity(jobject buf) { assert(false); _asm int 3}
diff --git a/jni/clr-win32/jnienv.h b/jni/clr-win32/jnienv.h
deleted file mode 100644
index 7978f47e..00000000
--- a/jni/clr-win32/jnienv.h
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
- Copyright (C) 2002, 2003, 2004 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
-
-*/
-
-#include <vcclr.h>
-
-using namespace System;
-using namespace System::Runtime::InteropServices;
-
-#pragma unmanaged
-
-#define JNI_TRUE 1
-#define JNI_FALSE 0
-
-typedef struct {
- char *name;
- char *signature;
- void *fnPtr;
-} JNINativeMethod;
-
-#define JNI_VERSION_1_1 0x00010001
-#define JNI_VERSION_1_2 0x00010002
-#define JNI_VERSION_1_4 0x00010004
-
-/*
- * possible return values for JNI functions.
- */
-
-#define JNI_OK 0
-#define JNI_ERR (-1)
-#define JNI_EDETACHED (-2)
-#define JNI_EVERSION (-3)
-/*
- * used in ReleaseScalarArrayElements
- */
-
-#define JNI_COMMIT 1
-#define JNI_ABORT 2
-
-class JavaVM;
-
-#define JNIEXPORT
-#define JNICALL __stdcall
-
-#ifndef _HELPERTYPES_
-#define _HELPERTYPES_
-class _jobject {};
-class _jclass : public _jobject {};
-class _jstring : public _jobject {};
-class _jthrowable : public _jobject {};
-class Array$ : public _jobject {};
-class ObjectArray$ : public Array$ {};
-class BooleanArray$ : public Array$ {};
-class ByteArray$ : public Array$ {};
-class CharArray$ : public Array$ {};
-class ShortArray$ : public Array$ {};
-class IntArray$ : public Array$ {};
-class LongArray$ : public Array$ {};
-class FloatArray$ : public Array$ {};
-class DoubleArray$ : public Array$ {};
-#endif //_HELPERTYPES_
-
-typedef class _jclass* jclass;
-typedef class _jobject* jobject;
-typedef jobject jweak;
-typedef class _jstring* jstring;
-typedef class _jthrowable* jthrowable;
-typedef class Array$* jarray;
-typedef class ObjectArray$* jobjectArray;
-typedef class BooleanArray$* jbooleanArray;
-typedef class ByteArray$* jbyteArray;
-typedef class CharArray$* jcharArray;
-typedef class ShortArray$* jshortArray;
-typedef class IntArray$* jintArray;
-typedef class LongArray$* jlongArray;
-typedef class FloatArray$* jfloatArray;
-typedef class DoubleArray$* jdoubleArray;
-typedef struct _jmethodID* jmethodID;
-typedef struct _jfieldID* jfieldID;
-
-struct _jmethodID
-{
-};
-
-struct _jfieldID
-{
-};
-
-/*
- * JNI Types
- */
-
-typedef unsigned char jboolean;
-typedef unsigned short jchar;
-typedef short jshort;
-typedef float jfloat;
-typedef double jdouble;
-
-typedef long jint;
-typedef __int64 jlong;
-typedef signed char jbyte;
-
-typedef jint jsize;
-
-typedef union jvalue {
- jboolean z;
- jbyte b;
- jchar c;
- jshort s;
- jint i;
- jlong j;
- jfloat f;
- jdouble d;
- jobject l;
-} jvalue;
-
-//public __value class LocalRefStruct;
-
-#pragma managed
-
-//[StructLayout(LayoutKind::Sequential)]
-//__value struct LocalRefCache
-//{
-// Object* loc1;
-// Object* loc2;
-// Object* loc3;
-// Object* loc4;
-// Object* loc5;
-// Object* loc6;
-// Object* loc7;
-// Object* loc8;
-// Object* loc9;
-// Object* loc10;
-//};
-//
-//#define STATIC_LIST_SIZE 10
-//#define BUCKET_SIZE (1 << LOCAL_REF_SHIFT)
-//#define LOCAL_REF_SHIFT 10
-//#define LOCAL_REF_MASK (BUCKET_SIZE - 1)
-//
-//__value struct LocalRefListEntry
-//{
-// Object* __nogc* static_list;
-// Object* dynamic_list __gc[];
-//
-// int MakeLocalRef(Object* o)
-// {
-// Object** p = static_list;
-// for(int i = 0; i < STATIC_LIST_SIZE; i++)
-// {
-// if(p[i] == 0)
-// {
-// p[i] = o;
-// return i;
-// }
-// }
-// if(!dynamic_list)
-// {
-// dynamic_list = new Object* __gc[32 - STATIC_LIST_SIZE];
-// }
-// for(int i = 0; i < dynamic_list->Length; i++)
-// {
-// if(dynamic_list[i] == 0)
-// {
-// dynamic_list[i] = o;
-// return i + STATIC_LIST_SIZE;
-// }
-// }
-// int newsize = (dynamic_list->Length + STATIC_LIST_SIZE) * 2 - STATIC_LIST_SIZE;
-// if(newsize > BUCKET_SIZE)
-// {
-// return -1;
-// }
-// Object* tmp __gc[] = dynamic_list;
-// dynamic_list = new Object* __gc[newsize];
-// Array::Copy(tmp, 0, dynamic_list, 0, tmp->Length);
-// dynamic_list[tmp->Length] = o;
-// return tmp->Length + STATIC_LIST_SIZE;
-// }
-//
-// void DeleteLocalRef(unsigned int i)
-// {
-// if(i < STATIC_LIST_SIZE)
-// {
-// static_list[i] = 0;
-// }
-// else
-// {
-// dynamic_list[i - STATIC_LIST_SIZE] = 0;
-// }
-// }
-//
-// Object* UnwrapLocalRef(unsigned int i)
-// {
-// if(i < STATIC_LIST_SIZE)
-// {
-// return static_list[i];
-// }
-// else
-// {
-// return dynamic_list[i - STATIC_LIST_SIZE];
-// }
-// }
-//};
-//
-//__gc struct GlobalRefs
-//{
-// static System::Collections::ArrayList* globalRefs = new System::Collections::ArrayList();
-//};
-//
-//class JNIEnv;
-//
-//public __value class LocalRefStruct
-//{
-// JNIEnv* pJNIEnv;
-// LocalRefStruct __nogc* pPrevLocalRefCache;
-// LocalRefCache fastlocalrefs;
-// LocalRefListEntry localRefs __gc[];
-//
-//public:
-// static JNIEnv* GetEnv();
-//
-// IntPtr Enter();
-// void Leave();
-//
-// IntPtr MakeLocalRef(Object* o);
-// Object* UnwrapLocalRef(IntPtr p);
-//};
-
-class JNIEnv
-{
-public:
- jobject MakeLocalRef(System::Object* obj);
- //{
- // return (jobject)(void*)pActiveLocalRefCache->MakeLocalRef(obj);
- //}
-
- Object* UnwrapRef(jobject o);
- //{
- // int i = (int)o;
- // if(i > 0)
- // {
- // return pActiveLocalRefCache->UnwrapLocalRef((void*)o);
- // }
- // if(i < 0)
- // {
- // return GlobalRefs::globalRefs->Item[(-i) - 1];
- // }
- // return 0;
- //}
-
- jmethodID FindMethodID(jclass cls, const char* name, const char* sig, bool isstatic);
- Object* InvokeHelper(jobject object, jmethodID methodID, jvalue* args, bool nonVirtual);
- jfieldID FindFieldID(jclass cls, const char* name, const char* sig, bool isstatic);
-
- //int localRefSlot;
- //LocalRefStruct __nogc* pActiveLocalRefCache;
- //gcroot<LocalRefListEntry __gc[]> localRefs;
- //jthrowable pendingException;
-
- JNIEnv();
- ~JNIEnv();
-
- virtual void JNICALL reserved0();
- virtual void JNICALL reserved1();
- virtual void JNICALL reserved2();
- virtual void JNICALL reserved3();
-
- virtual jint JNICALL GetVersion();
-
- virtual jclass JNICALL DefineClass(const char *name, jobject loader, const jbyte *buf, jsize len);
- virtual jclass JNICALL FindClass(const char *name);
-
- virtual jmethodID JNICALL FromReflectedMethod(jobject method);
- virtual jfieldID JNICALL FromReflectedField(jobject field);
- virtual jobject JNICALL ToReflectedMethod(jclass clazz, jmethodID methodID);
-
- virtual jclass JNICALL GetSuperclass(jclass sub);
- virtual jboolean JNICALL IsAssignableFrom(jclass sub, jclass sup);
-
- virtual jobject JNICALL ToReflectedField(jclass clazz, jfieldID fieldID);
-
- virtual jint JNICALL Throw(jthrowable obj);
- virtual jint JNICALL ThrowNew(jclass clazz, const char *msg);
- virtual jthrowable JNICALL ExceptionOccurred();
- virtual void JNICALL ExceptionDescribe();
- virtual void JNICALL ExceptionClear();
- virtual void JNICALL FatalError(const char *msg);
-
- virtual jint JNICALL PushLocalFrame(jint capacity);
- virtual jobject JNICALL PopLocalFrame(jobject result);
-
- virtual jobject JNICALL NewGlobalRef(jobject lobj);
- virtual void JNICALL DeleteGlobalRef(jobject gref);
- virtual void JNICALL DeleteLocalRef(jobject obj);
- virtual jboolean JNICALL IsSameObject(jobject obj1, jobject obj2);
-
- virtual jobject JNICALL NewLocalRef(jobject ref);
- virtual jint JNICALL EnsureLocalCapacity(jint capacity);
-
- virtual jobject JNICALL AllocObject(jclass clazz);
- virtual jobject JNICALL NewObject(jclass clazz, jmethodID methodID, ...);
- virtual jobject JNICALL NewObjectV(jclass clazz, jmethodID methodID, va_list args);
- virtual jobject JNICALL NewObjectA(jclass clazz, jmethodID methodID, jvalue *args);
-
- virtual jclass JNICALL GetObjectClass(jobject obj);
- virtual jboolean JNICALL IsInstanceOf(jobject obj, jclass clazz);
-
- virtual jmethodID JNICALL GetMethodID(jclass clazz, const char *name, const char *sig);
-
- virtual jobject JNICALL CallObjectMethod(jobject obj, jmethodID methodID, ...);
- virtual jobject JNICALL CallObjectMethodV(jobject obj, jmethodID methodID, va_list args);
- virtual jobject JNICALL CallObjectMethodA(jobject obj, jmethodID methodID, jvalue * args);
-
- virtual jboolean JNICALL CallBooleanMethod(jobject obj, jmethodID methodID, ...);
- virtual jboolean JNICALL CallBooleanMethodV(jobject obj, jmethodID methodID, va_list args);
- virtual jboolean JNICALL CallBooleanMethodA(jobject obj, jmethodID methodID, jvalue * args);
-
- virtual jbyte JNICALL CallByteMethod(jobject obj, jmethodID methodID, ...);
- virtual jbyte JNICALL CallByteMethodV(jobject obj, jmethodID methodID, va_list args);
- virtual jbyte JNICALL CallByteMethodA(jobject obj, jmethodID methodID, jvalue *args);
-
- virtual jchar JNICALL CallCharMethod(jobject obj, jmethodID methodID, ...);
- virtual jchar JNICALL CallCharMethodV(jobject obj, jmethodID methodID, va_list args);
- virtual jchar JNICALL CallCharMethodA(jobject obj, jmethodID methodID, jvalue *args);
-
- virtual jshort JNICALL CallShortMethod(jobject obj, jmethodID methodID, ...);
- virtual jshort JNICALL CallShortMethodV(jobject obj, jmethodID methodID, va_list args);
- virtual jshort JNICALL CallShortMethodA(jobject obj, jmethodID methodID, jvalue *args);
-
- virtual jint JNICALL CallIntMethod(jobject obj, jmethodID methodID, ...);
- virtual jint JNICALL CallIntMethodV(jobject obj, jmethodID methodID, va_list args);
- virtual jint JNICALL CallIntMethodA(jobject obj, jmethodID methodID, jvalue *args);
-
- virtual jlong JNICALL CallLongMethod(jobject obj, jmethodID methodID, ...);
- virtual jlong JNICALL CallLongMethodV(jobject obj, jmethodID methodID, va_list args);
- virtual jlong JNICALL CallLongMethodA(jobject obj, jmethodID methodID, jvalue *args);
-
- virtual jfloat JNICALL CallFloatMethod(jobject obj, jmethodID methodID, ...);
- virtual jfloat JNICALL CallFloatMethodV(jobject obj, jmethodID methodID, va_list args);
- virtual jfloat JNICALL CallFloatMethodA(jobject obj, jmethodID methodID, jvalue *args);
-
- virtual jdouble JNICALL CallDoubleMethod(jobject obj, jmethodID methodID, ...);
- virtual jdouble JNICALL CallDoubleMethodV(jobject obj, jmethodID methodID, va_list args);
- virtual jdouble JNICALL CallDoubleMethodA(jobject obj, jmethodID methodID, jvalue *args);
-
- virtual void JNICALL CallVoidMethod(jobject obj, jmethodID methodID, ...);
- virtual void JNICALL CallVoidMethodV(jobject obj, jmethodID methodID, va_list args);
- virtual void JNICALL CallVoidMethodA(jobject obj, jmethodID methodID, jvalue * args);
-
- virtual jobject JNICALL CallNonvirtualObjectMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
- virtual jobject JNICALL CallNonvirtualObjectMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
- virtual jobject JNICALL CallNonvirtualObjectMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue * args);
-
- virtual jboolean JNICALL CallNonvirtualBooleanMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
- virtual jboolean JNICALL CallNonvirtualBooleanMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
- virtual jboolean JNICALL CallNonvirtualBooleanMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue * args);
-
- virtual jbyte JNICALL CallNonvirtualByteMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
- virtual jbyte JNICALL CallNonvirtualByteMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
- virtual jbyte JNICALL CallNonvirtualByteMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
-
- virtual jchar JNICALL CallNonvirtualCharMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
- virtual jchar JNICALL CallNonvirtualCharMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
- virtual jchar JNICALL CallNonvirtualCharMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
-
- virtual jshort JNICALL CallNonvirtualShortMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
- virtual jshort JNICALL CallNonvirtualShortMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
- virtual jshort JNICALL CallNonvirtualShortMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
-
- virtual jint JNICALL CallNonvirtualIntMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
- virtual jint JNICALL CallNonvirtualIntMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
- virtual jint JNICALL CallNonvirtualIntMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
-
- virtual jlong JNICALL CallNonvirtualLongMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
- virtual jlong JNICALL CallNonvirtualLongMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
- virtual jlong JNICALL CallNonvirtualLongMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
-
- virtual jfloat JNICALL CallNonvirtualFloatMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
- virtual jfloat JNICALL CallNonvirtualFloatMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
- virtual jfloat JNICALL CallNonvirtualFloatMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
-
- virtual jdouble JNICALL CallNonvirtualDoubleMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
- virtual jdouble JNICALL CallNonvirtualDoubleMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
- virtual jdouble JNICALL CallNonvirtualDoubleMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
-
- virtual void JNICALL CallNonvirtualVoidMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
- virtual void JNICALL CallNonvirtualVoidMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
- virtual void JNICALL CallNonvirtualVoidMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue * args);
-
- virtual jfieldID JNICALL GetFieldID(jclass clazz, const char *name, const char *sig);
-
- virtual jobject JNICALL GetObjectField(jobject obj, jfieldID fieldID);
- virtual jboolean JNICALL GetBooleanField(jobject obj, jfieldID fieldID);
- virtual jbyte JNICALL GetByteField(jobject obj, jfieldID fieldID);
- virtual jchar JNICALL GetCharField(jobject obj, jfieldID fieldID);
- virtual jshort JNICALL GetShortField(jobject obj, jfieldID fieldID);
- virtual jint JNICALL GetIntField(jobject obj, jfieldID fieldID);
- virtual jlong JNICALL GetLongField(jobject obj, jfieldID fieldID);
- virtual jfloat JNICALL GetFloatField(jobject obj, jfieldID fieldID);
- virtual jdouble JNICALL GetDoubleField(jobject obj, jfieldID fieldID);
-
- virtual void JNICALL SetObjectField(jobject obj, jfieldID fieldID, jobject val);
- virtual void JNICALL SetBooleanField(jobject obj, jfieldID fieldID, jboolean val);
- virtual void JNICALL SetByteField(jobject obj, jfieldID fieldID, jbyte val);
- virtual void JNICALL SetCharField(jobject obj, jfieldID fieldID, jchar val);
- virtual void JNICALL SetShortField(jobject obj, jfieldID fieldID, jshort val);
- virtual void JNICALL SetIntField(jobject obj, jfieldID fieldID, jint val);
- virtual void JNICALL SetLongField(jobject obj, jfieldID fieldID, jlong val);
- virtual void JNICALL SetFloatField(jobject obj, jfieldID fieldID, jfloat val);
- virtual void JNICALL SetDoubleField(jobject obj, jfieldID fieldID, jdouble val);
-
- virtual jmethodID JNICALL GetStaticMethodID(jclass clazz, const char *name, const char *sig);
-
- virtual jobject JNICALL CallStaticObjectMethod(jclass clazz, jmethodID methodID, ...);
- virtual jobject JNICALL CallStaticObjectMethodV(jclass clazz, jmethodID methodID, va_list args);
- virtual jobject JNICALL CallStaticObjectMethodA(jclass clazz, jmethodID methodID, jvalue *args);
-
- virtual jboolean JNICALL CallStaticBooleanMethod(jclass clazz, jmethodID methodID, ...);
- virtual jboolean JNICALL CallStaticBooleanMethodV(jclass clazz, jmethodID methodID, va_list args);
- virtual jboolean JNICALL CallStaticBooleanMethodA(jclass clazz, jmethodID methodID, jvalue *args);
-
- virtual jbyte JNICALL CallStaticByteMethod(jclass clazz, jmethodID methodID, ...);
- virtual jbyte JNICALL CallStaticByteMethodV(jclass clazz, jmethodID methodID, va_list args);
- virtual jbyte JNICALL CallStaticByteMethodA(jclass clazz, jmethodID methodID, jvalue *args);
-
- virtual jchar JNICALL CallStaticCharMethod(jclass clazz, jmethodID methodID, ...);
- virtual jchar JNICALL CallStaticCharMethodV(jclass clazz, jmethodID methodID, va_list args);
- virtual jchar JNICALL CallStaticCharMethodA(jclass clazz, jmethodID methodID, jvalue *args);
-
- virtual jshort JNICALL CallStaticShortMethod(jclass clazz, jmethodID methodID, ...);
- virtual jshort JNICALL CallStaticShortMethodV(jclass clazz, jmethodID methodID, va_list args);
- virtual jshort JNICALL CallStaticShortMethodA(jclass clazz, jmethodID methodID, jvalue *args);
-
- virtual jint JNICALL CallStaticIntMethod(jclass clazz, jmethodID methodID, ...);
- virtual jint JNICALL CallStaticIntMethodV(jclass clazz, jmethodID methodID, va_list args);
- virtual jint JNICALL CallStaticIntMethodA(jclass clazz, jmethodID methodID, jvalue *args);
-
- virtual jlong JNICALL CallStaticLongMethod(jclass clazz, jmethodID methodID, ...);
- virtual jlong JNICALL CallStaticLongMethodV(jclass clazz, jmethodID methodID, va_list args);
- virtual jlong JNICALL CallStaticLongMethodA(jclass clazz, jmethodID methodID, jvalue *args);
-
- virtual jfloat JNICALL CallStaticFloatMethod(jclass clazz, jmethodID methodID, ...);
- virtual jfloat JNICALL CallStaticFloatMethodV(jclass clazz, jmethodID methodID, va_list args);
- virtual jfloat JNICALL CallStaticFloatMethodA(jclass clazz, jmethodID methodID, jvalue *args);
-
- virtual jdouble JNICALL CallStaticDoubleMethod(jclass clazz, jmethodID methodID, ...);
- virtual jdouble JNICALL CallStaticDoubleMethodV(jclass clazz, jmethodID methodID, va_list args);
- virtual jdouble JNICALL CallStaticDoubleMethodA(jclass clazz, jmethodID methodID, jvalue *args);
-
- virtual void JNICALL CallStaticVoidMethod(jclass cls, jmethodID methodID, ...);
- virtual void JNICALL CallStaticVoidMethodV(jclass cls, jmethodID methodID, va_list args);
- virtual void JNICALL CallStaticVoidMethodA(jclass cls, jmethodID methodID, jvalue * args);
-
- virtual jfieldID JNICALL GetStaticFieldID(jclass clazz, const char *name, const char *sig);
- virtual jobject JNICALL GetStaticObjectField(jclass clazz, jfieldID fieldID);
- virtual jboolean JNICALL GetStaticBooleanField(jclass clazz, jfieldID fieldID);
- virtual jbyte JNICALL GetStaticByteField(jclass clazz, jfieldID fieldID);
- virtual jchar JNICALL GetStaticCharField(jclass clazz, jfieldID fieldID);
- virtual jshort JNICALL GetStaticShortField(jclass clazz, jfieldID fieldID);
- virtual jint JNICALL GetStaticIntField(jclass clazz, jfieldID fieldID);
- virtual jlong JNICALL GetStaticLongField(jclass clazz, jfieldID fieldID);
- virtual jfloat JNICALL GetStaticFloatField(jclass clazz, jfieldID fieldID);
- virtual jdouble JNICALL GetStaticDoubleField(jclass clazz, jfieldID fieldID);
-
- virtual void JNICALL SetStaticObjectField(jclass clazz, jfieldID fieldID, jobject value);
- virtual void JNICALL SetStaticBooleanField(jclass clazz, jfieldID fieldID, jboolean value);
- virtual void JNICALL SetStaticByteField(jclass clazz, jfieldID fieldID, jbyte value);
- virtual void JNICALL SetStaticCharField(jclass clazz, jfieldID fieldID, jchar value);
- virtual void JNICALL SetStaticShortField(jclass clazz, jfieldID fieldID, jshort value);
- virtual void JNICALL SetStaticIntField(jclass clazz, jfieldID fieldID, jint value);
- virtual void JNICALL SetStaticLongField(jclass clazz, jfieldID fieldID, jlong value);
- virtual void JNICALL SetStaticFloatField(jclass clazz, jfieldID fieldID, jfloat value);
- virtual void JNICALL SetStaticDoubleField(jclass clazz, jfieldID fieldID, jdouble value);
-
- virtual jstring JNICALL NewString(const jchar *unicode, jsize len);
- virtual jsize JNICALL GetStringLength(jstring str);
- virtual const jchar *JNICALL GetStringChars(jstring str, jboolean *isCopy);
- virtual void JNICALL ReleaseStringChars(jstring str, const jchar *chars);
-
- virtual jstring JNICALL NewStringUTF(const char *utf);
- virtual jsize JNICALL GetStringUTFLength(jstring str);
- virtual const char* JNICALL GetStringUTFChars(jstring str, jboolean *isCopy);
- virtual void JNICALL ReleaseStringUTFChars(jstring str, const char* chars);
-
- virtual jsize JNICALL GetArrayLength(jarray array);
-
- virtual jobjectArray JNICALL NewObjectArray(jsize len, jclass clazz, jobject init);
- virtual jobject JNICALL GetObjectArrayElement(jobjectArray array, jsize index);
- virtual void JNICALL SetObjectArrayElement(jobjectArray array, jsize index, jobject val);
-
- virtual jbooleanArray JNICALL NewBooleanArray(jsize len);
- virtual jbyteArray JNICALL NewByteArray(jsize len);
- virtual jcharArray JNICALL NewCharArray(jsize len);
- virtual jshortArray JNICALL NewShortArray(jsize len);
- virtual jintArray JNICALL NewIntArray(jsize len);
- virtual jlongArray JNICALL NewLongArray(jsize len);
- virtual jfloatArray JNICALL NewFloatArray(jsize len);
- virtual jdoubleArray JNICALL NewDoubleArray(jsize len);
-
- virtual jboolean * JNICALL GetBooleanArrayElements(jbooleanArray array, jboolean *isCopy);
- virtual jbyte * JNICALL GetByteArrayElements(jbyteArray array, jboolean *isCopy);
- virtual jchar * JNICALL GetCharArrayElements(jcharArray array, jboolean *isCopy);
- virtual jshort * JNICALL GetShortArrayElements(jshortArray array, jboolean *isCopy);
- virtual jint * JNICALL GetIntArrayElements(jintArray array, jboolean *isCopy);
- virtual jlong * JNICALL GetLongArrayElements(jlongArray array, jboolean *isCopy);
- virtual jfloat * JNICALL GetFloatArrayElements(jfloatArray array, jboolean *isCopy);
- virtual jdouble * JNICALL GetDoubleArrayElements(jdoubleArray array, jboolean *isCopy);
-
- virtual void JNICALL ReleaseBooleanArrayElements(jbooleanArray array, jboolean *elems, jint mode);
- virtual void JNICALL ReleaseByteArrayElements(jbyteArray array, jbyte *elems, jint mode);
- virtual void JNICALL ReleaseCharArrayElements(jcharArray array, jchar *elems, jint mode);
- virtual void JNICALL ReleaseShortArrayElements(jshortArray array, jshort *elems, jint mode);
- virtual void JNICALL ReleaseIntArrayElements(jintArray array, jint *elems, jint mode);
- virtual void JNICALL ReleaseLongArrayElements(jlongArray array, jlong *elems, jint mode);
- virtual void JNICALL ReleaseFloatArrayElements(jfloatArray array, jfloat *elems, jint mode);
- virtual void JNICALL ReleaseDoubleArrayElements(jdoubleArray array, jdouble *elems, jint mode);
-
- virtual void JNICALL GetBooleanArrayRegion(jbooleanArray array, jsize start, jsize l, jboolean *buf);
- virtual void JNICALL GetByteArrayRegion(jbyteArray array, jsize start, jsize len, jbyte *buf);
- virtual void JNICALL GetCharArrayRegion(jcharArray array, jsize start, jsize len, jchar *buf);
- virtual void JNICALL GetShortArrayRegion(jshortArray array, jsize start, jsize len, jshort *buf);
- virtual void JNICALL GetIntArrayRegion(jintArray array, jsize start, jsize len, jint *buf);
- virtual void JNICALL GetLongArrayRegion(jlongArray array, jsize start, jsize len, jlong *buf);
- virtual void JNICALL GetFloatArrayRegion(jfloatArray array, jsize start, jsize len, jfloat *buf);
- virtual void JNICALL GetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, jdouble *buf);
-
- virtual void JNICALL SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize l, jboolean *buf);
- virtual void JNICALL SetByteArrayRegion(jbyteArray array, jsize start, jsize len, jbyte *buf);
- virtual void JNICALL SetCharArrayRegion(jcharArray array, jsize start, jsize len, jchar *buf);
- virtual void JNICALL SetShortArrayRegion(jshortArray array, jsize start, jsize len, jshort *buf);
- virtual void JNICALL SetIntArrayRegion(jintArray array, jsize start, jsize len, jint *buf);
- virtual void JNICALL SetLongArrayRegion(jlongArray array, jsize start, jsize len, jlong *buf);
- virtual void JNICALL SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, jfloat *buf);
- virtual void JNICALL SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, jdouble *buf);
-
- virtual jint JNICALL RegisterNatives(jclass clazz, const JNINativeMethod *methods, jint nMethods);
- virtual jint JNICALL UnregisterNatives(jclass clazz);
-
- virtual jint JNICALL MonitorEnter(jobject obj);
- virtual jint JNICALL MonitorExit(jobject obj);
-
- virtual jint JNICALL GetJavaVM(JavaVM **vm);
-
- virtual void JNICALL GetStringRegion(jstring str, jsize start, jsize len, jchar *buf);
- virtual void JNICALL GetStringUTFRegion(jstring str, jsize start, jsize len, char *buf);
-
- virtual void* JNICALL GetPrimitiveArrayCritical(jarray array, jboolean *isCopy);
- virtual void JNICALL ReleasePrimitiveArrayCritical(jarray array, void *carray, jint mode);
-
- virtual const jchar* JNICALL GetStringCritical(jstring string, jboolean *isCopy);
- virtual void JNICALL ReleaseStringCritical(jstring string, const jchar *cstring);
-
- virtual jweak JNICALL NewWeakGlobalRef(jobject obj);
- virtual void JNICALL DeleteWeakGlobalRef(jweak ref);
-
- virtual jboolean JNICALL ExceptionCheck();
-
- virtual jobject JNICALL NewDirectByteBuffer(void* address, jlong capacity);
- virtual void* JNICALL GetDirectBufferAddress(jobject buf);
- virtual jlong JNICALL GetDirectBufferCapacity(jobject buf);
-};
-
-class JavaVM
-{
-public:
- virtual void JNICALL reserved0();
- virtual void JNICALL reserved1();
- virtual void JNICALL reserved2();
- virtual jint JNICALL DestroyJavaVM();
- virtual jint JNICALL AttachCurrentThread(void **penv, void *args);
- virtual jint JNICALL DetachCurrentThread();
- virtual jint JNICALL GetEnv(void **penv, jint version);
- virtual jint JNICALL AttachCurrentThreadAsDaemon(void **penv, void *args);
-};
diff --git a/jni/mono/JNI.cs b/jni/mono/JNI.cs
deleted file mode 100644
index 4e68c9fb..00000000
--- a/jni/mono/JNI.cs
+++ /dev/null
@@ -1,567 +0,0 @@
-//
-// JNI: a class used by IKVM.NET to access JNI related functionality.
-//
-
-//
-// This is the mono version of the JNI provider. As much code is written in C#
-// as possible. The code depends on having a non-copying garbage collector.
-//
-
-using System;
-using System.Collections;
-using System.Text;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Threading;
-
-[assembly:AssemblyVersionAttribute("0.9.*")]
-//[assembly:AssemblyKeyFile("c:\\ikvm-key\\ikvm.snk")]
-
-public class VM
-{
- public static Exception UnsatisfiedLinkError (string msg) {
- return JniHelper.UnsatisfiedLinkError (msg);
- }
-}
-
-public class JNI : IJniProvider
-{
- static Hashtable modules = new Hashtable ();
-
- [DllImport("mono-ikvm-jni")]
- private static extern IntPtr native_load_native_library (string filename);
-
- [DllImport("mono-ikvm-jni")]
- private static extern bool native_lookup_symbol (IntPtr module, string symbol_name, ref int symbol);
-
- [DllImport("gmodule-2.0")]
- private static extern IntPtr g_module_open (string file_name, int flags);
-
- [DllImport("gmodule-2.0")]
- private static extern bool g_module_symbol (IntPtr module, string symbol_name, ref int symbol);
-
- public int LoadNativeLibrary (string filename) {
- Console.WriteLine ("LoadNativeLibrary : " + filename);
-
- IntPtr module = g_module_open (filename, 0);
- if (module == (IntPtr)0)
- return 0;
-
- modules [module] = filename;
- return 1;
- }
-
- public Type GetLocalRefStructType () {
- return typeof (IkvmJNIEnv);
- }
-
- public MethodInfo GetJniFuncPtrMethod () {
- return typeof (JNI).GetMethod ("GetJniFuncPtr");
- }
-
- //
- // Return a pointer to the C function implementing the given native
- // method.
- public static IntPtr GetJniFuncPtr (string method, string sig, string klass) {
- // Console.WriteLine ("JNI_FUNC: " + method + " " + sig + " " + klass);
-
- StringBuilder mangledSig = new StringBuilder ();
- int sp = 0;
- for (int i = 1; sig[i] != ')'; ++i) {
- switch (sig[i]) {
- case '[':
- mangledSig.Append("_3");
- sp += 4;
- while(sig[++i] == '[')
- mangledSig.Append("_3");
- mangledSig.Append(sig[i]);
- if(sig[i] == 'L') {
- while(sig[++i] != ';') {
- if(sig[i] == '/')
- mangledSig.Append("_");
- else if(sig[i] == '_')
- mangledSig.Append("_1");
- else
- mangledSig.Append(sig[i]);
- }
- mangledSig.Append("_2");
- }
- break;
- case 'L':
- sp += 4;
- mangledSig.Append("L");
- while(sig[++i] != ';') {
- if(sig[i] == '/')
- mangledSig.Append("_");
- else if(sig[i] == '_')
- mangledSig.Append("_1");
- else
- mangledSig.Append(sig[i]);
- }
- mangledSig.Append("_2");
- break;
- case 'J':
- case 'D':
- mangledSig.Append(sig[i]);
- sp += 8;
- break;
- case 'F':
- case 'I':
- case 'C':
- case 'Z':
- case 'S':
- case 'B':
- mangledSig.Append(sig[i]);
- sp += 4;
- break;
- default:
- throw new NotImplementedException();
- }
- }
-
- string methodName = "";
- for (int pass = 0; pass < 2; ++pass) {
- methodName = String.Format ("Java_{0}_{1}", klass.Replace("_", "_1").Replace('/', '_'), method.Replace("_", "_1"));
- if (pass == 1)
- methodName = methodName + "__" + mangledSig;
- Console.WriteLine ("METHOD_NAME1: " + methodName);
-
- foreach (IntPtr module in modules.Keys) {
- int function = 0;
- bool found = g_module_symbol (module, methodName, ref function);
- if (found) {
- // Console.WriteLine ("FOUND IN " + modules[module] + " -> " + function);
- return new IntPtr (function);
- }
- }
- }
-
- throw VM.UnsatisfiedLinkError(methodName);
- }
-}
-
-//
-// When running on a runtime with a non-copying collector, we can use object
-// references instead of handles.
-//
-
-// Hackish struct used for ptr<->reference conversion
-
-[StructLayout (LayoutKind.Sequential)]
-struct PtrStruct {
- public IntPtr ptr;
- public object localref;
-}
-
-[StructLayout (LayoutKind.Sequential)]
-class JNIEnv {
- IntPtr func_table;
-
- JNIEnv self;
-
- object[] localrefs;
-
- int localref_ptr;
-
- public object pendingException;
-
- GCHandle gc_handle;
-
- public JNIEnv (IntPtr the_func_table) {
- func_table = the_func_table;
- localrefs = new object[32];
- self = this;
-
- /* Pin ourselves */
- gc_handle = GCHandle.Alloc (this, GCHandleType.Pinned);
- }
-
- public IntPtr Enter () {
- pendingException = null;
- localref_ptr = 0;
- return GetEnvPtr ();
- }
-
- public void Leave () {
- if (localref_ptr > 0) {
- for (int i = 0; i < localref_ptr; ++i)
- localrefs [i] = null;
- localref_ptr = 0;
- }
- }
-
- public unsafe IntPtr GetEnvPtr () {
- void *current;
- fixed (void *p = &func_table) {
- current = p;
- }
-
- return (IntPtr)current;
- }
-
- public unsafe static JNIEnv GetJniEnvFromEnvPtr (IntPtr ptr) {
- /* FIXME: */
- return (JNIEnv)ConvertToObject (*(IntPtr*)((long)ptr + 4));
- }
-
- public IntPtr MakeLocalRef (object o) {
-#if COPYING_COLLECTOR
- // Console.WriteLine ("MakeLocalRef.");
-
- if (o == null)
- return (IntPtr)0;
-
- localrefs [localref_ptr] = o;
- localref_ptr ++;
- if (localref_ptr == localrefs.Length) {
- object[] localrefs2 = new object [localrefs.Length * 2];
- System.Array.Copy (localrefs, localrefs2, localrefs.Length);
- localrefs = localrefs2;
- }
- return (IntPtr)(localref_ptr);
-#else
- return ConvertToPtr (o);
-#endif
- }
-
- public unsafe void DeleteLocalRef (IntPtr localRef) {
-#if COPYING_COLLECTOR
- // Console.WriteLine ("DeleteLocalRef.");
-
- int index = (int)localRef;
- localrefs [index - 1] = null;
-#endif
- }
-
- public unsafe object UnwrapLocalRef (IntPtr localRef) {
-#if COPYING_COLLECTOR
- // Console.WriteLine ("UnwrapLocalRef.");
-
- int index = (int)localRef;
- if (index == 0)
- return null;
- else
- return localrefs [index - 1];
-#else
- return ConvertToObject (localRef);
-#endif
- }
-
- private unsafe static object ConvertToObject (IntPtr ptr) {
- PtrStruct s;
- s.ptr = ptr;
- s.localref = null;
- IntPtr *p = &s.ptr;
- p [1] = ptr;
- return s.localref;
- }
-
- private unsafe static IntPtr ConvertToPtr (object o) {
- PtrStruct s;
- s.localref = o;
- IntPtr *p = &s.ptr;
- return p [1];
- }
-}
-
-[StructLayout (LayoutKind.Sequential)]
-public unsafe struct IkvmJNIEnv {
- JNIEnv env;
-
- // This should be the first field in the structure
- IntPtr func_table;
-
-#if COPYING_COLLECTOR
- // Allocate most of the array in-line
- IntPtr localref0;
- object localref1;
- object localref2;
- object localref3;
- object localref4;
- object localref5;
- object localref6;
- object localref7;
- object localref8;
- object localref9;
- object localref10;
- object localref11;
- object localref12;
- object localref13;
- object localref14;
- object localref15;
- object localref16;
-
- object[] localrefs;
-
- int localref_ptr;
-#endif
-
- [ThreadStatic]
- static JNIEnv current;
-
- void* previous;
-
- public static IntPtr the_func_table;
-
- static ArrayList globalRefs;
-
- static int t_count = 0;
-
- //
- // Called before entering a native method
- //
- public IntPtr Enter () {
- env = current;
- if (env == null) {
- env = new JNIEnv (the_func_table);
- current = env;
- }
-
- return env.Enter ();
- }
-
- //
- // Called after leaving a native method
- //
- public void Leave () {
- env.Leave ();
- }
-
- public IntPtr MakeLocalRef (object o) {
- return env.MakeLocalRef (o);
- }
-
- public unsafe object UnwrapLocalRef (IntPtr localRef) {
- return env.UnwrapLocalRef (localRef);
- }
-
- [DllImport("mono-ikvm-jni")]
- private static extern IntPtr mono_jni_get_func_table ();
-
- [DllImport("mono-ikvm-jni")]
- private static extern int mono_jni_jnienv_init (
- Delegate makelocalref_func,
- Delegate unwind_func,
- Delegate makeglobalref_func,
- Delegate deleteglobalref_func,
- Delegate getfieldcookie_func,
- Delegate getmethodcookie_func,
- Delegate setfieldvalue_func,
- Delegate getfieldvalue_func,
- Delegate getclassfromobject_func,
- Delegate exceptioncheck_func,
- Delegate getpendingexception_func,
- Delegate setpendingexception_func,
- Delegate invokemethod_func,
- Delegate getmethodarglist_func,
- Delegate findclass_func,
- Delegate getjnienv_func,
- Delegate allocobject_func);
-
- [DllImport("mono-ikvm-jni")]
- public extern static void mono_jni_set_jnifunc (int index, Delegate func);
-
- static IkvmJNIEnv () {
- Console.WriteLine ("INIT");
-
- globalRefs = new ArrayList ();
-
- mono_jni_jnienv_init (
- new MakeLocalRefDelegate (HelperMakeLocalRef),
- new UnwrapRefDelegate (HelperUnwrapRef),
- new MakeGlobalRefDelegate (MakeGlobalRef),
- new DeleteRefDelegate (DeleteRef),
- new GetFieldCookieDelegate (GetFieldCookie),
- new GetMethodCookieDelegate (GetMethodCookie),
- new SetFieldValueDelegate (SetFieldValue),
- new GetFieldValueDelegate (GetFieldValue),
- new GetClassFromObjectDelegate (GetClassFromObject),
- new ExceptionCheckDelegate (ExceptionCheck),
- new GetPendingExceptionDelegate (GetPendingException),
- new SetPendingExceptionDelegate (SetPendingException),
- new InvokeMethodDelegate (InvokeMethod),
- new GetMethodArgListDelegate (GetMethodArgList),
- new FindClassDelegate (FindClass),
- new GetJniEnvDelegate (GetJniEnv),
- new AllocObjectDelegate (JniHelper.AllocObject));
-
- the_func_table = mono_jni_get_func_table ();
- }
-
- private static object ConvertToObject (IntPtr ptr) {
- PtrStruct s;
- s.ptr = ptr;
- s.localref = null;
- IntPtr *p = &s.ptr;
- p [1] = ptr;
- return s.localref;
- }
-
- private static IntPtr ConvertToPtr (object o) {
- PtrStruct s;
- s.localref = o;
- IntPtr *p = &s.ptr;
- return p [1];
- }
-
- /*
- // Return the address of the 'func_table' member from a boxed JNIEnv object
- // Implemented in IL
- private static IntPtr GetJniEnvPtr (object o) {
- return null;
- }
- */
-
- //
- // Methods called by the native code
- //
-
- public delegate IntPtr MakeLocalRefDelegate (IntPtr jniEnv, object obj);
-
- public static unsafe IntPtr HelperMakeLocalRef (IntPtr jniEnv, object obj) {
-#if COPYING_COLLECTOR
- return JNIEnv.GetJniEnvFromEnvPtr (jniEnv).MakeLocalRef (obj);
-#else
- return ConvertToPtr (obj);
-#endif
- }
-
- public delegate object UnwrapRefDelegate (IntPtr jniEnv, IntPtr reference);
-
- public static unsafe object HelperUnwrapRef (IntPtr jniEnv, IntPtr reference) {
-#if COPYING_COLLECTOR
- if ((int)reference >= 0)
- return JNIEnv.GetJniEnvFromEnvPtr (jniEnv).UnwrapLocalRef (reference);
- else
- return globalRefs [(- (int)reference) - 1];
-#else
- return ConvertToObject (reference);
-#endif
- }
-
- public delegate IntPtr MakeGlobalRefDelegate (object obj);
-
- public static IntPtr MakeGlobalRef (object obj) {
-#if COPYING_COLLECTOR
- if (obj == null)
- return (IntPtr)0;
- else
- return (IntPtr)(- (globalRefs.Add (obj) + 1));
-#else
- return ConvertToPtr (obj);
-#endif
- }
-
- public delegate void DeleteRefDelegate (IntPtr jniEnv, IntPtr reference);
-
- public static unsafe void DeleteRef (IntPtr jniEnv, IntPtr reference) {
-#if COPYING_COLLECTOR
- if ((int)reference == 0)
- return;
- else
- if ((int)reference > 0)
- JNIEnv.GetJniEnvFromEnvPtr (jniEnv).DeleteLocalRef (reference);
- else {
- int index = (- (int)reference) - 1;
- globalRefs [index] = null;
- }
-#endif
- }
-
- public delegate IntPtr GetFieldCookieDelegate(object clazz, object name, object sig, bool isStatic);
-
- public static IntPtr GetFieldCookie(object clazz, object name, object sig, bool isStatic) {
- IntPtr res = JniHelper.GetFieldCookie (clazz, (string)name, (string)sig, isStatic);
- return res;
- /*
- if ((int)res == 0)
- throw new NotImplementedException ();
- else
- return res;
- */
- }
-
- public delegate IntPtr GetMethodCookieDelegate (object clazz, object name, object sig, bool isStatic);
-
- public static IntPtr GetMethodCookie(object clazz, object name, object sig, bool isStatic) {
- IntPtr res = JniHelper.GetMethodCookie (clazz, (string)name, (string)sig, isStatic);
- return res;
- /*
- if ((int)res == 0)
- throw new NotImplementedException ();
- else
- return res;
- */
- }
-
- public delegate void SetFieldValueDelegate(IntPtr cookie, object obj, object val);
-
- public static void SetFieldValue (IntPtr cookie, object obj, object val) {
- JniHelper.SetFieldValue (cookie, obj, val);
- }
-
- public delegate object GetFieldValueDelegate (IntPtr cookie, object obj);
-
- public static object GetFieldValue (IntPtr cookie, object obj) {
- return JniHelper.GetFieldValue (cookie, obj);
- }
-
- public delegate object GetClassFromObjectDelegate (object obj);
-
- public static object GetClassFromObject (object obj) {
- return JniHelper.GetClassFromType (obj.GetType ());
- }
-
- public delegate bool ExceptionCheckDelegate (IntPtr jniEnv);
-
- public static unsafe bool ExceptionCheck (IntPtr jniEnv) {
- if (JNIEnv.GetJniEnvFromEnvPtr (jniEnv).pendingException == null)
- return false;
- else
- return true;
- }
-
- public delegate object GetPendingExceptionDelegate (IntPtr jniEnv);
-
- public static unsafe object GetPendingException (IntPtr jniEnv) {
- return JNIEnv.GetJniEnvFromEnvPtr (jniEnv).pendingException;
- }
-
- public delegate void SetPendingExceptionDelegate (IntPtr jniEnv, object obj);
-
- public static unsafe void SetPendingException (IntPtr jniEnv, object obj) {
- JNIEnv.GetJniEnvFromEnvPtr (jniEnv).pendingException = obj;
- }
-
- public delegate object InvokeMethodDelegate (IntPtr jniEnv, IntPtr cookie, object obj, object args, bool nonVirtual);
-
- public static object InvokeMethod (IntPtr jniEnv, IntPtr cookie, object obj, object args, bool nonVirtual) {
- try {
- return JniHelper.InvokeMethod (cookie, obj, (object[])args, nonVirtual);
- }
- catch (Exception ex) {
- SetPendingException (jniEnv, ex);
- return null;
- }
- }
-
- public delegate string GetMethodArgListDelegate (IntPtr cookie);
-
- public static string GetMethodArgList (IntPtr cookie) {
- return JniHelper.GetMethodArgList (cookie);
- }
-
- public delegate object FindClassDelegate (object javaName);
-
- public static object FindClass (object javaName) {
- return JniHelper.FindClass ((string)javaName);
- }
-
- public unsafe delegate IntPtr GetJniEnvDelegate ();
-
- public static unsafe IntPtr GetJniEnv () {
- return current.GetEnvPtr ();
- }
-
- public delegate object AllocObjectDelegate (object clazz);
-}
diff --git a/jni/mono/mono.build b/jni/mono/mono.build
deleted file mode 100644
index 3bdc182b..00000000
--- a/jni/mono/mono.build
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0"?>
-<project name="IKVM.JNI.Mono" default="all">
- <target name="all">
- <csc target="library" output="../../bin/IKVM.JNI.Mono.dll" define="TRACE">
- <sources>
- <includes name="JNI.cs" />
- </sources>
- <arg value="-unsafe"/>
- <references>
- <includes name="../../bin/IKVM.Runtime.dll" asis="true" />
- </references>
- </csc>
- </target>
-</project>
diff --git a/native/jni.c b/native/jni.c
new file mode 100644
index 00000000..33c78bec
--- /dev/null
+++ b/native/jni.c
@@ -0,0 +1,500 @@
+/*
+ Copyright (C) 2004 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
+
+*/
+#include <stdarg.h>
+#include <malloc.h>
+#include "jni.h"
+
+#ifdef _WIN32
+#define ALLOCA _alloca
+#else
+#include <alloca.h>
+#define ALLOCA alloca
+#endif
+
+static jobject JNICALL NewObject(JNIEnv* pEnv, jclass clazz, jmethodID methodID, ...)
+{
+ jobject o;
+ va_list args;
+ va_start(args, methodID);
+ o = (*pEnv)->NewObjectV(pEnv, clazz, methodID, args);
+ va_end(args);
+ return o;
+}
+
+#define MAKE_ARG_ARRAY(pEnv, args, argarray) \
+do { \
+ jbyte sig[257];\
+ int argc = (*pEnv)->GetMethodArgs(pEnv, methodID, sig);\
+ int i;\
+ argarray = (jvalue*)ALLOCA(argc * sizeof(jvalue));\
+ for(i = 0; i < argc; i++)\
+ {\
+ switch(sig[i])\
+ {\
+ case 'Z':\
+ case 'B':\
+ case 'S':\
+ case 'C':\
+ case 'I':\
+ argarray[i].i = va_arg(args, jint);\
+ break;\
+ case 'J':\
+ argarray[i].j = va_arg(args, jlong);\
+ break;\
+ case 'L':\
+ argarray[i].l = va_arg(args, jobject);\
+ break;\
+ case 'D':\
+ argarray[i].d = va_arg(args, double);\
+ break;\
+ case 'F':\
+ argarray[i].f = (float)va_arg(args, double);\
+ break;\
+ }\
+ }\
+} while(0);
+
+static jobject JNICALL NewObjectV(JNIEnv* pEnv, jclass clazz, jmethodID methodID, va_list args)
+{
+ jvalue* argarray;
+ MAKE_ARG_ARRAY(pEnv, args, argarray);
+ return (*pEnv)->NewObjectA(pEnv, clazz, methodID, argarray);
+}
+
+#define MAKE_METHOD(Type, type) \
+static type JNICALL Call##Type##Method(JNIEnv* pEnv, jobject obj, jmethodID methodID, ...)\
+{\
+ type ret;\
+ va_list args;\
+ va_start(args, methodID);\
+ ret = (*pEnv)->Call##Type##MethodV(pEnv, obj, methodID, args);\
+ va_end(args);\
+ return ret;\
+}\
+static type JNICALL Call##Type##MethodV(JNIEnv* pEnv, jobject obj, jmethodID methodID, va_list args)\
+{\
+ jvalue* argarray;\
+ MAKE_ARG_ARRAY(pEnv, args, argarray);\
+ return (*pEnv)->Call##Type##MethodA(pEnv, obj, methodID, argarray);\
+}\
+static type JNICALL CallNonvirtual##Type##Method(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, ...)\
+{\
+ type ret;\
+ va_list args;\
+ va_start(args, methodID);\
+ ret = (*pEnv)->CallNonvirtual##Type##MethodV(pEnv, obj, clazz, methodID, args);\
+ va_end(args);\
+ return ret;\
+}\
+static type JNICALL CallNonvirtual##Type##MethodV(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, va_list args)\
+{\
+ jvalue* argarray;\
+ MAKE_ARG_ARRAY(pEnv, args, argarray);\
+ return (*pEnv)->CallNonvirtual##Type##MethodA(pEnv, obj, clazz, methodID, argarray);\
+}\
+static type JNICALL CallStatic##Type##Method(JNIEnv* pEnv, jclass clazz, jmethodID methodID, ...)\
+{\
+ type ret;\
+ va_list args;\
+ va_start(args, methodID);\
+ ret = (*pEnv)->CallStatic##Type##MethodV(pEnv, clazz, methodID, args);\
+ va_end(args);\
+ return ret;\
+}\
+static type JNICALL CallStatic##Type##MethodV(JNIEnv* pEnv, jclass clazz, jmethodID methodID, va_list args)\
+{\
+ jvalue* argarray;\
+ MAKE_ARG_ARRAY(pEnv, args, argarray);\
+ return (*pEnv)->CallStatic##Type##MethodA(pEnv, clazz, methodID, argarray);\
+}
+
+MAKE_METHOD(Object, jobject)
+MAKE_METHOD(Boolean, jboolean)
+MAKE_METHOD(Byte, jbyte)
+MAKE_METHOD(Char, jchar)
+MAKE_METHOD(Short, jshort)
+MAKE_METHOD(Int, jint)
+MAKE_METHOD(Long, jlong)
+MAKE_METHOD(Float, jfloat)
+MAKE_METHOD(Double, jdouble)
+
+static void JNICALL CallVoidMethod(JNIEnv* pEnv, jobject obj, jmethodID methodID, ...)
+{
+ va_list args;
+ va_start(args, methodID);
+ (*pEnv)->CallVoidMethodV(pEnv, obj, methodID, args);
+ va_end(args);
+}
+static void JNICALL CallVoidMethodV(JNIEnv* pEnv, jobject obj, jmethodID methodID, va_list args)
+{
+ jvalue* argarray;
+ MAKE_ARG_ARRAY(pEnv, args, argarray);
+ (*pEnv)->CallVoidMethodA(pEnv, obj, methodID, argarray);
+}
+static void JNICALL CallNonvirtualVoidMethod(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, ...)
+{
+ va_list args;
+ va_start(args, methodID);
+ (*pEnv)->CallNonvirtualVoidMethodV(pEnv, obj, clazz, methodID, args);
+ va_end(args);
+}
+static void JNICALL CallNonvirtualVoidMethodV(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, va_list args)
+{
+ jvalue* argarray;
+ MAKE_ARG_ARRAY(pEnv, args, argarray);
+ (*pEnv)->CallNonvirtualVoidMethodA(pEnv, obj, clazz, methodID, argarray);
+}
+static void JNICALL CallStaticVoidMethod(JNIEnv* pEnv, jclass clazz, jmethodID methodID, ...)
+{
+ va_list args;
+ va_start(args, methodID);
+ (*pEnv)->CallStaticVoidMethodV(pEnv, clazz, methodID, args);
+ va_end(args);
+}
+static void JNICALL CallStaticVoidMethodV(JNIEnv* pEnv, jclass clazz, jmethodID methodID, va_list args)
+{
+ jvalue* argarray;
+ MAKE_ARG_ARRAY(pEnv, args, argarray);
+ (*pEnv)->CallStaticVoidMethodA(pEnv, clazz, methodID, argarray);
+}
+
+static void* JNIEnv_vtable[] =
+{
+ 0, // void JNICALL reserved0();
+ 0, // void JNICALL reserved1();
+ 0, // void JNICALL reserved2();
+ 0, // void JNICALL reserved3();
+
+ 0, // jint JNICALL GetVersion();
+
+ 0, // jclass JNICALL DefineClass(const char *name, jobject loader, const jbyte *buf, jsize len);
+ 0, // jclass JNICALL FindClass(const char *name);
+
+ 0, // jmethodID JNICALL FromReflectedMethod(jobject method);
+ 0, // jfieldID JNICALL FromReflectedField(jobject field);
+ 0, // jobject JNICALL ToReflectedMethod(jclass clazz, jmethodID methodID);
+
+ 0, // jclass JNICALL GetSuperclass(jclass sub);
+ 0, // jboolean JNICALL IsAssignableFrom(jclass sub, jclass sup);
+
+ 0, // jobject JNICALL ToReflectedField(jclass clazz, jfieldID fieldID);
+
+ 0, // jint JNICALL Throw(jthrowable obj);
+ 0, // jint JNICALL ThrowNew(jclass clazz, const char *msg);
+ 0, // jthrowable JNICALL ExceptionOccurred();
+ 0, // void JNICALL ExceptionDescribe();
+ 0, // void JNICALL ExceptionClear();
+ 0, // void JNICALL FatalError(const char *msg);
+
+ 0, // jint JNICALL PushLocalFrame(jint capacity);
+ 0, // jobject JNICALL PopLocalFrame(jobject result);
+
+ 0, // jobject JNICALL NewGlobalRef(jobject lobj);
+ 0, // void JNICALL DeleteGlobalRef(jobject gref);
+ 0, // void JNICALL DeleteLocalRef(jobject obj);
+ 0, // jboolean JNICALL IsSameObject(jobject obj1, jobject obj2);
+
+ 0, // jobject JNICALL NewLocalRef(jobject ref);
+ 0, // jint JNICALL EnsureLocalCapacity(jint capacity);
+
+ 0, // jobject JNICALL AllocObject(jclass clazz);
+ NewObject, // jobject JNICALL NewObject(jclass clazz, jmethodID methodID, ...);
+ NewObjectV, // jobject JNICALL NewObjectV(jclass clazz, jmethodID methodID, va_list args);
+ 0, // jobject JNICALL NewObjectA(jclass clazz, jmethodID methodID, jvalue *args);
+
+ 0, // jclass JNICALL GetObjectClass(jobject obj);
+ 0, // jboolean JNICALL IsInstanceOf(jobject obj, jclass clazz);
+
+ 0, // jmethodID JNICALL GetMethodID(jclass clazz, const char *name, const char *sig);
+
+ CallObjectMethod, // jobject JNICALL CallObjectMethod(jobject obj, jmethodID methodID, ...);
+ CallObjectMethodV, // jobject JNICALL CallObjectMethodV(jobject obj, jmethodID methodID, va_list args);
+ 0, // jobject JNICALL CallObjectMethodA(jobject obj, jmethodID methodID, jvalue * args);
+
+ CallBooleanMethod, // jboolean JNICALL CallBooleanMethod(jobject obj, jmethodID methodID, ...);
+ CallBooleanMethodV, // jboolean JNICALL CallBooleanMethodV(jobject obj, jmethodID methodID, va_list args);
+ 0, // jboolean JNICALL CallBooleanMethodA(jobject obj, jmethodID methodID, jvalue * args);
+
+ CallByteMethod, // jbyte JNICALL CallByteMethod(jobject obj, jmethodID methodID, ...);
+ CallByteMethodV, // jbyte JNICALL CallByteMethodV(jobject obj, jmethodID methodID, va_list args);
+ 0, // jbyte JNICALL CallByteMethodA(jobject obj, jmethodID methodID, jvalue *args);
+
+ CallCharMethod, // jchar JNICALL CallCharMethod(jobject obj, jmethodID methodID, ...);
+ CallCharMethodV, // jchar JNICALL CallCharMethodV(jobject obj, jmethodID methodID, va_list args);
+ 0, // jchar JNICALL CallCharMethodA(jobject obj, jmethodID methodID, jvalue *args);
+
+ CallShortMethod, // jshort JNICALL CallShortMethod(jobject obj, jmethodID methodID, ...);
+ CallShortMethodV, // jshort JNICALL CallShortMethodV(jobject obj, jmethodID methodID, va_list args);
+ 0, // jshort JNICALL CallShortMethodA(jobject obj, jmethodID methodID, jvalue *args);
+
+ CallIntMethod, // jint JNICALL CallIntMethod(jobject obj, jmethodID methodID, ...);
+ CallIntMethodV, // jint JNICALL CallIntMethodV(jobject obj, jmethodID methodID, va_list args);
+ 0, // jint JNICALL CallIntMethodA(jobject obj, jmethodID methodID, jvalue *args);
+
+ CallLongMethod, // jlong JNICALL CallLongMethod(jobject obj, jmethodID methodID, ...);
+ CallLongMethodV, // jlong JNICALL CallLongMethodV(jobject obj, jmethodID methodID, va_list args);
+ 0, // jlong JNICALL CallLongMethodA(jobject obj, jmethodID methodID, jvalue *args);
+
+ CallFloatMethod, // jfloat JNICALL CallFloatMethod(jobject obj, jmethodID methodID, ...);
+ CallFloatMethodV, // jfloat JNICALL CallFloatMethodV(jobject obj, jmethodID methodID, va_list args);
+ 0, // jfloat JNICALL CallFloatMethodA(jobject obj, jmethodID methodID, jvalue *args);
+
+ CallDoubleMethod, // jdouble JNICALL CallDoubleMethod(jobject obj, jmethodID methodID, ...);
+ CallDoubleMethodV, // jdouble JNICALL CallDoubleMethodV(jobject obj, jmethodID methodID, va_list args);
+ 0, // jdouble JNICALL CallDoubleMethodA(jobject obj, jmethodID methodID, jvalue *args);
+
+ CallVoidMethod, // void JNICALL CallVoidMethod(jobject obj, jmethodID methodID, ...);
+ CallVoidMethodV, // void JNICALL CallVoidMethodV(jobject obj, jmethodID methodID, va_list args);
+ 0, // void JNICALL CallVoidMethodA(jobject obj, jmethodID methodID, jvalue * args);
+
+ CallNonvirtualObjectMethod, // jobject JNICALL CallNonvirtualObjectMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
+ CallNonvirtualObjectMethodV, // jobject JNICALL CallNonvirtualObjectMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ 0, // jobject JNICALL CallNonvirtualObjectMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue * args);
+
+ CallNonvirtualBooleanMethod, // jboolean JNICALL CallNonvirtualBooleanMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
+ CallNonvirtualBooleanMethodV, // jboolean JNICALL CallNonvirtualBooleanMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ 0, // jboolean JNICALL CallNonvirtualBooleanMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue * args);
+
+ CallNonvirtualByteMethod, // jbyte JNICALL CallNonvirtualByteMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
+ CallNonvirtualByteMethodV, // jbyte JNICALL CallNonvirtualByteMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ 0, // jbyte JNICALL CallNonvirtualByteMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
+
+ CallNonvirtualCharMethod, // jchar JNICALL CallNonvirtualCharMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
+ CallNonvirtualCharMethodV, // jchar JNICALL CallNonvirtualCharMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ 0, // jchar JNICALL CallNonvirtualCharMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
+
+ CallNonvirtualShortMethod, // jshort JNICALL CallNonvirtualShortMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
+ CallNonvirtualShortMethodV, // jshort JNICALL CallNonvirtualShortMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ 0, // jshort JNICALL CallNonvirtualShortMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
+
+ CallNonvirtualIntMethod, // jint JNICALL CallNonvirtualIntMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
+ CallNonvirtualIntMethodV, // jint JNICALL CallNonvirtualIntMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ 0, // jint JNICALL CallNonvirtualIntMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
+
+ CallNonvirtualLongMethod, // jlong JNICALL CallNonvirtualLongMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
+ CallNonvirtualLongMethodV, // jlong JNICALL CallNonvirtualLongMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ 0, // jlong JNICALL CallNonvirtualLongMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
+
+ CallNonvirtualFloatMethod, // jfloat JNICALL CallNonvirtualFloatMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
+ CallNonvirtualFloatMethodV, // jfloat JNICALL CallNonvirtualFloatMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ 0, // jfloat JNICALL CallNonvirtualFloatMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
+
+ CallNonvirtualDoubleMethod, // jdouble JNICALL CallNonvirtualDoubleMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
+ CallNonvirtualDoubleMethodV, // jdouble JNICALL CallNonvirtualDoubleMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ 0, // jdouble JNICALL CallNonvirtualDoubleMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
+
+ CallNonvirtualVoidMethod, // void JNICALL CallNonvirtualVoidMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
+ CallNonvirtualVoidMethodV, // void JNICALL CallNonvirtualVoidMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ 0, // void JNICALL CallNonvirtualVoidMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue * args);
+
+ 0, // jfieldID JNICALL GetFieldID(jclass clazz, const char *name, const char *sig);
+
+ 0, // jobject JNICALL GetObjectField(jobject obj, jfieldID fieldID);
+ 0, // jboolean JNICALL GetBooleanField(jobject obj, jfieldID fieldID);
+ 0, // jbyte JNICALL GetByteField(jobject obj, jfieldID fieldID);
+ 0, // jchar JNICALL GetCharField(jobject obj, jfieldID fieldID);
+ 0, // jshort JNICALL GetShortField(jobject obj, jfieldID fieldID);
+ 0, // jint JNICALL GetIntField(jobject obj, jfieldID fieldID);
+ 0, // jlong JNICALL GetLongField(jobject obj, jfieldID fieldID);
+ 0, // jfloat JNICALL GetFloatField(jobject obj, jfieldID fieldID);
+ 0, // jdouble JNICALL GetDoubleField(jobject obj, jfieldID fieldID);
+
+ 0, // void JNICALL SetObjectField(jobject obj, jfieldID fieldID, jobject val);
+ 0, // void JNICALL SetBooleanField(jobject obj, jfieldID fieldID, jboolean val);
+ 0, // void JNICALL SetByteField(jobject obj, jfieldID fieldID, jbyte val);
+ 0, // void JNICALL SetCharField(jobject obj, jfieldID fieldID, jchar val);
+ 0, // void JNICALL SetShortField(jobject obj, jfieldID fieldID, jshort val);
+ 0, // void JNICALL SetIntField(jobject obj, jfieldID fieldID, jint val);
+ 0, // void JNICALL SetLongField(jobject obj, jfieldID fieldID, jlong val);
+ 0, // void JNICALL SetFloatField(jobject obj, jfieldID fieldID, jfloat val);
+ 0, // void JNICALL SetDoubleField(jobject obj, jfieldID fieldID, jdouble val);
+
+ 0, // jmethodID JNICALL GetStaticMethodID(jclass clazz, const char *name, const char *sig);
+
+ CallStaticObjectMethod, // jobject JNICALL CallStaticObjectMethod(jclass clazz, jmethodID methodID, ...);
+ CallStaticObjectMethodV, // jobject JNICALL CallStaticObjectMethodV(jclass clazz, jmethodID methodID, va_list args);
+ 0, // jobject JNICALL CallStaticObjectMethodA(jclass clazz, jmethodID methodID, jvalue *args);
+
+ CallStaticBooleanMethod, // jboolean JNICALL CallStaticBooleanMethod(jclass clazz, jmethodID methodID, ...);
+ CallStaticBooleanMethodV, // jboolean JNICALL CallStaticBooleanMethodV(jclass clazz, jmethodID methodID, va_list args);
+ 0, // jboolean JNICALL CallStaticBooleanMethodA(jclass clazz, jmethodID methodID, jvalue *args);
+
+ CallStaticByteMethod, // jbyte JNICALL CallStaticByteMethod(jclass clazz, jmethodID methodID, ...);
+ CallStaticByteMethodV, // jbyte JNICALL CallStaticByteMethodV(jclass clazz, jmethodID methodID, va_list args);
+ 0, // jbyte JNICALL CallStaticByteMethodA(jclass clazz, jmethodID methodID, jvalue *args);
+
+ CallStaticCharMethod, // jchar JNICALL CallStaticCharMethod(jclass clazz, jmethodID methodID, ...);
+ CallStaticCharMethodV, // jchar JNICALL CallStaticCharMethodV(jclass clazz, jmethodID methodID, va_list args);
+ 0, // jchar JNICALL CallStaticCharMethodA(jclass clazz, jmethodID methodID, jvalue *args);
+
+ CallStaticShortMethod, // jshort JNICALL CallStaticShortMethod(jclass clazz, jmethodID methodID, ...);
+ CallStaticShortMethodV, // jshort JNICALL CallStaticShortMethodV(jclass clazz, jmethodID methodID, va_list args);
+ 0, // jshort JNICALL CallStaticShortMethodA(jclass clazz, jmethodID methodID, jvalue *args);
+
+ CallStaticIntMethod, // jint JNICALL CallStaticIntMethod(jclass clazz, jmethodID methodID, ...);
+ CallStaticIntMethodV, // jint JNICALL CallStaticIntMethodV(jclass clazz, jmethodID methodID, va_list args);
+ 0, // jint JNICALL CallStaticIntMethodA(jclass clazz, jmethodID methodID, jvalue *args);
+
+ CallStaticLongMethod, // jlong JNICALL CallStaticLongMethod(jclass clazz, jmethodID methodID, ...);
+ CallStaticLongMethodV, // jlong JNICALL CallStaticLongMethodV(jclass clazz, jmethodID methodID, va_list args);
+ 0, // jlong JNICALL CallStaticLongMethodA(jclass clazz, jmethodID methodID, jvalue *args);
+
+ CallStaticFloatMethod, // jfloat JNICALL CallStaticFloatMethod(jclass clazz, jmethodID methodID, ...);
+ CallStaticFloatMethodV, // jfloat JNICALL CallStaticFloatMethodV(jclass clazz, jmethodID methodID, va_list args);
+ 0, // jfloat JNICALL CallStaticFloatMethodA(jclass clazz, jmethodID methodID, jvalue *args);
+
+ CallStaticDoubleMethod, // jdouble JNICALL CallStaticDoubleMethod(jclass clazz, jmethodID methodID, ...);
+ CallStaticDoubleMethodV, // jdouble JNICALL CallStaticDoubleMethodV(jclass clazz, jmethodID methodID, va_list args);
+ 0, // jdouble JNICALL CallStaticDoubleMethodA(jclass clazz, jmethodID methodID, jvalue *args);
+
+ CallStaticVoidMethod, // void JNICALL CallStaticVoidMethod(jclass cls, jmethodID methodID, ...);
+ CallStaticVoidMethodV, // void JNICALL CallStaticVoidMethodV(jclass cls, jmethodID methodID, va_list args);
+ 0, // void JNICALL CallStaticVoidMethodA(jclass cls, jmethodID methodID, jvalue * args);
+
+ 0, // jfieldID JNICALL GetStaticFieldID(jclass clazz, const char *name, const char *sig);
+
+ 0, // jobject JNICALL GetObjectField(jobject obj, jfieldID fieldID);
+ 0, // jboolean JNICALL GetBooleanField(jobject obj, jfieldID fieldID);
+ 0, // jbyte JNICALL GetByteField(jobject obj, jfieldID fieldID);
+ 0, // jchar JNICALL GetCharField(jobject obj, jfieldID fieldID);
+ 0, // jshort JNICALL GetShortField(jobject obj, jfieldID fieldID);
+ 0, // jint JNICALL GetIntField(jobject obj, jfieldID fieldID);
+ 0, // jlong JNICALL GetLongField(jobject obj, jfieldID fieldID);
+ 0, // jfloat JNICALL GetFloatField(jobject obj, jfieldID fieldID);
+ 0, // jdouble JNICALL GetDoubleField(jobject obj, jfieldID fieldID);
+
+ 0, // void JNICALL SetObjectField(jobject obj, jfieldID fieldID, jobject val);
+ 0, // void JNICALL SetBooleanField(jobject obj, jfieldID fieldID, jboolean val);
+ 0, // void JNICALL SetByteField(jobject obj, jfieldID fieldID, jbyte val);
+ 0, // void JNICALL SetCharField(jobject obj, jfieldID fieldID, jchar val);
+ 0, // void JNICALL SetShortField(jobject obj, jfieldID fieldID, jshort val);
+ 0, // void JNICALL SetIntField(jobject obj, jfieldID fieldID, jint val);
+ 0, // void JNICALL SetLongField(jobject obj, jfieldID fieldID, jlong val);
+ 0, // void JNICALL SetFloatField(jobject obj, jfieldID fieldID, jfloat val);
+ 0, // void JNICALL SetDoubleField(jobject obj, jfieldID fieldID, jdouble val);
+
+ 0, // jstring JNICALL NewString(const jchar *unicode, jsize len);
+ 0, // jsize JNICALL GetStringLength(jstring str);
+ 0, // const jchar *JNICALL GetStringChars(jstring str, jboolean *isCopy);
+ 0, // void JNICALL ReleaseStringChars(jstring str, const jchar *chars);
+
+ 0, // jstring JNICALL NewStringUTF(const char *utf);
+ 0, // jsize JNICALL GetStringUTFLength(jstring str);
+ 0, // const char* JNICALL GetStringUTFChars(jstring str, jboolean *isCopy);
+ 0, // void JNICALL ReleaseStringUTFChars(jstring str, const char* chars);
+
+ 0, // jsize JNICALL GetArrayLength(jarray array);
+
+ 0, // jobjectArray JNICALL NewObjectArray(jsize len, jclass clazz, jobject init);
+ 0, // jobject JNICALL GetObjectArrayElement(jobjectArray array, jsize index);
+ 0, // void JNICALL SetObjectArrayElement(jobjectArray array, jsize index, jobject val);
+
+ 0, // jbooleanArray JNICALL NewBooleanArray(jsize len);
+ 0, // jbyteArray JNICALL NewByteArray(jsize len);
+ 0, // jcharArray JNICALL NewCharArray(jsize len);
+ 0, // jshortArray JNICALL NewShortArray(jsize len);
+ 0, // jintArray JNICALL NewIntArray(jsize len);
+ 0, // jlongArray JNICALL NewLongArray(jsize len);
+ 0, // jfloatArray JNICALL NewFloatArray(jsize len);
+ 0, // jdoubleArray JNICALL NewDoubleArray(jsize len);
+
+ 0, // jboolean * JNICALL GetBooleanArrayElements(jbooleanArray array, jboolean *isCopy);
+ 0, // jbyte * JNICALL GetByteArrayElements(jbyteArray array, jboolean *isCopy);
+ 0, // jchar * JNICALL GetCharArrayElements(jcharArray array, jboolean *isCopy);
+ 0, // jshort * JNICALL GetShortArrayElements(jshortArray array, jboolean *isCopy);
+ 0, // jint * JNICALL GetIntArrayElements(jintArray array, jboolean *isCopy);
+ 0, // jlong * JNICALL GetLongArrayElements(jlongArray array, jboolean *isCopy);
+ 0, // jfloat * JNICALL GetFloatArrayElements(jfloatArray array, jboolean *isCopy);
+ 0, // jdouble * JNICALL GetDoubleArrayElements(jdoubleArray array, jboolean *isCopy);
+
+ 0, // void JNICALL ReleaseBooleanArrayElements(jbooleanArray array, jboolean *elems, jint mode);
+ 0, // void JNICALL ReleaseByteArrayElements(jbyteArray array, jbyte *elems, jint mode);
+ 0, // void JNICALL ReleaseCharArrayElements(jcharArray array, jchar *elems, jint mode);
+ 0, // void JNICALL ReleaseShortArrayElements(jshortArray array, jshort *elems, jint mode);
+ 0, // void JNICALL ReleaseIntArrayElements(jintArray array, jint *elems, jint mode);
+ 0, // void JNICALL ReleaseLongArrayElements(jlongArray array, jlong *elems, jint mode);
+ 0, // void JNICALL ReleaseFloatArrayElements(jfloatArray array, jfloat *elems, jint mode);
+ 0, // void JNICALL ReleaseDoubleArrayElements(jdoubleArray array, jdouble *elems, jint mode);
+
+ 0, // void JNICALL GetBooleanArrayRegion(jbooleanArray array, jsize start, jsize l, jboolean *buf);
+ 0, // void JNICALL GetByteArrayRegion(jbyteArray array, jsize start, jsize len, jbyte *buf);
+ 0, // void JNICALL GetCharArrayRegion(jcharArray array, jsize start, jsize len, jchar *buf);
+ 0, // void JNICALL GetShortArrayRegion(jshortArray array, jsize start, jsize len, jshort *buf);
+ 0, // void JNICALL GetIntArrayRegion(jintArray array, jsize start, jsize len, jint *buf);
+ 0, // void JNICALL GetLongArrayRegion(jlongArray array, jsize start, jsize len, jlong *buf);
+ 0, // void JNICALL GetFloatArrayRegion(jfloatArray array, jsize start, jsize len, jfloat *buf);
+ 0, // void JNICALL GetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, jdouble *buf);
+
+ 0, // void JNICALL SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize l, jboolean *buf);
+ 0, // void JNICALL SetByteArrayRegion(jbyteArray array, jsize start, jsize len, jbyte *buf);
+ 0, // void JNICALL SetCharArrayRegion(jcharArray array, jsize start, jsize len, jchar *buf);
+ 0, // void JNICALL SetShortArrayRegion(jshortArray array, jsize start, jsize len, jshort *buf);
+ 0, // void JNICALL SetIntArrayRegion(jintArray array, jsize start, jsize len, jint *buf);
+ 0, // void JNICALL SetLongArrayRegion(jlongArray array, jsize start, jsize len, jlong *buf);
+ 0, // void JNICALL SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, jfloat *buf);
+ 0, // void JNICALL SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, jdouble *buf);
+
+ 0, // jint JNICALL RegisterNatives(jclass clazz, const JNINativeMethod *methods, jint nMethods);
+ 0, // jint JNICALL UnregisterNatives(jclass clazz);
+
+ 0, // jint JNICALL MonitorEnter(jobject obj);
+ 0, // jint JNICALL MonitorExit(jobject obj);
+
+ 0, // jint JNICALL GetJavaVM(JavaVM **vm);
+
+ 0, // void JNICALL GetStringRegion(jstring str, jsize start, jsize len, jchar *buf);
+ 0, // void JNICALL GetStringUTFRegion(jstring str, jsize start, jsize len, char *buf);
+
+ 0, // void* JNICALL GetPrimitiveArrayCritical(jarray array, jboolean *isCopy);
+ 0, // void JNICALL ReleasePrimitiveArrayCritical(jarray array, void *carray, jint mode);
+
+ 0, // const jchar* JNICALL GetStringCritical(jstring string, jboolean *isCopy);
+ 0, // void JNICALL ReleaseStringCritical(jstring string, const jchar *cstring);
+
+ 0, // jweak JNICALL NewWeakGlobalRef(jobject obj);
+ 0, // void JNICALL DeleteWeakGlobalRef(jweak ref);
+
+ 0, // jboolean JNICALL ExceptionCheck();
+
+ 0, // jobject JNICALL NewDirectByteBuffer(void* address, jlong capacity);
+ 0, // void* JNICALL GetDirectBufferAddress(jobject buf);
+ 0 // jlong JNICALL GetDirectBufferCapacity(jobject buf);
+};
+
+JNIEXPORT void** JNICALL ikvm_GetJNIEnvVTable()
+{
+ return JNIEnv_vtable;
+}
+
+JNIEXPORT void* JNICALL ikvm_MarshalDelegate(void* p)
+{
+ return p;
+}
+
+typedef jint (JNICALL *PJNI_ONLOAD)(JavaVM* vm, void* reserved);
+
+JNIEXPORT jint JNICALL ikvm_CallOnLoad(PJNI_ONLOAD method, JavaVM* vm, void* reserved)
+{
+ return method(vm, reserved);
+}
diff --git a/native/jni.h b/native/jni.h
new file mode 100644
index 00000000..4fac309c
--- /dev/null
+++ b/native/jni.h
@@ -0,0 +1,401 @@
+/*
+ Copyright (C) 2004 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
+
+*/
+#ifndef __JNI_H__
+#define __JNI_H__
+
+#ifdef _WIN32
+ #define JNICALL __stdcall
+ #ifdef __cplusplus
+ #define JNIEXPORT extern "C" __declspec(dllexport)
+ #else
+ #define JNIEXPORT __declspec(dllexport)
+ #endif
+#else
+ #define JNICALL
+ #ifdef __cplusplus
+ #define JNIEXPORT extern "C"
+ #else
+ #define JNIEXPORT
+ #endif
+ #include <stdarg.h>
+#endif
+
+typedef void* jobject;
+typedef void* jstring;
+typedef void* jweak;
+typedef void* jthrowable;
+typedef void* jclass;
+typedef void* jmethodID;
+typedef void* jfieldID;
+typedef void* jarray;
+typedef void* jobjectArray;
+typedef void* jbooleanArray;
+typedef void* jbyteArray;
+typedef void* jcharArray;
+typedef void* jshortArray;
+typedef void* jintArray;
+typedef void* jlongArray;
+typedef void* jfloatArray;
+typedef void* jdoubleArray;
+
+typedef unsigned char jboolean;
+typedef signed char jbyte;
+typedef unsigned short jchar;
+typedef short jshort;
+typedef int jint;
+#ifdef __GNUC__
+ typedef long long int jlong;
+#else
+ typedef __int64 jlong;
+#endif
+typedef float jfloat;
+typedef double jdouble;
+typedef jint jsize;
+
+typedef struct
+{
+ char *name;
+ char *signature;
+ void *fnPtr;
+} JNINativeMethod;
+
+typedef union jvalue
+{
+ jboolean z;
+ jbyte b;
+ jchar c;
+ jshort s;
+ jint i;
+ jlong j;
+ jfloat f;
+ jdouble d;
+ jobject l;
+} jvalue;
+
+typedef void* JavaVM;
+typedef struct JNIEnv_methods *JNIEnv;
+
+struct JNIEnv_methods
+{
+ jint (JNICALL *GetMethodArgs)(JNIEnv* pEnv, jmethodID method, jbyte* sig);
+ void (JNICALL *reserved1)(JNIEnv* pEnv);
+ void (JNICALL *reserved2)(JNIEnv* pEnv);
+ void (JNICALL *reserved3)(JNIEnv* pEnv);
+
+ jint (JNICALL *GetVersion)(JNIEnv* pEnv);
+
+ jclass (JNICALL *DefineClass)(JNIEnv* pEnv, const char *name, jobject loader, const jbyte *buf, jsize len);
+ jclass (JNICALL *FindClass)(JNIEnv* pEnv, const char *name);
+
+ jmethodID (JNICALL *FromReflectedMethod)(JNIEnv* pEnv, jobject method);
+ jfieldID (JNICALL *FromReflectedField)(JNIEnv* pEnv, jobject field);
+ jobject (JNICALL *ToReflectedMethod)(JNIEnv* pEnv, jclass clazz, jmethodID methodID);
+
+ jclass (JNICALL *GetSuperclass)(JNIEnv* pEnv, jclass sub);
+ jboolean (JNICALL *IsAssignableFrom)(JNIEnv* pEnv, jclass sub, jclass sup);
+
+ jobject (JNICALL *ToReflectedField)(JNIEnv* pEnv, jclass clazz, jfieldID fieldID);
+
+ jint (JNICALL *Throw)(JNIEnv* pEnv, jthrowable obj);
+ jint (JNICALL *ThrowNew)(JNIEnv* pEnv, jclass clazz, const char *msg);
+ jthrowable (JNICALL *ExceptionOccurred)(JNIEnv* pEnv);
+ void (JNICALL *ExceptionDescribe)(JNIEnv* pEnv);
+ void (JNICALL *ExceptionClear)(JNIEnv* pEnv);
+ void (JNICALL *FatalError)(JNIEnv* pEnv, const char *msg);
+
+ jint (JNICALL *PushLocalFrame)(JNIEnv* pEnv, jint capacity);
+ jobject (JNICALL *PopLocalFrame)(JNIEnv* pEnv, jobject result);
+
+ jobject (JNICALL *NewGlobalRef)(JNIEnv* pEnv, jobject lobj);
+ void (JNICALL *DeleteGlobalRef)(JNIEnv* pEnv, jobject gref);
+ void (JNICALL *DeleteLocalRef)(JNIEnv* pEnv, jobject obj);
+ jboolean (JNICALL *IsSameObject)(JNIEnv* pEnv, jobject obj1, jobject obj2);
+
+ jobject (JNICALL *NewLocalRef)(JNIEnv* pEnv, jobject ref);
+ jint (JNICALL *EnsureLocalCapacity)(JNIEnv* pEnv, jint capacity);
+
+ jobject (JNICALL *AllocObject)(JNIEnv* pEnv, jclass clazz);
+ jobject (JNICALL *NewObject)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, ...);
+ jobject (JNICALL *NewObjectV)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, va_list args);
+ jobject (JNICALL *NewObjectA)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jclass (JNICALL *GetObjectClass)(JNIEnv* pEnv, jobject obj);
+ jboolean (JNICALL *IsInstanceOf)(JNIEnv* pEnv, jobject obj, jclass clazz);
+
+ jmethodID (JNICALL *GetMethodID)(JNIEnv* pEnv, jclass clazz, const char *name, const char *sig);
+
+ jobject (JNICALL *CallObjectMethod)(JNIEnv* pEnv, jobject obj, jmethodID methodID, ...);
+ jobject (JNICALL *CallObjectMethodV)(JNIEnv* pEnv, jobject obj, jmethodID methodID, va_list args);
+ jobject (JNICALL *CallObjectMethodA)(JNIEnv* pEnv, jobject obj, jmethodID methodID, jvalue * args);
+
+ jboolean (JNICALL *CallBooleanMethod)(JNIEnv* pEnv, jobject obj, jmethodID methodID, ...);
+ jboolean (JNICALL *CallBooleanMethodV)(JNIEnv* pEnv, jobject obj, jmethodID methodID, va_list args);
+ jboolean (JNICALL *CallBooleanMethodA)(JNIEnv* pEnv, jobject obj, jmethodID methodID, jvalue * args);
+
+ jbyte (JNICALL *CallByteMethod)(JNIEnv* pEnv, jobject obj, jmethodID methodID, ...);
+ jbyte (JNICALL *CallByteMethodV)(JNIEnv* pEnv, jobject obj, jmethodID methodID, va_list args);
+ jbyte (JNICALL *CallByteMethodA)(JNIEnv* pEnv, jobject obj, jmethodID methodID, jvalue *args);
+
+ jchar (JNICALL *CallCharMethod)(JNIEnv* pEnv, jobject obj, jmethodID methodID, ...);
+ jchar (JNICALL *CallCharMethodV)(JNIEnv* pEnv, jobject obj, jmethodID methodID, va_list args);
+ jchar (JNICALL *CallCharMethodA)(JNIEnv* pEnv, jobject obj, jmethodID methodID, jvalue *args);
+
+ jshort (JNICALL *CallShortMethod)(JNIEnv* pEnv, jobject obj, jmethodID methodID, ...);
+ jshort (JNICALL *CallShortMethodV)(JNIEnv* pEnv, jobject obj, jmethodID methodID, va_list args);
+ jshort (JNICALL *CallShortMethodA)(JNIEnv* pEnv, jobject obj, jmethodID methodID, jvalue *args);
+
+ jint (JNICALL *CallIntMethod)(JNIEnv* pEnv, jobject obj, jmethodID methodID, ...);
+ jint (JNICALL *CallIntMethodV)(JNIEnv* pEnv, jobject obj, jmethodID methodID, va_list args);
+ jint (JNICALL *CallIntMethodA)(JNIEnv* pEnv, jobject obj, jmethodID methodID, jvalue *args);
+
+ jlong (JNICALL *CallLongMethod)(JNIEnv* pEnv, jobject obj, jmethodID methodID, ...);
+ jlong (JNICALL *CallLongMethodV)(JNIEnv* pEnv, jobject obj, jmethodID methodID, va_list args);
+ jlong (JNICALL *CallLongMethodA)(JNIEnv* pEnv, jobject obj, jmethodID methodID, jvalue *args);
+
+ jfloat (JNICALL *CallFloatMethod)(JNIEnv* pEnv, jobject obj, jmethodID methodID, ...);
+ jfloat (JNICALL *CallFloatMethodV)(JNIEnv* pEnv, jobject obj, jmethodID methodID, va_list args);
+ jfloat (JNICALL *CallFloatMethodA)(JNIEnv* pEnv, jobject obj, jmethodID methodID, jvalue *args);
+
+ jdouble (JNICALL *CallDoubleMethod)(JNIEnv* pEnv, jobject obj, jmethodID methodID, ...);
+ jdouble (JNICALL *CallDoubleMethodV)(JNIEnv* pEnv, jobject obj, jmethodID methodID, va_list args);
+ jdouble (JNICALL *CallDoubleMethodA)(JNIEnv* pEnv, jobject obj, jmethodID methodID, jvalue *args);
+
+ void (JNICALL *CallVoidMethod)(JNIEnv* pEnv, jobject obj, jmethodID methodID, ...);
+ void (JNICALL *CallVoidMethodV)(JNIEnv* pEnv, jobject obj, jmethodID methodID, va_list args);
+ void (JNICALL *CallVoidMethodA)(JNIEnv* pEnv, jobject obj, jmethodID methodID, jvalue * args);
+
+ jobject (JNICALL *CallNonvirtualObjectMethod)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jobject (JNICALL *CallNonvirtualObjectMethodV)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ jobject (JNICALL *CallNonvirtualObjectMethodA)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, jvalue * args);
+
+ jboolean (JNICALL *CallNonvirtualBooleanMethod)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jboolean (JNICALL *CallNonvirtualBooleanMethodV)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ jboolean (JNICALL *CallNonvirtualBooleanMethodA)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, jvalue * args);
+
+ jbyte (JNICALL *CallNonvirtualByteMethod)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jbyte (JNICALL *CallNonvirtualByteMethodV)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ jbyte (JNICALL *CallNonvirtualByteMethodA)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jchar (JNICALL *CallNonvirtualCharMethod)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jchar (JNICALL *CallNonvirtualCharMethodV)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ jchar (JNICALL *CallNonvirtualCharMethodA)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jshort (JNICALL *CallNonvirtualShortMethod)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jshort (JNICALL *CallNonvirtualShortMethodV)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ jshort (JNICALL *CallNonvirtualShortMethodA)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jint (JNICALL *CallNonvirtualIntMethod)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jint (JNICALL *CallNonvirtualIntMethodV)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ jint (JNICALL *CallNonvirtualIntMethodA)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jlong (JNICALL *CallNonvirtualLongMethod)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jlong (JNICALL *CallNonvirtualLongMethodV)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ jlong (JNICALL *CallNonvirtualLongMethodA)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jfloat (JNICALL *CallNonvirtualFloatMethod)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jfloat (JNICALL *CallNonvirtualFloatMethodV)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ jfloat (JNICALL *CallNonvirtualFloatMethodA)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jdouble (JNICALL *CallNonvirtualDoubleMethod)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jdouble (JNICALL *CallNonvirtualDoubleMethodV)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ jdouble (JNICALL *CallNonvirtualDoubleMethodA)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
+
+ void (JNICALL *CallNonvirtualVoidMethod)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, ...);
+ void (JNICALL *CallNonvirtualVoidMethodV)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ void (JNICALL *CallNonvirtualVoidMethodA)(JNIEnv* pEnv, jobject obj, jclass clazz, jmethodID methodID, jvalue * args);
+
+ jfieldID (JNICALL *GetFieldID)(JNIEnv* pEnv, jclass clazz, const char *name, const char *sig);
+
+ jobject (JNICALL *GetObjectField)(JNIEnv* pEnv, jobject obj, jfieldID fieldID);
+ jboolean (JNICALL *GetBooleanField)(JNIEnv* pEnv, jobject obj, jfieldID fieldID);
+ jbyte (JNICALL *GetByteField)(JNIEnv* pEnv, jobject obj, jfieldID fieldID);
+ jchar (JNICALL *GetCharField)(JNIEnv* pEnv, jobject obj, jfieldID fieldID);
+ jshort (JNICALL *GetShortField)(JNIEnv* pEnv, jobject obj, jfieldID fieldID);
+ jint (JNICALL *GetIntField)(JNIEnv* pEnv, jobject obj, jfieldID fieldID);
+ jlong (JNICALL *GetLongField)(JNIEnv* pEnv, jobject obj, jfieldID fieldID);
+ jfloat (JNICALL *GetFloatField)(JNIEnv* pEnv, jobject obj, jfieldID fieldID);
+ jdouble (JNICALL *GetDoubleField)(JNIEnv* pEnv, jobject obj, jfieldID fieldID);
+
+ void (JNICALL *SetObjectField)(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jobject val);
+ void (JNICALL *SetBooleanField)(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jboolean val);
+ void (JNICALL *SetByteField)(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jbyte val);
+ void (JNICALL *SetCharField)(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jchar val);
+ void (JNICALL *SetShortField)(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jshort val);
+ void (JNICALL *SetIntField)(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jint val);
+ void (JNICALL *SetLongField)(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jlong val);
+ void (JNICALL *SetFloatField)(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jfloat val);
+ void (JNICALL *SetDoubleField)(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jdouble val);
+
+ jmethodID (JNICALL *GetStaticMethodID)(JNIEnv* pEnv, jclass clazz, const char *name, const char *sig);
+
+ jobject (JNICALL *CallStaticObjectMethod)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, ...);
+ jobject (JNICALL *CallStaticObjectMethodV)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, va_list args);
+ jobject (JNICALL *CallStaticObjectMethodA)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jboolean (JNICALL *CallStaticBooleanMethod)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, ...);
+ jboolean (JNICALL *CallStaticBooleanMethodV)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, va_list args);
+ jboolean (JNICALL *CallStaticBooleanMethodA)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jbyte (JNICALL *CallStaticByteMethod)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, ...);
+ jbyte (JNICALL *CallStaticByteMethodV)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, va_list args);
+ jbyte (JNICALL *CallStaticByteMethodA)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jchar (JNICALL *CallStaticCharMethod)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, ...);
+ jchar (JNICALL *CallStaticCharMethodV)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, va_list args);
+ jchar (JNICALL *CallStaticCharMethodA)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jshort (JNICALL *CallStaticShortMethod)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, ...);
+ jshort (JNICALL *CallStaticShortMethodV)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, va_list args);
+ jshort (JNICALL *CallStaticShortMethodA)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jint (JNICALL *CallStaticIntMethod)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, ...);
+ jint (JNICALL *CallStaticIntMethodV)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, va_list args);
+ jint (JNICALL *CallStaticIntMethodA)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jlong (JNICALL *CallStaticLongMethod)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, ...);
+ jlong (JNICALL *CallStaticLongMethodV)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, va_list args);
+ jlong (JNICALL *CallStaticLongMethodA)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jfloat (JNICALL *CallStaticFloatMethod)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, ...);
+ jfloat (JNICALL *CallStaticFloatMethodV)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, va_list args);
+ jfloat (JNICALL *CallStaticFloatMethodA)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jdouble (JNICALL *CallStaticDoubleMethod)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, ...);
+ jdouble (JNICALL *CallStaticDoubleMethodV)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, va_list args);
+ jdouble (JNICALL *CallStaticDoubleMethodA)(JNIEnv* pEnv, jclass clazz, jmethodID methodID, jvalue *args);
+
+ void (JNICALL *CallStaticVoidMethod)(JNIEnv* pEnv, jclass cls, jmethodID methodID, ...);
+ void (JNICALL *CallStaticVoidMethodV)(JNIEnv* pEnv, jclass cls, jmethodID methodID, va_list args);
+ void (JNICALL *CallStaticVoidMethodA)(JNIEnv* pEnv, jclass cls, jmethodID methodID, jvalue * args);
+
+ jfieldID (JNICALL *GetStaticFieldID)(JNIEnv* pEnv, jclass clazz, const char *name, const char *sig);
+ jobject (JNICALL *GetStaticObjectField)(JNIEnv* pEnv, jclass clazz, jfieldID fieldID);
+ jboolean (JNICALL *GetStaticBooleanField)(JNIEnv* pEnv, jclass clazz, jfieldID fieldID);
+ jbyte (JNICALL *GetStaticByteField)(JNIEnv* pEnv, jclass clazz, jfieldID fieldID);
+ jchar (JNICALL *GetStaticCharField)(JNIEnv* pEnv, jclass clazz, jfieldID fieldID);
+ jshort (JNICALL *GetStaticShortField)(JNIEnv* pEnv, jclass clazz, jfieldID fieldID);
+ jint (JNICALL *GetStaticIntField)(JNIEnv* pEnv, jclass clazz, jfieldID fieldID);
+ jlong (JNICALL *GetStaticLongField)(JNIEnv* pEnv, jclass clazz, jfieldID fieldID);
+ jfloat (JNICALL *GetStaticFloatField)(JNIEnv* pEnv, jclass clazz, jfieldID fieldID);
+ jdouble (JNICALL *GetStaticDoubleField)(JNIEnv* pEnv, jclass clazz, jfieldID fieldID);
+
+ void (JNICALL *SetStaticObjectField)(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jobject value);
+ void (JNICALL *SetStaticBooleanField)(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jboolean value);
+ void (JNICALL *SetStaticByteField)(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jbyte value);
+ void (JNICALL *SetStaticCharField)(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jchar value);
+ void (JNICALL *SetStaticShortField)(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jshort value);
+ void (JNICALL *SetStaticIntField)(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jint value);
+ void (JNICALL *SetStaticLongField)(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jlong value);
+ void (JNICALL *SetStaticFloatField)(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jfloat value);
+ void (JNICALL *SetStaticDoubleField)(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jdouble value);
+
+ jstring (JNICALL *NewString)(JNIEnv* pEnv, const jchar *unicode, jsize len);
+ jsize (JNICALL *GetStringLength)(JNIEnv* pEnv, jstring str);
+ const jchar *(JNICALL *GetStringChars)(JNIEnv* pEnv, jstring str, jboolean *isCopy);
+ void (JNICALL *ReleaseStringChars)(JNIEnv* pEnv, jstring str, const jchar *chars);
+
+ jstring (JNICALL *NewStringUTF)(JNIEnv* pEnv, const char *utf);
+ jsize (JNICALL *GetStringUTFLength)(JNIEnv* pEnv, jstring str);
+ const char* (JNICALL *GetStringUTFChars)(JNIEnv* pEnv, jstring str, jboolean *isCopy);
+ void (JNICALL *ReleaseStringUTFChars)(JNIEnv* pEnv, jstring str, const char* chars);
+
+ jsize (JNICALL *GetArrayLength)(JNIEnv* pEnv, jarray array);
+
+ jobjectArray (JNICALL *NewObjectArray)(JNIEnv* pEnv, jsize len, jclass clazz, jobject init);
+ jobject (JNICALL *GetObjectArrayElement)(JNIEnv* pEnv, jobjectArray array, jsize index);
+ void (JNICALL *SetObjectArrayElement)(JNIEnv* pEnv, jobjectArray array, jsize index, jobject val);
+
+ jbooleanArray (JNICALL *NewBooleanArray)(JNIEnv* pEnv, jsize len);
+ jbyteArray (JNICALL *NewByteArray)(JNIEnv* pEnv, jsize len);
+ jcharArray (JNICALL *NewCharArray)(JNIEnv* pEnv, jsize len);
+ jshortArray (JNICALL *NewShortArray)(JNIEnv* pEnv, jsize len);
+ jintArray (JNICALL *NewIntArray)(JNIEnv* pEnv, jsize len);
+ jlongArray (JNICALL *NewLongArray)(JNIEnv* pEnv, jsize len);
+ jfloatArray (JNICALL *NewFloatArray)(JNIEnv* pEnv, jsize len);
+ jdoubleArray (JNICALL *NewDoubleArray)(JNIEnv* pEnv, jsize len);
+
+ jboolean * (JNICALL *GetBooleanArrayElements)(JNIEnv* pEnv, jbooleanArray array, jboolean *isCopy);
+ jbyte * (JNICALL *GetByteArrayElements)(JNIEnv* pEnv, jbyteArray array, jboolean *isCopy);
+ jchar * (JNICALL *GetCharArrayElements)(JNIEnv* pEnv, jcharArray array, jboolean *isCopy);
+ jshort * (JNICALL *GetShortArrayElements)(JNIEnv* pEnv, jshortArray array, jboolean *isCopy);
+ jint * (JNICALL *GetIntArrayElements)(JNIEnv* pEnv, jintArray array, jboolean *isCopy);
+ jlong * (JNICALL *GetLongArrayElements)(JNIEnv* pEnv, jlongArray array, jboolean *isCopy);
+ jfloat * (JNICALL *GetFloatArrayElements)(JNIEnv* pEnv, jfloatArray array, jboolean *isCopy);
+ jdouble * (JNICALL *GetDoubleArrayElements)(JNIEnv* pEnv, jdoubleArray array, jboolean *isCopy);
+
+ void (JNICALL *ReleaseBooleanArrayElements)(JNIEnv* pEnv, jbooleanArray array, jboolean *elems, jint mode);
+ void (JNICALL *ReleaseByteArrayElements)(JNIEnv* pEnv, jbyteArray array, jbyte *elems, jint mode);
+ void (JNICALL *ReleaseCharArrayElements)(JNIEnv* pEnv, jcharArray array, jchar *elems, jint mode);
+ void (JNICALL *ReleaseShortArrayElements)(JNIEnv* pEnv, jshortArray array, jshort *elems, jint mode);
+ void (JNICALL *ReleaseIntArrayElements)(JNIEnv* pEnv, jintArray array, jint *elems, jint mode);
+ void (JNICALL *ReleaseLongArrayElements)(JNIEnv* pEnv, jlongArray array, jlong *elems, jint mode);
+ void (JNICALL *ReleaseFloatArrayElements)(JNIEnv* pEnv, jfloatArray array, jfloat *elems, jint mode);
+ void (JNICALL *ReleaseDoubleArrayElements)(JNIEnv* pEnv, jdoubleArray array, jdouble *elems, jint mode);
+
+ void (JNICALL *GetBooleanArrayRegion)(JNIEnv* pEnv, jbooleanArray array, jsize start, jsize l, jboolean *buf);
+ void (JNICALL *GetByteArrayRegion)(JNIEnv* pEnv, jbyteArray array, jsize start, jsize len, jbyte *buf);
+ void (JNICALL *GetCharArrayRegion)(JNIEnv* pEnv, jcharArray array, jsize start, jsize len, jchar *buf);
+ void (JNICALL *GetShortArrayRegion)(JNIEnv* pEnv, jshortArray array, jsize start, jsize len, jshort *buf);
+ void (JNICALL *GetIntArrayRegion)(JNIEnv* pEnv, jintArray array, jsize start, jsize len, jint *buf);
+ void (JNICALL *GetLongArrayRegion)(JNIEnv* pEnv, jlongArray array, jsize start, jsize len, jlong *buf);
+ void (JNICALL *GetFloatArrayRegion)(JNIEnv* pEnv, jfloatArray array, jsize start, jsize len, jfloat *buf);
+ void (JNICALL *GetDoubleArrayRegion)(JNIEnv* pEnv, jdoubleArray array, jsize start, jsize len, jdouble *buf);
+
+ void (JNICALL *SetBooleanArrayRegion)(JNIEnv* pEnv, jbooleanArray array, jsize start, jsize l, jboolean *buf);
+ void (JNICALL *SetByteArrayRegion)(JNIEnv* pEnv, jbyteArray array, jsize start, jsize len, jbyte *buf);
+ void (JNICALL *SetCharArrayRegion)(JNIEnv* pEnv, jcharArray array, jsize start, jsize len, jchar *buf);
+ void (JNICALL *SetShortArrayRegion)(JNIEnv* pEnv, jshortArray array, jsize start, jsize len, jshort *buf);
+ void (JNICALL *SetIntArrayRegion)(JNIEnv* pEnv, jintArray array, jsize start, jsize len, jint *buf);
+ void (JNICALL *SetLongArrayRegion)(JNIEnv* pEnv, jlongArray array, jsize start, jsize len, jlong *buf);
+ void (JNICALL *SetFloatArrayRegion)(JNIEnv* pEnv, jfloatArray array, jsize start, jsize len, jfloat *buf);
+ void (JNICALL *SetDoubleArrayRegion)(JNIEnv* pEnv, jdoubleArray array, jsize start, jsize len, jdouble *buf);
+
+ jint (JNICALL *RegisterNatives)(JNIEnv* pEnv, jclass clazz, const JNINativeMethod *methods, jint nMethods);
+ jint (JNICALL *UnregisterNatives)(JNIEnv* pEnv, jclass clazz);
+
+ jint (JNICALL *MonitorEnter)(JNIEnv* pEnv, jobject obj);
+ jint (JNICALL *MonitorExit)(JNIEnv* pEnv, jobject obj);
+
+ jint (JNICALL *GetJavaVM)(JNIEnv* pEnv, JavaVM **vm);
+
+ void (JNICALL *GetStringRegion)(JNIEnv* pEnv, jstring str, jsize start, jsize len, jchar *buf);
+ void (JNICALL *GetStringUTFRegion)(JNIEnv* pEnv, jstring str, jsize start, jsize len, char *buf);
+
+ void* (JNICALL *GetPrimitiveArrayCritical)(JNIEnv* pEnv, jarray array, jboolean *isCopy);
+ void (JNICALL *ReleasePrimitiveArrayCritical)(JNIEnv* pEnv, jarray array, void *carray, jint mode);
+
+ const jchar* (JNICALL *GetStringCritical)(JNIEnv* pEnv, jstring string, jboolean *isCopy);
+ void (JNICALL *ReleaseStringCritical)(JNIEnv* pEnv, jstring string, const jchar *cstring);
+
+ jweak (JNICALL *NewWeakGlobalRef)(JNIEnv* pEnv, jobject obj);
+ void (JNICALL *DeleteWeakGlobalRef)(JNIEnv* pEnv, jweak ref);
+
+ jboolean (JNICALL *ExceptionCheck)(JNIEnv* pEnv);
+
+ jobject (JNICALL *NewDirectByteBuffer)(JNIEnv* pEnv, void* address, jlong capacity);
+ void* (JNICALL *GetDirectBufferAddress)(JNIEnv* pEnv, jobject buf);
+ jlong (JNICALL *GetDirectBufferCapacity)(JNIEnv* pEnv, jobject buf);
+};
+
+#endif //__JNI_H__
diff --git a/native/native.build b/native/native.build
new file mode 100644
index 00000000..c35fc9af
--- /dev/null
+++ b/native/native.build
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<project name="ikvm-native" default="ikvm-native">
+ <target name="ikvm-native">
+ <if propertytrue="nant.platform.unix">
+ <call target="ikvm-native-unix"/>
+ </if>
+ <if propertytrue="nant.platform.win32">
+ <call target="ikvm-native-win32"/>
+ </if>
+ </target>
+ <target name="ikvm-native-unix">
+ <exec program="/bin/bash" commandline="-c 'gcc -o libikvm-native.so --shared -fPIC `pkg-config --cflags gmodule-2.0` jni.c os.c'"/>
+ <copy file="libikvm-native.so" todir="../bin"/>
+ </target>
+ <target name="ikvm-native-win32">
+ <mkdir dir="Release"/>
+ <cl outputdir="Release" options="/O2 /D WIN32 /D NDEBUG /D _WINDLL /D _MBCS /GS /W3 /nologo /c">
+ <sources>
+ <includes name="*.c"/>
+ </sources>
+ </cl>
+ <link output="Release/ikvm-native.dll" options="/DLL user32.lib">
+ <sources>
+ <includes name="Release/*.obj"/>
+ </sources>
+ </link>
+ <copy file="Release/ikvm-native.dll" todir="../bin" />
+ </target>
+</project>
diff --git a/jni/clr-win32/IKVM.JNI.CLR-Win32.vcproj b/native/native.vcproj
index e8997250..82f553c8 100644
--- a/jni/clr-win32/IKVM.JNI.CLR-Win32.vcproj
+++ b/native/native.vcproj
@@ -2,9 +2,9 @@
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
- Name="IKVM.JNI.CLR-Win32"
- ProjectGUID="{4D400F9D-68A1-4066-95F6-85AF0E58B710}"
- Keyword="ManagedCProj">
+ Name="ikvm-native"
+ ProjectGUID="{14EC8F2A-90C6-4CFC-AD26-04C9A3392B8E}"
+ Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
@@ -15,27 +15,29 @@
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="2"
- CharacterSet="2"
- ManagedExtensions="TRUE">
+ CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- PreprocessorDefinitions="WIN32;_DEBUG"
- MinimalRebuild="FALSE"
- BasicRuntimeChecks="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;NATIVE_EXPORTS"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
RuntimeLibrary="1"
- TreatWChar_tAsBuiltInType="TRUE"
- ForceConformanceInForLoopScope="TRUE"
- UsePrecompiledHeader="3"
+ UsePrecompiledHeader="0"
WarningLevel="3"
- DebugInformationFormat="3"/>
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- OutputFile="$(OutDir)/IKVM.JNI.CLR-Win32.dll"
+ OutputFile="$(OutDir)/ikvm-native.dll"
LinkIncremental="2"
- GenerateDebugInformation="TRUE"/>
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/native.pdb"
+ SubSystem="2"
+ ImportLibrary="$(OutDir)/native.lib"
+ TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
@@ -62,26 +64,27 @@
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="2"
- CharacterSet="2"
- ManagedExtensions="TRUE">
+ CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- PreprocessorDefinitions="WIN32;NDEBUG"
- MinimalRebuild="FALSE"
- TreatWChar_tAsBuiltInType="TRUE"
- ForceConformanceInForLoopScope="TRUE"
- UsePrecompiledHeader="3"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;NATIVE_EXPORTS"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- OutputFile="$(OutDir)/IKVM.JNI.CLR-Win32.dll"
+ OutputFile="$(OutDir)/ikvm-native.dll"
LinkIncremental="1"
- GenerateDebugInformation="TRUE"/>
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary="$(OutDir)/native.lib"
+ TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
@@ -105,55 +108,31 @@
</Configuration>
</Configurations>
<References>
- <ProjectReference
- ReferencedProjectIdentifier="{F5C7B588-0403-4AF2-A4DE-5697DE21BC2C}"
- Name="IKVM.Runtime"/>
</References>
<Files>
<Filter
Name="Source Files"
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
- <File
- RelativePath="AssemblyInfo.cpp">
- </File>
- <File
- RelativePath="jni.cpp">
- </File>
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
- RelativePath="jnienv.cpp">
+ RelativePath=".\jni.c">
</File>
<File
- RelativePath="Stdafx.cpp">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- UsePrecompiledHeader="1"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- UsePrecompiledHeader="1"/>
- </FileConfiguration>
+ RelativePath=".\os.c">
</File>
</Filter>
<Filter
Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc">
- <File
- RelativePath="jni.h">
- </File>
- <File
- RelativePath="jnienv.h">
- </File>
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
- RelativePath="Stdafx.h">
+ RelativePath=".\jni.h">
</File>
</Filter>
<Filter
Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;r">
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
</Filter>
</Files>
<Globals>
diff --git a/native/os.c b/native/os.c
new file mode 100644
index 00000000..55ecd378
--- /dev/null
+++ b/native/os.c
@@ -0,0 +1,73 @@
+/*
+ Copyright (C) 2004 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
+
+*/
+#ifdef _WIN32
+ #include <windows.h>
+ #include "jni.h"
+
+ JNIEXPORT void* JNICALL ikvm_LoadLibrary(char* psz)
+ {
+ return LoadLibrary(psz);
+ }
+
+ JNIEXPORT void JNICALL ikvm_FreeLibrary(HMODULE handle)
+ {
+ FreeLibrary(handle);
+ }
+
+ JNIEXPORT void* JNICALL ikvm_GetProcAddress(HMODULE handle, char* name, jint argc)
+ {
+ char buf[512];
+ if(strlen(name) > sizeof(buf) - 11)
+ {
+ return 0;
+ }
+ wsprintf(buf, "_%s@%d", name, argc);
+ return GetProcAddress(handle, buf);
+ }
+#else
+ #include <gmodule.h>
+ #include "jni.h"
+
+ JNIEXPORT void* JNICALL ikvm_LoadLibrary(char* psz)
+ {
+ return g_module_open(psz, 0);
+ }
+
+ JNIEXPORT void JNICALL ikvm_FreeLibrary(GModule* handle)
+ {
+ g_module_close(handle);
+ }
+
+ JNIEXPORT void* JNICALL ikvm_GetProcAddress(GModule* handle, char* name, jint argc)
+ {
+ void *symbol;
+
+ gboolean res = g_module_symbol(handle, name, &symbol);
+
+ if (res)
+ return symbol;
+ else
+ return NULL;
+ }
+#endif
diff --git a/runtime/BigEndianBinaryReader.cs b/runtime/BigEndianBinaryReader.cs
index 71d3a17c..07a99eff 100644
--- a/runtime/BigEndianBinaryReader.cs
+++ b/runtime/BigEndianBinaryReader.cs
@@ -28,30 +28,26 @@ sealed class BigEndianBinaryReader
{
private byte[] buf;
private int pos;
+ private int end;
- internal BigEndianBinaryReader(byte[] buf)
- : this(buf, 0)
- {
- }
-
- internal BigEndianBinaryReader(byte[] buf, int offset)
+ internal BigEndianBinaryReader(byte[] buf, int offset, int length)
{
this.buf = buf;
this.pos = offset;
+ this.end = checked(offset + length);
+ if(offset < 0 || length < 0 || buf.Length - offset < length)
+ {
+ throw new ClassFormatError("Truncated class file");
+ }
}
- internal BigEndianBinaryReader Section(int length)
+ internal BigEndianBinaryReader Section(uint length)
{
- BigEndianBinaryReader br = new BigEndianBinaryReader(buf, pos);
- pos += length;
+ BigEndianBinaryReader br = new BigEndianBinaryReader(buf, pos, checked((int)length));
+ Skip(length);
return br;
}
- internal BigEndianBinaryReader Duplicate()
- {
- return new BigEndianBinaryReader(buf, pos);
- }
-
internal int Position
{
get
@@ -60,18 +56,33 @@ sealed class BigEndianBinaryReader
}
}
- internal void Skip(int count)
+ internal void Skip(uint count)
{
- pos += count;
+ if(end - pos < count)
+ {
+ throw new ClassFormatError("Truncated class file");
+ }
+ checked
+ {
+ pos += (int)count;
+ }
}
internal byte ReadByte()
{
+ if(pos == end)
+ {
+ throw new ClassFormatError("Truncated class file");
+ }
return buf[pos++];
}
internal sbyte ReadSByte()
{
+ if(pos == end)
+ {
+ throw new ClassFormatError("Truncated class file");
+ }
return (sbyte)buf[pos++];
}
@@ -82,6 +93,10 @@ sealed class BigEndianBinaryReader
internal short ReadInt16()
{
+ if(end - pos < 2)
+ {
+ throw new ClassFormatError("Truncated class file");
+ }
short s = (short)((buf[pos] << 8) + buf[pos + 1]);
pos += 2;
return s;
@@ -89,6 +104,10 @@ sealed class BigEndianBinaryReader
internal int ReadInt32()
{
+ if(end - pos < 4)
+ {
+ throw new ClassFormatError("Truncated class file");
+ }
int i = (int)((buf[pos] << 24) + (buf[pos + 1] << 16) + (buf[pos + 2] << 8) + buf[pos + 3]);
pos += 4;
return i;
@@ -96,6 +115,10 @@ sealed class BigEndianBinaryReader
internal long ReadInt64()
{
+ if(end - pos < 8)
+ {
+ throw new ClassFormatError("Truncated class file");
+ }
uint i1 = (uint)((buf[pos] << 24) + (buf[pos + 1] << 16) + (buf[pos + 2] << 8) + buf[pos + 3]);
uint i2 = (uint)((buf[pos + 4] << 24) + (buf[pos + 5] << 16) + (buf[pos + 6] << 8) + buf[pos + 7]);
long l = (((long)i1) << 32) + i2;
@@ -111,6 +134,10 @@ sealed class BigEndianBinaryReader
internal string ReadString()
{
int len = ReadUInt16();
+ if(end - pos < len)
+ {
+ throw new ClassFormatError("Truncated class file");
+ }
// special code path for ASCII strings (which occur *very* frequently)
for(int j = 0; j < len; j++)
{
@@ -129,7 +156,7 @@ sealed class BigEndianBinaryReader
case 0:
if(c == 0)
{
- throw new FormatException();
+ throw new ClassFormatError("Illegal UTF8 string in constant pool");
}
break;
case 1: case 2: case 3: case 4: case 5: case 6: case 7:
@@ -140,7 +167,7 @@ sealed class BigEndianBinaryReader
char2 = buf[pos + ++i];
if((char2 & 0xc0) != 0x80)
{
- throw new FormatException();
+ throw new ClassFormatError("Illegal UTF8 string in constant pool");
}
c = (((c & 0x1F) << 6) | (char2 & 0x3F));
break;
@@ -150,12 +177,12 @@ sealed class BigEndianBinaryReader
char3 = buf[pos + ++i];
if((char2 & 0xc0) != 0x80 || (char3 & 0xc0) != 0x80)
{
- throw new FormatException();
+ throw new ClassFormatError("Illegal UTF8 string in constant pool");
}
c = (((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));
break;
default:
- throw new FormatException();
+ throw new ClassFormatError("Illegal UTF8 string in constant pool");
}
ch[l++] = (char)c;
}
@@ -170,6 +197,10 @@ sealed class BigEndianBinaryReader
internal ushort ReadUInt16()
{
+ if(end - pos < 2)
+ {
+ throw new ClassFormatError("Truncated class file");
+ }
ushort s = (ushort)((buf[pos] << 8) + buf[pos + 1]);
pos += 2;
return s;
@@ -177,6 +208,10 @@ sealed class BigEndianBinaryReader
internal uint ReadUInt32()
{
+ if(end - pos < 4)
+ {
+ throw new ClassFormatError("Truncated class file");
+ }
uint i = (uint)((buf[pos] << 24) + (buf[pos + 1] << 16) + (buf[pos + 2] << 8) + buf[pos + 3]);
pos += 4;
return i;
diff --git a/runtime/ByteCode.cs b/runtime/ByteCode.cs
index 8862a94b..da3bd1f0 100644
--- a/runtime/ByteCode.cs
+++ b/runtime/ByteCode.cs
@@ -23,7 +23,7 @@
*/
using System;
-enum ByteCode
+enum ByteCode : byte
{
__nop = 0,
__aconst_null = 1,
@@ -229,11 +229,11 @@ enum ByteCode
__jsr_w = 201
}
-enum NormalizedByteCode
+enum NormalizedByteCode : byte
{
__nop = 0,
__aconst_null = 1,
- __iconst = -1,
+ __iconst = 255,
__lconst_0 = 9,
__lconst_1 = 10,
__fconst_0 = 11,
@@ -380,7 +380,7 @@ enum NormalizedByteCode
__ifnonnull = 199,
}
-enum ByteCodeMode
+enum ByteCodeMode : byte
{
Unused,
Simple,
@@ -388,58 +388,80 @@ enum ByteCodeMode
Constant_2,
Branch_2,
Local_1,
- Local_2,
Constant_2_1_1,
Immediate_1,
Immediate_2,
Local_1_Immediate_1,
- Local_2_Immediate_2,
Tableswitch,
Lookupswitch,
Constant_2_Immediate_1,
- Branch_4
+ Branch_4,
+ WidePrefix
+}
+
+enum ByteCodeModeWide : byte
+{
+ Unused,
+ Local_2,
+ Local_2_Immediate_2
+}
+
+[Flags]
+enum ByteCodeFlags : byte
+{
+ None = 0,
+ FixedArg = 1,
+ CannotThrow = 2
}
struct ByteCodeMetaData
{
private static ByteCodeMetaData[] data = new ByteCodeMetaData[202];
private ByteCodeMode reg;
- private ByteCodeMode wide;
+ private ByteCodeModeWide wide;
private NormalizedByteCode normbc;
+ private ByteCodeFlags flags;
private int arg;
- private bool hasFixedArg;
- private bool cannotThrow;
- private ByteCodeMetaData(ByteCode bc, ByteCodeMode reg, ByteCodeMode wide, bool cannotThrow)
+ private ByteCodeMetaData(ByteCode bc, ByteCodeMode reg, ByteCodeModeWide wide, bool cannotThrow)
{
this.reg = reg;
this.wide = wide;
- this.normbc = (NormalizedByteCode)Enum.Parse(typeof(NormalizedByteCode), bc.ToString());
+ this.normbc = (NormalizedByteCode)bc;
this.arg = 0;
- this.hasFixedArg = false;
- this.cannotThrow = cannotThrow;
+ this.flags = ByteCodeFlags.None;
+ if(cannotThrow)
+ {
+ this.flags |= ByteCodeFlags.CannotThrow;
+ }
data[(int)bc] = this;
}
- private ByteCodeMetaData(ByteCode bc, NormalizedByteCode normbc, ByteCodeMode reg, ByteCodeMode wide, bool cannotThrow)
+ private ByteCodeMetaData(ByteCode bc, NormalizedByteCode normbc, ByteCodeMode reg, ByteCodeModeWide wide, bool cannotThrow)
{
this.reg = reg;
this.wide = wide;
this.normbc = normbc;
this.arg = 0;
- this.hasFixedArg = false;
- this.cannotThrow = cannotThrow;
+ this.flags = ByteCodeFlags.None;
+ if(cannotThrow)
+ {
+ this.flags |= ByteCodeFlags.CannotThrow;
+ }
data[(int)bc] = this;
}
- private ByteCodeMetaData(ByteCode bc, NormalizedByteCode normbc, int arg, ByteCodeMode reg, ByteCodeMode wide, bool cannotThrow)
+ private ByteCodeMetaData(ByteCode bc, NormalizedByteCode normbc, int arg, ByteCodeMode reg, ByteCodeModeWide wide, bool cannotThrow)
{
this.reg = reg;
this.wide = wide;
this.normbc = normbc;
this.arg = arg;
- this.hasFixedArg = true;
- this.cannotThrow = cannotThrow;
+ this.flags = ByteCodeFlags.FixedArg;
+ if(cannotThrow)
+ {
+ this.flags |= ByteCodeFlags.CannotThrow;
+ }
data[(int)bc] = this;
}
@@ -450,7 +472,7 @@ struct ByteCodeMetaData
internal static int GetArg(ByteCode bc, int arg)
{
- if(data[(int)bc].hasFixedArg)
+ if((data[(int)bc].flags & ByteCodeFlags.FixedArg) != 0)
{
return data[(int)bc].arg;
}
@@ -462,224 +484,219 @@ struct ByteCodeMetaData
return data[(int)bc].reg;
}
- internal static ByteCodeMode GetWideMode(ByteCode bc)
+ internal static ByteCodeModeWide GetWideMode(ByteCode bc)
{
- ByteCodeMode m = data[(int)bc].wide;
- if(m == ByteCodeMode.Unused)
- {
- throw new ArgumentException("Wide version of " + bc + " is not a valid instruction", "bc");
- }
- return m;
+ return data[(int)bc].wide;
}
internal static bool CanThrowException(ByteCode bc)
{
- return !data[(int)bc].cannotThrow;
+ return (data[(int)bc].flags & ByteCodeFlags.CannotThrow) == 0;
}
static ByteCodeMetaData()
{
- new ByteCodeMetaData(ByteCode.__nop, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__aconst_null, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__iconst_m1, NormalizedByteCode.__iconst, -1, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__iconst_0, NormalizedByteCode.__iconst, 0, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__iconst_1, NormalizedByteCode.__iconst, 1, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__iconst_2, NormalizedByteCode.__iconst, 2, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__iconst_3, NormalizedByteCode.__iconst, 3, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__iconst_4, NormalizedByteCode.__iconst, 4, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__iconst_5, NormalizedByteCode.__iconst, 5, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lconst_0, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lconst_1, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__fconst_0, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__fconst_1, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__fconst_2, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dconst_0, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dconst_1, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__bipush, NormalizedByteCode.__iconst, ByteCodeMode.Immediate_1, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__sipush, NormalizedByteCode.__iconst, ByteCodeMode.Immediate_2, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__ldc, ByteCodeMode.Constant_1, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__ldc_w, NormalizedByteCode.__ldc, ByteCodeMode.Constant_2, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__ldc2_w, NormalizedByteCode.__ldc, ByteCodeMode.Constant_2, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__iload, ByteCodeMode.Local_1, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lload, ByteCodeMode.Local_1, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__fload, ByteCodeMode.Local_1, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dload, ByteCodeMode.Local_1, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__aload, ByteCodeMode.Local_1, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__iload_0, NormalizedByteCode.__iload, 0, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__iload_1, NormalizedByteCode.__iload, 1, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__iload_2, NormalizedByteCode.__iload, 2, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__iload_3, NormalizedByteCode.__iload, 3, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lload_0, NormalizedByteCode.__lload, 0, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lload_1, NormalizedByteCode.__lload, 1, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lload_2, NormalizedByteCode.__lload, 2, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lload_3, NormalizedByteCode.__lload, 3, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__fload_0, NormalizedByteCode.__fload, 0, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__fload_1, NormalizedByteCode.__fload, 1, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__fload_2, NormalizedByteCode.__fload, 2, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__fload_3, NormalizedByteCode.__fload, 3, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dload_0, NormalizedByteCode.__dload, 0, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dload_1, NormalizedByteCode.__dload, 1, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dload_2, NormalizedByteCode.__dload, 2, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dload_3, NormalizedByteCode.__dload, 3, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__aload_0, NormalizedByteCode.__aload, 0, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__aload_1, NormalizedByteCode.__aload, 1, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__aload_2, NormalizedByteCode.__aload, 2, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__aload_3, NormalizedByteCode.__aload, 3, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__iaload, ByteCodeMode.Simple, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__laload, ByteCodeMode.Simple, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__faload, ByteCodeMode.Simple, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__daload, ByteCodeMode.Simple, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__aaload, ByteCodeMode.Simple, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__baload, ByteCodeMode.Simple, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__caload, ByteCodeMode.Simple, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__saload, ByteCodeMode.Simple, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__istore, ByteCodeMode.Local_1, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lstore, ByteCodeMode.Local_1, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__fstore, ByteCodeMode.Local_1, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dstore, ByteCodeMode.Local_1, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__astore, ByteCodeMode.Local_1, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__istore_0, NormalizedByteCode.__istore, 0, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__istore_1, NormalizedByteCode.__istore, 1, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__istore_2, NormalizedByteCode.__istore, 2, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__istore_3, NormalizedByteCode.__istore, 3, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lstore_0, NormalizedByteCode.__lstore, 0, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lstore_1, NormalizedByteCode.__lstore, 1, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lstore_2, NormalizedByteCode.__lstore, 2, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lstore_3, NormalizedByteCode.__lstore, 3, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__fstore_0, NormalizedByteCode.__fstore, 0, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__fstore_1, NormalizedByteCode.__fstore, 1, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__fstore_2, NormalizedByteCode.__fstore, 2, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__fstore_3, NormalizedByteCode.__fstore, 3, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dstore_0, NormalizedByteCode.__dstore, 0, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dstore_1, NormalizedByteCode.__dstore, 1, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dstore_2, NormalizedByteCode.__dstore, 2, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dstore_3, NormalizedByteCode.__dstore, 3, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__astore_0, NormalizedByteCode.__astore, 0, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__astore_1, NormalizedByteCode.__astore, 1, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__astore_2, NormalizedByteCode.__astore, 2, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__astore_3, NormalizedByteCode.__astore, 3, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__iastore, ByteCodeMode.Simple, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__lastore, ByteCodeMode.Simple, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__fastore, ByteCodeMode.Simple, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__dastore, ByteCodeMode.Simple, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__aastore, ByteCodeMode.Simple, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__bastore, ByteCodeMode.Simple, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__castore, ByteCodeMode.Simple, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__sastore, ByteCodeMode.Simple, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__pop, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__pop2, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dup, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dup_x1, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dup_x2, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dup2, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dup2_x1, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dup2_x2, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__swap, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__iadd, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__ladd, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__fadd, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dadd, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__isub, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lsub, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__fsub, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dsub, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__imul, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lmul, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__fmul, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dmul, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__idiv, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__ldiv, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__fdiv, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__ddiv, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__irem, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lrem, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__frem, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__drem, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__ineg, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lneg, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__fneg, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dneg, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__ishl, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lshl, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__ishr, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lshr, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__iushr, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lushr, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__iand, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__land, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__ior, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lor, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__ixor, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lxor, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__iinc, ByteCodeMode.Local_1_Immediate_1, ByteCodeMode.Local_2_Immediate_2, true);
- new ByteCodeMetaData(ByteCode.__i2l, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__i2f, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__i2d, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__l2i, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__l2f, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__l2d, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__f2i, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__f2l, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__f2d, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__d2i, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__d2l, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__d2f, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__i2b, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__i2c, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__i2s, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lcmp, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__fcmpl, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__fcmpg, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dcmpl, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dcmpg, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__ifeq, ByteCodeMode.Branch_2, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__ifne, ByteCodeMode.Branch_2, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__iflt, ByteCodeMode.Branch_2, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__ifge, ByteCodeMode.Branch_2, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__ifgt, ByteCodeMode.Branch_2, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__ifle, ByteCodeMode.Branch_2, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__if_icmpeq, ByteCodeMode.Branch_2, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__if_icmpne, ByteCodeMode.Branch_2, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__if_icmplt, ByteCodeMode.Branch_2, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__if_icmpge, ByteCodeMode.Branch_2, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__if_icmpgt, ByteCodeMode.Branch_2, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__if_icmple, ByteCodeMode.Branch_2, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__if_acmpeq, ByteCodeMode.Branch_2, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__if_acmpne, ByteCodeMode.Branch_2, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__goto, ByteCodeMode.Branch_2, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__jsr, ByteCodeMode.Branch_2, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__ret, ByteCodeMode.Local_1, ByteCodeMode.Local_2, true);
- new ByteCodeMetaData(ByteCode.__tableswitch, NormalizedByteCode.__lookupswitch, ByteCodeMode.Tableswitch, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lookupswitch, ByteCodeMode.Lookupswitch, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__ireturn, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__lreturn, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__freturn, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__dreturn, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__areturn, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__return, ByteCodeMode.Simple, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__getstatic, ByteCodeMode.Constant_2, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__putstatic, ByteCodeMode.Constant_2, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__getfield, ByteCodeMode.Constant_2, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__putfield, ByteCodeMode.Constant_2, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__invokevirtual, ByteCodeMode.Constant_2, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__invokespecial, ByteCodeMode.Constant_2, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__invokestatic, ByteCodeMode.Constant_2, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__invokeinterface, ByteCodeMode.Constant_2_1_1, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__xxxunusedxxx, NormalizedByteCode.__nop, ByteCodeMode.Unused, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__new, ByteCodeMode.Constant_2, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__newarray, ByteCodeMode.Immediate_1, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__anewarray, ByteCodeMode.Constant_2, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__arraylength, ByteCodeMode.Simple, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__athrow, ByteCodeMode.Simple, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__checkcast, ByteCodeMode.Constant_2, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__instanceof, ByteCodeMode.Constant_2, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__monitorenter, ByteCodeMode.Simple, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__monitorexit, ByteCodeMode.Simple, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__wide, NormalizedByteCode.__nop, ByteCodeMode.Unused, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__multianewarray, ByteCodeMode.Constant_2_Immediate_1, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__ifnull, ByteCodeMode.Branch_2, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__ifnonnull, ByteCodeMode.Branch_2, ByteCodeMode.Unused, false);
- new ByteCodeMetaData(ByteCode.__goto_w, NormalizedByteCode.__goto, ByteCodeMode.Branch_4, ByteCodeMode.Unused, true);
- new ByteCodeMetaData(ByteCode.__jsr_w, NormalizedByteCode.__jsr, ByteCodeMode.Branch_4, ByteCodeMode.Unused, true);
+ new ByteCodeMetaData(ByteCode.__nop, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__aconst_null, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iconst_m1, NormalizedByteCode.__iconst, -1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iconst_0, NormalizedByteCode.__iconst, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iconst_1, NormalizedByteCode.__iconst, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iconst_2, NormalizedByteCode.__iconst, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iconst_3, NormalizedByteCode.__iconst, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iconst_4, NormalizedByteCode.__iconst, 4, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iconst_5, NormalizedByteCode.__iconst, 5, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lconst_0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lconst_1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fconst_0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fconst_1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fconst_2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dconst_0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dconst_1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__bipush, NormalizedByteCode.__iconst, ByteCodeMode.Immediate_1, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__sipush, NormalizedByteCode.__iconst, ByteCodeMode.Immediate_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ldc, ByteCodeMode.Constant_1, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ldc_w, NormalizedByteCode.__ldc, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ldc2_w, NormalizedByteCode.__ldc, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iload, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__lload, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__fload, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__dload, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__aload, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__iload_0, NormalizedByteCode.__iload, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iload_1, NormalizedByteCode.__iload, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iload_2, NormalizedByteCode.__iload, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iload_3, NormalizedByteCode.__iload, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lload_0, NormalizedByteCode.__lload, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lload_1, NormalizedByteCode.__lload, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lload_2, NormalizedByteCode.__lload, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lload_3, NormalizedByteCode.__lload, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fload_0, NormalizedByteCode.__fload, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fload_1, NormalizedByteCode.__fload, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fload_2, NormalizedByteCode.__fload, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fload_3, NormalizedByteCode.__fload, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dload_0, NormalizedByteCode.__dload, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dload_1, NormalizedByteCode.__dload, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dload_2, NormalizedByteCode.__dload, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dload_3, NormalizedByteCode.__dload, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__aload_0, NormalizedByteCode.__aload, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__aload_1, NormalizedByteCode.__aload, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__aload_2, NormalizedByteCode.__aload, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__aload_3, NormalizedByteCode.__aload, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iaload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__laload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__faload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__daload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__aaload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__baload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__caload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__saload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__istore, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__lstore, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__fstore, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__dstore, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__astore, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__istore_0, NormalizedByteCode.__istore, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__istore_1, NormalizedByteCode.__istore, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__istore_2, NormalizedByteCode.__istore, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__istore_3, NormalizedByteCode.__istore, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lstore_0, NormalizedByteCode.__lstore, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lstore_1, NormalizedByteCode.__lstore, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lstore_2, NormalizedByteCode.__lstore, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lstore_3, NormalizedByteCode.__lstore, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fstore_0, NormalizedByteCode.__fstore, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fstore_1, NormalizedByteCode.__fstore, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fstore_2, NormalizedByteCode.__fstore, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fstore_3, NormalizedByteCode.__fstore, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dstore_0, NormalizedByteCode.__dstore, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dstore_1, NormalizedByteCode.__dstore, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dstore_2, NormalizedByteCode.__dstore, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dstore_3, NormalizedByteCode.__dstore, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__astore_0, NormalizedByteCode.__astore, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__astore_1, NormalizedByteCode.__astore, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__astore_2, NormalizedByteCode.__astore, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__astore_3, NormalizedByteCode.__astore, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iastore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__lastore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__fastore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__dastore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__aastore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__bastore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__castore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__sastore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__pop, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__pop2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dup, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dup_x1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dup_x2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dup2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dup2_x1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dup2_x2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__swap, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iadd, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ladd, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fadd, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dadd, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__isub, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lsub, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fsub, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dsub, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__imul, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lmul, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fmul, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dmul, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__idiv, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ldiv, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fdiv, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ddiv, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__irem, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lrem, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__frem, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__drem, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ineg, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lneg, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fneg, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dneg, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ishl, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lshl, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ishr, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lshr, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iushr, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lushr, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iand, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__land, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ior, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lor, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ixor, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lxor, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iinc, ByteCodeMode.Local_1_Immediate_1, ByteCodeModeWide.Local_2_Immediate_2, true);
+ new ByteCodeMetaData(ByteCode.__i2l, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__i2f, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__i2d, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__l2i, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__l2f, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__l2d, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__f2i, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__f2l, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__f2d, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__d2i, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__d2l, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__d2f, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__i2b, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__i2c, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__i2s, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lcmp, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fcmpl, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fcmpg, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dcmpl, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dcmpg, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ifeq, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ifne, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iflt, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ifge, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ifgt, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ifle, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__if_icmpeq, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__if_icmpne, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__if_icmplt, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__if_icmpge, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__if_icmpgt, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__if_icmple, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__if_acmpeq, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__if_acmpne, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__goto, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__jsr, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ret, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__tableswitch, NormalizedByteCode.__lookupswitch, ByteCodeMode.Tableswitch, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lookupswitch, ByteCodeMode.Lookupswitch, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ireturn, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lreturn, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__freturn, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dreturn, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__areturn, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__return, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__getstatic, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__putstatic, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__getfield, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__putfield, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__invokevirtual, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__invokespecial, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__invokestatic, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__invokeinterface, ByteCodeMode.Constant_2_1_1, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__xxxunusedxxx, NormalizedByteCode.__nop, ByteCodeMode.Unused, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__new, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__newarray, ByteCodeMode.Immediate_1, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__anewarray, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__arraylength, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__athrow, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__checkcast, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__instanceof, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__monitorenter, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__monitorexit, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__wide, NormalizedByteCode.__nop, ByteCodeMode.WidePrefix, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__multianewarray, ByteCodeMode.Constant_2_Immediate_1, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__ifnull, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ifnonnull, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__goto_w, NormalizedByteCode.__goto, ByteCodeMode.Branch_4, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__jsr_w, NormalizedByteCode.__jsr, ByteCodeMode.Branch_4, ByteCodeModeWide.Unused, true);
}
}
diff --git a/runtime/ClassFile.cs b/runtime/ClassFile.cs
index 890379c7..15a8a7f0 100644
--- a/runtime/ClassFile.cs
+++ b/runtime/ClassFile.cs
@@ -24,28 +24,32 @@
using System;
using System.IO;
using System.Collections;
+// MONOBUG mcs 1.0 still has problems resolving properties vs. type names
+using __Modifiers = Modifiers;
class ClassFile
{
private ConstantPoolItem[] constantpool;
+ private string[] utf8_cp;
private Modifiers access_flags;
private ConstantPoolItemClass this_cpi;
private ConstantPoolItemClass super_cpi;
private ConstantPoolItemClass[] interfaces;
private Field[] fields;
private Method[] methods;
- private Attribute[] attributes;
private string sourceFile;
- private bool sourceFileCached;
private ClassFile outerClass;
- private int majorVersion;
+ private ushort majorVersion;
+ private bool deprecated;
+ private string ikvmAssembly;
+ private InnerClass[] innerClasses;
private static readonly char[] illegalcharacters = { '<', '>' };
- internal ClassFile(byte[] buf, int offset, int length, string inputClassName)
+ internal ClassFile(byte[] buf, int offset, int length, string inputClassName, bool allowJavaLangObject)
{
try
{
- BigEndianBinaryReader br = new BigEndianBinaryReader(buf, offset);
+ BigEndianBinaryReader br = new BigEndianBinaryReader(buf, offset, length);
if(br.ReadUInt32() != 0xCAFEBABE)
{
throw new ClassFormatError("Bad magic number");
@@ -56,16 +60,51 @@ class ClassFile
{
throw new UnsupportedClassVersionError(majorVersion + "." + minorVersion);
}
- Hashtable classCache = new Hashtable();
int constantpoolcount = br.ReadUInt16();
constantpool = new ConstantPoolItem[constantpoolcount];
+ utf8_cp = new string[constantpoolcount];
for(int i = 1; i < constantpoolcount; i++)
{
- constantpool[i] = ConstantPoolItem.Read(inputClassName, classCache, br);
- // LONG and DOUBLE items take up two slots...
- if(constantpool[i].IsWide)
+ Constant tag = (Constant)br.ReadByte();
+ switch(tag)
{
- i++;
+ case Constant.Class:
+ constantpool[i] = new ConstantPoolItemClass(br);
+ break;
+ case Constant.Double:
+ constantpool[i] = new ConstantPoolItemDouble(br);
+ i++;
+ break;
+ case Constant.Fieldref:
+ constantpool[i] = new ConstantPoolItemFieldref(br);
+ break;
+ case Constant.Float:
+ constantpool[i] = new ConstantPoolItemFloat(br);
+ break;
+ case Constant.Integer:
+ constantpool[i] = new ConstantPoolItemInteger(br);
+ break;
+ case Constant.InterfaceMethodref:
+ constantpool[i] = new ConstantPoolItemInterfaceMethodref(br);
+ break;
+ case Constant.Long:
+ constantpool[i] = new ConstantPoolItemLong(br);
+ i++;
+ break;
+ case Constant.Methodref:
+ constantpool[i] = new ConstantPoolItemMethodref(br);
+ break;
+ case Constant.NameAndType:
+ constantpool[i] = new ConstantPoolItemNameAndType(br);
+ break;
+ case Constant.String:
+ constantpool[i] = new ConstantPoolItemString(br);
+ break;
+ case Constant.Utf8:
+ utf8_cp[i] = br.ReadString();
+ break;
+ default:
+ throw new ClassFormatError("{0} (Illegal constant pool type 0x{1:X})", inputClassName, tag);
}
}
for(int i = 1; i < constantpoolcount; i++)
@@ -119,7 +158,7 @@ class ClassFile
}
else
{
- if(this.Name != "java.lang.Object")
+ if(this.Name != "java.lang.Object" || !allowJavaLangObject)
{
throw new ClassFormatError("{0} (Bad superclass index)", Name);
}
@@ -135,8 +174,7 @@ class ClassFile
}
int interfaces_count = br.ReadUInt16();
interfaces = new ConstantPoolItemClass[interfaces_count];
- Hashtable interfaceNames = new Hashtable();
- for(int i = 0; i < interfaces_count; i++)
+ for(int i = 0; i < interfaces.Length; i++)
{
int index = br.ReadUInt16();
if(index == 0 || index >= constantpool.Length)
@@ -148,39 +186,43 @@ class ClassFile
{
throw new ClassFormatError("{0} (Interface name has bad constant type)", Name);
}
- interfaces[i] = (ConstantPoolItemClass)GetConstantPoolItem(index);
- if(interfaceNames.ContainsKey(interfaces[i]))
+ interfaces[i] = cpi;
+ for(int j = 0; j < i; j++)
{
- throw new ClassFormatError("{0} (Repetitive interface name)", Name);
+ if(interfaces[j].Name == cpi.Name)
+ {
+ throw new ClassFormatError("{0} (Repetitive interface name)", Name);
+ }
}
- interfaceNames.Add(interfaces[i], interfaces[i]);
}
int fields_count = br.ReadUInt16();
fields = new Field[fields_count];
Hashtable fieldNameSigs = new Hashtable();
for(int i = 0; i < fields_count; i++)
{
- fields[i] = new Field(this, classCache, br);
+ fields[i] = new Field(this, br);
string name = fields[i].Name;
- // NOTE It's not in the vmspec (as far as I can tell), but Sun's VM doens't allow names that
+ // NOTE It's not in the vmspec (as far as I can tell), but Sun's VM doesn't allow names that
// contain '<' or '>'
if(name.Length == 0 || name.IndexOfAny(illegalcharacters) != -1)
{
throw new ClassFormatError("{0} (Illegal field name \"{1}\")", Name, name);
}
- string nameSig = name + fields[i].Signature;
- if(fieldNameSigs.ContainsKey(nameSig))
+ try
+ {
+ fieldNameSigs.Add(name + fields[i].Signature, null);
+ }
+ catch(ArgumentException)
{
throw new ClassFormatError("{0} (Repetitive field name/signature)", Name);
}
- fieldNameSigs.Add(nameSig, nameSig);
}
int methods_count = br.ReadUInt16();
methods = new Method[methods_count];
Hashtable methodNameSigs = new Hashtable();
for(int i = 0; i < methods_count; i++)
{
- methods[i] = new Method(this, classCache, br);
+ methods[i] = new Method(this, br);
string name = methods[i].Name;
string sig = methods[i].Signature;
if(name.Length == 0 || (name.IndexOfAny(illegalcharacters) != -1 && name != "<init>" && name != "<clinit>"))
@@ -191,29 +233,61 @@ class ClassFile
{
throw new ClassFormatError("{0} (Method \"{1}\" has illegal signature \"{2}\")", Name, name, sig);
}
- string nameSig = name + sig;
- if(methodNameSigs.ContainsKey(nameSig))
+ try
+ {
+ methodNameSigs.Add(name + sig, null);
+ }
+ catch(ArgumentException)
{
throw new ClassFormatError("{0} (Repetitive method name/signature)", Name);
}
- methodNameSigs.Add(nameSig, nameSig);
}
int attributes_count = br.ReadUInt16();
- attributes = new Attribute[attributes_count];
for(int i = 0; i < attributes_count; i++)
{
- attributes[i] = Attribute.Read(this, br);
+ switch(GetConstantPoolUtf8String(br.ReadUInt16()))
+ {
+ case "Deprecated":
+ deprecated = true;
+ if(br.ReadUInt32() != 0)
+ {
+ throw new ClassFormatError("Deprecated attribute has non-zero length");
+ }
+ break;
+ case "SourceFile":
+ if(br.ReadUInt32() != 2)
+ {
+ throw new ClassFormatError("SourceFile attribute has incorrect length");
+ }
+ sourceFile = GetConstantPoolUtf8String(br.ReadUInt16());
+ break;
+ case "InnerClasses":
+ BigEndianBinaryReader rdr = br.Section(br.ReadUInt32());
+ ushort count = rdr.ReadUInt16();
+ innerClasses = new InnerClass[count];
+ for(int j = 0; j < innerClasses.Length; j++)
+ {
+ innerClasses[j].innerClass = rdr.ReadUInt16();
+ innerClasses[j].outerClass = rdr.ReadUInt16();
+ innerClasses[j].name = rdr.ReadUInt16();
+ innerClasses[j].accessFlags = (Modifiers)rdr.ReadUInt16();
+ }
+ break;
+ case "IKVM.NET.Assembly":
+ if(br.ReadUInt32() != 2)
+ {
+ throw new ClassFormatError("IKVM.NET.Assembly attribute has incorrect length");
+ }
+ ikvmAssembly = GetConstantPoolUtf8String(br.ReadUInt16());
+ break;
+ default:
+ br.Skip(br.ReadUInt32());
+ break;
+ }
}
if(br.Position != offset + length)
{
- if(br.Position > offset + length)
- {
- throw new ClassFormatError("Truncated class file");
- }
- else
- {
- throw new ClassFormatError("Extra bytes at the end of the class file");
- }
+ throw new ClassFormatError("Extra bytes at the end of the class file");
}
}
catch(IndexOutOfRangeException)
@@ -251,13 +325,13 @@ class ClassFile
}
}
- internal void Link(TypeWrapper thisType)
+ internal void Link(TypeWrapper thisType, Hashtable classCache)
{
for(int i = 1; i < constantpool.Length; i++)
{
if(constantpool[i] != null)
{
- constantpool[i].Link(thisType);
+ constantpool[i].Link(thisType, classCache);
}
}
}
@@ -331,9 +405,9 @@ class ClassFile
return ((ConstantPoolItemClass)constantpool[index]).Name;
}
- internal TypeWrapper GetConstantPoolClassType(int index, ClassLoaderWrapper classLoader)
+ internal TypeWrapper GetConstantPoolClassType(int index)
{
- return ((ConstantPoolItemClass)constantpool[index]).GetClassType(classLoader);
+ return ((ConstantPoolItemClass)constantpool[index]).GetClassType();
}
private string GetConstantPoolString(int index)
@@ -341,14 +415,9 @@ class ClassFile
return ((ConstantPoolItemString)constantpool[index]).Value;
}
- private ConstantPoolItemUtf8 GetConstantPoolUtf8(int index)
- {
- return ((ConstantPoolItemUtf8)constantpool[index]);
- }
-
internal string GetConstantPoolUtf8String(int index)
{
- return GetConstantPoolUtf8(index).Value;
+ return utf8_cp[index];
}
internal ConstantType GetConstantPoolConstantType(int index)
@@ -389,20 +458,6 @@ class ClassFile
}
}
- internal string PackageName
- {
- get
- {
- string name = Name;
- int index = name.LastIndexOf('.');
- if(index == -1)
- {
- return "";
- }
- return name.Substring(0, index);
- }
- }
-
internal string SuperClass
{
get
@@ -435,31 +490,10 @@ class ClassFile
}
}
- private Attribute GetAttribute(string name)
- {
- for(int i = 0; i < attributes.Length; i++)
- {
- if(attributes[i].Name == name)
- {
- return attributes[i];
- }
- }
- return null;
- }
-
internal string SourceFileAttribute
{
get
{
- if(!sourceFileCached)
- {
- sourceFileCached = true;
- Attribute attr = GetAttribute("SourceFile");
- if(attr != null)
- {
- sourceFile = ((ConstantPoolItemUtf8)GetConstantPoolItem(attr.Data.ReadUInt16())).Value;
- }
- }
return sourceFile;
}
}
@@ -468,12 +502,7 @@ class ClassFile
{
get
{
- Attribute attr = GetAttribute("IKVM.NET.Assembly");
- if(attr != null)
- {
- return ((ConstantPoolItemUtf8)GetConstantPoolItem(attr.Data.ReadUInt16())).Value;
- }
- return null;
+ return ikvmAssembly;
}
}
@@ -481,15 +510,15 @@ class ClassFile
{
get
{
- return GetAttribute("Deprecated") != null;
+ return deprecated;
}
}
internal struct InnerClass
{
- internal int innerClass; // ConstantPoolItemClass
- internal int outerClass; // ConstantPoolItemClass
- internal int name; // ConstantPoolItemUtf8
+ internal ushort innerClass; // ConstantPoolItemClass
+ internal ushort outerClass; // ConstantPoolItemClass
+ internal ushort name; // ConstantPoolItemUtf8
internal Modifiers accessFlags;
}
@@ -497,22 +526,7 @@ class ClassFile
{
get
{
- Attribute attr = GetAttribute("InnerClasses");
- if(attr != null)
- {
- BigEndianBinaryReader rdr = attr.Data;
- ushort count = rdr.ReadUInt16();
- InnerClass[] list = new InnerClass[count];
- for(int i = 0; i < list.Length; i++)
- {
- list[i].innerClass = rdr.ReadUInt16();
- list[i].outerClass = rdr.ReadUInt16();
- list[i].name = rdr.ReadUInt16();
- list[i].accessFlags = (Modifiers)rdr.ReadUInt16();
- }
- return list;
- }
- return null;
+ return innerClasses;
}
}
@@ -528,19 +542,11 @@ class ClassFile
internal abstract class ConstantPoolItem
{
- internal virtual bool IsWide
- {
- get
- {
- return false;
- }
- }
-
internal virtual void Resolve(ClassFile classFile)
{
}
- internal virtual void Link(TypeWrapper thisType)
+ internal virtual void Link(TypeWrapper thisType, Hashtable classCache)
{
}
@@ -548,38 +554,6 @@ class ClassFile
{
throw new InvalidOperationException();
}
-
- internal static ConstantPoolItem Read(string inputClassName, Hashtable classCache, BigEndianBinaryReader br)
- {
- byte tag = br.ReadByte();
- switch((Constant)tag)
- {
- case Constant.Class:
- return new ConstantPoolItemClass(classCache, br);
- case Constant.Double:
- return new ConstantPoolItemDouble(br);
- case Constant.Fieldref:
- return new ConstantPoolItemFieldref(br);
- case Constant.Float:
- return new ConstantPoolItemFloat(br);
- case Constant.Integer:
- return new ConstantPoolItemInteger(br);
- case Constant.InterfaceMethodref:
- return new ConstantPoolItemInterfaceMethodref(br);
- case Constant.Long:
- return new ConstantPoolItemLong(br);
- case Constant.Methodref:
- return new ConstantPoolItemMethodref(br);
- case Constant.NameAndType:
- return new ConstantPoolItemNameAndType(classCache, br);
- case Constant.String:
- return new ConstantPoolItemString(br);
- case Constant.Utf8:
- return new ConstantPoolItemUtf8(inputClassName, br);
- default:
- throw new ClassFormatError("{0} (Illegal constant pool type 0x{1:X})", inputClassName, tag);
- }
- }
}
internal class ConstantPoolItemClass : ConstantPoolItem
@@ -587,17 +561,23 @@ class ClassFile
private ushort name_index;
private string name;
private TypeWrapper typeWrapper;
- private Hashtable classCache;
- internal ConstantPoolItemClass(Hashtable classCache, BigEndianBinaryReader br)
+ internal ConstantPoolItemClass(BigEndianBinaryReader br)
{
- this.classCache = classCache;
name_index = br.ReadUInt16();
}
internal override void Resolve(ClassFile classFile)
{
- name = ((ConstantPoolItemUtf8)classFile.GetConstantPoolItem(name_index)).DottifiedValue;;
+ name = classFile.GetConstantPoolUtf8String(name_index).Replace('/', '.');
+ }
+
+ internal override void Link(TypeWrapper thisType, Hashtable classCache)
+ {
+ if(typeWrapper == null)
+ {
+ typeWrapper = LoadClassHelper(thisType.GetClassLoader(), classCache, name);
+ }
}
internal string Name
@@ -608,12 +588,8 @@ class ClassFile
}
}
- internal TypeWrapper GetClassType(ClassLoaderWrapper classLoader)
+ internal TypeWrapper GetClassType()
{
- if(typeWrapper == null)
- {
- typeWrapper = LoadClassHelper(classLoader, classCache, name);
- }
return typeWrapper;
}
@@ -784,14 +760,6 @@ class ClassFile
return d;
}
}
-
- internal override bool IsWide
- {
- get
- {
- return true;
- }
- }
}
internal class ConstantPoolItemFMI : ConstantPoolItem
@@ -813,6 +781,12 @@ class ClassFile
clazz = (ConstantPoolItemClass)classFile.GetConstantPoolItem(class_index);
}
+ internal override void Link(TypeWrapper thisType, Hashtable classCache)
+ {
+ name_and_type.Link(thisType, classCache);
+ clazz.Link(thisType, classCache);
+ }
+
internal string Name
{
get
@@ -837,9 +811,9 @@ class ClassFile
}
}
- internal TypeWrapper GetClassType(ClassLoaderWrapper classLoader)
+ internal TypeWrapper GetClassType()
{
- return clazz.GetClassType(classLoader);
+ return clazz.GetClassType();
}
}
@@ -851,19 +825,18 @@ class ClassFile
{
}
- internal TypeWrapper GetFieldType(ClassLoaderWrapper classLoader)
+ internal TypeWrapper GetFieldType()
{
- return name_and_type.GetFieldType(classLoader);
+ return name_and_type.GetFieldType();
}
- internal override void Link(TypeWrapper thisType)
+ internal override void Link(TypeWrapper thisType, Hashtable classCache)
{
- ClassLoaderWrapper classLoader = thisType.GetClassLoader();
- GetFieldType(classLoader);
- TypeWrapper wrapper = GetClassType(classLoader);
+ base.Link(thisType, classCache);
+ TypeWrapper wrapper = GetClassType();
if(!wrapper.IsUnloadable)
{
- field = wrapper.GetFieldWrapper(Name, GetFieldType(classLoader));
+ field = wrapper.GetFieldWrapper(Name, GetFieldType());
if(field != null)
{
field.Link();
@@ -886,14 +859,14 @@ class ClassFile
{
}
- internal TypeWrapper[] GetArgTypes(ClassLoaderWrapper classLoader)
+ internal TypeWrapper[] GetArgTypes()
{
- return name_and_type.GetArgTypes(classLoader);
+ return name_and_type.GetArgTypes();
}
- internal TypeWrapper GetRetType(ClassLoaderWrapper classLoader)
+ internal TypeWrapper GetRetType()
{
- return name_and_type.GetRetType(classLoader);
+ return name_and_type.GetRetType();
}
internal MethodWrapper GetMethod()
@@ -913,12 +886,10 @@ class ClassFile
{
}
- internal override void Link(TypeWrapper thisType)
+ internal override void Link(TypeWrapper thisType, Hashtable classCache)
{
- ClassLoaderWrapper classLoader = thisType.GetClassLoader();
- TypeWrapper wrapper = GetClassType(classLoader);
- GetArgTypes(classLoader);
- GetRetType(classLoader);
+ base.Link(thisType, classCache);
+ TypeWrapper wrapper = GetClassType();
if(!wrapper.IsUnloadable)
{
MethodDescriptor md = new MethodDescriptor(Name, Signature);
@@ -928,7 +899,7 @@ class ClassFile
method.Link();
}
if(Name != "<init>" &&
- (thisType.Modifiers & (Modifiers.Interface | Modifiers.Super)) == Modifiers.Super &&
+ (thisType.Modifiers & (__Modifiers.Interface | __Modifiers.Super)) == __Modifiers.Super &&
thisType != wrapper && thisType.IsSubTypeOf(wrapper))
{
invokespecialMethod = thisType.BaseTypeWrapper.GetMethodWrapper(md, true);
@@ -966,12 +937,10 @@ class ClassFile
return null;
}
- internal override void Link(TypeWrapper thisType)
+ internal override void Link(TypeWrapper thisType, Hashtable classCache)
{
- ClassLoaderWrapper classLoader = thisType.GetClassLoader();
- TypeWrapper wrapper = GetClassType(classLoader);
- GetArgTypes(classLoader);
- GetRetType(classLoader);
+ base.Link(thisType, classCache);
+ TypeWrapper wrapper = GetClassType();
if(!wrapper.IsUnloadable)
{
MethodDescriptor md = new MethodDescriptor(Name, Signature);
@@ -1056,14 +1025,6 @@ class ClassFile
return l;
}
}
-
- internal override bool IsWide
- {
- get
- {
- return true;
- }
- }
}
internal class ConstantPoolItemNameAndType : ConstantPoolItem
@@ -1075,23 +1036,38 @@ class ClassFile
private TypeWrapper[] argTypeWrappers;
private TypeWrapper retTypeWrapper;
private TypeWrapper fieldTypeWrapper;
- private Hashtable classCache;
- internal ConstantPoolItemNameAndType(Hashtable classCache, BigEndianBinaryReader br)
+ internal ConstantPoolItemNameAndType(BigEndianBinaryReader br)
{
- this.classCache = classCache;
name_index = br.ReadUInt16();
descriptor_index = br.ReadUInt16();
}
internal override void Resolve(ClassFile classFile)
{
- ConstantPoolItemUtf8 nameUtf8 = (ConstantPoolItemUtf8)classFile.GetConstantPoolItem(name_index);
- nameUtf8.Resolve(classFile);
- name = nameUtf8.Value;
- ConstantPoolItemUtf8 descriptorUtf8 = (ConstantPoolItemUtf8)classFile.GetConstantPoolItem(descriptor_index);
- descriptorUtf8.Resolve(classFile);
- descriptor = descriptorUtf8.DottifiedValue;
+ name = classFile.GetConstantPoolUtf8String(name_index).Replace('/', '.');
+ descriptor = classFile.GetConstantPoolUtf8String(descriptor_index).Replace('/', '.');
+ }
+
+ internal override void Link(TypeWrapper thisType, Hashtable classCache)
+ {
+ if(descriptor[0] == '(')
+ {
+ if(argTypeWrappers == null)
+ {
+ ClassLoaderWrapper classLoader = thisType.GetClassLoader();
+ argTypeWrappers = ArgTypeWrapperListFromSig(classLoader, classCache, descriptor);
+ retTypeWrapper = RetTypeWrapperFromSig(classLoader, classCache, descriptor);
+ }
+ }
+ else
+ {
+ if(fieldTypeWrapper == null)
+ {
+ ClassLoaderWrapper classLoader = thisType.GetClassLoader();
+ fieldTypeWrapper = FieldTypeWrapperFromSig(classLoader, classCache, descriptor);
+ }
+ }
}
internal string Name
@@ -1110,30 +1086,18 @@ class ClassFile
}
}
- internal TypeWrapper[] GetArgTypes(ClassLoaderWrapper classLoader)
+ internal TypeWrapper[] GetArgTypes()
{
- if(argTypeWrappers == null)
- {
- argTypeWrappers = ArgTypeWrapperListFromSig(classLoader, classCache, descriptor);
- }
return argTypeWrappers;
}
- internal TypeWrapper GetRetType(ClassLoaderWrapper classLoader)
+ internal TypeWrapper GetRetType()
{
- if(retTypeWrapper == null)
- {
- retTypeWrapper = RetTypeWrapperFromSig(classLoader, classCache, descriptor);
- }
return retTypeWrapper;
}
- internal TypeWrapper GetFieldType(ClassLoaderWrapper classLoader)
+ internal TypeWrapper GetFieldType()
{
- if(fieldTypeWrapper == null)
- {
- fieldTypeWrapper = FieldTypeWrapperFromSig(classLoader, classCache, descriptor);
- }
return fieldTypeWrapper;
}
}
@@ -1150,9 +1114,7 @@ class ClassFile
internal override void Resolve(ClassFile classFile)
{
- ConstantPoolItemUtf8 utf8 = (ConstantPoolItemUtf8)classFile.GetConstantPoolItem(string_index);
- utf8.Resolve(classFile);
- s = utf8.Value;
+ s = classFile.GetConstantPoolUtf8String(string_index);
}
internal override ConstantType GetConstantType()
@@ -1169,40 +1131,7 @@ class ClassFile
}
}
- private class ConstantPoolItemUtf8 : ConstantPoolItem
- {
- private string s;
-
- internal ConstantPoolItemUtf8(string inputClassName, BigEndianBinaryReader br)
- {
- try
- {
- s = br.ReadString();
- }
- catch(FormatException)
- {
- throw new ClassFormatError("{0} (Illegal UTF8 string in constant pool)", inputClassName);
- }
- }
-
- internal string Value
- {
- get
- {
- return s;
- }
- }
-
- internal string DottifiedValue
- {
- get
- {
- return s.Replace('/', '.');
- }
- }
- }
-
- private enum Constant
+ internal enum Constant
{
Utf8 = 1,
Integer = 3,
@@ -1217,90 +1146,26 @@ class ClassFile
NameAndType = 12
}
- internal class Attribute
- {
- private string name;
- private BigEndianBinaryReader data;
-
- private Attribute()
- {
- }
-
- internal static Attribute Read(ClassFile classFile, BigEndianBinaryReader br)
- {
- try
- {
- int name_index = br.ReadUInt16();
- string name = classFile.GetConstantPoolUtf8(name_index).Value;
- int attribute_length = br.ReadInt32();
- Attribute a = new Attribute();
- a.name = name;
- a.data = br.Section(attribute_length);
- return a;
- }
- catch(InvalidCastException)
- {
- }
- catch(NullReferenceException)
- {
- }
- catch(IndexOutOfRangeException)
- {
- }
- throw new ClassFormatError("{0} (Attribute name invalid type)", classFile.Name);
- }
-
- internal string Name
- {
- get
- {
- return name;
- }
- }
-
- internal BigEndianBinaryReader Data
- {
- get
- {
- return data.Duplicate();
- }
- }
- }
-
internal class FieldOrMethod
{
- private ClassFile classFile;
protected Modifiers access_flags;
- private ushort name_index;
- private ushort descriptor_index;
- private Attribute[] attributes;
- private TypeWrapper[] argTypeWrappers;
- private TypeWrapper retTypeWrapper;
- private TypeWrapper fieldTypeWrapper;
- private Hashtable classCache;
+ private string name;
+ private string descriptor;
+ protected bool deprecated;
- internal FieldOrMethod(ClassFile classFile, Hashtable classCache, BigEndianBinaryReader br)
+ internal FieldOrMethod(ClassFile classFile, BigEndianBinaryReader br)
{
- this.classFile = classFile;
- this.classCache = classCache;
access_flags = (Modifiers)br.ReadUInt16();
- // TODO check that name is ConstantPoolItemUtf8
- name_index = br.ReadUInt16();
- // TODO check that descriptor is ConstantPoolItemUtf8 and validate the descriptor
- descriptor_index = br.ReadUInt16();
- int attributes_count = br.ReadUInt16();
- attributes = new Attribute[attributes_count];
- for(int i = 0; i < attributes_count; i++)
- {
- attributes[i] = Attribute.Read(classFile, br);
- }
+ name = classFile.GetConstantPoolUtf8String(br.ReadUInt16());
+ // TODO validate the descriptor
+ descriptor = classFile.GetConstantPoolUtf8String(br.ReadUInt16()).Replace('/', '.');
}
internal string Name
{
get
{
- return classFile.GetConstantPoolUtf8(name_index).Value;
+ return name;
}
}
@@ -1308,35 +1173,8 @@ class ClassFile
{
get
{
- return classFile.GetConstantPoolUtf8(descriptor_index).DottifiedValue;
- }
- }
-
- internal TypeWrapper[] GetArgTypes(ClassLoaderWrapper classLoader)
- {
- if(argTypeWrappers == null)
- {
- argTypeWrappers = ArgTypeWrapperListFromSig(classLoader, classCache, Signature);
- }
- return argTypeWrappers;
- }
-
- internal TypeWrapper GetRetType(ClassLoaderWrapper classLoader)
- {
- if(retTypeWrapper == null)
- {
- retTypeWrapper = RetTypeWrapperFromSig(classLoader, classCache, Signature);
- }
- return retTypeWrapper;
- }
-
- internal TypeWrapper GetFieldType(ClassLoaderWrapper classLoader)
- {
- if(fieldTypeWrapper == null)
- {
- fieldTypeWrapper = FieldTypeWrapperFromSig(classLoader, classCache, Signature);
+ return descriptor;
}
- return fieldTypeWrapper;
}
internal Modifiers Modifiers
@@ -1427,31 +1265,11 @@ class ClassFile
}
}
- protected Attribute GetAttribute(string name)
- {
- foreach(Attribute attr in attributes)
- {
- if(attr.Name == name)
- {
- return attr;
- }
- }
- return null;
- }
-
- internal ClassFile ClassFile
- {
- get
- {
- return classFile;
- }
- }
-
internal bool DeprecatedAttribute
{
get
{
- return GetAttribute("Deprecated") != null;
+ return deprecated;
}
}
}
@@ -1460,7 +1278,7 @@ class ClassFile
{
private object constantValue;
- internal Field(ClassFile classFile, Hashtable classCache, BigEndianBinaryReader br) : base(classFile, classCache, br)
+ internal Field(ClassFile classFile, BigEndianBinaryReader br) : base(classFile, br)
{
if((IsPrivate && IsPublic) || (IsPrivate && IsProtected) || (IsPublic && IsProtected)
|| (IsFinal && IsVolatile)
@@ -1468,67 +1286,90 @@ class ClassFile
{
throw new ClassFormatError("{0} (Illegal field modifiers: 0x{1:X})", classFile.Name, access_flags);
}
- // spec (4.7.2) says we should silently ignore ConstantValue attribute on non-static fields
- // NOTE a field doesn't have to be final to have a constant value!
- if(IsStatic)
+ int attributes_count = br.ReadUInt16();
+ for(int i = 0; i < attributes_count; i++)
{
- Attribute attr = GetAttribute("ConstantValue");
- if(attr != null)
+ switch(classFile.GetConstantPoolUtf8String(br.ReadUInt16()))
{
- ushort index = attr.Data.ReadUInt16();
- try
- {
- switch(Signature)
+ case "Deprecated":
+ deprecated = true;
+ if(br.ReadUInt32() != 0)
{
- case "I":
- constantValue = classFile.GetConstantPoolConstantInteger(index);
- break;
- case "S":
- constantValue = (short)classFile.GetConstantPoolConstantInteger(index);
- break;
- case "B":
- constantValue = (sbyte)classFile.GetConstantPoolConstantInteger(index);
- break;
- case "C":
- constantValue = (char)classFile.GetConstantPoolConstantInteger(index);
- break;
- case "Z":
- constantValue = classFile.GetConstantPoolConstantInteger(index) != 0;
- break;
- case "J":
- constantValue = classFile.GetConstantPoolConstantLong(index);
- break;
- case "F":
- constantValue = classFile.GetConstantPoolConstantFloat(index);
- break;
- case "D":
- constantValue = classFile.GetConstantPoolConstantDouble(index);
- break;
- case "Ljava.lang.String;":
- constantValue = classFile.GetConstantPoolConstantString(index);
- break;
- default:
- throw new ClassFormatError("{0} (Invalid signature for constant)", classFile.Name);
+ throw new ClassFormatError("Deprecated attribute has non-zero length");
}
- }
- catch(InvalidCastException)
+ break;
+ case "ConstantValue":
{
- throw new ClassFormatError("{0} (Bad index into constant pool)", classFile.Name);
- }
- catch(IndexOutOfRangeException)
- {
- throw new ClassFormatError("{0} (Bad index into constant pool)", classFile.Name);
- }
- catch(InvalidOperationException)
- {
- throw new ClassFormatError("{0} (Bad index into constant pool)", classFile.Name);
- }
- catch(NullReferenceException)
- {
- throw new ClassFormatError("{0} (Bad index into constant pool)", classFile.Name);
+ if(br.ReadUInt32() != 2)
+ {
+ throw new ClassFormatError("Invalid ConstantValue attribute length");
+ }
+ ushort index = br.ReadUInt16();
+ try
+ {
+ switch(Signature)
+ {
+ case "I":
+ constantValue = classFile.GetConstantPoolConstantInteger(index);
+ break;
+ case "S":
+ constantValue = (short)classFile.GetConstantPoolConstantInteger(index);
+ break;
+ case "B":
+ constantValue = (sbyte)classFile.GetConstantPoolConstantInteger(index);
+ break;
+ case "C":
+ constantValue = (char)classFile.GetConstantPoolConstantInteger(index);
+ break;
+ case "Z":
+ constantValue = classFile.GetConstantPoolConstantInteger(index) != 0;
+ break;
+ case "J":
+ constantValue = classFile.GetConstantPoolConstantLong(index);
+ break;
+ case "F":
+ constantValue = classFile.GetConstantPoolConstantFloat(index);
+ break;
+ case "D":
+ constantValue = classFile.GetConstantPoolConstantDouble(index);
+ break;
+ case "Ljava.lang.String;":
+ constantValue = classFile.GetConstantPoolConstantString(index);
+ break;
+ default:
+ throw new ClassFormatError("{0} (Invalid signature for constant)", classFile.Name);
+ }
+ }
+ catch(InvalidCastException)
+ {
+ throw new ClassFormatError("{0} (Bad index into constant pool)", classFile.Name);
+ }
+ catch(IndexOutOfRangeException)
+ {
+ throw new ClassFormatError("{0} (Bad index into constant pool)", classFile.Name);
+ }
+ catch(InvalidOperationException)
+ {
+ throw new ClassFormatError("{0} (Bad index into constant pool)", classFile.Name);
+ }
+ catch(NullReferenceException)
+ {
+ throw new ClassFormatError("{0} (Bad index into constant pool)", classFile.Name);
+ }
+ break;
}
+ default:
+ br.Skip(br.ReadUInt32());
+ break;
}
}
+ // spec (4.7.2) says we should silently ignore ConstantValue attribute on non-static fields
+ // NOTE a field doesn't have to be final to have a constant value!
+ if(!IsStatic)
+ {
+ // TODO is this needed?
+ constantValue = null;
+ }
}
internal object ConstantValue
@@ -1543,8 +1384,9 @@ class ClassFile
internal class Method : FieldOrMethod
{
private Code code;
+ private string[] exceptions;
- internal Method(ClassFile classFile, Hashtable classCache, BigEndianBinaryReader br) : base(classFile, classCache, br)
+ internal Method(ClassFile classFile, BigEndianBinaryReader br) : base(classFile, br)
{
// vmspec 4.6 says that all flags, except ACC_STRICT are ignored on <clinit>
if(Name == "<clinit>" && Signature == "()V")
@@ -1564,8 +1406,57 @@ class ClassFile
throw new ClassFormatError("{0} (Illegal method modifiers: 0x{1:X})", classFile.Name, access_flags);
}
}
- // TODO if the method is abstract or native it may not have a Code attribute (right?)
- // and if it is not abstract or native, it must have a Code attribute
+ int attributes_count = br.ReadUInt16();
+ for(int i = 0; i < attributes_count; i++)
+ {
+ switch(classFile.GetConstantPoolUtf8String(br.ReadUInt16()))
+ {
+ case "Deprecated":
+ deprecated = true;
+ if(br.ReadUInt32() != 0)
+ {
+ throw new ClassFormatError("Deprecated attribute has non-zero length");
+ }
+ break;
+ case "Code":
+ if(!code.IsEmpty)
+ {
+ throw new ClassFormatError("Duplicate Code attribute");
+ }
+ code.Read(classFile, this, br.Section(br.ReadUInt32()));
+ break;
+ case "Exceptions":
+ if(exceptions != null)
+ {
+ throw new ClassFormatError("Duplicate Exceptions attribute");
+ }
+ BigEndianBinaryReader rdr = br.Section(br.ReadUInt32());
+ ushort count = rdr.ReadUInt16();
+ exceptions = new string[count];
+ for(int j = 0; j < count; j++)
+ {
+ exceptions[j] = classFile.GetConstantPoolClass(rdr.ReadUInt16());
+ }
+ break;
+ default:
+ br.Skip(br.ReadUInt32());
+ break;
+ }
+ }
+ if(IsAbstract || IsNative)
+ {
+ if(!code.IsEmpty)
+ {
+ throw new ClassFormatError("Abstract or native method cannot have a Code attribute");
+ }
+ }
+ else
+ {
+ if(code.IsEmpty)
+ {
+ throw new ClassFormatError("Method has no Code attribute");
+ }
+ }
}
internal bool IsStrictfp
@@ -1585,73 +1476,106 @@ class ClassFile
}
}
- internal Code CodeAttribute
+ internal string[] ExceptionsAttribute
{
get
{
- if(code == null)
- {
- Attribute attr = GetAttribute("Code");
- if(attr != null)
- {
- code = new Code(this, attr);
- }
- }
- return code;
+ return exceptions;
}
}
- internal string[] ExceptionsAttribute
+ // maps argument 'slot' (as encoded in the xload/xstore instructions) into the ordinal
+ internal int[] ArgMap
{
get
{
- Attribute attr = GetAttribute("Exceptions");
- if(attr != null)
- {
- BigEndianBinaryReader rdr = attr.Data;
- ushort count = rdr.ReadUInt16();
- string[] exceptions = new string[count];
- for(int i = 0; i < count; i++)
- {
- exceptions[i] = ClassFile.GetConstantPoolClass(rdr.ReadUInt16());
- }
- return exceptions;
- }
- return null;
+ return code.argmap;
}
}
- internal class Code
+ internal int MaxStack
{
- private Method method;
- private ushort max_stack;
- private ushort max_locals;
- private Instruction[] instructions;
- private int[] pcIndexMap;
- private ExceptionTableEntry[] exception_table;
- private Attribute[] codeAttributes;
- private int[] argmap;
- private LineNumberTableEntry[] lineNumberTable;
- private bool lineNumberTableCached;
- private LocalVariableTableEntry[] localVariableTable;
- private bool localVariableTableCached;
+ get
+ {
+ return code.max_stack;
+ }
+ }
- internal Code(Method method, Attribute attr)
+ internal int MaxLocals
+ {
+ get
+ {
+ return code.max_locals;
+ }
+ }
+
+ internal Instruction[] Instructions
+ {
+ get
+ {
+ return code.instructions;
+ }
+ }
+
+ // maps a PC to an index in the Instruction[], invalid PCs return -1
+ internal int[] PcIndexMap
+ {
+ get
+ {
+ return code.pcIndexMap;
+ }
+ }
+
+ internal ExceptionTableEntry[] ExceptionTable
+ {
+ get
+ {
+ return code.exception_table;
+ }
+ }
+
+ internal LineNumberTableEntry[] LineNumberTableAttribute
+ {
+ get
+ {
+ return code.lineNumberTable;
+ }
+ }
+
+ internal LocalVariableTableEntry[] LocalVariableTableAttribute
+ {
+ get
+ {
+ return code.localVariableTable;
+ }
+ }
+
+ private struct Code
+ {
+ internal ushort max_stack;
+ internal ushort max_locals;
+ internal Instruction[] instructions;
+ internal int[] pcIndexMap;
+ internal ExceptionTableEntry[] exception_table;
+ internal int[] argmap;
+ internal LineNumberTableEntry[] lineNumberTable;
+ internal LocalVariableTableEntry[] localVariableTable;
+
+ internal void Read(ClassFile classFile, Method method, BigEndianBinaryReader br)
{
- this.method = method;
- BigEndianBinaryReader br = attr.Data;
max_stack = br.ReadUInt16();
max_locals = br.ReadUInt16();
uint code_length = br.ReadUInt32();
- ArrayList instructions = new ArrayList();
+ Instruction[] instructions = new Instruction[code_length + 1];
int basePosition = br.Position;
+ int instructionIndex = 0;
while(br.Position - basePosition < code_length)
{
- instructions.Add(Instruction.Read(this, br.Position - basePosition, br));
+ instructions[instructionIndex++].Read((ushort)(br.Position - basePosition), br);
}
// we add an additional nop instruction to make it easier for consumers of the code array
- instructions.Add(new Instruction(this, br.Position - basePosition, ByteCode.__nop));
- this.instructions = (Instruction[])instructions.ToArray(typeof(Instruction));
+ instructions[instructionIndex++].SetTermNop((ushort)(br.Position - basePosition));
+ this.instructions = instructions;
ushort exception_table_length = br.ReadUInt16();
exception_table = new ExceptionTableEntry[exception_table_length];
for(int i = 0; i < exception_table_length; i++)
@@ -1664,179 +1588,105 @@ class ClassFile
exception_table[i].ordinal = i;
}
ushort attributes_count = br.ReadUInt16();
- codeAttributes = new Attribute[attributes_count];
for(int i = 0; i < attributes_count; i++)
{
- codeAttributes[i] = Attribute.Read(method.ClassFile, br);
- }
- // build the pcIndexMap
- pcIndexMap = new int[this.instructions[this.instructions.Length - 1].PC + 1];
- for(int i = 0; i < pcIndexMap.Length; i++)
- {
- pcIndexMap[i] = -1;
- }
- for(int i = 0; i < this.instructions.Length - 1; i++)
- {
- pcIndexMap[this.instructions[i].PC] = i;
- }
- }
-
- // maps argument 'slot' (as encoded in the xload/xstore instructions) into the ordinal
- internal int[] ArgMap
- {
- get
- {
- if(argmap == null)
+ switch(classFile.GetConstantPoolUtf8String(br.ReadUInt16()))
{
- string sig = method.Signature;
- ArrayList args = new ArrayList();
- int pos = 0;
- if(!method.IsStatic)
- {
- args.Add(pos++);
- }
- for(int i = 1; sig[i] != ')'; i++)
- {
- args.Add(pos++);
- switch(sig[i])
+ case "LineNumberTable":
+ if(JVM.Debug)
{
- case 'L':
- i = sig.IndexOf(';', i);
- break;
- case 'D':
- case 'J':
- args.Add(-1);
- break;
- case '[':
+ BigEndianBinaryReader rdr = br.Section(br.ReadUInt32());
+ int count = rdr.ReadUInt16();
+ lineNumberTable = new LineNumberTableEntry[count];
+ for(int j = 0; j < count; j++)
{
- while(sig[i] == '[')
- {
- i++;
- }
- if(sig[i] == 'L')
- {
- i = sig.IndexOf(';', i);
- }
- break;
+ lineNumberTable[j].start_pc = rdr.ReadUInt16();
+ lineNumberTable[j].line_number = rdr.ReadUInt16();
}
}
- }
- argmap = new int[args.Count];
- args.CopyTo(argmap);
+ else
+ {
+ br.Skip(br.ReadUInt32());
+ }
+ break;
+ case "LocalVariableTable":
+ if(JVM.Debug)
+ {
+ BigEndianBinaryReader rdr = br.Section(br.ReadUInt32());
+ int count = rdr.ReadUInt16();
+ localVariableTable = new LocalVariableTableEntry[count];
+ for(int j = 0; j < count; j++)
+ {
+ localVariableTable[j].start_pc = rdr.ReadUInt16();
+ localVariableTable[j].length = rdr.ReadUInt16();
+ localVariableTable[j].name = classFile.GetConstantPoolUtf8String(rdr.ReadUInt16());
+ localVariableTable[j].descriptor = classFile.GetConstantPoolUtf8String(rdr.ReadUInt16()).Replace('/', '.');
+ localVariableTable[j].index = rdr.ReadUInt16();
+ }
+ }
+ else
+ {
+ br.Skip(br.ReadUInt32());
+ }
+ break;
+ default:
+ br.Skip(br.ReadUInt32());
+ break;
}
- return argmap;
}
- }
-
- internal Method Method
- {
- get
- {
- return method;
- }
- }
-
- internal int MaxStack
- {
- get
- {
- return max_stack;
- }
- }
-
- internal int MaxLocals
- {
- get
- {
- return max_locals;
- }
- }
-
- internal Instruction[] Instructions
- {
- get
- {
- return instructions;
- }
- }
-
- // maps a PC to an index in the Instruction[], invalid PCs return -1
- internal int[] PcIndexMap
- {
- get
+ // build the pcIndexMap
+ pcIndexMap = new int[this.instructions[instructionIndex - 1].PC + 1];
+ for(int i = 0; i < pcIndexMap.Length; i++)
{
- return pcIndexMap;
+ pcIndexMap[i] = -1;
}
- }
-
- internal ExceptionTableEntry[] ExceptionTable
- {
- get
+ for(int i = 0; i < instructionIndex - 1; i++)
{
- return exception_table;
+ pcIndexMap[this.instructions[i].PC] = i;
}
- }
-
- private Attribute GetAttribute(string name)
- {
- foreach(Attribute attr in codeAttributes)
+ // build the argmap
+ string sig = method.Signature;
+ ArrayList args = new ArrayList();
+ int pos = 0;
+ if(!method.IsStatic)
{
- if(attr.Name == name)
- {
- return attr;
- }
+ args.Add(pos++);
}
- return null;
- }
-
- internal LineNumberTableEntry[] LineNumberTableAttribute
- {
- get
+ for(int i = 1; sig[i] != ')'; i++)
{
- if(!lineNumberTableCached)
+ args.Add(pos++);
+ switch(sig[i])
{
- lineNumberTableCached = true;
- Attribute attr = GetAttribute("LineNumberTable");
- if(attr != null)
+ case 'L':
+ i = sig.IndexOf(';', i);
+ break;
+ case 'D':
+ case 'J':
+ args.Add(-1);
+ break;
+ case '[':
{
- BigEndianBinaryReader rdr = attr.Data;
- int count = rdr.ReadUInt16();
- lineNumberTable = new LineNumberTableEntry[count];
- for(int i = 0; i < count; i++)
+ while(sig[i] == '[')
{
- lineNumberTable[i].start_pc = rdr.ReadUInt16();
- lineNumberTable[i].line_number = rdr.ReadUInt16();
+ i++;
}
+ if(sig[i] == 'L')
+ {
+ i = sig.IndexOf(';', i);
+ }
+ break;
}
}
- return lineNumberTable;
}
+ argmap = new int[args.Count];
+ args.CopyTo(argmap);
}
- internal LocalVariableTableEntry[] LocalVariableTableAttribute
+ internal bool IsEmpty
{
get
{
- if(!localVariableTableCached)
- {
- localVariableTableCached = true;
- Attribute attr = GetAttribute("LocalVariableTable");
- if(attr != null)
- {
- BigEndianBinaryReader rdr = attr.Data;
- int count = rdr.ReadUInt16();
- localVariableTable = new LocalVariableTableEntry[count];
- for(int i = 0; i < count; i++)
- {
- localVariableTable[i].start_pc = rdr.ReadUInt16();
- localVariableTable[i].length = rdr.ReadUInt16();
- localVariableTable[i].name = method.ClassFile.GetConstantPoolUtf8(rdr.ReadUInt16()).Value;
- localVariableTable[i].descriptor = method.ClassFile.GetConstantPoolUtf8(rdr.ReadUInt16()).DottifiedValue;
- localVariableTable[i].index = rdr.ReadUInt16();
- }
- }
- }
- return localVariableTable;
+ return instructions == null;
}
}
}
@@ -1850,131 +1700,139 @@ class ClassFile
internal int ordinal;
}
- internal class Instruction
+ internal struct Instruction
{
- private Method.Code method;
- private int pc;
+ private ushort pc;
private ByteCode opcode;
+ private NormalizedByteCode normopcode;
private int arg1;
- private int arg2;
- private int default_offset;
- private int[] values;
- private int[] target_offsets;
+ private short arg2;
+ private SwitchEntry[] switch_entries;
- internal Instruction(Method.Code method, int pc, ByteCode opcode)
- : this(method, pc, opcode, 0)
+ struct SwitchEntry
{
+ internal int value;
+ internal int target_offset;
}
- private Instruction(Method.Code method, int pc, ByteCode opcode, int arg1)
- : this(method, pc, opcode, arg1, 0)
+ internal void SetTermNop(ushort pc)
{
- }
-
- private Instruction(Method.Code method, int pc, ByteCode opcode, int arg1, int arg2)
- {
- this.method = method;
+ // TODO what happens if we already have exactly the maximum number of instructions?
this.pc = pc;
- this.opcode = opcode;
- this.arg1 = arg1;
- this.arg2 = arg2;
+ this.opcode = ByteCode.__nop;
}
- private Instruction(Method.Code method, int pc, ByteCode opcode, int default_offset, int[] values, int[] target_offsets)
- : this(method, pc, opcode)
- {
- this.default_offset = default_offset;
- this.values = values;
- this.target_offsets = target_offsets;
- }
-
- internal static Instruction Read(Method.Code method, int pc, BigEndianBinaryReader br)
+ internal void Read(ushort pc, BigEndianBinaryReader br)
{
+ this.pc = pc;
ByteCode bc = (ByteCode)br.ReadByte();
- ByteCodeMode mode = ByteCodeMetaData.GetMode(bc);
- if(bc == ByteCode.__wide)
- {
- bc = (ByteCode)br.ReadByte();
- // NOTE the PC of a wide instruction is actually the PC of the
- // wide prefix, not the following instruction (vmspec 4.9.2)
- mode = ByteCodeMetaData.GetWideMode(bc);
- }
- switch(mode)
+ switch(ByteCodeMetaData.GetMode(bc))
{
case ByteCodeMode.Simple:
- return new Instruction(method, pc, bc);
+ break;
case ByteCodeMode.Constant_1:
case ByteCodeMode.Local_1:
- return new Instruction(method, pc, bc, br.ReadByte());
+ arg1 = br.ReadByte();
+ break;
case ByteCodeMode.Constant_2:
- case ByteCodeMode.Local_2:
- return new Instruction(method, pc, bc, br.ReadUInt16());
+ arg1 = br.ReadUInt16();
+ break;
case ByteCodeMode.Branch_2:
- return new Instruction(method, pc, bc, br.ReadInt16());
+ arg1 = br.ReadInt16();
+ break;
case ByteCodeMode.Branch_4:
- return new Instruction(method, pc, bc, br.ReadInt32());
+ arg1 = br.ReadInt32();
+ break;
case ByteCodeMode.Constant_2_1_1:
- {
- Instruction instr = new Instruction(method, pc, bc, br.ReadUInt16());
+ arg1 = br.ReadUInt16();
// TODO validate these
br.ReadByte(); // count
br.ReadByte(); // unused
- return instr;
- }
+ break;
case ByteCodeMode.Immediate_1:
- return new Instruction(method, pc, bc, br.ReadSByte());
+ arg1 = br.ReadSByte();
+ break;
case ByteCodeMode.Immediate_2:
- return new Instruction(method, pc, bc, br.ReadInt16());
+ arg1 = br.ReadInt16();
+ break;
case ByteCodeMode.Local_1_Immediate_1:
- return new Instruction(method, pc, bc, br.ReadByte(), br.ReadSByte());
- case ByteCodeMode.Local_2_Immediate_2:
- return new Instruction(method, pc, bc, br.ReadUInt16(), br.ReadInt16());
+ arg1 = br.ReadByte();
+ arg2 = br.ReadSByte();
+ break;
case ByteCodeMode.Constant_2_Immediate_1:
- return new Instruction(method, pc, bc, br.ReadUInt16(), br.ReadSByte());
+ arg1 = br.ReadUInt16();
+ arg2 = br.ReadSByte();
+ break;
case ByteCodeMode.Tableswitch:
{
// skip the padding
- int p = pc + 1;
- int align = ((p + 3) & 0x7ffffffc) - p;
- for(int i = 0; i < align; i++)
- {
- br.ReadByte();
- }
+ uint p = pc + 1u;
+ uint align = ((p + 3) & 0x7ffffffc) - p;
+ br.Skip(align);
int default_offset = br.ReadInt32();
+ this.arg1 = default_offset;
int low = br.ReadInt32();
int high = br.ReadInt32();
- int[] values = new int[high - low + 1];
- int[] target_offset = new int[high - low + 1];
+ if(low > high)
+ {
+ // TODO is this the right exception?
+ throw new ClassFormatError("Incorrect tableswitch (low > high)");
+ }
+ SwitchEntry[] entries = new SwitchEntry[high - low + 1];
for(int i = low; i <= high; i++)
{
- values[i - low] = i;
- target_offset[i - low] = br.ReadInt32();
+ entries[i - low].value = i;
+ entries[i - low].target_offset = br.ReadInt32();
}
- return new Instruction(method, pc, bc, default_offset, values, target_offset);
+ this.switch_entries = entries;
+ break;
}
case ByteCodeMode.Lookupswitch:
{
// skip the padding
- int p = pc + 1;
- int align = ((p + 3) & 0x7ffffffc) - p;
- for(int i = 0; i < align; i++)
- {
- br.ReadByte();
- }
+ uint p = pc + 1u;
+ uint align = ((p + 3) & 0x7ffffffc) - p;
+ br.Skip(align);
int default_offset = br.ReadInt32();
+ this.arg1 = default_offset;
int count = br.ReadInt32();
- int[] values = new int[count];
- int[] target_offset = new int[count];
+ if(count < 0)
+ {
+ // TODO is this the right exception?
+ throw new ClassFormatError("Incorrect lookupswitch (npairs < 0)");
+ }
+ SwitchEntry[] entries = new SwitchEntry[count];
for(int i = 0; i < count; i++)
{
- values[i] = br.ReadInt32();
- target_offset[i] = br.ReadInt32();
+ entries[i].value = br.ReadInt32();
+ entries[i].target_offset = br.ReadInt32();
}
- return new Instruction(method, pc, bc, default_offset, values, target_offset);
+ this.switch_entries = entries;
+ break;
}
+ case ByteCodeMode.WidePrefix:
+ bc = (ByteCode)br.ReadByte();
+ // NOTE the PC of a wide instruction is actually the PC of the
+ // wide prefix, not the following instruction (vmspec 4.9.2)
+ switch(ByteCodeMetaData.GetWideMode(bc))
+ {
+ case ByteCodeModeWide.Local_2:
+ arg1 = br.ReadUInt16();
+ break;
+ case ByteCodeModeWide.Local_2_Immediate_2:
+ arg1 = br.ReadUInt16();
+ arg2 = br.ReadInt16();
+ break;
+ default:
+ throw new ClassFormatError("Invalid wide prefix on opcode: {0}", bc);
+ }
+ break;
default:
throw new ClassFormatError("Invalid opcode: {0}", bc);
}
+ this.opcode = bc;
+ this.normopcode = ByteCodeMetaData.GetNormalizedByteCode(bc);
+ arg1 = ByteCodeMetaData.GetArg(opcode, arg1);
}
internal int PC
@@ -1997,7 +1855,7 @@ class ClassFile
{
get
{
- return ByteCodeMetaData.GetNormalizedByteCode(opcode);
+ return normopcode;
}
}
@@ -2021,7 +1879,7 @@ class ClassFile
{
get
{
- return ByteCodeMetaData.GetArg(opcode, arg1);
+ return arg1;
}
}
@@ -2029,48 +1887,42 @@ class ClassFile
{
get
{
- return default_offset;
+ return arg1;
}
}
- internal int[] Values
+ internal int SwitchEntryCount
{
get
{
- return values;
+ return switch_entries.Length;
}
}
- internal int[] TargetOffsets
+ internal int GetSwitchValue(int i)
{
- get
- {
- return target_offsets;
- }
+ return switch_entries[i].value;
}
- internal Method.Code MethodCode
+ internal int GetSwitchTargetOffset(int i)
{
- get
- {
- return method;
- }
+ return switch_entries[i].target_offset;
}
}
internal struct LineNumberTableEntry
{
- internal int start_pc;
- internal int line_number;
+ internal ushort start_pc;
+ internal ushort line_number;
}
internal struct LocalVariableTableEntry
{
- internal int start_pc;
- internal int length;
+ internal ushort start_pc;
+ internal ushort length;
internal string name;
internal string descriptor;
- internal int index;
+ internal ushort index;
}
}
}
diff --git a/runtime/ClassLoaderWrapper.cs b/runtime/ClassLoaderWrapper.cs
index e4357fea..1945fc88 100644
--- a/runtime/ClassLoaderWrapper.cs
+++ b/runtime/ClassLoaderWrapper.cs
@@ -42,6 +42,7 @@ class ClassLoaderWrapper
private static ClassLoaderWrapper bootstrapClassLoader;
private object javaClassLoader;
private Hashtable types = new Hashtable();
+ private ArrayList nativeLibraries;
// FXBUG moduleBuilder is static, because multiple dynamic assemblies is broken (TypeResolve doesn't fire)
// so for the time being, we share one dynamic assembly among all classloaders
private static ModuleBuilder moduleBuilder;
@@ -193,7 +194,7 @@ class ClassLoaderWrapper
{
Tracer.Warning(Tracer.Compiler, "Class name clash: {0}", name);
}
- return name + "\\\\" + instanceId;
+ return name + "/" + instanceId;
}
else
{
@@ -902,4 +903,28 @@ class ClassLoaderWrapper
return null;
}
}
+
+ internal void RegisterNativeLibrary(IntPtr p)
+ {
+ lock(this)
+ {
+ if(nativeLibraries == null)
+ {
+ nativeLibraries = new ArrayList();
+ }
+ nativeLibraries.Add(p);
+ }
+ }
+
+ internal IntPtr[] GetNativeLibraries()
+ {
+ lock(this)
+ {
+ if(nativeLibraries == null)
+ {
+ return new IntPtr[0];
+ }
+ return (IntPtr[])nativeLibraries.ToArray(typeof(IntPtr));
+ }
+ }
}
diff --git a/runtime/IKVM.Runtime.csproj b/runtime/IKVM.Runtime.csproj
index 79320c0f..54f9d0cd 100644
--- a/runtime/IKVM.Runtime.csproj
+++ b/runtime/IKVM.Runtime.csproj
@@ -24,7 +24,7 @@
>
<Config
Name = "Debug"
- AllowUnsafeBlocks = "false"
+ AllowUnsafeBlocks = "true"
BaseAddress = "285212672"
CheckForOverflowUnderflow = "false"
ConfigurationOverrideFile = ""
diff --git a/runtime/JavaException.cs b/runtime/JavaException.cs
index 1bfd2d4a..4b642d87 100644
--- a/runtime/JavaException.cs
+++ b/runtime/JavaException.cs
@@ -303,4 +303,14 @@ sealed class JavaException
{
return (Exception)Activator.CreateInstance(Load("java.lang.InstantiationError"), new object[] { String.Format(s, args) });
}
+
+ internal static Exception InterruptedException()
+ {
+ return (Exception)Activator.CreateInstance(Load("java.lang.InterruptedException"));
+ }
+
+ internal static Exception IllegalMonitorStateException()
+ {
+ return (Exception)Activator.CreateInstance(Load("java.lang.IllegalMonitorStateException"));
+ }
}
diff --git a/runtime/JniInterface.cs b/runtime/JniInterface.cs
index 65dd750d..f1064601 100644
--- a/runtime/JniInterface.cs
+++ b/runtime/JniInterface.cs
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2002 Jeroen Frijters
+ Copyright (C) 2002, 2003, 2004 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
@@ -22,43 +22,776 @@
*/
using System;
+using System.Collections;
using System.Diagnostics;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;
-public sealed class JniHelper
+sealed class JniHelper
{
- // NOTE sig contains slashed class names
- public static IntPtr GetMethodCookie(object clazz, string name, string sig, bool isStatic)
+ [DllImport("ikvm-native")]
+ private static extern IntPtr ikvm_LoadLibrary(string filename);
+ [DllImport("ikvm-native")]
+ private static extern void ikvm_FreeLibrary(IntPtr handle);
+ [DllImport("ikvm-native")]
+ internal static extern IntPtr ikvm_GetProcAddress(IntPtr handle, string name, int argc);
+ [DllImport("ikvm-native")]
+ private unsafe static extern int ikvm_CallOnLoad(IntPtr method, void* jvm, void* reserved);
+ [DllImport("ikvm-native")]
+ internal unsafe static extern void** ikvm_GetJNIEnvVTable();
+ [DllImport("ikvm-native")]
+ internal unsafe static extern void* ikvm_MarshalDelegate(Delegate d);
+
+ private static MethodBase FindCaller()
{
- try
+ StackTrace st = new StackTrace();
+ for(int i = 0; i < st.FrameCount; i++)
{
- TypeWrapper wrapper = NativeCode.java.lang.VMClass.getWrapperFromClass(clazz);
- MethodWrapper mw = wrapper.GetMethodWrapper(new MethodDescriptor(name, sig.Replace('/', '.')), true);
- if(mw != null)
+ StackFrame frame = st.GetFrame(i);
+ Type type = frame.GetMethod().DeclaringType;
+ if(type != null)
{
- if(mw.IsStatic == isStatic)
+ // TODO we need a more robust algorithm to find the "caller" (note that in addition to native methods,
+ // System.loadLibrary can also trigger executing native code)
+ ClassLoaderWrapper loader = ClassLoaderWrapper.GetWrapperFromType(type).GetClassLoader();
+ if(loader.GetJavaClassLoader() != null)
{
- mw.Link();
- return mw.Cookie;
+ return frame.GetMethod();
}
}
- return (IntPtr)0;
}
- catch
+ return null;
+ }
+
+ private static ArrayList nativeLibraries = new ArrayList();
+ internal static readonly object JniLock = new object();
+
+ internal unsafe static int LoadLibrary(string filename)
+ {
+ MethodBase m = FindCaller();
+ ClassLoaderWrapper loader;
+ if(m != null)
{
- Debug.Assert(false);
- throw;
+ loader = ClassLoaderWrapper.GetWrapperFromType(m.DeclaringType).GetClassLoader();
+ }
+ else
+ {
+ loader = ClassLoaderWrapper.GetBootstrapClassLoader();
+ }
+ lock(JniLock)
+ {
+ IntPtr p = ikvm_LoadLibrary(filename);
+ if(p == IntPtr.Zero)
+ {
+ return 0;
+ }
+ try
+ {
+ foreach(IntPtr tmp in loader.GetNativeLibraries())
+ {
+ if(tmp == p)
+ {
+ // the library was already loaded by the current class loader,
+ // no need to do anything
+ ikvm_FreeLibrary(p);
+ return 1;
+ }
+ }
+ if(nativeLibraries.Contains(p))
+ {
+ throw JavaException.UnsatisfiedLinkError("Native library {0} already loaded in another classloader", filename);
+ }
+ IntPtr onload = ikvm_GetProcAddress(p, "JNI_OnLoad", IntPtr.Size * 2);
+ if(onload != IntPtr.Zero)
+ {
+ JniFrame f = new JniFrame();
+ f.Enter(m.MethodHandle);
+ int version = ikvm_CallOnLoad(onload, JavaVM.pJavaVM, null);
+ f.Leave();
+ if(version != JNIEnv.JNI_VERSION_1_1 && version != JNIEnv.JNI_VERSION_1_2 && version != JNIEnv.JNI_VERSION_1_4)
+ {
+ throw JavaException.UnsatisfiedLinkError("Unsupported JNI version 0x{0:X} required by {1}", version, filename);
+ }
+ }
+ nativeLibraries.Add(p);
+ loader.RegisterNativeLibrary(p);
+ return 1;
+ }
+ catch
+ {
+ ikvm_FreeLibrary(p);
+ throw;
+ }
}
}
+}
+
+[StructLayout(LayoutKind.Sequential)]
+struct LocalRefCache
+{
+ internal object loc1;
+ object loc2;
+ object loc3;
+ object loc4;
+ object loc5;
+ object loc6;
+ object loc7;
+ object loc8;
+ object loc9;
+ object loc10;
+}
+
+unsafe struct LocalRefListEntry
+{
+ internal const int STATIC_LIST_SIZE = 10;
+ internal const int LOCAL_REF_SHIFT = 10;
+ internal const int BUCKET_SIZE = (1 << LOCAL_REF_SHIFT);
+ internal const int LOCAL_REF_MASK = (BUCKET_SIZE - 1);
+
+ [StructLayout(LayoutKind.Explicit)]
+ internal struct Union
+ {
+ [FieldOffset(0)]
+ internal Object* static_list;
+ [FieldOffset(0)]
+ internal void* pv;
+ }
+ internal Union u;
+ internal object[] dynamic_list;
+
+ internal int MakeLocalRef(object o)
+ {
+ for(int i = 0; i < STATIC_LIST_SIZE; i++)
+ {
+ if(u.static_list[i] == null)
+ {
+ u.static_list[i] = o;
+ return i;
+ }
+ }
+ if(dynamic_list == null)
+ {
+ dynamic_list = new object[32 - STATIC_LIST_SIZE];
+ }
+ for(int i = 0; i < dynamic_list.Length; i++)
+ {
+ if(dynamic_list[i] == null)
+ {
+ dynamic_list[i] = o;
+ return i + STATIC_LIST_SIZE;
+ }
+ }
+ int newsize = (dynamic_list.Length + STATIC_LIST_SIZE) * 2 - STATIC_LIST_SIZE;
+ if(newsize > BUCKET_SIZE)
+ {
+ return -1;
+ }
+ object[] tmp = dynamic_list;
+ dynamic_list = new object[newsize];
+ Array.Copy(tmp, 0, dynamic_list, 0, tmp.Length);
+ dynamic_list[tmp.Length] = o;
+ return tmp.Length + STATIC_LIST_SIZE;
+ }
+
+ internal void DeleteLocalRef(int i)
+ {
+ if(i < STATIC_LIST_SIZE)
+ {
+ u.static_list[i] = null;
+ }
+ else
+ {
+ dynamic_list[i - STATIC_LIST_SIZE] = null;
+ }
+ }
+
+ internal object UnwrapLocalRef(int i)
+ {
+ if(i < STATIC_LIST_SIZE)
+ {
+ return u.static_list[i];
+ }
+ else
+ {
+ return dynamic_list[i - STATIC_LIST_SIZE];
+ }
+ }
+}
+
+class GlobalRefs
+{
+ internal static System.Collections.ArrayList globalRefs = new System.Collections.ArrayList();
+}
+
+unsafe class VtableBuilder
+{
+ delegate int pf_int_IntPtr(JNIEnv* pEnv, IntPtr p);
+ delegate IntPtr pf_IntPtr_IntPtr(JNIEnv* pEnv, IntPtr p);
+ delegate void pf_void_IntPtr(JNIEnv* pEnv, IntPtr p);
+ delegate IntPtr pf_IntPtr(JNIEnv* pEnv);
+ delegate void pf_void(JNIEnv* pEnv);
+ delegate sbyte pf_sbyte(JNIEnv* pEnv);
+ delegate IntPtr pf_IntPtr_pbyte(JNIEnv* pEnv, byte* p);
+ delegate int pf_int(JNIEnv* pEnv);
+ delegate IntPtr pf_IntPtr_pbyte_IntPtr_pbyte_IntPtr(JNIEnv* pEnv, byte* p1, IntPtr p2, byte* p3, int p4);
+ delegate IntPtr pf_IntPtr_IntPtr_IntPtr(JNIEnv* pEnv, IntPtr p1, IntPtr p2);
+ delegate int pf_int_IntPtr_pbyte(JNIEnv* pEnv, IntPtr p1, byte* p2);
+ delegate void pf_void_pbyte(JNIEnv* pEnv, byte* p1);
+ delegate IntPtr pf_IntPtr_IntPtr_pbyte_pbyte(JNIEnv* pEnv, IntPtr p1, byte* p2, byte* p3);
+ delegate int pf_int_IntPtr_pJNINativeMethod_int(JNIEnv* pEnv, IntPtr p1, JNIEnv.JNINativeMethod* p2, int p3);
+ delegate int pf_int_ppJavaVM(JNIEnv* pEnv, JavaVM** ppJavaVM);
+ delegate sbyte pf_sbyte_IntPtr_IntPtr(JNIEnv* pEnv, IntPtr p1, IntPtr p2);
+ delegate short pf_short_IntPtr_IntPtr(JNIEnv* pEnv, IntPtr p1, IntPtr p2);
+ delegate int pf_int_IntPtr_IntPtr(JNIEnv* pEnv, IntPtr p1, IntPtr p2);
+ delegate long pf_long_IntPtr_IntPtr(JNIEnv* pEnv, IntPtr p1, IntPtr p2);
+ delegate float pf_float_IntPtr_IntPtr(JNIEnv* pEnv, IntPtr p1, IntPtr p2);
+ delegate double pf_double_IntPtr_IntPtr(JNIEnv* pEnv, IntPtr p1, IntPtr p2);
+ delegate void pf_void_IntPtr_IntPtr_IntPtr(JNIEnv* pEnv, IntPtr p1, IntPtr p2, IntPtr p3);
+ delegate void pf_void_IntPtr_IntPtr_sbyte(JNIEnv* pEnv, IntPtr p1, IntPtr p2, sbyte p3);
+ delegate void pf_void_IntPtr_IntPtr_short(JNIEnv* pEnv, IntPtr p1, IntPtr p2, short p3);
+ delegate void pf_void_IntPtr_IntPtr_int(JNIEnv* pEnv, IntPtr p1, IntPtr p2, int p3);
+ delegate void pf_void_IntPtr_IntPtr_long(JNIEnv* pEnv, IntPtr p1, IntPtr p2, long p3);
+ delegate void pf_void_IntPtr_IntPtr_float(JNIEnv* pEnv, IntPtr p1, IntPtr p2, float p3);
+ delegate void pf_void_IntPtr_IntPtr_double(JNIEnv* pEnv, IntPtr p1, IntPtr p2, double p3);
+ delegate IntPtr pf_IntPtr_pchar_int(JNIEnv* pEnv, char* p1, int p2);
+ delegate void pf_void_IntPtr_IntPtr(JNIEnv* pEnv, IntPtr p1, IntPtr p2);
+ delegate IntPtr pf_IntPtr_int_IntPtr_IntPtr(JNIEnv* pEnv, int p1, IntPtr p2, IntPtr p3);
+ delegate IntPtr pf_IntPtr_IntPtr_int(JNIEnv* pEnv, IntPtr p1, int p2);
+ delegate void pf_void_IntPtr_int_IntPtr(JNIEnv* pEnv, IntPtr p1, int p2, IntPtr p3);
+ delegate IntPtr pf_IntPtr_int(JNIEnv* pEnv, int p1);
+ delegate void pf_void_IntPtr_int_int_IntPtr(JNIEnv* pEnv, IntPtr p1, int p2, int p3, IntPtr p4);
+ delegate IntPtr pf_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv* pEnv, IntPtr p1, IntPtr p2, JNIEnv.jvalue* p3);
+ delegate sbyte pf_sbyte_IntPtr_IntPtr_pjvalue(JNIEnv* pEnv, IntPtr p1, IntPtr p2, JNIEnv.jvalue* p3);
+ delegate short pf_short_IntPtr_IntPtr_pjvalue(JNIEnv* pEnv, IntPtr p1, IntPtr p2, JNIEnv.jvalue* p3);
+ delegate int pf_int_IntPtr_IntPtr_pjvalue(JNIEnv* pEnv, IntPtr p1, IntPtr p2, JNIEnv.jvalue* p3);
+ delegate long pf_long_IntPtr_IntPtr_pjvalue(JNIEnv* pEnv, IntPtr p1, IntPtr p2, JNIEnv.jvalue* p3);
+ delegate float pf_float_IntPtr_IntPtr_pjvalue(JNIEnv* pEnv, IntPtr p1, IntPtr p2, JNIEnv.jvalue* p3);
+ delegate double pf_double_IntPtr_IntPtr_pjvalue(JNIEnv* pEnv, IntPtr p1, IntPtr p2, JNIEnv.jvalue* p3);
+ delegate void pf_void_IntPtr_IntPtr_pjvalue(JNIEnv* pEnv, IntPtr p1, IntPtr p2, JNIEnv.jvalue* p3);
+ delegate IntPtr pf_IntPtr_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv* pEnv, IntPtr p1, IntPtr p2, IntPtr p3, JNIEnv.jvalue* p4);
+ delegate sbyte pf_sbyte_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv* pEnv, IntPtr p1, IntPtr p2, IntPtr p3, JNIEnv.jvalue* p4);
+ delegate short pf_short_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv* pEnv, IntPtr p1, IntPtr p2, IntPtr p3, JNIEnv.jvalue* p4);
+ delegate int pf_int_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv* pEnv, IntPtr p1, IntPtr p2, IntPtr p3, JNIEnv.jvalue* p4);
+ delegate long pf_long_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv* pEnv, IntPtr p1, IntPtr p2, IntPtr p3, JNIEnv.jvalue* p4);
+ delegate float pf_float_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv* pEnv, IntPtr p1, IntPtr p2, IntPtr p3, JNIEnv.jvalue* p4);
+ delegate double pf_double_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv* pEnv, IntPtr p1, IntPtr p2, IntPtr p3, JNIEnv.jvalue* p4);
+ delegate void pf_void_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv* pEnv, IntPtr p1, IntPtr p2, IntPtr p3, JNIEnv.jvalue* p4);
+
+ internal static void* vtable;
+
+ static VtableBuilder()
+ {
+ // JNIEnv
+ void** pmcpp = JniHelper.ikvm_GetJNIEnvVTable();
+ void** p = (void**)Marshal.AllocHGlobal(IntPtr.Size * vtableDelegates.Length);
+ for(int i = 0; i < vtableDelegates.Length; i++)
+ {
+ if(vtableDelegates[i] != null)
+ {
+ p[i] = JniHelper.ikvm_MarshalDelegate(vtableDelegates[i]);
+ }
+ else
+ {
+ p[i] = pmcpp[i];
+ }
+ }
+ vtable = p;
+ }
+
+ static Delegate[] vtableDelegates =
+ {
+ new pf_int_IntPtr_pbyte(JNIEnv.GetMethodArgs), //virtual void JNICALL reserved0();
+ null, //virtual void JNICALL reserved1();
+ null, //virtual void JNICALL reserved2();
+ null, //virtual void JNICALL reserved3();
+
+ new pf_int(JNIEnv.GetVersion), //virtual jint JNICALL GetVersion();
+
+ new pf_IntPtr_pbyte_IntPtr_pbyte_IntPtr(JNIEnv.DefineClass), //virtual jclass JNICALL DefineClass(const char *name, jobject loader, const jbyte *buf, jsize len);
+ new pf_IntPtr_pbyte(JNIEnv.FindClass), //virtual jclass JNICALL FindClass(const char *name);
+
+ new pf_IntPtr_IntPtr(JNIEnv.FromReflectedMethod), //virtual jmethodID JNICALL FromReflectedMethod(jobject method);
+ new pf_IntPtr_IntPtr(JNIEnv.FromReflectedField), //virtual jfieldID JNICALL FromReflectedField(jobject field);
+ new pf_IntPtr_IntPtr_IntPtr(JNIEnv.ToReflectedMethod), //virtual jobject JNICALL ToReflectedMethod(jclass clazz, jmethodID methodID);
+
+ new pf_IntPtr_IntPtr(JNIEnv.GetSuperclass), //virtual jclass JNICALL GetSuperclass(jclass sub);
+ new pf_sbyte_IntPtr_IntPtr(JNIEnv.IsAssignableFrom), //virtual jboolean JNICALL IsAssignableFrom(jclass sub, jclass sup);
+
+ new pf_IntPtr_IntPtr_IntPtr(JNIEnv.ToReflectedField), //virtual jobject JNICALL ToReflectedField(jclass clazz, jfieldID fieldID);
+
+ new pf_int_IntPtr(JNIEnv.Throw), //virtual jint JNICALL Throw(jthrowable obj);
+ new pf_int_IntPtr_pbyte(JNIEnv.ThrowNew), //virtual jint JNICALL ThrowNew(jclass clazz, const char *msg);
+ new pf_IntPtr(JNIEnv.ExceptionOccurred), //virtual jthrowable JNICALL ExceptionOccurred();
+ new pf_void(JNIEnv.ExceptionDescribe), //virtual void JNICALL ExceptionDescribe();
+ new pf_void(JNIEnv.ExceptionClear), //virtual void JNICALL ExceptionClear();
+ new pf_void_pbyte(JNIEnv.FatalError), //virtual void JNICALL FatalError(const char *msg);
+
+ new pf_void(JNIEnv.NotImplemented), //virtual jint JNICALL PushLocalFrame(jint capacity);
+ new pf_void(JNIEnv.NotImplemented), //virtual jobject JNICALL PopLocalFrame(jobject result);
+
+ new pf_IntPtr_IntPtr(JNIEnv.NewGlobalRef), //virtual jobject JNICALL NewGlobalRef(jobject lobj);
+ new pf_void_IntPtr(JNIEnv.DeleteGlobalRef), //virtual void JNICALL DeleteGlobalRef(jobject gref);
+ new pf_void_IntPtr(JNIEnv.DeleteLocalRef), //virtual void JNICALL DeleteLocalRef(jobject obj);
+ new pf_sbyte_IntPtr_IntPtr(JNIEnv.IsSameObject), //virtual jboolean JNICALL IsSameObject(jobject obj1, jobject obj2);
+
+ new pf_IntPtr_IntPtr(JNIEnv.NewLocalRef), //virtual jobject JNICALL NewLocalRef(jobject ref);
+ new pf_void(JNIEnv.NotImplemented), //virtual jint JNICALL EnsureLocalCapacity(jint capacity);
+
+ new pf_IntPtr_IntPtr(JNIEnv.AllocObject), //virtual jobject JNICALL AllocObject(jclass clazz);
+ null, //virtual jobject JNICALL NewObject(jclass clazz, jmethodID methodID, ...);
+ null, //virtual jobject JNICALL NewObjectV(jclass clazz, jmethodID methodID, va_list args);
+ new pf_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv.NewObjectA), //virtual jobject JNICALL NewObjectA(jclass clazz, jmethodID methodID, jvalue *args);
+
+ new pf_IntPtr_IntPtr(JNIEnv.GetObjectClass), //virtual jclass JNICALL GetObjectClass(jobject obj);
+ new pf_sbyte_IntPtr_IntPtr(JNIEnv.IsInstanceOf), //virtual jboolean JNICALL IsInstanceOf(jobject obj, jclass clazz);
+
+ new pf_IntPtr_IntPtr_pbyte_pbyte(JNIEnv.GetMethodID), //virtual jmethodID JNICALL GetMethodID(jclass clazz, const char *name, const char *sig);
+
+ null, //virtual jobject JNICALL CallObjectMethod(jobject obj, jmethodID methodID, ...);
+ null, //virtual jobject JNICALL CallObjectMethodV(jobject obj, jmethodID methodID, va_list args);
+ new pf_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv.CallObjectMethodA), //virtual jobject JNICALL CallObjectMethodA(jobject obj, jmethodID methodID, jvalue * args);
+
+ null, //virtual jboolean JNICALL CallBooleanMethod(jobject obj, jmethodID methodID, ...);
+ null, //virtual jboolean JNICALL CallBooleanMethodV(jobject obj, jmethodID methodID, va_list args);
+ new pf_sbyte_IntPtr_IntPtr_pjvalue(JNIEnv.CallBooleanMethodA), //virtual jboolean JNICALL CallBooleanMethodA(jobject obj, jmethodID methodID, jvalue * args);
+
+ null, //virtual jbyte JNICALL CallByteMethod(jobject obj, jmethodID methodID, ...);
+ null, //virtual jbyte JNICALL CallByteMethodV(jobject obj, jmethodID methodID, va_list args);
+ new pf_sbyte_IntPtr_IntPtr_pjvalue(JNIEnv.CallByteMethodA), //virtual jbyte JNICALL CallByteMethodA(jobject obj, jmethodID methodID, jvalue *args);
+
+ null, //virtual jchar JNICALL CallCharMethod(jobject obj, jmethodID methodID, ...);
+ null, //virtual jchar JNICALL CallCharMethodV(jobject obj, jmethodID methodID, va_list args);
+ new pf_short_IntPtr_IntPtr_pjvalue(JNIEnv.CallCharMethodA), //virtual jchar JNICALL CallCharMethodA(jobject obj, jmethodID methodID, jvalue *args);
+
+ null, //virtual jshort JNICALL CallShortMethod(jobject obj, jmethodID methodID, ...);
+ null, //virtual jshort JNICALL CallShortMethodV(jobject obj, jmethodID methodID, va_list args);
+ new pf_short_IntPtr_IntPtr_pjvalue(JNIEnv.CallShortMethodA), //virtual jshort JNICALL CallShortMethodA(jobject obj, jmethodID methodID, jvalue *args);
+
+ null, //virtual jint JNICALL CallIntMethod(jobject obj, jmethodID methodID, ...);
+ null, //virtual jint JNICALL CallIntMethodV(jobject obj, jmethodID methodID, va_list args);
+ new pf_int_IntPtr_IntPtr_pjvalue(JNIEnv.CallIntMethodA), //virtual jint JNICALL CallIntMethodA(jobject obj, jmethodID methodID, jvalue *args);
+
+ null, //virtual jlong JNICALL CallLongMethod(jobject obj, jmethodID methodID, ...);
+ null, //virtual jlong JNICALL CallLongMethodV(jobject obj, jmethodID methodID, va_list args);
+ new pf_long_IntPtr_IntPtr_pjvalue(JNIEnv.CallLongMethodA), //virtual jlong JNICALL CallLongMethodA(jobject obj, jmethodID methodID, jvalue *args);
+
+ null, //virtual jfloat JNICALL CallFloatMethod(jobject obj, jmethodID methodID, ...);
+ null, //virtual jfloat JNICALL CallFloatMethodV(jobject obj, jmethodID methodID, va_list args);
+ new pf_float_IntPtr_IntPtr_pjvalue(JNIEnv.CallFloatMethodA), //virtual jfloat JNICALL CallFloatMethodA(jobject obj, jmethodID methodID, jvalue *args);
+
+ null, //virtual jdouble JNICALL CallDoubleMethod(jobject obj, jmethodID methodID, ...);
+ null, //virtual jdouble JNICALL CallDoubleMethodV(jobject obj, jmethodID methodID, va_list args);
+ new pf_double_IntPtr_IntPtr_pjvalue(JNIEnv.CallDoubleMethodA), //virtual jdouble JNICALL CallDoubleMethodA(jobject obj, jmethodID methodID, jvalue *args);
+
+ null, //virtual void JNICALL CallVoidMethod(jobject obj, jmethodID methodID, ...);
+ null, //virtual void JNICALL CallVoidMethodV(jobject obj, jmethodID methodID, va_list args);
+ new pf_void_IntPtr_IntPtr_pjvalue(JNIEnv.CallVoidMethodA), //virtual void JNICALL CallVoidMethodA(jobject obj, jmethodID methodID, jvalue * args);
+
+ null, //virtual jobject JNICALL CallNonvirtualObjectMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
+ null, //virtual jobject JNICALL CallNonvirtualObjectMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ new pf_IntPtr_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv.CallNonvirtualObjectMethodA), //virtual jobject JNICALL CallNonvirtualObjectMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue * args);
+
+ null, //virtual jboolean JNICALL CallNonvirtualBooleanMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
+ null, //virtual jboolean JNICALL CallNonvirtualBooleanMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ new pf_sbyte_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv.CallNonvirtualBooleanMethodA), //virtual jboolean JNICALL CallNonvirtualBooleanMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue * args);
+
+ null, //virtual jbyte JNICALL CallNonvirtualByteMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
+ null, //virtual jbyte JNICALL CallNonvirtualByteMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ new pf_sbyte_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv.CallNonvirtualByteMethodA), //virtual jbyte JNICALL CallNonvirtualByteMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
+
+ null, //virtual jchar JNICALL CallNonvirtualCharMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
+ null, //virtual jchar JNICALL CallNonvirtualCharMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ new pf_short_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv.CallNonvirtualCharMethodA), //virtual jchar JNICALL CallNonvirtualCharMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
+
+ null, //virtual jshort JNICALL CallNonvirtualShortMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
+ null, //virtual jshort JNICALL CallNonvirtualShortMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ new pf_short_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv.CallNonvirtualShortMethodA), //virtual jshort JNICALL CallNonvirtualShortMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
+
+ null, //virtual jint JNICALL CallNonvirtualIntMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
+ null, //virtual jint JNICALL CallNonvirtualIntMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ new pf_int_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv.CallNonvirtualIntMethodA), //virtual jint JNICALL CallNonvirtualIntMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
+
+ null, //virtual jlong JNICALL CallNonvirtualLongMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
+ null, //virtual jlong JNICALL CallNonvirtualLongMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ new pf_long_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv.CallNonvirtualLongMethodA), //virtual jlong JNICALL CallNonvirtualLongMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
+
+ null, //virtual jfloat JNICALL CallNonvirtualFloatMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
+ null, //virtual jfloat JNICALL CallNonvirtualFloatMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ new pf_float_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv.CallNonvirtualFloatMethodA), //virtual jfloat JNICALL CallNonvirtualFloatMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
+
+ null, //virtual jdouble JNICALL CallNonvirtualDoubleMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
+ null, //virtual jdouble JNICALL CallNonvirtualDoubleMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ new pf_double_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv.CallNonvirtualDoubleMethodA), //virtual jdouble JNICALL CallNonvirtualDoubleMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
+
+ null, //virtual void JNICALL CallNonvirtualVoidMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
+ null, //virtual void JNICALL CallNonvirtualVoidMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
+ new pf_void_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv.CallNonvirtualVoidMethodA), //virtual void JNICALL CallNonvirtualVoidMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue * args);
+
+ new pf_IntPtr_IntPtr_pbyte_pbyte(JNIEnv.GetFieldID), //virtual jfieldID JNICALL GetFieldID(jclass clazz, const char *name, const char *sig);
+
+ new pf_IntPtr_IntPtr_IntPtr(JNIEnv.GetObjectField), //virtual jobject JNICALL GetObjectField(jobject obj, jfieldID fieldID);
+ new pf_sbyte_IntPtr_IntPtr(JNIEnv.GetBooleanField), //virtual jboolean JNICALL GetBooleanField(jobject obj, jfieldID fieldID);
+ new pf_sbyte_IntPtr_IntPtr(JNIEnv.GetByteField), //virtual jbyte JNICALL GetByteField(jobject obj, jfieldID fieldID);
+ new pf_short_IntPtr_IntPtr(JNIEnv.GetCharField), //virtual jchar JNICALL GetCharField(jobject obj, jfieldID fieldID);
+ new pf_short_IntPtr_IntPtr(JNIEnv.GetShortField), //virtual jshort JNICALL GetShortField(jobject obj, jfieldID fieldID);
+ new pf_int_IntPtr_IntPtr(JNIEnv.GetIntField), //virtual jint JNICALL GetIntField(jobject obj, jfieldID fieldID);
+ new pf_long_IntPtr_IntPtr(JNIEnv.GetLongField), //virtual jlong JNICALL GetLongField(jobject obj, jfieldID fieldID);
+ new pf_float_IntPtr_IntPtr(JNIEnv.GetFloatField), //virtual jfloat JNICALL GetFloatField(jobject obj, jfieldID fieldID);
+ new pf_double_IntPtr_IntPtr(JNIEnv.GetDoubleField), //virtual jdouble JNICALL GetDoubleField(jobject obj, jfieldID fieldID);
+
+ new pf_void_IntPtr_IntPtr_IntPtr(JNIEnv.SetObjectField), //virtual void JNICALL SetObjectField(jobject obj, jfieldID fieldID, jobject val);
+ new pf_void_IntPtr_IntPtr_sbyte(JNIEnv.SetBooleanField), //virtual void JNICALL SetBooleanField(jobject obj, jfieldID fieldID, jboolean val);
+ new pf_void_IntPtr_IntPtr_sbyte(JNIEnv.SetByteField), //virtual void JNICALL SetByteField(jobject obj, jfieldID fieldID, jbyte val);
+ new pf_void_IntPtr_IntPtr_short(JNIEnv.SetCharField), //virtual void JNICALL SetCharField(jobject obj, jfieldID fieldID, jchar val);
+ new pf_void_IntPtr_IntPtr_short(JNIEnv.SetShortField), //virtual void JNICALL SetShortField(jobject obj, jfieldID fieldID, jshort val);
+ new pf_void_IntPtr_IntPtr_int(JNIEnv.SetIntField), //virtual void JNICALL SetIntField(jobject obj, jfieldID fieldID, jint val);
+ new pf_void_IntPtr_IntPtr_long(JNIEnv.SetLongField), //virtual void JNICALL SetLongField(jobject obj, jfieldID fieldID, jlong val);
+ new pf_void_IntPtr_IntPtr_float(JNIEnv.SetFloatField), //virtual void JNICALL SetFloatField(jobject obj, jfieldID fieldID, jfloat val);
+ new pf_void_IntPtr_IntPtr_double(JNIEnv.SetDoubleField), //virtual void JNICALL SetDoubleField(jobject obj, jfieldID fieldID, jdouble val);
+
+ new pf_IntPtr_IntPtr_pbyte_pbyte(JNIEnv.GetStaticMethodID), //virtual jmethodID JNICALL GetStaticMethodID(jclass clazz, const char *name, const char *sig);
+
+ null, //virtual jobject JNICALL CallStaticObjectMethod(jclass clazz, jmethodID methodID, ...);
+ null, //virtual jobject JNICALL CallStaticObjectMethodV(jclass clazz, jmethodID methodID, va_list args);
+ new pf_IntPtr_IntPtr_IntPtr_pjvalue(JNIEnv.CallStaticObjectMethodA), //virtual jobject JNICALL CallStaticObjectMethodA(jclass clazz, jmethodID methodID, jvalue *args);
+
+ null, //virtual jboolean JNICALL CallStaticBooleanMethod(jclass clazz, jmethodID methodID, ...);
+ null, //virtual jboolean JNICALL CallStaticBooleanMethodV(jclass clazz, jmethodID methodID, va_list args);
+ new pf_sbyte_IntPtr_IntPtr_pjvalue(JNIEnv.CallStaticBooleanMethodA), //virtual jboolean JNICALL CallStaticBooleanMethodA(jclass clazz, jmethodID methodID, jvalue *args);
+
+ null, //virtual jbyte JNICALL CallStaticByteMethod(jclass clazz, jmethodID methodID, ...);
+ null, //virtual jbyte JNICALL CallStaticByteMethodV(jclass clazz, jmethodID methodID, va_list args);
+ new pf_sbyte_IntPtr_IntPtr_pjvalue(JNIEnv.CallStaticByteMethodA), //virtual jbyte JNICALL CallStaticByteMethodA(jclass clazz, jmethodID methodID, jvalue *args);
+
+ null, //virtual jchar JNICALL CallStaticCharMethod(jclass clazz, jmethodID methodID, ...);
+ null, //virtual jchar JNICALL CallStaticCharMethodV(jclass clazz, jmethodID methodID, va_list args);
+ new pf_short_IntPtr_IntPtr_pjvalue(JNIEnv.CallStaticCharMethodA), //virtual jchar JNICALL CallStaticCharMethodA(jclass clazz, jmethodID methodID, jvalue *args);
+
+ null, //virtual jshort JNICALL CallStaticShortMethod(jclass clazz, jmethodID methodID, ...);
+ null, //virtual jshort JNICALL CallStaticShortMethodV(jclass clazz, jmethodID methodID, va_list args);
+ new pf_short_IntPtr_IntPtr_pjvalue(JNIEnv.CallStaticShortMethodA), //virtual jshort JNICALL CallStaticShortMethodA(jclass clazz, jmethodID methodID, jvalue *args);
+
+ null, //virtual jint JNICALL CallStaticIntMethod(jclass clazz, jmethodID methodID, ...);
+ null, //virtual jint JNICALL CallStaticIntMethodV(jclass clazz, jmethodID methodID, va_list args);
+ new pf_int_IntPtr_IntPtr_pjvalue(JNIEnv.CallStaticIntMethodA), //virtual jint JNICALL CallStaticIntMethodA(jclass clazz, jmethodID methodID, jvalue *args);
+
+ null, //virtual jlong JNICALL CallStaticLongMethod(jclass clazz, jmethodID methodID, ...);
+ null, //virtual jlong JNICALL CallStaticLongMethodV(jclass clazz, jmethodID methodID, va_list args);
+ new pf_long_IntPtr_IntPtr_pjvalue(JNIEnv.CallStaticLongMethodA), //virtual jlong JNICALL CallStaticLongMethodA(jclass clazz, jmethodID methodID, jvalue *args);
+
+ null, //virtual jfloat JNICALL CallStaticFloatMethod(jclass clazz, jmethodID methodID, ...);
+ null, //virtual jfloat JNICALL CallStaticFloatMethodV(jclass clazz, jmethodID methodID, va_list args);
+ new pf_float_IntPtr_IntPtr_pjvalue(JNIEnv.CallStaticFloatMethodA), //virtual jfloat JNICALL CallStaticFloatMethodA(jclass clazz, jmethodID methodID, jvalue *args);
+
+ null, //virtual jdouble JNICALL CallStaticDoubleMethod(jclass clazz, jmethodID methodID, ...);
+ null, //virtual jdouble JNICALL CallStaticDoubleMethodV(jclass clazz, jmethodID methodID, va_list args);
+ new pf_double_IntPtr_IntPtr_pjvalue(JNIEnv.CallStaticDoubleMethodA), //virtual jdouble JNICALL CallStaticDoubleMethodA(jclass clazz, jmethodID methodID, jvalue *args);
+
+ null, //virtual void JNICALL CallStaticVoidMethod(jclass cls, jmethodID methodID, ...);
+ null, //virtual void JNICALL CallStaticVoidMethodV(jclass cls, jmethodID methodID, va_list args);
+ new pf_void_IntPtr_IntPtr_pjvalue(JNIEnv.CallStaticVoidMethodA), //virtual void JNICALL CallStaticVoidMethodA(jclass cls, jmethodID methodID, jvalue * args);
+
+ new pf_IntPtr_IntPtr_pbyte_pbyte(JNIEnv.GetStaticFieldID), //virtual jfieldID JNICALL GetStaticFieldID(jclass clazz, const char *name, const char *sig);
+
+ new pf_IntPtr_IntPtr_IntPtr(JNIEnv.GetStaticObjectField), //virtual jobject JNICALL GetObjectField(jobject obj, jfieldID fieldID);
+ new pf_sbyte_IntPtr_IntPtr(JNIEnv.GetStaticBooleanField), //virtual jboolean JNICALL GetBooleanField(jobject obj, jfieldID fieldID);
+ new pf_sbyte_IntPtr_IntPtr(JNIEnv.GetStaticByteField), //virtual jbyte JNICALL GetByteField(jobject obj, jfieldID fieldID);
+ new pf_short_IntPtr_IntPtr(JNIEnv.GetStaticCharField), //virtual jchar JNICALL GetCharField(jobject obj, jfieldID fieldID);
+ new pf_short_IntPtr_IntPtr(JNIEnv.GetStaticShortField), //virtual jshort JNICALL GetShortField(jobject obj, jfieldID fieldID);
+ new pf_int_IntPtr_IntPtr(JNIEnv.GetStaticIntField), //virtual jint JNICALL GetIntField(jobject obj, jfieldID fieldID);
+ new pf_long_IntPtr_IntPtr(JNIEnv.GetStaticLongField), //virtual jlong JNICALL GetLongField(jobject obj, jfieldID fieldID);
+ new pf_float_IntPtr_IntPtr(JNIEnv.GetStaticFloatField), //virtual jfloat JNICALL GetFloatField(jobject obj, jfieldID fieldID);
+ new pf_double_IntPtr_IntPtr(JNIEnv.GetStaticDoubleField), //virtual jdouble JNICALL GetDoubleField(jobject obj, jfieldID fieldID);
+
+ new pf_void_IntPtr_IntPtr_IntPtr(JNIEnv.SetStaticObjectField), //virtual void JNICALL SetObjectField(jobject obj, jfieldID fieldID, jobject val);
+ new pf_void_IntPtr_IntPtr_sbyte(JNIEnv.SetStaticBooleanField), //virtual void JNICALL SetBooleanField(jobject obj, jfieldID fieldID, jboolean val);
+ new pf_void_IntPtr_IntPtr_sbyte(JNIEnv.SetStaticByteField), //virtual void JNICALL SetByteField(jobject obj, jfieldID fieldID, jbyte val);
+ new pf_void_IntPtr_IntPtr_short(JNIEnv.SetStaticCharField), //virtual void JNICALL SetCharField(jobject obj, jfieldID fieldID, jchar val);
+ new pf_void_IntPtr_IntPtr_short(JNIEnv.SetStaticShortField), //virtual void JNICALL SetShortField(jobject obj, jfieldID fieldID, jshort val);
+ new pf_void_IntPtr_IntPtr_int(JNIEnv.SetStaticIntField), //virtual void JNICALL SetIntField(jobject obj, jfieldID fieldID, jint val);
+ new pf_void_IntPtr_IntPtr_long(JNIEnv.SetStaticLongField), //virtual void JNICALL SetLongField(jobject obj, jfieldID fieldID, jlong val);
+ new pf_void_IntPtr_IntPtr_float(JNIEnv.SetStaticFloatField), //virtual void JNICALL SetFloatField(jobject obj, jfieldID fieldID, jfloat val);
+ new pf_void_IntPtr_IntPtr_double(JNIEnv.SetStaticDoubleField), //virtual void JNICALL SetDoubleField(jobject obj, jfieldID fieldID, jdouble val);
+
+ new pf_IntPtr_pchar_int(JNIEnv.NewString), //virtual jstring JNICALL NewString(const jchar *unicode, jsize len);
+ new pf_int_IntPtr(JNIEnv.GetStringLength), //virtual jsize JNICALL GetStringLength(jstring str);
+ new pf_IntPtr_IntPtr_IntPtr(JNIEnv.GetStringChars), //virtual const jchar *JNICALL GetStringChars(jstring str, jboolean *isCopy);
+ new pf_void_IntPtr_IntPtr(JNIEnv.ReleaseStringChars), //virtual void JNICALL ReleaseStringChars(jstring str, const jchar *chars);
+
+ new pf_IntPtr_IntPtr(JNIEnv.NewStringUTF), //virtual jstring JNICALL NewStringUTF(const char *utf);
+ new pf_int_IntPtr(JNIEnv.GetStringUTFLength), //virtual jsize JNICALL GetStringUTFLength(jstring str);
+ new pf_IntPtr_IntPtr_IntPtr(JNIEnv.GetStringUTFChars), //virtual const char* JNICALL GetStringUTFChars(jstring str, jboolean *isCopy);
+ new pf_void_IntPtr_IntPtr(JNIEnv.ReleaseStringUTFChars), //virtual void JNICALL ReleaseStringUTFChars(jstring str, const char* chars);
+
+ new pf_int_IntPtr(JNIEnv.GetArrayLength), //virtual jsize JNICALL GetArrayLength(jarray array);
+
+ new pf_IntPtr_int_IntPtr_IntPtr(JNIEnv.NewObjectArray), //virtual jobjectArray JNICALL NewObjectArray(jsize len, jclass clazz, jobject init);
+ new pf_IntPtr_IntPtr_int(JNIEnv.GetObjectArrayElement), //virtual jobject JNICALL GetObjectArrayElement(jobjectArray array, jsize index);
+ new pf_void_IntPtr_int_IntPtr(JNIEnv.SetObjectArrayElement), //virtual void JNICALL SetObjectArrayElement(jobjectArray array, jsize index, jobject val);
+
+ new pf_IntPtr_int(JNIEnv.NewBooleanArray), //virtual jbooleanArray JNICALL NewBooleanArray(jsize len);
+ new pf_IntPtr_int(JNIEnv.NewByteArray), //virtual jbyteArray JNICALL NewByteArray(jsize len);
+ new pf_IntPtr_int(JNIEnv.NewCharArray), //virtual jcharArray JNICALL NewCharArray(jsize len);
+ new pf_IntPtr_int(JNIEnv.NewShortArray), //virtual jshortArray JNICALL NewShortArray(jsize len);
+ new pf_IntPtr_int(JNIEnv.NewIntArray), //virtual jintArray JNICALL NewIntArray(jsize len);
+ new pf_IntPtr_int(JNIEnv.NewLongArray), //virtual jlongArray JNICALL NewLongArray(jsize len);
+ new pf_IntPtr_int(JNIEnv.NewFloatArray), //virtual jfloatArray JNICALL NewFloatArray(jsize len);
+ new pf_IntPtr_int(JNIEnv.NewDoubleArray), //virtual jdoubleArray JNICALL NewDoubleArray(jsize len);
+
+ new pf_IntPtr_IntPtr_IntPtr(JNIEnv.GetBooleanArrayElements), //virtual jboolean * JNICALL GetBooleanArrayElements(jbooleanArray array, jboolean *isCopy);
+ new pf_IntPtr_IntPtr_IntPtr(JNIEnv.GetByteArrayElements), //virtual jbyte * JNICALL GetByteArrayElements(jbyteArray array, jboolean *isCopy);
+ new pf_IntPtr_IntPtr_IntPtr(JNIEnv.GetCharArrayElements), //virtual jchar * JNICALL GetCharArrayElements(jcharArray array, jboolean *isCopy);
+ new pf_IntPtr_IntPtr_IntPtr(JNIEnv.GetShortArrayElements), //virtual jshort * JNICALL GetShortArrayElements(jshortArray array, jboolean *isCopy);
+ new pf_IntPtr_IntPtr_IntPtr(JNIEnv.GetIntArrayElements), //virtual jint * JNICALL GetIntArrayElements(jintArray array, jboolean *isCopy);
+ new pf_IntPtr_IntPtr_IntPtr(JNIEnv.GetLongArrayElements), //virtual jlong * JNICALL GetLongArrayElements(jlongArray array, jboolean *isCopy);
+ new pf_IntPtr_IntPtr_IntPtr(JNIEnv.GetFloatArrayElements), //virtual jfloat * JNICALL GetFloatArrayElements(jfloatArray array, jboolean *isCopy);
+ new pf_IntPtr_IntPtr_IntPtr(JNIEnv.GetDoubleArrayElements), //virtual jdouble * JNICALL GetDoubleArrayElements(jdoubleArray array, jboolean *isCopy);
+
+ new pf_void_IntPtr_IntPtr_int(JNIEnv.ReleaseBooleanArrayElements), //virtual void JNICALL ReleaseBooleanArrayElements(jbooleanArray array, jboolean *elems, jint mode);
+ new pf_void_IntPtr_IntPtr_int(JNIEnv.ReleaseByteArrayElements), //virtual void JNICALL ReleaseByteArrayElements(jbyteArray array, jbyte *elems, jint mode);
+ new pf_void_IntPtr_IntPtr_int(JNIEnv.ReleaseCharArrayElements), //virtual void JNICALL ReleaseCharArrayElements(jcharArray array, jchar *elems, jint mode);
+ new pf_void_IntPtr_IntPtr_int(JNIEnv.ReleaseShortArrayElements), //virtual void JNICALL ReleaseShortArrayElements(jshortArray array, jshort *elems, jint mode);
+ new pf_void_IntPtr_IntPtr_int(JNIEnv.ReleaseIntArrayElements), //virtual void JNICALL ReleaseIntArrayElements(jintArray array, jint *elems, jint mode);
+ new pf_void_IntPtr_IntPtr_int(JNIEnv.ReleaseLongArrayElements), //virtual void JNICALL ReleaseLongArrayElements(jlongArray array, jlong *elems, jint mode);
+ new pf_void_IntPtr_IntPtr_int(JNIEnv.ReleaseFloatArrayElements), //virtual void JNICALL ReleaseFloatArrayElements(jfloatArray array, jfloat *elems, jint mode);
+ new pf_void_IntPtr_IntPtr_int(JNIEnv.ReleaseDoubleArrayElements), //virtual void JNICALL ReleaseDoubleArrayElements(jdoubleArray array, jdouble *elems, jint mode);
+
+ new pf_void_IntPtr_int_int_IntPtr(JNIEnv.GetBooleanArrayRegion), //virtual void JNICALL GetBooleanArrayRegion(jbooleanArray array, jsize start, jsize l, jboolean *buf);
+ new pf_void_IntPtr_int_int_IntPtr(JNIEnv.GetByteArrayRegion), //virtual void JNICALL GetByteArrayRegion(jbyteArray array, jsize start, jsize len, jbyte *buf);
+ new pf_void_IntPtr_int_int_IntPtr(JNIEnv.GetCharArrayRegion), //virtual void JNICALL GetCharArrayRegion(jcharArray array, jsize start, jsize len, jchar *buf);
+ new pf_void_IntPtr_int_int_IntPtr(JNIEnv.GetShortArrayRegion), //virtual void JNICALL GetShortArrayRegion(jshortArray array, jsize start, jsize len, jshort *buf);
+ new pf_void_IntPtr_int_int_IntPtr(JNIEnv.GetIntArrayRegion), //virtual void JNICALL GetIntArrayRegion(jintArray array, jsize start, jsize len, jint *buf);
+ new pf_void_IntPtr_int_int_IntPtr(JNIEnv.GetLongArrayRegion), //virtual void JNICALL GetLongArrayRegion(jlongArray array, jsize start, jsize len, jlong *buf);
+ new pf_void_IntPtr_int_int_IntPtr(JNIEnv.GetFloatArrayRegion), //virtual void JNICALL GetFloatArrayRegion(jfloatArray array, jsize start, jsize len, jfloat *buf);
+ new pf_void_IntPtr_int_int_IntPtr(JNIEnv.GetDoubleArrayRegion), //virtual void JNICALL GetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, jdouble *buf);
+
+ new pf_void_IntPtr_int_int_IntPtr(JNIEnv.SetBooleanArrayRegion), //virtual void JNICALL SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize l, jboolean *buf);
+ new pf_void_IntPtr_int_int_IntPtr(JNIEnv.SetByteArrayRegion), //virtual void JNICALL SetByteArrayRegion(jbyteArray array, jsize start, jsize len, jbyte *buf);
+ new pf_void_IntPtr_int_int_IntPtr(JNIEnv.SetCharArrayRegion), //virtual void JNICALL SetCharArrayRegion(jcharArray array, jsize start, jsize len, jchar *buf);
+ new pf_void_IntPtr_int_int_IntPtr(JNIEnv.SetShortArrayRegion), //virtual void JNICALL SetShortArrayRegion(jshortArray array, jsize start, jsize len, jshort *buf);
+ new pf_void_IntPtr_int_int_IntPtr(JNIEnv.SetIntArrayRegion), //virtual void JNICALL SetIntArrayRegion(jintArray array, jsize start, jsize len, jint *buf);
+ new pf_void_IntPtr_int_int_IntPtr(JNIEnv.SetLongArrayRegion), //virtual void JNICALL SetLongArrayRegion(jlongArray array, jsize start, jsize len, jlong *buf);
+ new pf_void_IntPtr_int_int_IntPtr(JNIEnv.SetFloatArrayRegion), //virtual void JNICALL SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, jfloat *buf);
+ new pf_void_IntPtr_int_int_IntPtr(JNIEnv.SetDoubleArrayRegion), //virtual void JNICALL SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, jdouble *buf);
+
+ new pf_int_IntPtr_pJNINativeMethod_int(JNIEnv.RegisterNatives), //virtual jint JNICALL RegisterNatives(jclass clazz, const JNINativeMethod *methods, jint nMethods);
+ new pf_int_IntPtr(JNIEnv.UnregisterNatives), //virtual jint JNICALL UnregisterNatives(jclass clazz);
+
+ new pf_int_IntPtr(JNIEnv.MonitorEnter), //virtual jint JNICALL MonitorEnter(jobject obj);
+ new pf_int_IntPtr(JNIEnv.MonitorExit), //virtual jint JNICALL MonitorExit(jobject obj);
+
+ new pf_int_ppJavaVM(JNIEnv.GetJavaVM), //virtual jint JNICALL GetJavaVM(JavaVM **vm);
+
+ new pf_void_IntPtr_int_int_IntPtr(JNIEnv.GetStringRegion), //virtual void JNICALL GetStringRegion(jstring str, jsize start, jsize len, jchar *buf);
+ new pf_void_IntPtr_int_int_IntPtr(JNIEnv.GetStringUTFRegion), //virtual void JNICALL GetStringUTFRegion(jstring str, jsize start, jsize len, char *buf);
+
+ new pf_IntPtr_IntPtr_IntPtr(JNIEnv.GetPrimitiveArrayCritical), //virtual void* JNICALL GetPrimitiveArrayCritical(jarray array, jboolean *isCopy);
+ new pf_void_IntPtr_IntPtr_int(JNIEnv.ReleasePrimitiveArrayCritical), //virtual void JNICALL ReleasePrimitiveArrayCritical(jarray array, void *carray, jint mode);
+
+ new pf_IntPtr_IntPtr_IntPtr(JNIEnv.GetStringCritical), //virtual const jchar* JNICALL GetStringCritical(jstring string, jboolean *isCopy);
+ new pf_void_IntPtr_IntPtr(JNIEnv.ReleaseStringCritical), //virtual void JNICALL ReleaseStringCritical(jstring string, const jchar *cstring);
+
+ new pf_void(JNIEnv.NotImplemented), //virtual jweak JNICALL NewWeakGlobalRef(jobject obj);
+ new pf_void(JNIEnv.NotImplemented), //virtual void JNICALL DeleteWeakGlobalRef(jweak ref);
+
+ new pf_sbyte(JNIEnv.ExceptionCheck), //virtual jboolean JNICALL ExceptionCheck();
+
+ new pf_void(JNIEnv.NotImplemented), //virtual jobject JNICALL NewDirectByteBuffer(void* address, jlong capacity);
+ new pf_void(JNIEnv.NotImplemented), //virtual void* JNICALL GetDirectBufferAddress(jobject buf);
+ new pf_void(JNIEnv.NotImplemented) //virtual jlong JNICALL GetDirectBufferCapacity(jobject buf);
+ };
+}
+
+[StructLayout(LayoutKind.Sequential)]
+unsafe struct JavaVM
+{
+ internal static JavaVM* pJavaVM;
+ void** vtable;
+ void* firstVtableEntry;
+ delegate int pf_int(JavaVM* pJVM);
+ delegate int pf_int_ppvoid_pvoid(JavaVM* pJVM, void** p1, void* p2);
+ delegate int pf_int_ppvoid_int(JavaVM* pJVM, void** p1, int p2);
+
+ static Delegate[] vtableDelegates =
+ {
+ null,
+ null,
+ null,
+ new pf_int(DestroyJavaVM),
+ new pf_int_ppvoid_pvoid(AttachCurrentThread),
+ new pf_int(DetachCurrentThread),
+ new pf_int_ppvoid_int(GetEnv),
+ new pf_int_ppvoid_pvoid(AttachCurrentThreadAsDaemon)
+ };
+
+ static JavaVM()
+ {
+ pJavaVM = (JavaVM*)(void*)Marshal.AllocHGlobal(IntPtr.Size * (1 + vtableDelegates.Length));
+#if __MonoCS__
+ // MONOBUG mcs requires this bogus fixed construct (and Microsoft doesn't allow it)
+ fixed(void** p = &pJavaVM->firstVtableEntry) { pJavaVM->vtable = p; }
+#else
+ pJavaVM->vtable = &pJavaVM->firstVtableEntry;
+#endif
+ for(int i = 0; i < vtableDelegates.Length; i++)
+ {
+ pJavaVM->vtable[i] = JniHelper.ikvm_MarshalDelegate(vtableDelegates[i]);
+ }
+ }
+
+ internal static int DestroyJavaVM(JavaVM* pJVM)
+ {
+ return JNIEnv.JNI_ERR;
+ }
+
+ internal static int AttachCurrentThread(JavaVM* pJVM, void **penv, void *args)
+ {
+ // TODO do we need a new local ref frame?
+ // TODO for now we only support attaching to an existing thread
+ // TODO support args (JavaVMAttachArgs)
+ JNIEnv* p = TlsHack.pJNIEnv;
+ if(p != null)
+ {
+ *penv = p;
+ return JNIEnv.JNI_OK;
+ }
+ JVM.CriticalFailure("AttachCurrentThread for non-Java threads not implemented", null);
+ return JNIEnv.JNI_ERR;
+ }
+
+ internal static int DetachCurrentThread(JavaVM* pJVM)
+ {
+ JVM.CriticalFailure("DetachCurrentThread not implemented", null);
+ return JNIEnv.JNI_ERR;
+ }
+
+ internal static int GetEnv(JavaVM* pJVM, void **penv, int version)
+ {
+ // TODO we should check the version
+ JNIEnv* p = TlsHack.pJNIEnv;
+ if(p != null)
+ {
+ *penv = p;
+ return JNIEnv.JNI_OK;
+ }
+ return JNIEnv.JNI_EDETACHED;
+ }
+
+ internal static int AttachCurrentThreadAsDaemon(JavaVM* pJVM, void **penv, void *args)
+ {
+ // TODO do we need a new local ref frame?
+ // TODO for now we only support attaching to an existing thread
+ // TODO support args (JavaVMAttachArgs)
+ JNIEnv* p = TlsHack.pJNIEnv;
+ if(p != null)
+ {
+ *penv = p;
+ return JNIEnv.JNI_OK;
+ }
+ JVM.CriticalFailure("AttachCurrentThreadAsDaemon not implemented", null);
+ return JNIEnv.JNI_ERR;
+ }
+}
+
+[StructLayout(LayoutKind.Sequential)]
+unsafe struct JNIEnv
+{
+ internal const int JNI_OK = 0;
+ internal const int JNI_ERR = -1;
+ internal const int JNI_EDETACHED = -2;
+ internal const int JNI_EVERSION = -3;
+ internal const int JNI_COMMIT = 1;
+ internal const int JNI_ABORT = 2;
+ internal const int JNI_VERSION_1_1 = 0x00010001;
+ internal const int JNI_VERSION_1_2 = 0x00010002;
+ internal const int JNI_VERSION_1_4 = 0x00010004;
+ internal const sbyte JNI_TRUE = 1;
+ internal const sbyte JNI_FALSE = 0;
+ internal void* vtable;
+ [StructLayout(LayoutKind.Explicit)]
+ internal unsafe struct Union
+ {
+ [FieldOffset(0)]
+ internal JniFrame* activeFrame;
+ [FieldOffset(0)]
+ internal void* pFrame;
+ }
+ internal Union u;
+ internal GCHandle localRefs;
+ internal int localRefSlot;
+ internal IntPtr pendingException;
+
+ private static string StringFromUTF8(byte* psz)
+ {
+ // Sun's modified UTF8 encoding is not compatible with System.Text.Encoding.UTF8,
+ // so we need to roll our own
+ int len = 0;
+ bool hasNonAscii = false;
+ while(psz[len] != 0)
+ {
+ hasNonAscii |= psz[len] >= 128;
+ len++;
+ }
+ if(!hasNonAscii)
+ {
+ // optimize the common case of 7-bit ASCII
+ return new String((sbyte*)psz);
+ }
+ StringBuilder sb = new StringBuilder(len);
+ for(int i = 0; i < len; i++)
+ {
+ int c = *psz++;
+ int char2, char3;
+ switch(c >> 4)
+ {
+ case 12:
+ case 13:
+ char2 = *psz++;
+ i++;
+ c = (((c & 0x1F) << 6) | (char2 & 0x3F));
+ break;
+ case 14:
+ char2 = *psz++;
+ char3 = *psz++;
+ i++;
+ i++;
+ c = ((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | (char3 & 0x3F);
+ break;
+ }
+ sb.Append((char)c);
+ }
+ return sb.ToString();
+ }
+
+ private static int StringUTF8Length(string s)
+ {
+ int len = 0;
+ for(int i = 0; i < s.Length; i++)
+ {
+ char ch = s[i];
+ if((ch != 0) && (ch <= 0x7F))
+ {
+ len++;
+ }
+ else if(ch <= 0x7FF)
+ {
+ len += 2;
+ }
+ else
+ {
+ len += 3;
+ }
+ }
+ return len;
+ }
// this method returns a simplified method argument descriptor.
// some examples:
// "()V" -> ""
// "(ILjava.lang.String;)I" -> "IL"
// "([Ljava.lang.String;)V" -> "L"
- public static string GetMethodArgList(IntPtr cookie)
+ private static string GetMethodArgList(IntPtr cookie)
{
try
{
@@ -95,44 +828,583 @@ public sealed class JniHelper
}
}
- public static object InvokeMethod(IntPtr cookie, object obj, object[] args, bool nonVirtual)
+ internal static int GetMethodArgs(JNIEnv* pEnv, IntPtr method, byte* sig)
+ {
+ string s = GetMethodArgList(method);
+ for(int i = 0; i < s.Length; i++)
+ {
+ sig[i] = (byte)s[i];
+ }
+ return s.Length;
+ }
+
+ internal static int GetVersion(JNIEnv* pEnv)
+ {
+ return JNI_VERSION_1_4;
+ }
+
+ internal static IntPtr DefineClass(JNIEnv* pEnv, byte* name, IntPtr loader, byte* pbuf, int length)
+ {
+ byte[] buf = new byte[length];
+ Marshal.Copy((IntPtr)(void*)pbuf, buf, 0, length);
+ // TODO what should the protection domain be?
+ return pEnv->MakeLocalRef(NativeCode.java.lang.VMClassLoader.defineClass(pEnv->UnwrapRef(loader), StringFromUTF8(name), buf, 0, buf.Length, null));
+ }
+
+ private static ClassLoaderWrapper FindNativeMethodClassLoader()
+ {
+ StackTrace st = new StackTrace();
+ for(int i = 0; i < st.FrameCount; i++)
+ {
+ StackFrame frame = st.GetFrame(i);
+ Type type = frame.GetMethod().DeclaringType;
+ if(type != null)
+ {
+ // TODO we need a more robust algorithm to find the "caller" (note that in addition to native methods,
+ // System.loadLibrary can also trigger executing native code)
+ ClassLoaderWrapper loader = ClassLoaderWrapper.GetWrapperFromType(type).GetClassLoader();
+ if(loader.GetJavaClassLoader() != null)
+ {
+ return loader;
+ }
+ }
+ }
+ // TODO instead of using the bootstrap class loader, we need to use the system (aka application) class loader
+ return ClassLoaderWrapper.GetBootstrapClassLoader();
+ }
+
+ internal static IntPtr FindClass(JNIEnv* pEnv, byte* name)
{
try
{
- return MethodWrapper.FromCookie(cookie).Invoke(obj, args, nonVirtual);
+ TypeWrapper wrapper = FindNativeMethodClassLoader().LoadClassByDottedName(StringFromUTF8(name).Replace('/', '.'));
+ // TODO is this needed?
+ wrapper.Finish();
+ return pEnv->MakeLocalRef(NativeCode.java.lang.VMClass.getClassFromWrapper(wrapper));
}
catch(Exception x)
{
- throw ExceptionHelper.MapExceptionFast(x);
+ SetPendingException(pEnv, x);
+ return IntPtr.Zero;
+ }
+ }
+
+ internal static IntPtr FromReflectedMethod(JNIEnv* pEnv, IntPtr method)
+ {
+ object methodObj = pEnv->UnwrapRef(method);
+ MethodWrapper mw = (MethodWrapper)methodObj.GetType().GetField("methodCookie", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(methodObj);
+ return mw.Cookie;
+ }
+
+ internal static IntPtr FromReflectedField(JNIEnv* pEnv, IntPtr field)
+ {
+ object fieldObj = pEnv->UnwrapRef(field);
+ FieldWrapper fw = (FieldWrapper)fieldObj.GetType().GetField("fieldCookie", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(fieldObj);
+ return fw.Cookie;
+ }
+
+ internal static IntPtr ToReflectedMethod(JNIEnv* pEnv, IntPtr clazz_ignored, IntPtr method)
+ {
+ MethodWrapper mw = MethodWrapper.FromCookie(method);
+ TypeWrapper tw;
+ if(mw.Name == "<init>")
+ {
+ tw = ClassLoaderWrapper.LoadClassCritical("java.lang.reflect.Constructor");
+ }
+ else
+ {
+ tw = ClassLoaderWrapper.LoadClassCritical("java.lang.reflect.Method");
}
+ object clazz = NativeCode.java.lang.VMClass.getClassFromWrapper(mw.DeclaringType);
+ return pEnv->MakeLocalRef(Activator.CreateInstance(tw.TypeAsTBD, new object[] { clazz, mw }));
+ }
+
+ internal static IntPtr GetSuperclass(JNIEnv* pEnv, IntPtr sub)
+ {
+ TypeWrapper wrapper = NativeCode.java.lang.VMClass.getWrapperFromClass(pEnv->UnwrapRef(sub)).BaseTypeWrapper;
+ return pEnv->MakeLocalRef(wrapper == null ? null : NativeCode.java.lang.VMClass.getClassFromWrapper(wrapper));
}
- // NOTE sig contains slashed class names
- public static IntPtr GetFieldCookie(object clazz, string name, string sig, bool isStatic)
+ internal static sbyte IsAssignableFrom(JNIEnv* pEnv, IntPtr sub, IntPtr super)
+ {
+ TypeWrapper w1 = NativeCode.java.lang.VMClass.getWrapperFromClass(pEnv->UnwrapRef(sub));
+ TypeWrapper w2 = NativeCode.java.lang.VMClass.getWrapperFromClass(pEnv->UnwrapRef(super));
+ return w2.IsAssignableTo(w1) ? JNI_TRUE : JNI_FALSE;
+ }
+
+ internal static IntPtr ToReflectedField(JNIEnv* pEnv, IntPtr clazz_ignored, IntPtr field)
+ {
+ FieldWrapper fw = FieldWrapper.FromCookie(field);
+ TypeWrapper tw = ClassLoaderWrapper.LoadClassCritical("java.lang.reflect.Field");
+ object clazz = NativeCode.java.lang.VMClass.getClassFromWrapper(fw.DeclaringType);
+ return pEnv->MakeLocalRef(Activator.CreateInstance(tw.TypeAsTBD, new object[] { clazz, fw }));
+ }
+
+ private static void SetPendingException(JNIEnv* pEnv, Exception x)
+ {
+ DeleteLocalRef(pEnv, pEnv->pendingException);
+ pEnv->pendingException = pEnv->MakeLocalRef(x);
+ }
+
+ internal static int Throw(JNIEnv* pEnv, IntPtr throwable)
+ {
+ DeleteLocalRef(pEnv, pEnv->pendingException);
+ pEnv->pendingException = NewLocalRef(pEnv, throwable);
+ return JNI_OK;
+ }
+
+ internal static int ThrowNew(JNIEnv* pEnv, IntPtr clazz, byte* msg)
+ {
+ TypeWrapper wrapper = NativeCode.java.lang.VMClass.getWrapperFromClass(pEnv->UnwrapRef(clazz));
+ MethodWrapper mw = wrapper.GetMethodWrapper(new MethodDescriptor("<init>", "(Ljava.lang.String;)V"), false);
+ if(mw != null)
+ {
+ int rc;
+ Exception exception;
+ try
+ {
+ wrapper.Finish();
+ exception = (Exception)mw.Invoke(null, new object[] { StringFromUTF8(msg) }, false);
+ rc = JNI_OK;
+ }
+ catch(Exception x)
+ {
+ exception = x;
+ rc = JNI_ERR;
+ }
+ SetPendingException(pEnv, exception);
+ return rc;
+ }
+ else
+ {
+ SetPendingException(pEnv, JavaException.NoSuchMethodError("<init>(Ljava.lang.String;)V"));
+ return JNI_ERR;
+ }
+ }
+
+ internal static IntPtr ExceptionOccurred(JNIEnv* pEnv)
+ {
+ return NewLocalRef(pEnv, pEnv->pendingException);
+ }
+
+ internal static void ExceptionDescribe(JNIEnv* pEnv)
+ {
+ Exception x = (Exception)pEnv->UnwrapRef(pEnv->pendingException);
+ if(x != null)
+ {
+ try
+ {
+ MethodWrapper mw = ClassLoaderWrapper.LoadClassCritical("java.lang.Throwable").GetMethodWrapper(new MethodDescriptor("printStackTrace", "()V"), false);
+ mw.Invoke(x, null, false);
+ }
+ catch(Exception ex)
+ {
+ Debug.Assert(false, ex.ToString());
+ }
+ }
+ }
+
+ internal static void ExceptionClear(JNIEnv* pEnv)
+ {
+ DeleteLocalRef(pEnv, pEnv->pendingException);
+ pEnv->pendingException = IntPtr.Zero;
+ }
+
+ internal static void FatalError(JNIEnv* pEnv, byte* msg)
+ {
+ JVM.CriticalFailure(StringFromUTF8(msg), null);
+ }
+
+ internal static IntPtr NewGlobalRef(JNIEnv* pEnv, IntPtr obj)
+ {
+ if(obj == IntPtr.Zero)
+ {
+ return IntPtr.Zero;
+ }
+ // TODO search for an empty slot before adding it to the end...
+ return (IntPtr)(-(GlobalRefs.globalRefs.Add(pEnv->UnwrapRef(obj)) + 1));
+ }
+
+ internal static void DeleteGlobalRef(JNIEnv* pEnv, IntPtr obj)
+ {
+ int i = obj.ToInt32();
+ if(i < 0)
+ {
+ GlobalRefs.globalRefs[(-i) - 1] = null;
+ return;
+ }
+ if(i > 0)
+ {
+ Debug.Assert(false, "Local ref passed to DeleteGlobalRef");
+ }
+ }
+
+ internal static void DeleteLocalRef(JNIEnv* pEnv, IntPtr obj)
+ {
+ int i = obj.ToInt32();
+ if(i > 0)
+ {
+ pEnv->u.activeFrame->localRefs[i >> LocalRefListEntry.LOCAL_REF_SHIFT].DeleteLocalRef(i & LocalRefListEntry.LOCAL_REF_MASK);
+ return;
+ }
+ if(i < 0)
+ {
+ Debug.Assert(false, "bogus localref in DeleteLocalRef");
+ }
+ }
+
+ internal static sbyte IsSameObject(JNIEnv* pEnv, IntPtr obj1, IntPtr obj2)
+ {
+ return pEnv->UnwrapRef(obj1) == pEnv->UnwrapRef(obj2) ? JNI_TRUE : JNI_FALSE;
+ }
+
+ internal static IntPtr NewLocalRef(JNIEnv* pEnv, IntPtr obj)
+ {
+ return pEnv->MakeLocalRef(pEnv->UnwrapRef(obj));
+ }
+
+ internal static IntPtr AllocObject(JNIEnv* pEnv, IntPtr clazz)
+ {
+ try
+ {
+ TypeWrapper wrapper = NativeCode.java.lang.VMClass.getWrapperFromClass(pEnv->UnwrapRef(clazz));
+ wrapper.Finish();
+ // TODO add error handling (e.g. when trying to instantiate an interface or abstract class)
+ return pEnv->MakeLocalRef(System.Runtime.Serialization.FormatterServices.GetUninitializedObject(wrapper.TypeAsBaseType));
+ }
+ catch(Exception x)
+ {
+ SetPendingException(pEnv, x);
+ return IntPtr.Zero;
+ }
+ }
+
+ [StructLayout(LayoutKind.Explicit)]
+ internal struct jvalue
+ {
+ [FieldOffset(0)]
+ public sbyte b;
+ [FieldOffset(0)]
+ public short s;
+ [FieldOffset(0)]
+ public int i;
+ [FieldOffset(0)]
+ public long j;
+ [FieldOffset(0)]
+ public float f;
+ [FieldOffset(0)]
+ public double d;
+ [FieldOffset(0)]
+ public IntPtr l;
+ }
+
+ private static object InvokeHelper(JNIEnv* pEnv, IntPtr obj, IntPtr methodID, jvalue *args, bool nonVirtual)
+ {
+ string sig = GetMethodArgList(methodID);
+ object[] argarray = new object[sig.Length];
+ for(int i = 0; i < sig.Length; i++)
+ {
+ switch(sig[i])
+ {
+ case 'Z':
+ argarray[i] = args[i].b != 0;
+ break;
+ case 'B':
+ argarray[i] = args[i].b;
+ break;
+ case 'C':
+ argarray[i] = (char)args[i].s;
+ break;
+ case 'S':
+ argarray[i] = args[i].s;
+ break;
+ case 'I':
+ argarray[i] = args[i].i;
+ break;
+ case 'J':
+ argarray[i] = args[i].j;
+ break;
+ case 'F':
+ argarray[i] = args[i].f;
+ break;
+ case 'D':
+ argarray[i] = args[i].d;
+ break;
+ case 'L':
+ argarray[i] = pEnv->UnwrapRef(args[i].l);
+ break;
+ }
+ }
+ try
+ {
+ return MethodWrapper.FromCookie(methodID).Invoke(pEnv->UnwrapRef(obj), argarray, nonVirtual);
+ }
+ catch(Exception x)
+ {
+ SetPendingException(pEnv, ExceptionHelper.MapExceptionFast(x));
+ return null;
+ }
+ }
+
+ internal static IntPtr NewObjectA(JNIEnv* pEnv, IntPtr clazz, IntPtr methodID, jvalue *args)
+ {
+ return pEnv->MakeLocalRef(InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false));
+ }
+
+ internal static IntPtr GetObjectClass(JNIEnv* pEnv, IntPtr obj)
+ {
+ return pEnv->MakeLocalRef(NativeCode.java.lang.VMClass.getClassFromType(pEnv->UnwrapRef(obj).GetType()));
+ }
+
+ internal static sbyte IsInstanceOf(JNIEnv* pEnv, IntPtr obj, IntPtr clazz)
+ {
+ object objClass = NativeCode.java.lang.VMClass.getClassFromType(pEnv->UnwrapRef(obj).GetType());
+ TypeWrapper w1 = NativeCode.java.lang.VMClass.getWrapperFromClass(pEnv->UnwrapRef(clazz));
+ TypeWrapper w2 = NativeCode.java.lang.VMClass.getWrapperFromClass(objClass);
+ return w2.IsAssignableTo(w1) ? JNI_TRUE : JNI_FALSE;
+ }
+
+ private static IntPtr FindMethodID(JNIEnv* pEnv, IntPtr clazz, byte* name, byte* sig, bool isstatic)
+ {
+ try
+ {
+ TypeWrapper wrapper = 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);
+ if(mw != null)
+ {
+ if(mw.IsStatic == isstatic)
+ {
+ mw.Link();
+ return mw.Cookie;
+ }
+ }
+ SetPendingException(pEnv, JavaException.NoSuchMethodError("{0}{1}", md.Name, md.Signature));
+ }
+ catch(Exception x)
+ {
+ SetPendingException(pEnv, x);
+ }
+ return IntPtr.Zero;
+ }
+
+ internal static IntPtr GetMethodID(JNIEnv* pEnv, IntPtr clazz, byte* name, byte* sig)
+ {
+ return FindMethodID(pEnv, clazz, name, sig, false);
+ }
+
+ internal static IntPtr CallObjectMethodA(JNIEnv* pEnv, IntPtr obj, IntPtr methodID, jvalue* args)
+ {
+ return pEnv->MakeLocalRef(InvokeHelper(pEnv, obj, methodID, args, false));
+ }
+
+ internal static sbyte CallBooleanMethodA(JNIEnv* pEnv, IntPtr obj, IntPtr methodID, jvalue* args)
+ {
+ object o = InvokeHelper(pEnv, obj, methodID, args, false);
+ if(o != null)
+ {
+ return ((bool)o) ? JNI_TRUE : JNI_FALSE;
+ }
+ return JNI_FALSE;
+ }
+
+ internal static sbyte CallByteMethodA(JNIEnv* pEnv, IntPtr obj, IntPtr methodID, jvalue* args)
+ {
+ object o = InvokeHelper(pEnv, obj, methodID, args, false);
+ if(o != null)
+ {
+ return (sbyte)o;
+ }
+ return 0;
+ }
+
+ internal static short CallCharMethodA(JNIEnv* pEnv, IntPtr obj, IntPtr methodID, jvalue* args)
+ {
+ object o = InvokeHelper(pEnv, obj, methodID, args, false);
+ if(o != null)
+ {
+ return (short)(char)o;
+ }
+ return 0;
+ }
+
+ internal static short CallShortMethodA(JNIEnv* pEnv, IntPtr obj, IntPtr methodID, jvalue* args)
+ {
+ object o = InvokeHelper(pEnv, obj, methodID, args, false);
+ if(o != null)
+ {
+ return (short)o;
+ }
+ return 0;
+ }
+
+ internal static int CallIntMethodA(JNIEnv* pEnv, IntPtr obj, IntPtr methodID, jvalue* args)
+ {
+ object o = InvokeHelper(pEnv, obj, methodID, args, false);
+ if(o != null)
+ {
+ return (int)o;
+ }
+ return 0;
+ }
+
+ internal static long CallLongMethodA(JNIEnv* pEnv, IntPtr obj, IntPtr methodID, jvalue* args)
+ {
+ object o = InvokeHelper(pEnv, obj, methodID, args, false);
+ if(o != null)
+ {
+ return (long)o;
+ }
+ return 0;
+ }
+
+ internal static float CallFloatMethodA(JNIEnv* pEnv, IntPtr obj, IntPtr methodID, jvalue* args)
+ {
+ object o = InvokeHelper(pEnv, obj, methodID, args, false);
+ if(o != null)
+ {
+ return (float)o;
+ }
+ return 0;
+ }
+
+ internal static double CallDoubleMethodA(JNIEnv* pEnv, IntPtr obj, IntPtr methodID, jvalue* args)
+ {
+ object o = InvokeHelper(pEnv, obj, methodID, args, false);
+ if(o != null)
+ {
+ return (double)o;
+ }
+ return 0;
+ }
+
+ internal static void CallVoidMethodA(JNIEnv* pEnv, IntPtr obj, IntPtr methodID, jvalue* args)
+ {
+ InvokeHelper(pEnv, obj, methodID, args, false);
+ }
+
+ internal static IntPtr CallNonvirtualObjectMethodA(JNIEnv* pEnv, IntPtr obj, IntPtr clazz, IntPtr methodID, jvalue* args)
+ {
+ return pEnv->MakeLocalRef(InvokeHelper(pEnv, obj, methodID, args, true));
+ }
+
+ internal static sbyte CallNonvirtualBooleanMethodA(JNIEnv* pEnv, IntPtr obj, IntPtr clazz, IntPtr methodID, jvalue* args)
+ {
+ object o = InvokeHelper(pEnv, obj, methodID, args, true);
+ if(o != null)
+ {
+ return ((bool)o) ? JNI_TRUE : JNI_FALSE;
+ }
+ return JNI_FALSE;
+ }
+
+ internal static sbyte CallNonvirtualByteMethodA(JNIEnv* pEnv, IntPtr obj, IntPtr clazz, IntPtr methodID, jvalue* args)
+ {
+ object o = InvokeHelper(pEnv, obj, methodID, args, true);
+ if(o != null)
+ {
+ return (sbyte)o;
+ }
+ return 0;
+ }
+
+ internal static short CallNonvirtualCharMethodA(JNIEnv* pEnv, IntPtr obj, IntPtr clazz, IntPtr methodID, jvalue* args)
+ {
+ object o = InvokeHelper(pEnv, obj, methodID, args, true);
+ if(o != null)
+ {
+ return (short)(char)o;
+ }
+ return 0;
+ }
+
+ internal static short CallNonvirtualShortMethodA(JNIEnv* pEnv, IntPtr obj, IntPtr clazz, IntPtr methodID, jvalue* args)
+ {
+ object o = InvokeHelper(pEnv, obj, methodID, args, true);
+ if(o != null)
+ {
+ return (short)o;
+ }
+ return 0;
+ }
+
+ internal static int CallNonvirtualIntMethodA(JNIEnv* pEnv, IntPtr obj, IntPtr clazz, IntPtr methodID, jvalue* args)
+ {
+ object o = InvokeHelper(pEnv, obj, methodID, args, true);
+ if(o != null)
+ {
+ return (int)o;
+ }
+ return 0;
+ }
+
+ internal static long CallNonvirtualLongMethodA(JNIEnv* pEnv, IntPtr obj, IntPtr clazz, IntPtr methodID, jvalue* args)
+ {
+ object o = InvokeHelper(pEnv, obj, methodID, args, true);
+ if(o != null)
+ {
+ return (long)o;
+ }
+ return 0;
+ }
+
+ internal static float CallNonvirtualFloatMethodA(JNIEnv* pEnv, IntPtr obj, IntPtr clazz, IntPtr methodID, jvalue* args)
+ {
+ object o = InvokeHelper(pEnv, obj, methodID, args, true);
+ if(o != null)
+ {
+ return (float)o;
+ }
+ return 0;
+ }
+
+ internal static double CallNonvirtualDoubleMethodA(JNIEnv* pEnv, IntPtr obj, IntPtr clazz, IntPtr methodID, jvalue* args)
+ {
+ object o = InvokeHelper(pEnv, obj, methodID, args, true);
+ if(o != null)
+ {
+ return (double)o;
+ }
+ return 0;
+ }
+
+ internal static void CallNonvirtualVoidMethodA(JNIEnv* pEnv, IntPtr obj, IntPtr clazz, IntPtr methodID, jvalue* args)
+ {
+ InvokeHelper(pEnv, obj, methodID, args, true);
+ }
+
+ private static IntPtr FindFieldID(JNIEnv* pEnv, IntPtr clazz, byte* name, byte* sig, bool isstatic)
{
try
{
- TypeWrapper wrapper = NativeCode.java.lang.VMClass.getWrapperFromClass(clazz);
+ TypeWrapper wrapper = NativeCode.java.lang.VMClass.getWrapperFromClass(pEnv->UnwrapRef(clazz));
wrapper.Finish();
// TODO what about searching the base classes?
- FieldWrapper fw = wrapper.GetFieldWrapper(name, wrapper.GetClassLoader().ExpressionTypeWrapper(sig.Replace('/', '.')));
+ FieldWrapper fw = wrapper.GetFieldWrapper(StringFromUTF8(name), wrapper.GetClassLoader().ExpressionTypeWrapper(StringFromUTF8(sig).Replace('/', '.')));
if(fw != null)
{
- if(fw.IsStatic == isStatic)
+ if(fw.IsStatic == isstatic)
{
+ // TODO fw.Link()
return fw.Cookie;
}
}
- return (IntPtr)0;
+ SetPendingException(pEnv, JavaException.NoSuchFieldError(StringFromUTF8(name)));
}
- catch
+ catch(Exception x)
{
- Debug.Assert(false);
- throw;
+ SetPendingException(pEnv, x);
}
+ return IntPtr.Zero;
+ }
+
+ internal static IntPtr GetFieldID(JNIEnv* pEnv, IntPtr clazz, byte* name, byte* sig)
+ {
+ return FindFieldID(pEnv, clazz, name, sig, false);
}
- public static void SetFieldValue(IntPtr cookie, object obj, object val)
+ private static void SetFieldValue(IntPtr cookie, object obj, object val)
{
try
{
@@ -145,7 +1417,7 @@ public sealed class JniHelper
}
}
- public static object GetFieldValue(IntPtr cookie, object obj)
+ private static object GetFieldValue(IntPtr cookie, object obj)
{
try
{
@@ -158,206 +1430,1264 @@ public sealed class JniHelper
}
}
- public static object FindClass(string javaName)
+ internal static IntPtr GetObjectField(JNIEnv* pEnv, IntPtr obj, IntPtr fieldID)
{
- try
+ return pEnv->MakeLocalRef(GetFieldValue(fieldID, pEnv->UnwrapRef(obj)));
+ }
+
+ internal static sbyte GetBooleanField(JNIEnv* pEnv, IntPtr obj, IntPtr fieldID)
+ {
+ return ((bool)GetFieldValue(fieldID, pEnv->UnwrapRef(obj))) ? JNI_TRUE : JNI_FALSE;
+ }
+
+ internal static sbyte GetByteField(JNIEnv* pEnv, IntPtr obj, IntPtr fieldID)
+ {
+ return (sbyte)GetFieldValue(fieldID, pEnv->UnwrapRef(obj));
+ }
+
+ internal static short GetCharField(JNIEnv* pEnv, IntPtr obj, IntPtr fieldID)
+ {
+ return (short)(char)GetFieldValue(fieldID, pEnv->UnwrapRef(obj));
+ }
+
+ internal static short GetShortField(JNIEnv* pEnv, IntPtr obj, IntPtr fieldID)
+ {
+ return (short)GetFieldValue(fieldID, pEnv->UnwrapRef(obj));
+ }
+
+ internal static int GetIntField(JNIEnv* pEnv, IntPtr obj, IntPtr fieldID)
+ {
+ return (int)GetFieldValue(fieldID, pEnv->UnwrapRef(obj));
+ }
+
+ internal static long GetLongField(JNIEnv* pEnv, IntPtr obj, IntPtr fieldID)
+ {
+ return (long)GetFieldValue(fieldID, pEnv->UnwrapRef(obj));
+ }
+
+ internal static float GetFloatField(JNIEnv* pEnv, IntPtr obj, IntPtr fieldID)
+ {
+ return (float)GetFieldValue(fieldID, pEnv->UnwrapRef(obj));
+ }
+
+ internal static double GetDoubleField(JNIEnv* pEnv, IntPtr obj, IntPtr fieldID)
+ {
+ return (double)GetFieldValue(fieldID, pEnv->UnwrapRef(obj));
+ }
+
+ internal static void SetObjectField(JNIEnv* pEnv, IntPtr obj, IntPtr fieldID, IntPtr val)
+ {
+ SetFieldValue(fieldID, pEnv->UnwrapRef(obj), pEnv->UnwrapRef(val));
+ }
+
+ internal static void SetBooleanField(JNIEnv* pEnv, IntPtr obj, IntPtr fieldID, sbyte val)
+ {
+ SetFieldValue(fieldID, pEnv->UnwrapRef(obj), val != JNI_FALSE);
+ }
+
+ internal static void SetByteField(JNIEnv* pEnv, IntPtr obj, IntPtr fieldID, sbyte val)
+ {
+ SetFieldValue(fieldID, pEnv->UnwrapRef(obj), val);
+ }
+
+ internal static void SetCharField(JNIEnv* pEnv, IntPtr obj, IntPtr fieldID, short val)
+ {
+ SetFieldValue(fieldID, pEnv->UnwrapRef(obj), (char)val);
+ }
+
+ internal static void SetShortField(JNIEnv* pEnv, IntPtr obj, IntPtr fieldID, short val)
+ {
+ SetFieldValue(fieldID, pEnv->UnwrapRef(obj), val);
+ }
+
+ internal static void SetIntField(JNIEnv* pEnv, IntPtr obj, IntPtr fieldID, int val)
+ {
+ SetFieldValue(fieldID, pEnv->UnwrapRef(obj), val);
+ }
+
+ internal static void SetLongField(JNIEnv* pEnv, IntPtr obj, IntPtr fieldID, long val)
+ {
+ SetFieldValue(fieldID, pEnv->UnwrapRef(obj), val);
+ }
+
+ internal static void SetFloatField(JNIEnv* pEnv, IntPtr obj, IntPtr fieldID, float val)
+ {
+ SetFieldValue(fieldID, pEnv->UnwrapRef(obj), val);
+ }
+
+ internal static void SetDoubleField(JNIEnv* pEnv, IntPtr obj, IntPtr fieldID, double val)
+ {
+ SetFieldValue(fieldID, pEnv->UnwrapRef(obj), val);
+ }
+
+ internal static IntPtr GetStaticMethodID(JNIEnv* pEnv, IntPtr clazz, byte* name, byte* sig)
+ {
+ return FindMethodID(pEnv, clazz, name, sig, true);
+ }
+
+ internal static IntPtr CallStaticObjectMethodA(JNIEnv* pEnv, IntPtr clazz, IntPtr methodID, jvalue *args)
+ {
+ return pEnv->MakeLocalRef(InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false));
+ }
+
+ internal static sbyte CallStaticBooleanMethodA(JNIEnv* pEnv, IntPtr clazz, IntPtr methodID, jvalue *args)
+ {
+ object o = InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false);
+ if(o != null)
{
- // TODO instead of using the bootstrap class loader, we need to use the system (aka application) class loader
- TypeWrapper wrapper = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(javaName.Replace('/', '.'));
- wrapper.Finish();
- return NativeCode.java.lang.VMClass.getClassFromWrapper(wrapper);
+ return ((bool)o) ? JNI_TRUE : JNI_FALSE;
}
- catch
+ return JNI_FALSE;
+ }
+
+ internal static sbyte CallStaticByteMethodA(JNIEnv* pEnv, IntPtr clazz, IntPtr methodID, jvalue *args)
+ {
+ object o = InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false);
+ if(o != null)
{
- Debug.Assert(false);
- throw;
+ return (sbyte)o;
}
+ return 0;
}
- public static Exception UnsatisfiedLinkError(string msg)
+ internal static short CallStaticCharMethodA(JNIEnv* pEnv, IntPtr clazz, IntPtr methodID, jvalue *args)
{
- try
+ object o = InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false);
+ if(o != null)
{
- return JavaException.UnsatisfiedLinkError(msg);
+ return (short)(char)o;
}
- catch
+ return 0;
+ }
+
+ internal static short CallStaticShortMethodA(JNIEnv* pEnv, IntPtr clazz, IntPtr methodID, jvalue *args)
+ {
+ object o = InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false);
+ if(o != null)
{
- Debug.Assert(false);
- throw;
+ return (short)o;
}
+ return 0;
}
- [Obsolete]
- public static object GetClassFromType(Type type)
+ internal static int CallStaticIntMethodA(JNIEnv* pEnv, IntPtr clazz, IntPtr methodID, jvalue *args)
{
- try
+ object o = InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false);
+ if(o != null)
{
- return NativeCode.java.lang.VMClass.getClassFromType(type);
+ return (int)o;
}
- catch
+ return 0;
+ }
+
+ internal static long CallStaticLongMethodA(JNIEnv* pEnv, IntPtr clazz, IntPtr methodID, jvalue *args)
+ {
+ object o = InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false);
+ if(o != null)
{
- Debug.Assert(false);
- throw;
+ return (long)o;
}
+ return 0;
}
- public static object GetObjectClass(object o)
+ internal static float CallStaticFloatMethodA(JNIEnv* pEnv, IntPtr clazz, IntPtr methodID, jvalue *args)
{
- try
+ object o = InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false);
+ if(o != null)
{
- return NativeCode.java.lang.VMClass.getClassFromType(o.GetType());
+ return (float)o;
}
- catch
+ return 0;
+ }
+
+ internal static double CallStaticDoubleMethodA(JNIEnv* pEnv, IntPtr clazz, IntPtr methodID, jvalue *args)
+ {
+ object o = InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false);
+ if(o != null)
{
- Debug.Assert(false);
- throw;
+ return (double)o;
}
+ return 0;
}
- public static bool IsInstanceOf(object o, object clazz)
+ internal static void CallStaticVoidMethodA(JNIEnv* pEnv, IntPtr cls, IntPtr methodID, jvalue * args)
{
- try
+ InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false);
+ }
+
+ internal static IntPtr GetStaticFieldID(JNIEnv* pEnv, IntPtr clazz, byte* name, byte* sig)
+ {
+ return FindFieldID(pEnv, clazz, name, sig, true);
+ }
+
+ internal static IntPtr GetStaticObjectField(JNIEnv* pEnv, IntPtr clazz, IntPtr fieldID)
+ {
+ return pEnv->MakeLocalRef(GetFieldValue(fieldID, null));
+ }
+
+ internal static sbyte GetStaticBooleanField(JNIEnv* pEnv, IntPtr clazz, IntPtr fieldID)
+ {
+ return ((bool)GetFieldValue(fieldID, null)) ? JNI_TRUE : JNI_FALSE;
+ }
+
+ internal static sbyte GetStaticByteField(JNIEnv* pEnv, IntPtr clazz, IntPtr fieldID)
+ {
+ return (sbyte)GetFieldValue(fieldID, null);
+ }
+
+ internal static short GetStaticCharField(JNIEnv* pEnv, IntPtr clazz, IntPtr fieldID)
+ {
+ return (short)(char)GetFieldValue(fieldID, null);
+ }
+
+ internal static short GetStaticShortField(JNIEnv* pEnv, IntPtr clazz, IntPtr fieldID)
+ {
+ return (short)GetFieldValue(fieldID, null);
+ }
+
+ internal static int GetStaticIntField(JNIEnv* pEnv, IntPtr clazz, IntPtr fieldID)
+ {
+ return (int)GetFieldValue(fieldID, null);
+ }
+
+ internal static long GetStaticLongField(JNIEnv* pEnv, IntPtr clazz, IntPtr fieldID)
+ {
+ return (long)GetFieldValue(fieldID, null);
+ }
+
+ internal static float GetStaticFloatField(JNIEnv* pEnv, IntPtr clazz, IntPtr fieldID)
+ {
+ return (float)GetFieldValue(fieldID, null);
+ }
+
+ internal static double GetStaticDoubleField(JNIEnv* pEnv, IntPtr clazz, IntPtr fieldID)
+ {
+ return (double)GetFieldValue(fieldID, null);
+ }
+
+ internal static void SetStaticObjectField(JNIEnv* pEnv, IntPtr clazz, IntPtr fieldID, IntPtr val)
+ {
+ SetFieldValue(fieldID, null, pEnv->UnwrapRef(val));
+ }
+
+ internal static void SetStaticBooleanField(JNIEnv* pEnv, IntPtr clazz, IntPtr fieldID, sbyte val)
+ {
+ SetFieldValue(fieldID, null, val != JNI_FALSE);
+ }
+
+ internal static void SetStaticByteField(JNIEnv* pEnv, IntPtr clazz, IntPtr fieldID, sbyte val)
+ {
+ SetFieldValue(fieldID, null, val);
+ }
+
+ internal static void SetStaticCharField(JNIEnv* pEnv, IntPtr clazz, IntPtr fieldID, short val)
+ {
+ SetFieldValue(fieldID, null, (char)val);
+ }
+
+ internal static void SetStaticShortField(JNIEnv* pEnv, IntPtr clazz, IntPtr fieldID, short val)
+ {
+ SetFieldValue(fieldID, null, val);
+ }
+
+ internal static void SetStaticIntField(JNIEnv* pEnv, IntPtr clazz, IntPtr fieldID, int val)
+ {
+ SetFieldValue(fieldID, null, val);
+ }
+
+ internal static void SetStaticLongField(JNIEnv* pEnv, IntPtr clazz, IntPtr fieldID, long val)
+ {
+ SetFieldValue(fieldID, null, val);
+ }
+
+ internal static void SetStaticFloatField(JNIEnv* pEnv, IntPtr clazz, IntPtr fieldID, float val)
+ {
+ SetFieldValue(fieldID, null, val);
+ }
+
+ internal static void SetStaticDoubleField(JNIEnv* pEnv, IntPtr clazz, IntPtr fieldID, double val)
+ {
+ SetFieldValue(fieldID, null, val);
+ }
+
+ internal static IntPtr NewString(JNIEnv* pEnv, char* unicode, int len)
+ {
+ return pEnv->MakeLocalRef(new String(unicode, 0, len));
+ }
+
+ internal static int GetStringLength(JNIEnv* pEnv, IntPtr str)
+ {
+ return ((string)pEnv->UnwrapRef(str)).Length;
+ }
+
+ internal static IntPtr GetStringChars(JNIEnv* pEnv, IntPtr str, IntPtr isCopy)
+ {
+ string s = (string)pEnv->UnwrapRef(str);
+ if(isCopy != IntPtr.Zero)
{
- return IsAssignableFrom(clazz, GetObjectClass(o));
+ *((sbyte*)(void*)isCopy) = JNI_TRUE;
}
- catch
+ return Marshal.StringToHGlobalUni(s);
+ }
+
+ internal static void ReleaseStringChars(JNIEnv* pEnv, IntPtr str, IntPtr chars)
+ {
+ Marshal.FreeHGlobal(chars);
+ }
+
+ internal static IntPtr NewStringUTF(JNIEnv* pEnv, IntPtr psz)
+ {
+ return pEnv->MakeLocalRef(StringFromUTF8((byte*)(void*)psz));
+ }
+
+ internal static int GetStringUTFLength(JNIEnv* pEnv, IntPtr str)
+ {
+ return StringUTF8Length((string)pEnv->UnwrapRef(str));
+ }
+
+ internal static IntPtr GetStringUTFChars(JNIEnv* pEnv, IntPtr str, IntPtr isCopy)
+ {
+ string s = (string)pEnv->UnwrapRef(str);
+ byte* buf = (byte*)Marshal.AllocHGlobal(StringUTF8Length(s) + 1);
+ int j = 0;
+ for(int i = 0; i < s.Length; i++)
{
- Debug.Assert(false);
- throw;
+ char ch = s[i];
+ if((ch != 0) && (ch <= 0x7F))
+ {
+ buf[j++] = (byte)ch;
+ }
+ else if(ch <= 0x7FF)
+ {
+ buf[j++] = (byte)((ch >> 6) | 0xC0);
+ buf[j++] = (byte)((ch & 0x3F) | 0x80);
+ }
+ else
+ {
+ buf[j++] = (byte)((ch >> 12) | 0xE0);
+ buf[j++] = (byte)(((ch >> 6) & 0x3F) | 0x80);
+ buf[j++] = (byte)((ch & 0x3F) | 0x80);
+ }
+ }
+ buf[j] = 0;
+ if(isCopy != IntPtr.Zero)
+ {
+ *((sbyte*)(void*)isCopy) = JNI_TRUE;
+ }
+ return (IntPtr)(void*)buf;
+ }
+
+ internal static void ReleaseStringUTFChars(JNIEnv* pEnv, IntPtr str, IntPtr chars)
+ {
+ Marshal.FreeHGlobal(chars);
+ }
+
+ internal static int GetArrayLength(JNIEnv* pEnv, IntPtr array)
+ {
+ return ((Array)pEnv->UnwrapRef(array)).Length;
+ }
+
+ internal static IntPtr NewObjectArray(JNIEnv* pEnv, int len, IntPtr clazz, IntPtr init)
+ {
+ // TODO if we want to support (non-primitive) value types we can't use the object[] cast
+ object[] array = (object[])Array.CreateInstance(NativeCode.java.lang.VMClass.getWrapperFromClass(pEnv->UnwrapRef(clazz)).TypeAsArrayType, len);
+ object o = pEnv->UnwrapRef(init);
+ if(o != null)
+ {
+ for(int i = 0; i < array.Length; i++)
+ {
+ array[i] = o;
+ }
}
+ return pEnv->MakeLocalRef(array);
}
- public static bool IsAssignableFrom(object sub, object sup)
+ internal static IntPtr GetObjectArrayElement(JNIEnv* pEnv, IntPtr array, int index)
{
try
{
- TypeWrapper w1 = NativeCode.java.lang.VMClass.getWrapperFromClass(sub);
- TypeWrapper w2 = NativeCode.java.lang.VMClass.getWrapperFromClass(sup);
- return w2.IsAssignableTo(w1);
+ // TODO if we want to support (non-primitive) value types we can't use the object[] cast
+ return pEnv->MakeLocalRef(((object[])pEnv->UnwrapRef(array))[index]);
}
- catch
+ catch(IndexOutOfRangeException)
{
- Debug.Assert(false);
- throw;
+ SetPendingException(pEnv, JavaException.ArrayIndexOutOfBoundsException());
+ return IntPtr.Zero;
}
}
-
- public static object GetSuperclass(object clazz)
+
+ internal static void SetObjectArrayElement(JNIEnv* pEnv, IntPtr array, int index, IntPtr val)
{
try
{
- TypeWrapper wrapper = NativeCode.java.lang.VMClass.getWrapperFromClass(clazz).BaseTypeWrapper;
- return wrapper == null ? null : NativeCode.java.lang.VMClass.getClassFromWrapper(wrapper);
+ // TODO if we want to support (non-primitive) value types we can't use the object[] cast
+ ((object[])pEnv->UnwrapRef(array))[index] = pEnv->UnwrapRef(val);
}
- catch
+ catch(IndexOutOfRangeException)
{
- Debug.Assert(false);
- throw;
+ SetPendingException(pEnv, JavaException.ArrayIndexOutOfBoundsException());
+ }
+ }
+
+ internal static IntPtr NewBooleanArray(JNIEnv* pEnv, int len)
+ {
+ return pEnv->MakeLocalRef(new bool[len]);
+ }
+
+ internal static IntPtr NewByteArray(JNIEnv* pEnv, int len)
+ {
+ return pEnv->MakeLocalRef(new sbyte[len]);
+ }
+
+ internal static IntPtr NewCharArray(JNIEnv* pEnv, int len)
+ {
+ return pEnv->MakeLocalRef(new char[len]);
+ }
+
+ internal static IntPtr NewShortArray(JNIEnv* pEnv, int len)
+ {
+ return pEnv->MakeLocalRef(new short[len]);
+ }
+
+ internal static IntPtr NewIntArray(JNIEnv* pEnv, int len)
+ {
+ return pEnv->MakeLocalRef(new int[len]);
+ }
+
+ internal static IntPtr NewLongArray(JNIEnv* pEnv, int len)
+ {
+ return pEnv->MakeLocalRef(new long[len]);
+ }
+
+ internal static IntPtr NewFloatArray(JNIEnv* pEnv, int len)
+ {
+ return pEnv->MakeLocalRef(new float[len]);
+ }
+
+ internal static IntPtr NewDoubleArray(JNIEnv* pEnv, int len)
+ {
+ return pEnv->MakeLocalRef(new double[len]);
+ }
+
+ internal static IntPtr GetBooleanArrayElements(JNIEnv* pEnv, IntPtr array, IntPtr isCopy)
+ {
+ bool[] b = (bool[])pEnv->UnwrapRef(array);
+ IntPtr buf = Marshal.AllocHGlobal(b.Length * 1);
+ sbyte* p = (sbyte*)(void*)buf;
+ for(int i = 0; i < b.Length; i++)
+ {
+ *p++ = b[i] ? JNI_TRUE : JNI_FALSE;
+ }
+ if(isCopy != IntPtr.Zero)
+ {
+ *((sbyte*)(void*)isCopy) = JNI_TRUE;
+ }
+ return buf;
+ }
+
+ internal static IntPtr GetByteArrayElements(JNIEnv* pEnv, IntPtr array, IntPtr isCopy)
+ {
+ sbyte[] b = (sbyte[])pEnv->UnwrapRef(array);
+ IntPtr buf = Marshal.AllocHGlobal(b.Length * 1);
+ sbyte* p = (sbyte*)(void*)buf;
+ for(int i = 0; i < b.Length; i++)
+ {
+ *p++ = b[i];
+ }
+ if(isCopy != IntPtr.Zero)
+ {
+ *((sbyte*)(void*)isCopy) = JNI_TRUE;
+ }
+ return buf;
+ }
+
+ internal static IntPtr GetCharArrayElements(JNIEnv* pEnv, IntPtr array, IntPtr isCopy)
+ {
+ char[] b = (char[])pEnv->UnwrapRef(array);
+ IntPtr buf = Marshal.AllocHGlobal(b.Length * 2);
+ Marshal.Copy(b, 0, buf, b.Length);
+ if(isCopy != IntPtr.Zero)
+ {
+ *((sbyte*)(void*)isCopy) = JNI_TRUE;
+ }
+ return buf;
+ }
+
+ internal static IntPtr GetShortArrayElements(JNIEnv* pEnv, IntPtr array, IntPtr isCopy)
+ {
+ short[] b = (short[])pEnv->UnwrapRef(array);
+ IntPtr buf = Marshal.AllocHGlobal(b.Length * 2);
+ Marshal.Copy(b, 0, buf, b.Length);
+ if(isCopy != IntPtr.Zero)
+ {
+ *((sbyte*)(void*)isCopy) = JNI_TRUE;
+ }
+ return buf;
+ }
+
+ internal static IntPtr GetIntArrayElements(JNIEnv* pEnv, IntPtr array, IntPtr isCopy)
+ {
+ int[] b = (int[])pEnv->UnwrapRef(array);
+ IntPtr buf = Marshal.AllocHGlobal(b.Length * 4);
+ Marshal.Copy(b, 0, buf, b.Length);
+ if(isCopy != IntPtr.Zero)
+ {
+ *((sbyte*)(void*)isCopy) = JNI_TRUE;
+ }
+ return buf;
+ }
+
+ internal static IntPtr GetLongArrayElements(JNIEnv* pEnv, IntPtr array, IntPtr isCopy)
+ {
+ long[] b = (long[])pEnv->UnwrapRef(array);
+ IntPtr buf = Marshal.AllocHGlobal(b.Length * 8);
+ Marshal.Copy(b, 0, buf, b.Length);
+ if(isCopy != IntPtr.Zero)
+ {
+ *((sbyte*)(void*)isCopy) = JNI_TRUE;
+ }
+ return buf;
+ }
+
+ internal static IntPtr GetFloatArrayElements(JNIEnv* pEnv, IntPtr array, IntPtr isCopy)
+ {
+ float[] b = (float[])pEnv->UnwrapRef(array);
+ IntPtr buf = Marshal.AllocHGlobal(b.Length * 4);
+ Marshal.Copy(b, 0, buf, b.Length);
+ if(isCopy != IntPtr.Zero)
+ {
+ *((sbyte*)(void*)isCopy) = JNI_TRUE;
+ }
+ return buf;
+ }
+
+ internal static IntPtr GetDoubleArrayElements(JNIEnv* pEnv, IntPtr array, IntPtr isCopy)
+ {
+ double[] b = (double[])pEnv->UnwrapRef(array);
+ IntPtr buf = Marshal.AllocHGlobal(b.Length * 8);
+ Marshal.Copy(b, 0, buf, b.Length);
+ if(isCopy != IntPtr.Zero)
+ {
+ *((sbyte*)(void*)isCopy) = JNI_TRUE;
+ }
+ return buf;
+ }
+
+ internal static void ReleaseBooleanArrayElements(JNIEnv* pEnv, IntPtr array, IntPtr elems, int mode)
+ {
+ if(mode == 0 || mode == JNI_COMMIT)
+ {
+ bool[] b = (bool[])pEnv->UnwrapRef(array);
+ sbyte* p = (sbyte*)(void*)elems;
+ for(int i = 0; i < b.Length; i++)
+ {
+ b[i] = *p++ != JNI_FALSE;
+ }
+ }
+ if(mode == 0 || mode == JNI_ABORT)
+ {
+ Marshal.FreeHGlobal(elems);
+ }
+ }
+
+ internal static void ReleaseByteArrayElements(JNIEnv* pEnv, IntPtr array, IntPtr elems, int mode)
+ {
+ if(mode == 0 || mode == JNI_COMMIT)
+ {
+ sbyte[] b = (sbyte[])pEnv->UnwrapRef(array);
+ sbyte* p = (sbyte*)(void*)elems;
+ for(int i = 0; i < b.Length; i++)
+ {
+ b[i] = *p++;
+ }
+ }
+ if(mode == 0 || mode == JNI_ABORT)
+ {
+ Marshal.FreeHGlobal(elems);
+ }
+ }
+
+ internal static void ReleaseCharArrayElements(JNIEnv* pEnv, IntPtr array, IntPtr elems, int mode)
+ {
+ if(mode == 0 || mode == JNI_COMMIT)
+ {
+ char[] b = (char[])pEnv->UnwrapRef(array);
+ Marshal.Copy(elems, b, 0, b.Length);
+ }
+ if(mode == 0 || mode == JNI_ABORT)
+ {
+ Marshal.FreeHGlobal(elems);
+ }
+ }
+
+ internal static void ReleaseShortArrayElements(JNIEnv* pEnv, IntPtr array, IntPtr elems, int mode)
+ {
+ if(mode == 0 || mode == JNI_COMMIT)
+ {
+ short[] b = (short[])pEnv->UnwrapRef(array);
+ Marshal.Copy(elems, b, 0, b.Length);
+ }
+ if(mode == 0 || mode == JNI_ABORT)
+ {
+ Marshal.FreeHGlobal(elems);
+ }
+ }
+
+ internal static void ReleaseIntArrayElements(JNIEnv* pEnv, IntPtr array, IntPtr elems, int mode)
+ {
+ if(mode == 0 || mode == JNI_COMMIT)
+ {
+ int[] b = (int[])pEnv->UnwrapRef(array);
+ Marshal.Copy(elems, b, 0, b.Length);
+ }
+ if(mode == 0 || mode == JNI_ABORT)
+ {
+ Marshal.FreeHGlobal(elems);
+ }
+ }
+
+ internal static void ReleaseLongArrayElements(JNIEnv* pEnv, IntPtr array, IntPtr elems, int mode)
+ {
+ if(mode == 0 || mode == JNI_COMMIT)
+ {
+ long[] b = (long[])pEnv->UnwrapRef(array);
+ Marshal.Copy(elems, b, 0, b.Length);
+ }
+ if(mode == 0 || mode == JNI_ABORT)
+ {
+ Marshal.FreeHGlobal(elems);
+ }
+ }
+
+ internal static void ReleaseFloatArrayElements(JNIEnv* pEnv, IntPtr array, IntPtr elems, int mode)
+ {
+ if(mode == 0 || mode == JNI_COMMIT)
+ {
+ float[] b = (float[])pEnv->UnwrapRef(array);
+ Marshal.Copy(elems, b, 0, b.Length);
+ }
+ if(mode == 0 || mode == JNI_ABORT)
+ {
+ Marshal.FreeHGlobal(elems);
+ }
+ }
+
+ internal static void ReleaseDoubleArrayElements(JNIEnv* pEnv, IntPtr array, IntPtr elems, int mode)
+ {
+ if(mode == 0 || mode == JNI_COMMIT)
+ {
+ double[] b = (double[])pEnv->UnwrapRef(array);
+ Marshal.Copy(elems, b, 0, b.Length);
+ }
+ if(mode == 0 || mode == JNI_ABORT)
+ {
+ Marshal.FreeHGlobal(elems);
+ }
+ }
+
+ internal static void GetBooleanArrayRegion(JNIEnv* pEnv, IntPtr array, int start, int len, IntPtr buf)
+ {
+ bool[] b = (bool[])pEnv->UnwrapRef(array);
+ sbyte* p = (sbyte*)(void*)buf;
+ for(int i = 0; i < len; i++)
+ {
+ *p++ = b[start + i] ? JNI_TRUE : JNI_FALSE;
+ }
+ }
+
+ internal static void GetByteArrayRegion(JNIEnv* pEnv, IntPtr array, int start, int len, IntPtr buf)
+ {
+ sbyte[] b = (sbyte[])pEnv->UnwrapRef(array);
+ sbyte* p = (sbyte*)(void*)buf;
+ for(int i = 0; i < len; i++)
+ {
+ *p++ = b[start + i];
+ }
+ }
+
+ internal static void GetCharArrayRegion(JNIEnv* pEnv, IntPtr array, int start, int len, IntPtr buf)
+ {
+ char[] b = (char[])pEnv->UnwrapRef(array);
+ Marshal.Copy(b, start, buf, len);
+ }
+
+ internal static void GetShortArrayRegion(JNIEnv* pEnv, IntPtr array, int start, int len, IntPtr buf)
+ {
+ short[] b = (short[])pEnv->UnwrapRef(array);
+ Marshal.Copy(b, start, buf, len);
+ }
+
+ internal static void GetIntArrayRegion(JNIEnv* pEnv, IntPtr array, int start, int len, IntPtr buf)
+ {
+ int[] b = (int[])pEnv->UnwrapRef(array);
+ Marshal.Copy(b, start, buf, len);
+ }
+
+ internal static void GetLongArrayRegion(JNIEnv* pEnv, IntPtr array, int start, int len, IntPtr buf)
+ {
+ long[] b = (long[])pEnv->UnwrapRef(array);
+ Marshal.Copy(b, start, buf, len);
+ }
+
+ internal static void GetFloatArrayRegion(JNIEnv* pEnv, IntPtr array, int start, int len, IntPtr buf)
+ {
+ float[] b = (float[])pEnv->UnwrapRef(array);
+ Marshal.Copy(b, start, buf, len);
+ }
+
+ internal static void GetDoubleArrayRegion(JNIEnv* pEnv, IntPtr array, int start, int len, IntPtr buf)
+ {
+ double[] b = (double[])pEnv->UnwrapRef(array);
+ Marshal.Copy(b, start, buf, len);
+ }
+
+ internal static void SetBooleanArrayRegion(JNIEnv* pEnv, IntPtr array, int start, int len, IntPtr buf)
+ {
+ bool[] b = (bool[])pEnv->UnwrapRef(array);
+ sbyte* p = (sbyte*)(void*)buf;
+ for(int i = 0; i < len; i++)
+ {
+ b[start + i] = *p++ != JNI_FALSE;
+ }
+ }
+
+ internal static void SetByteArrayRegion(JNIEnv* pEnv, IntPtr array, int start, int len, IntPtr buf)
+ {
+ sbyte[] b = (sbyte[])pEnv->UnwrapRef(array);
+ sbyte* p = (sbyte*)(void*)buf;
+ for(int i = 0; i < len; i++)
+ {
+ b[start + i] = *p++;
}
}
- public static object AllocObject(object clazz)
+ internal static void SetCharArrayRegion(JNIEnv* pEnv, IntPtr array, int start, int len, IntPtr buf)
+ {
+ char[] b = (char[])pEnv->UnwrapRef(array);
+ Marshal.Copy(buf, b, start, len);
+ }
+
+ internal static void SetShortArrayRegion(JNIEnv* pEnv, IntPtr array, int start, int len, IntPtr buf)
+ {
+ short[] b = (short[])pEnv->UnwrapRef(array);
+ Marshal.Copy(buf, b, start, len);
+ }
+
+ internal static void SetIntArrayRegion(JNIEnv* pEnv, IntPtr array, int start, int len, IntPtr buf)
+ {
+ int[] b = (int[])pEnv->UnwrapRef(array);
+ Marshal.Copy(buf, b, start, len);
+ }
+
+ internal static void SetLongArrayRegion(JNIEnv* pEnv, IntPtr array, int start, int len, IntPtr buf)
+ {
+ long[] b = (long[])pEnv->UnwrapRef(array);
+ Marshal.Copy(buf, b, start, len);
+ }
+
+ internal static void SetFloatArrayRegion(JNIEnv* pEnv, IntPtr array, int start, int len, IntPtr buf)
+ {
+ float[] b = (float[])pEnv->UnwrapRef(array);
+ Marshal.Copy(buf, b, start, len);
+ }
+
+ internal static void SetDoubleArrayRegion(JNIEnv* pEnv, IntPtr array, int start, int len, IntPtr buf)
+ {
+ double[] b = (double[])pEnv->UnwrapRef(array);
+ Marshal.Copy(buf, b, start, len);
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct JNINativeMethod
+ {
+ public byte* name;
+ public byte* signature;
+ public void* fnPtr;
+ }
+
+ internal static int RegisterNatives(JNIEnv* pEnv, IntPtr clazz, JNINativeMethod* methods, int nMethods)
{
try
{
- TypeWrapper wrapper = NativeCode.java.lang.VMClass.getWrapperFromClass(clazz);
+ TypeWrapper wrapper = NativeCode.java.lang.VMClass.getWrapperFromClass(pEnv->UnwrapRef(clazz));
wrapper.Finish();
- // TODO add error handling (e.g. when trying to instantiate an interface or abstract class)
- return System.Runtime.Serialization.FormatterServices.GetUninitializedObject(wrapper.TypeAsBaseType);
+ for(int i = 0; i < nMethods; i++)
+ {
+ FieldInfo fi = wrapper.TypeAsTBD.GetField("jniptr/" + StringFromUTF8(methods[i].name) + StringFromUTF8(methods[i].signature).Replace('/', '.'), BindingFlags.Static | BindingFlags.NonPublic);
+ if(fi == null)
+ {
+ SetPendingException(pEnv, JavaException.NoSuchMethodError(StringFromUTF8(methods[i].name)));
+ return JNI_ERR;
+ }
+ fi.SetValue(null, (IntPtr)methods[i].fnPtr);
+ }
+ return JNI_OK;
}
- catch
+ catch(Exception x)
{
- Debug.Assert(false);
- throw;
+ SetPendingException(pEnv, x);
+ return JNI_ERR;
}
}
- public static IntPtr MethodToCookie(object method)
+ internal static int UnregisterNatives(JNIEnv* pEnv, IntPtr clazz)
{
try
{
- MethodWrapper mw = (MethodWrapper)method.GetType().GetField("methodCookie", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(method);
- return mw.Cookie;
+ TypeWrapper wrapper = NativeCode.java.lang.VMClass.getWrapperFromClass(pEnv->UnwrapRef(clazz));
+ wrapper.Finish();
+ foreach(FieldInfo fi in wrapper.TypeAsTBD.GetFields(BindingFlags.Static | BindingFlags.NonPublic))
+ {
+ if(fi.Name.StartsWith("jniptr/"))
+ {
+ fi.SetValue(null, IntPtr.Zero);
+ }
+ }
+ return JNI_OK;
}
- catch
+ catch(Exception x)
{
- Debug.Assert(false);
- throw;
+ SetPendingException(pEnv, x);
+ return JNI_ERR;
}
}
- public static IntPtr FieldToCookie(object field)
+ internal static int MonitorEnter(JNIEnv* pEnv, IntPtr obj)
{
try
{
- FieldWrapper fw = (FieldWrapper)field.GetType().GetField("fieldCookie", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(field);
- return fw.Cookie;
+ System.Threading.Monitor.Enter(pEnv->UnwrapRef(obj));
+ return JNI_OK;
}
- catch
+ catch(System.Threading.ThreadInterruptedException)
{
- Debug.Assert(false);
- throw;
+ SetPendingException(pEnv, JavaException.InterruptedException());
+ return JNI_ERR;
}
}
- public static object CookieToMethod(IntPtr method)
+ internal static int MonitorExit(JNIEnv* pEnv, IntPtr obj)
{
try
{
- MethodWrapper mw = MethodWrapper.FromCookie(method);
- TypeWrapper tw;
- if(mw.Name == "<init>")
+ System.Threading.Monitor.Exit(pEnv->UnwrapRef(obj));
+ return JNI_OK;
+ }
+ catch(System.Threading.SynchronizationLockException)
+ {
+ SetPendingException(pEnv, JavaException.IllegalMonitorStateException());
+ return JNI_ERR;
+ }
+ }
+
+ internal static int GetJavaVM(JNIEnv* pEnv, JavaVM **ppJavaVM)
+ {
+ *ppJavaVM = JavaVM.pJavaVM;
+ return JNI_OK;
+ }
+
+ internal static void GetStringRegion(JNIEnv* pEnv, IntPtr str, int start, int len, IntPtr buf)
+ {
+ string s = (string)pEnv->UnwrapRef(str);
+ if(s != null)
+ {
+ if(start < 0 || start > s.Length || s.Length - start < len)
{
- tw = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName("java.lang.reflect.Constructor");
+ SetPendingException(pEnv, JavaException.StringIndexOutOfBoundsException(""));
+ return;
}
else
{
- tw = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName("java.lang.reflect.Method");
+ char* p = (char*)(void*)buf;
+ // TODO isn't there a managed memcpy?
+ for(int i = 0; i < len; i++)
+ {
+ *p++ = s[start + i];
+ }
+ return;
}
- object clazz = NativeCode.java.lang.VMClass.getClassFromWrapper(mw.DeclaringType);
- return Activator.CreateInstance(tw.TypeAsTBD, new object[] { clazz, mw });
}
- catch
+ else
{
- Debug.Assert(false);
- throw;
+ SetPendingException(pEnv, JavaException.NullPointerException());
+ }
+ }
+
+ internal static void GetStringUTFRegion(JNIEnv* pEnv, IntPtr str, int start, int len, IntPtr buf)
+ {
+ string s = (string)pEnv->UnwrapRef(str);
+ if(s != null)
+ {
+ if(start < 0 || start > s.Length || s.Length - start < len)
+ {
+ SetPendingException(pEnv, JavaException.StringIndexOutOfBoundsException(""));
+ return;
+ }
+ else
+ {
+ byte* p = (byte*)(void*)buf;
+ for(int i = 0; i < len; i++)
+ {
+ char ch = s[start + i];
+ if((ch != 0) && (ch <= 0x7F))
+ {
+ *p++ = (byte)ch;
+ }
+ else if(ch <= 0x7FF)
+ {
+ *p++ = (byte)((ch >> 6) | 0xC0);
+ *p++ = (byte)((ch & 0x3F) | 0x80);
+ }
+ else
+ {
+ *p++ = (byte)((ch >> 12) | 0xE0);
+ *p++ = (byte)(((ch >> 6) & 0x3F) | 0x80);
+ *p++ = (byte)((ch & 0x3F) | 0x80);
+ }
+ }
+ return;
+ }
+ }
+ else
+ {
+ SetPendingException(pEnv, JavaException.NullPointerException());
+ }
+ }
+
+ private static int GetPrimitiveArrayElementSize(Array ar)
+ {
+ Type type = ar.GetType().GetElementType();
+ if(type == typeof(sbyte) || type == typeof(bool))
+ {
+ return 1;
+ }
+ else if(type == typeof(short) || type == typeof(char))
+ {
+ return 2;
+ }
+ else if(type == typeof(int) || type == typeof(float))
+ {
+ return 4;
+ }
+ else if(type == typeof(long) || type == typeof(double))
+ {
+ return 8;
+ }
+ else
+ {
+ JVM.CriticalFailure("invalid array type", null);
+ return 0;
}
}
- public static object CookieToField(IntPtr field)
+ internal static IntPtr GetPrimitiveArrayCritical(JNIEnv* pEnv, IntPtr array, IntPtr isCopy)
{
+ Array ar = (Array)pEnv->UnwrapRef(array);
+ int len = ar.Length * GetPrimitiveArrayElementSize(ar);
+ GCHandle h = GCHandle.Alloc(ar, GCHandleType.Pinned);
try
{
- FieldWrapper fw = FieldWrapper.FromCookie(field);
- TypeWrapper tw = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName("java.lang.reflect.Field");
- object clazz = NativeCode.java.lang.VMClass.getClassFromWrapper(fw.DeclaringType);
- return Activator.CreateInstance(tw.TypeAsTBD, new object[] { clazz, fw });
+ IntPtr hglobal = Marshal.AllocHGlobal(len);
+ byte* pdst = (byte*)(void*)hglobal;
+ byte* psrc = (byte*)(void*)h.AddrOfPinnedObject();
+ // TODO isn't there a managed memcpy?
+ for(int i = 0; i < len; i++)
+ {
+ *pdst++ = *psrc++;
+ }
+ if(isCopy != IntPtr.Zero)
+ {
+ *((sbyte*)(void*)isCopy) = JNI_TRUE;
+ }
+ return hglobal;
}
- catch
+ finally
{
- Debug.Assert(false);
- throw;
+ h.Free();
+ }
+ }
+
+ internal static void ReleasePrimitiveArrayCritical(JNIEnv* pEnv, IntPtr array, IntPtr carray, int mode)
+ {
+ if(mode == 0 || mode == JNI_COMMIT)
+ {
+ Array ar = (Array)pEnv->UnwrapRef(array);
+ int len = ar.Length * GetPrimitiveArrayElementSize(ar);
+ GCHandle h = GCHandle.Alloc(ar, GCHandleType.Pinned);
+ try
+ {
+ byte* pdst = (byte*)(void*)h.AddrOfPinnedObject();
+ byte* psrc = (byte*)(void*)carray;
+ // TODO isn't there a managed memcpy?
+ for(int i = 0; i < len; i++)
+ {
+ *pdst++ = *psrc++;
+ }
+ }
+ finally
+ {
+ h.Free();
+ }
+ }
+ if(mode == 0 || mode == JNI_ABORT)
+ {
+ Marshal.FreeHGlobal(carray);
}
}
- public static void FatalError(string msg)
+ internal static IntPtr GetStringCritical(JNIEnv* pEnv, IntPtr str, IntPtr isCopy)
{
- JVM.CriticalFailure(msg, null);
+ string s = (string)pEnv->UnwrapRef(str);
+ if(s != null)
+ {
+ if(isCopy != IntPtr.Zero)
+ {
+ *((sbyte*)(void*)isCopy) = JNI_TRUE;
+ }
+ return Marshal.StringToHGlobalUni(s);
+ }
+ SetPendingException(pEnv, JavaException.NullPointerException());
+ return IntPtr.Zero;
}
- public static object DefineClass(string name, object classLoader, byte[] buf)
+ internal static void ReleaseStringCritical(JNIEnv* pEnv, IntPtr str, IntPtr cstring)
{
- // TODO what should the protection domain be?
- return NativeCode.java.lang.VMClassLoader.defineClass(classLoader, name, buf, 0, buf.Length, null);
+ Marshal.FreeHGlobal(cstring);
+ }
+
+ internal static sbyte ExceptionCheck(JNIEnv* pEnv)
+ {
+ return pEnv->UnwrapRef(pEnv->pendingException) != null ? JNI_TRUE : JNI_FALSE;
+ }
+
+ internal static void NotImplemented(JNIEnv* pEnv)
+ {
+ JVM.CriticalFailure("Unimplemented JNIEnv function called", null);
+ }
+
+ internal IntPtr MakeLocalRef(object obj)
+ {
+ return u.activeFrame->MakeLocalRef(obj);
}
+
+ internal object UnwrapRef(IntPtr o)
+ {
+ int i = o.ToInt32();
+ if(i > 0)
+ {
+ return u.activeFrame->UnwrapLocalRef(o);
+ }
+ if(i < 0)
+ {
+ return GlobalRefs.globalRefs[(-i) - 1];
+ }
+ return null;
+ }
+}
+
+unsafe class TlsHack
+{
+ [ThreadStatic]
+ internal static JNIEnv* pJNIEnv;
}
-public interface IJniProvider
+[StructLayout(LayoutKind.Sequential)]
+public unsafe struct JniFrame
{
- int LoadNativeLibrary(string filename);
- Type GetLocalRefStructType();
- // NOTE the signature of the GetJniFuncPtr method is:
- // IntPtr GetJniFuncPtr(String method, String sig, String clazz)
- // sig & clazz are contain slashed class names
- MethodInfo GetJniFuncPtrMethod();
+ private JNIEnv* pJNIEnv;
+ private JniFrame* pPrevFrame;
+ private LocalRefCache fastlocalrefs;
+ internal LocalRefListEntry[] localRefs;
+ private RuntimeMethodHandle method;
+ // HACK since this isn't a blittable type and C# doesn't allow us to turn the this pointer into a JniFrame*, we need
+ // this hack to turn the address of a field into a pointer to the struct (it turns out that on the 1.1 CLR the address
+ // of the first field is not equal to the this pointer [for this particular struct])
+ private static readonly int jniFramePointerAdjustment = (int)new JNIEnv.Union().activeFrame->GetAddress();
+
+ private byte* GetAddress()
+ {
+ fixed(void* p = &pJNIEnv)
+ {
+ return (byte*)p;
+ }
+ }
+
+ public IntPtr Enter(RuntimeMethodHandle method)
+ {
+ this.method = method;
+ pJNIEnv = TlsHack.pJNIEnv;
+ if(pJNIEnv == null)
+ {
+ // TODO when the thread dies, we're leaking the JNIEnv and the GCHandle
+ pJNIEnv = TlsHack.pJNIEnv = (JNIEnv*)Marshal.AllocHGlobal(sizeof(JNIEnv));
+ pJNIEnv->vtable = VtableBuilder.vtable;
+ pJNIEnv->u.activeFrame = null;
+ localRefs = new LocalRefListEntry[32];
+ pJNIEnv->localRefs = GCHandle.Alloc(localRefs);
+ pJNIEnv->localRefSlot = 0;
+ pJNIEnv->pendingException = IntPtr.Zero;
+ }
+ else
+ {
+ localRefs = (LocalRefListEntry[])pJNIEnv->localRefs.Target;
+ }
+ pPrevFrame = pJNIEnv->u.activeFrame;
+ pJNIEnv->u.pFrame = GetAddress() - jniFramePointerAdjustment;
+ pJNIEnv->localRefSlot++;
+ if(pJNIEnv->localRefSlot >= localRefs.Length)
+ {
+ // TODO instead of bailing out, we should grow the array
+ JVM.CriticalFailure("JNI nesting too deep", null);
+ }
+ fixed(void* p = &pPrevFrame)
+ {
+ // HACK we assume that the fastlocalrefs struct starts at &pPrevFrame + IntPtr.Size
+ localRefs[pJNIEnv->localRefSlot].u.pv = ((byte*)p) + IntPtr.Size;
+ }
+ return (IntPtr)(void*)pJNIEnv;
+ }
+
+ public void Leave()
+ {
+ Exception x = (Exception)pJNIEnv->UnwrapRef(pJNIEnv->pendingException);
+ pJNIEnv->pendingException = IntPtr.Zero;
+ pJNIEnv->u.activeFrame = pPrevFrame;
+ localRefs[pJNIEnv->localRefSlot].dynamic_list = null;
+ // TODO figure out if it is legal to Leave a JNI method while PushLocalFrame is active
+ // (i.e. without the corresponding PopLocalFrame)
+ pJNIEnv->localRefSlot--;
+ if(x != null)
+ {
+ throw x;
+ }
+ }
+
+ public static IntPtr GetFuncPtr(RuntimeMethodHandle method, string clazz, string name, string sig)
+ {
+ MethodBase mb = MethodBase.GetMethodFromHandle(method);
+ // MONOBUG Mono 1.0 doesn't implement MethodBase.GetMethodFromHandle
+ if(mb == null)
+ {
+ mb = new StackFrame(1).GetMethod();
+ }
+ ClassLoaderWrapper loader = ClassLoaderWrapper.GetWrapperFromType(mb.DeclaringType).GetClassLoader();
+ StringBuilder mangledSig = new StringBuilder();
+ int sp = 0;
+ for(int i = 1; sig[i] != ')'; i++)
+ {
+ switch(sig[i])
+ {
+ case '[':
+ mangledSig.Append("_3");
+ sp += IntPtr.Size;
+ while(sig[++i] == '[')
+ {
+ mangledSig.Append("_3");
+ }
+ mangledSig.Append(sig[i]);
+ if(sig[i] == 'L')
+ {
+ while(sig[++i] != ';')
+ {
+ if(sig[i] == '/')
+ {
+ mangledSig.Append("_");
+ }
+ else if(sig[i] == '_')
+ {
+ mangledSig.Append("_1");
+ }
+ else
+ {
+ mangledSig.Append(sig[i]);
+ }
+ }
+ mangledSig.Append("_2");
+ }
+ break;
+ case 'L':
+ sp += IntPtr.Size;
+ mangledSig.Append("L");
+ while(sig[++i] != ';')
+ {
+ if(sig[i] == '/')
+ {
+ mangledSig.Append("_");
+ }
+ else if(sig[i] == '_')
+ {
+ mangledSig.Append("_1");
+ }
+ else
+ {
+ mangledSig.Append(sig[i]);
+ }
+ }
+ mangledSig.Append("_2");
+ break;
+ case 'J':
+ case 'D':
+ mangledSig.Append(sig[i]);
+ sp += 8;
+ break;
+ case 'F':
+ case 'I':
+ case 'C':
+ case 'Z':
+ case 'S':
+ case 'B':
+ mangledSig.Append(sig[i]);
+ sp += 4;
+ break;
+ default:
+ Debug.Assert(false);
+ break;
+ }
+ }
+ lock(JniHelper.JniLock)
+ {
+ string methodName = String.Format("Java_{0}_{1}", clazz.Replace("_", "_1").Replace('/', '_'), name.Replace("_", "_1"));
+ foreach(IntPtr p in loader.GetNativeLibraries())
+ {
+ IntPtr pfunc = JniHelper.ikvm_GetProcAddress(p, methodName, sp + 2 * IntPtr.Size);
+ if(pfunc != IntPtr.Zero)
+ {
+ return pfunc;
+ }
+ }
+ methodName = String.Format("Java_{0}_{1}__{2}", clazz.Replace("_", "_1").Replace('/', '_'), name.Replace("_", "_1"), mangledSig);
+ foreach(IntPtr p in loader.GetNativeLibraries())
+ {
+ IntPtr pfunc = JniHelper.ikvm_GetProcAddress(p, methodName, sp + 2 * IntPtr.Size);
+ if(pfunc != IntPtr.Zero)
+ {
+ return pfunc;
+ }
+ }
+ }
+ throw JavaException.UnsatisfiedLinkError("{0}.{1}{2}", clazz, name, sig);
+ }
+
+ public IntPtr MakeLocalRef(object obj)
+ {
+ if(obj == null)
+ {
+ return IntPtr.Zero;
+ }
+ int i = localRefs[pJNIEnv->localRefSlot].MakeLocalRef(obj);
+ if(i >= 0)
+ {
+ return (IntPtr)((pJNIEnv->localRefSlot << LocalRefListEntry.LOCAL_REF_SHIFT) + i);
+ }
+ // TODO consider allocating a new slot (if we do this, the code in
+ // PushLocalFrame/PopLocalFrame (and Leave) must be fixed to take this into account)
+ JVM.CriticalFailure("Too many JNI local references", null);
+ return IntPtr.Zero;
+ }
+
+ public object UnwrapLocalRef(IntPtr p)
+ {
+ int i = p.ToInt32();
+ return localRefs[i >> LocalRefListEntry.LOCAL_REF_SHIFT].UnwrapLocalRef(i & LocalRefListEntry.LOCAL_REF_MASK);
+ }
}
diff --git a/runtime/MemberWrapper.cs b/runtime/MemberWrapper.cs
index 5959a768..6356b220 100644
--- a/runtime/MemberWrapper.cs
+++ b/runtime/MemberWrapper.cs
@@ -1135,6 +1135,7 @@ class FieldWrapper : MemberWrapper
// HACK if linking fails, we unlink to make sure
// that the next link attempt will fail again
fieldType = null;
+ throw;
}
}
}
diff --git a/runtime/TypeWrapper.cs b/runtime/TypeWrapper.cs
index 696cbed2..1de8d192 100644
--- a/runtime/TypeWrapper.cs
+++ b/runtime/TypeWrapper.cs
@@ -102,7 +102,7 @@ class EmitHelper
// have a <clinit> now, a newer version that does have a <clinit> will not have it's <clinit> called by us.
// A possible solution would be to use RuntimeHelpers.RunClassConstructor when "type" is a Java type and
// lives in another assembly as the caller (which we don't know at the moment).
- FieldInfo field = type.GetField("__<clinit>");
+ FieldInfo field = type.GetField("__<clinit>", BindingFlags.Static | BindingFlags.NonPublic);
if(field != null)
{
ilgen.Emit(OpCodes.Ldsfld, field);
@@ -676,10 +676,6 @@ abstract class TypeWrapper
protected abstract FieldWrapper GetFieldImpl(string fieldName, TypeWrapper fieldType);
-// internal FieldWrapper GetFieldWrapper(string fieldName, string fieldSig)
-// {
-// }
-
internal virtual FieldWrapper GetFieldWrapper(string fieldName, TypeWrapper fieldType)
{
lock(fields.SyncRoot)
@@ -1385,9 +1381,7 @@ abstract class TypeWrapper
{
ilgen.Emit(OpCodes.Isinst, TypeAsTBD);
ilgen.Emit(OpCodes.Ldnull);
- ilgen.Emit(OpCodes.Ceq);
- ilgen.Emit(OpCodes.Ldc_I4_0);
- ilgen.Emit(OpCodes.Ceq);
+ ilgen.Emit(OpCodes.Cgt_Un);
}
}
@@ -2013,6 +2007,7 @@ sealed class DynamicTypeWrapper : TypeWrapper
private readonly TypeWrapper outerClassWrapper;
private readonly TypeBuilder typeBuilderGhostInterface;
private Hashtable memberclashtable;
+ private Hashtable classCache = new Hashtable();
internal JavaTypeImpl(ClassFile f, DynamicTypeWrapper wrapper)
{
@@ -2376,7 +2371,7 @@ sealed class DynamicTypeWrapper : TypeWrapper
// make sure all classes are loaded, before we start finishing the type. During finishing, we
// may not run any Java code, because that might result in a request to finish the type that we
// are in the process of finishing, and this would be a problem.
- classFile.Link(wrapper);
+ classFile.Link(wrapper, classCache);
// for(int i = 0; i < fields.Length; i++)
// {
// fields[i].Link();
@@ -2408,13 +2403,13 @@ sealed class DynamicTypeWrapper : TypeWrapper
{
if(innerclasses[i].innerClass != 0 && innerclasses[i].outerClass != 0)
{
- if(classFile.GetConstantPoolClassType(innerclasses[i].outerClass, wrapper.GetClassLoader()) == wrapper)
+ if(classFile.GetConstantPoolClassType(innerclasses[i].outerClass) == wrapper)
{
- wrappers.Add(classFile.GetConstantPoolClassType(innerclasses[i].innerClass, wrapper.GetClassLoader()));
+ wrappers.Add(classFile.GetConstantPoolClassType(innerclasses[i].innerClass));
}
- if(classFile.GetConstantPoolClassType(innerclasses[i].innerClass, wrapper.GetClassLoader()) == wrapper)
+ if(classFile.GetConstantPoolClassType(innerclasses[i].innerClass) == wrapper)
{
- declaringTypeWrapper = classFile.GetConstantPoolClassType(innerclasses[i].outerClass, wrapper.GetClassLoader());
+ declaringTypeWrapper = classFile.GetConstantPoolClassType(innerclasses[i].outerClass);
AttributeHelper.SetInnerClass(typeBuilder,
classFile.GetConstantPoolClass(innerclasses[i].innerClass),
classFile.GetConstantPoolClass(innerclasses[i].outerClass),
@@ -2532,9 +2527,7 @@ sealed class DynamicTypeWrapper : TypeWrapper
ilgen.Emit(OpCodes.Ldarg_0);
ilgen.Emit(OpCodes.Isinst, wrapper.TypeAsBaseType);
ilgen.Emit(OpCodes.Ldnull);
- ilgen.Emit(OpCodes.Ceq);
- ilgen.Emit(OpCodes.Ldc_I4_0);
- ilgen.Emit(OpCodes.Ceq);
+ ilgen.Emit(OpCodes.Cgt_Un);
ilgen.MarkLabel(end);
ilgen.Emit(OpCodes.Ret);
// Implement the "IsInstanceArray" method
@@ -2673,7 +2666,7 @@ sealed class DynamicTypeWrapper : TypeWrapper
if(mb is ConstructorBuilder)
{
ILGenerator ilGenerator = ((ConstructorBuilder)mb).GetILGenerator();
- Tracer.EmitMethodTrace(ilGenerator, m.ClassFile.Name + "." + m.Name + m.Signature);
+ Tracer.EmitMethodTrace(ilGenerator, classFile.Name + "." + m.Name + m.Signature);
if(basehasclinit && m.IsClassInitializer && !classFile.IsInterface)
{
hasclinit = true;
@@ -2681,7 +2674,7 @@ sealed class DynamicTypeWrapper : TypeWrapper
EmitConstantValueInitialization(ilGenerator);
EmitHelper.RunClassConstructor(ilGenerator, Type.BaseType);
}
- Compiler.Compile(wrapper, m, ilGenerator);
+ Compiler.Compile(wrapper, methods[i], classFile, m, ilGenerator);
}
else
{
@@ -2689,11 +2682,11 @@ sealed class DynamicTypeWrapper : TypeWrapper
{
// NOTE in the JVM it is apparently legal for a non-abstract class to have abstract methods, but
// the CLR doens't allow this, so we have to emit a method that throws an AbstractMethodError
- if(!m.ClassFile.IsAbstract && !m.ClassFile.IsInterface)
+ if(!classFile.IsAbstract && !classFile.IsInterface)
{
ILGenerator ilGenerator = ((MethodBuilder)mb).GetILGenerator();
- Tracer.EmitMethodTrace(ilGenerator, m.ClassFile.Name + "." + m.Name + m.Signature);
- EmitHelper.Throw(ilGenerator, "java.lang.AbstractMethodError", m.ClassFile.Name + "." + m.Name + m.Signature);
+ Tracer.EmitMethodTrace(ilGenerator, classFile.Name + "." + m.Name + m.Signature);
+ EmitHelper.Throw(ilGenerator, "java.lang.AbstractMethodError", classFile.Name + "." + m.Name + m.Signature);
}
}
else if(m.IsNative)
@@ -2702,7 +2695,7 @@ sealed class DynamicTypeWrapper : TypeWrapper
try
{
ILGenerator ilGenerator = ((MethodBuilder)mb).GetILGenerator();
- Tracer.EmitMethodTrace(ilGenerator, m.ClassFile.Name + "." + m.Name + m.Signature);
+ Tracer.EmitMethodTrace(ilGenerator, classFile.Name + "." + m.Name + m.Signature);
// do we have a native implementation in map.xml?
if(nativeMethods != null)
{
@@ -2716,7 +2709,7 @@ sealed class DynamicTypeWrapper : TypeWrapper
// see if there exists a NativeCode class for this type
Type nativeCodeType = Type.GetType("NativeCode." + classFile.Name.Replace('$', '+'));
MethodInfo nativeMethod = null;
- TypeWrapper[] args = m.GetArgTypes(wrapper.GetClassLoader());
+ TypeWrapper[] args = methods[i].GetParameters();
if(nativeCodeType != null)
{
TypeWrapper[] nargs = args;
@@ -2775,11 +2768,11 @@ sealed class DynamicTypeWrapper : TypeWrapper
{
if(ClassLoaderWrapper.IsSaveDebugImage)
{
- JniProxyBuilder.Generate(ilGenerator, wrapper, typeBuilder, m, args);
+ JniProxyBuilder.Generate(ilGenerator, wrapper, methods[i], typeBuilder, classFile, m, args);
}
else
{
- JniBuilder.Generate(ilGenerator, wrapper, typeBuilder, m, args);
+ JniBuilder.Generate(ilGenerator, wrapper, methods[i], typeBuilder, classFile, m, args);
}
}
}
@@ -2792,8 +2785,8 @@ sealed class DynamicTypeWrapper : TypeWrapper
else
{
ILGenerator ilGenerator = ((MethodBuilder)mb).GetILGenerator();
- Tracer.EmitMethodTrace(ilGenerator, m.ClassFile.Name + "." + m.Name + m.Signature);
- Compiler.Compile(wrapper, m, ilGenerator);
+ Tracer.EmitMethodTrace(ilGenerator, classFile.Name + "." + m.Name + m.Signature);
+ Compiler.Compile(wrapper, methods[i], classFile, m, ilGenerator);
}
}
}
@@ -2935,7 +2928,7 @@ sealed class DynamicTypeWrapper : TypeWrapper
return n;
}
- internal static void Generate(ILGenerator ilGenerator, TypeWrapper wrapper, TypeBuilder typeBuilder, ClassFile.Method m, TypeWrapper[] args)
+ internal static void Generate(ILGenerator ilGenerator, TypeWrapper wrapper, MethodWrapper mw, TypeBuilder typeBuilder, ClassFile classFile, ClassFile.Method m, TypeWrapper[] args)
{
if(mod == null)
{
@@ -2952,8 +2945,8 @@ sealed class DynamicTypeWrapper : TypeWrapper
{
argTypes[i] = args[i].TypeAsParameterType;
}
- MethodBuilder mb = tb.DefineMethod("method", MethodAttributes.Public | MethodAttributes.Static, m.GetRetType(wrapper.GetClassLoader()).TypeAsParameterType, argTypes);
- JniBuilder.Generate(mb.GetILGenerator(), wrapper, tb, m, args);
+ MethodBuilder mb = tb.DefineMethod("method", MethodAttributes.Public | MethodAttributes.Static, mw.ReturnType.TypeAsParameterType, argTypes);
+ JniBuilder.Generate(mb.GetILGenerator(), wrapper, mw, tb, classFile, m, args);
for(int i = 0; i < argTypes.Length; i++)
{
ilGenerator.Emit(OpCodes.Ldarg, (short)i);
@@ -2971,8 +2964,8 @@ sealed class DynamicTypeWrapper : TypeWrapper
private class JniBuilder
{
- private static readonly Type localRefStructType = JVM.JniProvider.GetLocalRefStructType();
- private static readonly MethodInfo jniFuncPtrMethod = JVM.JniProvider.GetJniFuncPtrMethod();
+ private static readonly Type localRefStructType = typeof(JniFrame);
+ private static readonly MethodInfo jniFuncPtrMethod = localRefStructType.GetMethod("GetFuncPtr");
private static readonly MethodInfo enterLocalRefStruct = localRefStructType.GetMethod("Enter");
private static readonly MethodInfo leaveLocalRefStruct = localRefStructType.GetMethod("Leave");
private static readonly MethodInfo makeLocalRef = localRefStructType.GetMethod("MakeLocalRef");
@@ -2981,27 +2974,29 @@ sealed class DynamicTypeWrapper : TypeWrapper
private static readonly MethodInfo getClassFromType = typeof(NativeCode.java.lang.VMClass).GetMethod("getClassFromType");
private static readonly MethodInfo writeLine = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(object) }, null);
- internal static void Generate(ILGenerator ilGenerator, TypeWrapper wrapper, TypeBuilder typeBuilder, ClassFile.Method m, TypeWrapper[] args)
+ internal static void Generate(ILGenerator ilGenerator, TypeWrapper wrapper, MethodWrapper mw, TypeBuilder typeBuilder, ClassFile classFile, ClassFile.Method m, TypeWrapper[] args)
{
- FieldBuilder methodPtr = typeBuilder.DefineField(m.Name + "$Ptr", typeof(IntPtr), FieldAttributes.Static | FieldAttributes.PrivateScope);
+ FieldBuilder methodPtr = typeBuilder.DefineField("jniptr/" + m.Name + m.Signature, typeof(IntPtr), FieldAttributes.Static | FieldAttributes.PrivateScope);
LocalBuilder localRefStruct = ilGenerator.DeclareLocal(localRefStructType);
ilGenerator.Emit(OpCodes.Ldloca, localRefStruct);
ilGenerator.Emit(OpCodes.Initobj, localRefStructType);
ilGenerator.Emit(OpCodes.Ldsfld, methodPtr);
Label oklabel = ilGenerator.DefineLabel();
ilGenerator.Emit(OpCodes.Brtrue, oklabel);
+ ilGenerator.Emit(OpCodes.Ldtoken, (MethodInfo)mw.GetMethod());
+ ilGenerator.Emit(OpCodes.Ldstr, classFile.Name.Replace('.', '/'));
ilGenerator.Emit(OpCodes.Ldstr, m.Name);
ilGenerator.Emit(OpCodes.Ldstr, m.Signature.Replace('.', '/'));
- ilGenerator.Emit(OpCodes.Ldstr, m.ClassFile.Name.Replace('.', '/'));
ilGenerator.Emit(OpCodes.Call, jniFuncPtrMethod);
ilGenerator.Emit(OpCodes.Stsfld, methodPtr);
ilGenerator.MarkLabel(oklabel);
ilGenerator.Emit(OpCodes.Ldloca, localRefStruct);
+ ilGenerator.Emit(OpCodes.Ldtoken, (MethodInfo)mw.GetMethod());
ilGenerator.Emit(OpCodes.Call, enterLocalRefStruct);
LocalBuilder jnienv = ilGenerator.DeclareLocal(typeof(IntPtr));
ilGenerator.Emit(OpCodes.Stloc, jnienv);
Label tryBlock = ilGenerator.BeginExceptionBlock();
- TypeWrapper retTypeWrapper = m.GetRetType(wrapper.GetClassLoader());
+ TypeWrapper retTypeWrapper = mw.ReturnType;
if(!retTypeWrapper.IsPrimitive)
{
// this one is for use after we return from "calli"
@@ -3188,7 +3183,8 @@ sealed class DynamicTypeWrapper : TypeWrapper
FieldBuilder field;
ClassFile.Field fld = classFile.Fields[i];
string fieldName = fld.Name;
- TypeWrapper typeWrapper = fld.GetFieldType(wrapper.GetClassLoader());
+ // TODO we're not allowed to load types here (potentially), it needs to be done in the Link step
+ TypeWrapper typeWrapper = ClassFile.FieldTypeWrapperFromSig(wrapper.GetClassLoader(), classCache, fld.Signature);
Type type = typeWrapper.TypeAsFieldType;
bool setNameSig = typeWrapper.IsUnloadable || typeWrapper.IsGhostArray;
if(setNameSig)
@@ -3236,7 +3232,7 @@ sealed class DynamicTypeWrapper : TypeWrapper
attribs |= FieldAttributes.Literal;
field = typeBuilder.DefineField(fieldName, type, attribs);
field.SetConstant(constantValue);
- fields[i] = new FieldWrapper.ConstantFieldWrapper(wrapper, fld.GetFieldType(wrapper.GetClassLoader()), fld.Name, fld.Signature, fld.Modifiers, field, constantValue);
+ fields[i] = new FieldWrapper.ConstantFieldWrapper(wrapper, typeWrapper, fld.Name, fld.Signature, fld.Modifiers, field, constantValue);
}
else
{
@@ -3244,7 +3240,8 @@ sealed class DynamicTypeWrapper : TypeWrapper
if(isWrappedFinal)
{
// NOTE public/protected blank final fields get converted into a read-only property with a private field
- // backing store we used to make the field privatescope, but that really serves no purpose (and it hinders
+ // backing store
+ // we used to make the field privatescope, but that really serves no purpose (and it hinders
// serialization, which uses .NET reflection to get at the field)
attribs &= ~FieldAttributes.FieldAccessMask;
attribs |= FieldAttributes.Private;
@@ -3302,11 +3299,11 @@ sealed class DynamicTypeWrapper : TypeWrapper
{
emitSet += CodeEmitter.Create(OpCodes.Stfld, field);
}
- fields[i] = FieldWrapper.Create1(wrapper, fld.GetFieldType(wrapper.GetClassLoader()), fld.Name, fld.Signature, fld.Modifiers, field, emitGet, emitSet);
+ fields[i] = FieldWrapper.Create1(wrapper, typeWrapper, fld.Name, fld.Signature, fld.Modifiers, field, emitGet, emitSet);
}
else
{
- fields[i] = FieldWrapper.Create3(wrapper, fld.GetFieldType(wrapper.GetClassLoader()), field, fld.Signature, fld.Modifiers);
+ fields[i] = FieldWrapper.Create3(wrapper, typeWrapper, field, fld.Signature, fld.Modifiers);
}
}
// if the Java modifiers cannot be expressed in .NET, we emit the Modifiers attribute to store
@@ -3337,7 +3334,7 @@ sealed class DynamicTypeWrapper : TypeWrapper
{
// We create a field that the derived classes can access in their .cctor to trigger our .cctor
// (previously we used RuntimeHelpers.RunClassConstructor, but that is slow and requires additional privileges)
- FieldBuilder field = typeBuilder.DefineField("__<clinit>", typeof(int), FieldAttributes.SpecialName | FieldAttributes.Public | FieldAttributes.Static);
+ FieldBuilder field = typeBuilder.DefineField("__<clinit>", typeof(int), FieldAttributes.SpecialName | FieldAttributes.Family | FieldAttributes.Static);
AttributeHelper.HideFromJava(field);
}
if(typeBuilder.IsInterface)
@@ -3500,7 +3497,7 @@ sealed class DynamicTypeWrapper : TypeWrapper
// only if the classfile is abstract, we make the CLR method abstract, otherwise,
// we have to generate a method that throws an AbstractMethodError (because the JVM
// allows abstract methods in non-abstract classes)
- if(m.ClassFile.IsAbstract || m.ClassFile.IsInterface)
+ if(classFile.IsAbstract || classFile.IsInterface)
{
attribs |= MethodAttributes.Abstract;
}
@@ -3685,40 +3682,37 @@ sealed class DynamicTypeWrapper : TypeWrapper
private static ParameterBuilder[] AddParameterNames(MethodBase mb, ClassFile.Method m)
{
- if(m.CodeAttribute != null)
+ ClassFile.Method.LocalVariableTableEntry[] localVars = m.LocalVariableTableAttribute;
+ if(localVars != null)
{
- ClassFile.Method.LocalVariableTableEntry[] localVars = m.CodeAttribute.LocalVariableTableAttribute;
- if(localVars != null)
+ int bias = 1;
+ if(m.IsStatic)
{
- int bias = 1;
- if(m.IsStatic)
- {
- bias = 0;
- }
- ParameterBuilder[] parameterBuilders = new ParameterBuilder[m.CodeAttribute.ArgMap.Length - bias];
- for(int i = bias; i < m.CodeAttribute.ArgMap.Length; i++)
+ bias = 0;
+ }
+ ParameterBuilder[] parameterBuilders = new ParameterBuilder[m.ArgMap.Length - bias];
+ for(int i = bias; i < m.ArgMap.Length; i++)
+ {
+ if(m.ArgMap[i] != -1)
{
- if(m.CodeAttribute.ArgMap[i] != -1)
+ for(int j = 0; j < localVars.Length; j++)
{
- for(int j = 0; j < localVars.Length; j++)
+ if(localVars[j].index == i && parameterBuilders[i - bias] == null)
{
- if(localVars[j].index == i && parameterBuilders[i - bias] == null)
+ if(mb is MethodBuilder)
{
- if(mb is MethodBuilder)
- {
- parameterBuilders[i - bias] = ((MethodBuilder)mb).DefineParameter(m.CodeAttribute.ArgMap[i] + 1 - bias, ParameterAttributes.None, localVars[j].name);
- }
- else if(mb is ConstructorBuilder)
- {
- parameterBuilders[i - bias] = ((ConstructorBuilder)mb).DefineParameter(m.CodeAttribute.ArgMap[i], ParameterAttributes.None, localVars[j].name);
- }
- break;
+ parameterBuilders[i - bias] = ((MethodBuilder)mb).DefineParameter(m.ArgMap[i] + 1 - bias, ParameterAttributes.None, localVars[j].name);
}
+ else if(mb is ConstructorBuilder)
+ {
+ parameterBuilders[i - bias] = ((ConstructorBuilder)mb).DefineParameter(m.ArgMap[i], ParameterAttributes.None, localVars[j].name);
+ }
+ break;
}
}
}
- return parameterBuilders;
}
+ return parameterBuilders;
}
return null;
}
diff --git a/runtime/classpath.cs b/runtime/classpath.cs
index 389b2464..500f23fe 100644
--- a/runtime/classpath.cs
+++ b/runtime/classpath.cs
@@ -409,8 +409,7 @@ namespace NativeCode.java
public static int nativeLoad(string filename)
{
- // TODO native libraries somehow need to be scoped by class loader
- return JVM.JniProvider.LoadNativeLibrary(filename);
+ return JniHelper.LoadLibrary(filename);
}
}
@@ -532,7 +531,7 @@ namespace NativeCode.java
try
{
// TODO I doubt that this is correct
- return double.Parse(s);
+ return double.Parse(s, System.Globalization.CultureInfo.InvariantCulture);
}
catch(FormatException x)
{
@@ -788,21 +787,11 @@ namespace NativeCode.java
}
}
- public static bool isWordsBigEndian()
- {
- return !BitConverter.IsLittleEndian;
- }
-
- public static long currentTimeMillis()
- {
- const long january_1st_1970 = 62135596800000L;
- return DateTime.UtcNow.Ticks / 10000L - january_1st_1970;
- }
-
public static void setErr(object printStream)
{
TypeWrapper tw = ClassLoaderWrapper.LoadClassCritical("java.lang.System");
FieldWrapper fw = tw.GetFieldWrapper("err", ClassLoaderWrapper.LoadClassCritical("java.io.PrintStream"));
+ fw.SetValue(null, printStream);
}
public static void setIn(object inputStream)
@@ -818,11 +807,6 @@ namespace NativeCode.java
FieldWrapper fw = tw.GetFieldWrapper("out", ClassLoaderWrapper.LoadClassCritical("java.io.PrintStream"));
fw.SetValue(null, printStream);
}
-
- public static int identityHashCode(object o)
- {
- return RuntimeHelpers.GetHashCode(o);
- }
}
public class VMClassLoader
@@ -914,7 +898,7 @@ namespace NativeCode.java
{
try
{
- ClassFile classFile = new ClassFile(data, offset, length, name);
+ ClassFile classFile = new ClassFile(data, offset, length, name, false);
if(name != null && classFile.Name != name)
{
throw new NoClassDefFoundError(name + " (wrong name: " + classFile.Name + ")");
@@ -1511,7 +1495,28 @@ namespace NativeCode.java
int hours = timeSpan.Hours;
int mins = timeSpan.Minutes;
- return "GMT" + hours + ":" + mins;
+ if(mins != 0)
+ {
+ if(hours < 0)
+ {
+ return "GMT+" + ((-hours) * 60 + mins);
+ }
+ else
+ {
+ return "GMT-" + (hours * 60 + mins);
+ }
+ }
+ else
+ {
+ if(hours < 0)
+ {
+ return "GMT+" + (-hours);
+ }
+ else
+ {
+ return "GMT-" + (hours + mins);
+ }
+ }
}
}
}
diff --git a/runtime/compiler.cs b/runtime/compiler.cs
index 103fc196..7ce2565f 100644
--- a/runtime/compiler.cs
+++ b/runtime/compiler.cs
@@ -56,7 +56,9 @@ class Compiler
private static TypeWrapper java_lang_Throwable;
private static TypeWrapper java_lang_ThreadDeath;
private TypeWrapper clazz;
- private ClassFile.Method.Code m;
+ private MethodWrapper mw;
+ private ClassFile classFile;
+ private ClassFile.Method m;
private ILGenerator ilGenerator;
private ClassLoaderWrapper classLoader;
private MethodAnalyzer ma;
@@ -122,9 +124,11 @@ class Compiler
}
}
- private Compiler(TypeWrapper clazz, ClassFile.Method.Code m, ILGenerator ilGenerator, ClassLoaderWrapper classLoader, ISymbolDocumentWriter symboldocument)
+ private Compiler(TypeWrapper clazz, MethodWrapper mw, ClassFile classFile, ClassFile.Method m, ILGenerator ilGenerator, ClassLoaderWrapper classLoader, ISymbolDocumentWriter symboldocument)
{
this.clazz = clazz;
+ this.mw = mw;
+ this.classFile = classFile;
this.m = m;
this.ilGenerator = ilGenerator;
this.classLoader = classLoader;
@@ -133,14 +137,14 @@ class Compiler
Profiler.Enter("MethodAnalyzer");
try
{
- ma = new MethodAnalyzer(clazz, m, classLoader);
+ ma = new MethodAnalyzer(clazz, mw, classFile, m, classLoader);
}
finally
{
Profiler.Leave("MethodAnalyzer");
}
- TypeWrapper[] args = m.Method.GetArgTypes(classLoader);
+ TypeWrapper[] args = mw.GetParameters();
LocalVar[] locals = ma.GetAllLocalVars();
foreach(LocalVar v in locals)
{
@@ -148,7 +152,7 @@ class Compiler
{
int arg = m.ArgMap[v.local];
TypeWrapper tw;
- if(m.Method.IsStatic)
+ if(m.IsStatic)
{
tw = args[arg];
}
@@ -287,9 +291,9 @@ class Compiler
{
case NormalizedByteCode.__lookupswitch:
// start at -1 to have an opportunity to handle the default offset
- for(int k = -1; k < m.Instructions[j].Values.Length; k++)
+ for(int k = -1; k < m.Instructions[j].SwitchEntryCount; k++)
{
- int targetPC = m.Instructions[j].PC + (k == -1 ? m.Instructions[j].DefaultOffset : m.Instructions[j].TargetOffsets[k]);
+ int targetPC = m.Instructions[j].PC + (k == -1 ? m.Instructions[j].DefaultOffset : m.Instructions[j].GetSwitchTargetOffset(k));
if(ei.start_pc < targetPC && targetPC < ei.end_pc)
{
ExceptionTableEntry en = new ExceptionTableEntry();
@@ -378,7 +382,7 @@ class Compiler
// we run finally blocks when a thread is killed.
if(ei.catch_type != 0)
{
- TypeWrapper exceptionType = m.Method.ClassFile.GetConstantPoolClassType(ei.catch_type, classLoader);
+ TypeWrapper exceptionType = classFile.GetConstantPoolClassType(ei.catch_type);
if(!exceptionType.IsUnloadable && !java_lang_ThreadDeath.IsAssignableTo(exceptionType))
{
int start = FindPcIndex(ei.start_pc);
@@ -457,9 +461,9 @@ class Compiler
this.type = type;
}
- internal void Emit(ILGenerator ilgen, ClassFile.Method m)
+ internal void Emit(ILGenerator ilgen, ClassFile classFile, ClassFile.Method m)
{
- Tracer.Warning(Tracer.Compiler, "{0}: {1}\n\tat {2}.{3}{4}", type.Name, Message, m.ClassFile.Name, m.Name, m.Signature);
+ Tracer.Warning(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);
method.Link();
@@ -661,13 +665,13 @@ class Compiler
}
}
- internal static void Compile(TypeWrapper clazz, ClassFile.Method m, ILGenerator ilGenerator)
+ internal static void Compile(TypeWrapper clazz, MethodWrapper mw, ClassFile classFile, ClassFile.Method m, ILGenerator ilGenerator)
{
ClassLoaderWrapper classLoader = clazz.GetClassLoader();
ISymbolDocumentWriter symboldocument = null;
if(JVM.Debug)
{
- string sourcefile = m.ClassFile.SourceFileAttribute;
+ string sourcefile = classFile.SourceFileAttribute;
if(sourcefile != null)
{
if(JVM.SourcePath != null)
@@ -677,7 +681,7 @@ class Compiler
symboldocument = classLoader.ModuleBuilder.DefineDocument(sourcefile, SymLanguageType.Java, Guid.Empty, SymDocumentType.Text);
// the very first instruction in the method must have an associated line number, to be able
// to step into the method in Visual Studio .NET
- ClassFile.Method.LineNumberTableEntry[] table = m.CodeAttribute.LineNumberTableAttribute;
+ ClassFile.Method.LineNumberTableEntry[] table = m.LineNumberTableAttribute;
if(table != null)
{
int firstPC = int.MaxValue;
@@ -697,7 +701,7 @@ class Compiler
}
}
}
- TypeWrapper[] args= m.GetArgTypes(classLoader);
+ TypeWrapper[] args = mw.GetParameters();
for(int i = 0; i < args.Length; i++)
{
if(args[i].IsUnloadable)
@@ -716,7 +720,7 @@ class Compiler
Profiler.Enter("new Compiler");
try
{
- c = new Compiler(clazz, m.CodeAttribute, ilGenerator, classLoader, symboldocument);
+ c = new Compiler(clazz, mw, classFile, m, ilGenerator, classLoader, symboldocument);
}
finally
{
@@ -986,7 +990,7 @@ class Compiler
private void CheckLoaderConstraints(ClassFile.ConstantPoolItemFieldref cpi, FieldWrapper fw)
{
- if(cpi.GetFieldType(classLoader) != fw.FieldTypeWrapper && !fw.FieldTypeWrapper.IsUnloadable)
+ if(cpi.GetFieldType() != fw.FieldTypeWrapper && !fw.FieldTypeWrapper.IsUnloadable)
{
throw new LinkageError("Loader constraints violated: " + fw.Name);
}
@@ -994,11 +998,11 @@ class Compiler
private void CheckLoaderConstraints(ClassFile.ConstantPoolItemMI cpi, MethodWrapper mw)
{
- if(cpi.GetRetType(classLoader) != mw.ReturnType && !mw.ReturnType.IsUnloadable)
+ if(cpi.GetRetType() != mw.ReturnType && !mw.ReturnType.IsUnloadable)
{
throw new LinkageError("Loader constraints violated: " + mw.Name + mw.Signature);
}
- TypeWrapper[] here = cpi.GetArgTypes(classLoader);
+ TypeWrapper[] here = cpi.GetArgTypes();
TypeWrapper[] there = mw.GetParameters();
for(int i = 0; i < here.Length; i++)
{
@@ -1091,7 +1095,7 @@ class Compiler
}
else
{
- exceptionTypeWrapper = m.Method.ClassFile.GetConstantPoolClassType(exc.catch_type, classLoader);
+ exceptionTypeWrapper = classFile.GetConstantPoolClassType(exc.catch_type);
}
Type excType = exceptionTypeWrapper.TypeAsExceptionType;
bool mapSafe = !exceptionTypeWrapper.IsUnloadable && !exceptionTypeWrapper.IsMapUnsafeException;
@@ -1299,28 +1303,27 @@ class Compiler
break;
case NormalizedByteCode.__ldc:
{
- ClassFile cf = instr.MethodCode.Method.ClassFile;
int constant = instr.Arg1;
- switch(cf.GetConstantPoolConstantType(constant))
+ switch(classFile.GetConstantPoolConstantType(constant))
{
case ClassFile.ConstantType.Double:
- ilGenerator.Emit(OpCodes.Ldc_R8, cf.GetConstantPoolConstantDouble(constant));
+ ilGenerator.Emit(OpCodes.Ldc_R8, classFile.GetConstantPoolConstantDouble(constant));
break;
case ClassFile.ConstantType.Float:
- ilGenerator.Emit(OpCodes.Ldc_R4, cf.GetConstantPoolConstantFloat(constant));
+ ilGenerator.Emit(OpCodes.Ldc_R4, classFile.GetConstantPoolConstantFloat(constant));
break;
case ClassFile.ConstantType.Integer:
- EmitLdc_I4(cf.GetConstantPoolConstantInteger(constant));
+ EmitLdc_I4(classFile.GetConstantPoolConstantInteger(constant));
break;
case ClassFile.ConstantType.Long:
- ilGenerator.Emit(OpCodes.Ldc_I8, cf.GetConstantPoolConstantLong(constant));
+ ilGenerator.Emit(OpCodes.Ldc_I8, classFile.GetConstantPoolConstantLong(constant));
break;
case ClassFile.ConstantType.String:
- ilGenerator.Emit(OpCodes.Ldstr, cf.GetConstantPoolConstantString(constant));
+ ilGenerator.Emit(OpCodes.Ldstr, classFile.GetConstantPoolConstantString(constant));
break;
case ClassFile.ConstantType.Class:
{
- TypeWrapper tw = cf.GetConstantPoolClassType(constant, classLoader);
+ TypeWrapper tw = classFile.GetConstantPoolClassType(constant);
if(tw.IsUnloadable)
{
Profiler.Count("EmitDynamicClassLiteral");
@@ -1344,13 +1347,13 @@ class Compiler
}
case NormalizedByteCode.__invokestatic:
{
- ClassFile.ConstantPoolItemMI cpi = m.Method.ClassFile.GetMethodref(instr.Arg1);
+ ClassFile.ConstantPoolItemMI cpi = classFile.GetMethodref(instr.Arg1);
// HACK special case for calls to System.arraycopy, if the array arguments on the stack
// are of a known array type, we can redirect to an optimized version of arraycopy.
if(cpi.Class == "java.lang.System" &&
cpi.Name == "arraycopy" &&
cpi.Signature == "(Ljava.lang.Object;ILjava.lang.Object;II)V" &&
- cpi.GetClassType(classLoader).GetClassLoader() == ClassLoaderWrapper.GetBootstrapClassLoader())
+ cpi.GetClassType().GetClassLoader() == ClassLoaderWrapper.GetBootstrapClassLoader())
{
TypeWrapper t1 = ma.GetRawStackTypeWrapper(i, 2);
TypeWrapper t2 = ma.GetRawStackTypeWrapper(i, 4);
@@ -1384,7 +1387,7 @@ class Compiler
MethodWrapper method = GetMethodCallEmitter(cpi, null, NormalizedByteCode.__invokestatic);
// if the stack values don't match the argument types (for interface argument types)
// we must emit code to cast the stack value to the interface type
- CastInterfaceArgs(method, cpi.GetArgTypes(classLoader), i, false, false);
+ CastInterfaceArgs(method, cpi.GetArgTypes(), i, false, false);
method.EmitCall(ilGenerator);
break;
}
@@ -1392,10 +1395,10 @@ class Compiler
case NormalizedByteCode.__invokeinterface:
case NormalizedByteCode.__invokespecial:
{
- ClassFile.ConstantPoolItemMI cpi = m.Method.ClassFile.GetMethodref(instr.Arg1);
- int argcount = cpi.GetArgTypes(classLoader).Length;
+ ClassFile.ConstantPoolItemMI cpi = classFile.GetMethodref(instr.Arg1);
+ int argcount = cpi.GetArgTypes().Length;
TypeWrapper type = ma.GetRawStackTypeWrapper(i, argcount);
- TypeWrapper thisType = SigTypeToClassName(type, cpi.GetClassType(classLoader));
+ TypeWrapper thisType = SigTypeToClassName(type, cpi.GetClassType());
MethodWrapper method = GetMethodCallEmitter(cpi, thisType, instr.NormalizedOpCode);
@@ -1403,18 +1406,18 @@ class Compiler
// we must emit code to cast the stack value to the interface type
if(instr.NormalizedOpCode == NormalizedByteCode.__invokespecial && cpi.Name == "<init>" && VerifierTypeWrapper.IsNew(type))
{
- TypeWrapper[] args = cpi.GetArgTypes(classLoader);
+ TypeWrapper[] args = cpi.GetArgTypes();
CastInterfaceArgs(method, args, i, false, false);
}
else
{
// the this reference is included in the argument list because it may also need to be cast
- TypeWrapper[] methodArgs = cpi.GetArgTypes(classLoader);
+ TypeWrapper[] methodArgs = cpi.GetArgTypes();
TypeWrapper[] args = new TypeWrapper[methodArgs.Length + 1];
methodArgs.CopyTo(args, 1);
if(instr.NormalizedOpCode == NormalizedByteCode.__invokeinterface)
{
- args[0] = cpi.GetClassType(classLoader);
+ args[0] = cpi.GetClassType();
}
else
{
@@ -1586,7 +1589,7 @@ class Compiler
LocalBuilder local = null;
if(instr.NormalizedOpCode != NormalizedByteCode.__return)
{
- TypeWrapper retTypeWrapper = m.Method.GetRetType(classLoader);
+ TypeWrapper retTypeWrapper = mw.ReturnType;
retTypeWrapper.EmitConvStackToParameterType(ilGenerator, ma.GetRawStackTypeWrapper(i, 0));
if(ma.GetRawStackTypeWrapper(i, 0).IsUnloadable)
{
@@ -1615,7 +1618,7 @@ class Compiler
}
else
{
- TypeWrapper retTypeWrapper = m.Method.GetRetType(classLoader);
+ TypeWrapper retTypeWrapper = mw.ReturnType;
retTypeWrapper.EmitConvStackToParameterType(ilGenerator, ma.GetRawStackTypeWrapper(i, 0));
if(ma.GetRawStackTypeWrapper(i, 0).IsUnloadable)
{
@@ -1706,7 +1709,7 @@ class Compiler
break;
case NormalizedByteCode.__new:
{
- TypeWrapper wrapper = instr.MethodCode.Method.ClassFile.GetConstantPoolClassType(instr.Arg1, classLoader);
+ TypeWrapper wrapper = classFile.GetConstantPoolClassType(instr.Arg1);
if(wrapper.IsUnloadable)
{
Profiler.Count("EmitDynamicNewCheckOnly");
@@ -1742,7 +1745,7 @@ class Compiler
ilGenerator.Emit(OpCodes.Ldloc, localInt);
ilGenerator.Emit(OpCodes.Stelem_I4);
}
- TypeWrapper wrapper = instr.MethodCode.Method.ClassFile.GetConstantPoolClassType(instr.Arg1, classLoader);
+ TypeWrapper wrapper = classFile.GetConstantPoolClassType(instr.Arg1);
if(wrapper.IsUnloadable)
{
Profiler.Count("EmitDynamicMultianewarray");
@@ -1767,7 +1770,7 @@ class Compiler
}
case NormalizedByteCode.__anewarray:
{
- TypeWrapper wrapper = instr.MethodCode.Method.ClassFile.GetConstantPoolClassType(instr.Arg1, classLoader);
+ TypeWrapper wrapper = classFile.GetConstantPoolClassType(instr.Arg1);
if(wrapper.IsUnloadable)
{
Profiler.Count("EmitDynamicNewarray");
@@ -1829,7 +1832,7 @@ class Compiler
break;
case NormalizedByteCode.__checkcast:
{
- TypeWrapper wrapper = instr.MethodCode.Method.ClassFile.GetConstantPoolClassType(instr.Arg1, classLoader);
+ TypeWrapper wrapper = classFile.GetConstantPoolClassType(instr.Arg1);
if(!wrapper.IsUnloadable && !wrapper.IsAccessibleFrom(clazz))
{
throw new IllegalAccessError("Try to access class " + wrapper.Name + " from class " + clazz.Name);
@@ -1839,7 +1842,7 @@ class Compiler
}
case NormalizedByteCode.__instanceof:
{
- TypeWrapper wrapper = instr.MethodCode.Method.ClassFile.GetConstantPoolClassType(instr.Arg1, classLoader);
+ TypeWrapper wrapper = classFile.GetConstantPoolClassType(instr.Arg1);
if(!wrapper.IsUnloadable && !wrapper.IsAccessibleFrom(clazz))
{
throw new IllegalAccessError("Try to access class " + wrapper.Name + " from class " + clazz.Name);
@@ -2476,14 +2479,14 @@ class Compiler
break;
case NormalizedByteCode.__lookupswitch:
// TODO use OpCodes.Switch
- for(int j = 0; j < instr.Values.Length; j++)
+ for(int j = 0; j < instr.SwitchEntryCount; j++)
{
ilGenerator.Emit(OpCodes.Dup);
- EmitLdc_I4(instr.Values[j]);
+ 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.TargetOffsets[j]));
+ ilGenerator.Emit(OpCodes.Br, block.GetLabel(instr.PC + instr.GetSwitchTargetOffset(j)));
ilGenerator.MarkLabel(label);
}
ilGenerator.Emit(OpCodes.Pop);
@@ -2598,7 +2601,7 @@ class Compiler
}
catch(EmitException x)
{
- x.Emit(ilGenerator, m.Method);
+ x.Emit(ilGenerator, classFile, m);
// mark the next instruction as not forward reachable,
// this will cause the stack to be loaded from locals
// (which is needed for the code to be verifiable)
@@ -2781,12 +2784,12 @@ class Compiler
private void GetPutField(Instruction instr, int i)
{
NormalizedByteCode bytecode = instr.NormalizedOpCode;
- ClassFile.ConstantPoolItemFieldref cpi = m.Method.ClassFile.GetFieldref(instr.Arg1);
+ ClassFile.ConstantPoolItemFieldref cpi = classFile.GetFieldref(instr.Arg1);
bool write = (bytecode == NormalizedByteCode.__putfield || bytecode == NormalizedByteCode.__putstatic);
- TypeWrapper wrapper = cpi.GetClassType(classLoader);
+ TypeWrapper wrapper = cpi.GetClassType();
if(wrapper.IsUnloadable)
{
- TypeWrapper fieldTypeWrapper = cpi.GetFieldType(classLoader);
+ TypeWrapper fieldTypeWrapper = cpi.GetFieldType();
if(write && !fieldTypeWrapper.IsUnloadable && fieldTypeWrapper.IsPrimitive)
{
ilGenerator.Emit(OpCodes.Box, fieldTypeWrapper.TypeAsTBD);
@@ -2827,11 +2830,11 @@ class Compiler
TypeWrapper thisType = null;
if(bytecode == NormalizedByteCode.__getfield)
{
- thisType = SigTypeToClassName(ma.GetRawStackTypeWrapper(i, 0), cpi.GetClassType(classLoader));
+ thisType = SigTypeToClassName(ma.GetRawStackTypeWrapper(i, 0), cpi.GetClassType());
}
else if(bytecode == NormalizedByteCode.__putfield)
{
- thisType = SigTypeToClassName(ma.GetRawStackTypeWrapper(i, 1), cpi.GetClassType(classLoader));
+ thisType = SigTypeToClassName(ma.GetRawStackTypeWrapper(i, 1), cpi.GetClassType());
}
bool isStatic = (bytecode == NormalizedByteCode.__putstatic || bytecode == NormalizedByteCode.__getstatic);
FieldWrapper field = cpi.GetField(); //wrapper.GetFieldWrapper(cpi.Name, cpi.GetFieldType(classLoader));
@@ -2925,23 +2928,23 @@ class Compiler
internal override void EmitCall(ILGenerator ilgen)
{
- Emit(dynamicInvokestatic, ilgen, cpi.GetRetType(classLoader));
+ Emit(dynamicInvokestatic, ilgen, cpi.GetRetType());
}
internal override void EmitCallvirt(ILGenerator ilgen)
{
- Emit(dynamicInvokevirtual, ilgen, cpi.GetRetType(classLoader));
+ Emit(dynamicInvokevirtual, ilgen, cpi.GetRetType());
}
internal override void EmitNewobj(ILGenerator ilgen)
{
- Emit(dynamicInvokeSpecialNew, ilgen, cpi.GetClassType(classLoader));
+ Emit(dynamicInvokeSpecialNew, ilgen, cpi.GetClassType());
}
private void Emit(MethodInfo helperMethod, ILGenerator ilGenerator, TypeWrapper retTypeWrapper)
{
Profiler.Count("EmitDynamicInvokeEmitter");
- TypeWrapper[] args = cpi.GetArgTypes(classLoader);
+ TypeWrapper[] args = cpi.GetArgTypes();
LocalBuilder argarray = ilGenerator.DeclareLocal(typeof(object[]));
LocalBuilder val = ilGenerator.DeclareLocal(typeof(object));
ilGenerator.Emit(OpCodes.Ldc_I4, args.Length);
@@ -2971,7 +2974,7 @@ class Compiler
private MethodWrapper GetMethodCallEmitter(ClassFile.ConstantPoolItemMI cpi, TypeWrapper thisType, NormalizedByteCode invoke)
{
- TypeWrapper wrapper = cpi.GetClassType(classLoader);
+ TypeWrapper wrapper = cpi.GetClassType();
if(wrapper.IsUnloadable || (thisType != null && thisType.IsUnloadable))
{
return new DynamicMethodWrapper(classLoader, clazz, cpi);
@@ -3149,11 +3152,11 @@ class Compiler
private bool IsUnloadable(ClassFile.ConstantPoolItemMI cpi)
{
- if(cpi.GetClassType(classLoader).IsUnloadable || cpi.GetRetType(classLoader).IsUnloadable)
+ if(cpi.GetClassType().IsUnloadable || cpi.GetRetType().IsUnloadable)
{
return true;
}
- TypeWrapper[] args = cpi.GetArgTypes(classLoader);
+ TypeWrapper[] args = cpi.GetArgTypes();
for(int i = 0; i < args.Length; i++)
{
if(args[i].IsUnloadable)
diff --git a/runtime/runtime.build b/runtime/runtime.build
index ee1536d5..f839a04f 100644
--- a/runtime/runtime.build
+++ b/runtime/runtime.build
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<project name="IKVM.Runtime" default="IKVM.Runtime">
<target name="IKVM.Runtime">
- <csc target="library" output="../bin/IKVM.Runtime.dll" define="TRACE" optimize="true">
+ <csc target="library" output="../bin/IKVM.Runtime.dll" define="TRACE" optimize="true" unsafe="true">
<sources>
<includes name="*.cs" />
</sources>
diff --git a/runtime/verifier.cs b/runtime/verifier.cs
index 5105a743..10ecb9fe 100644
--- a/runtime/verifier.cs
+++ b/runtime/verifier.cs
@@ -1051,7 +1051,7 @@ class LocalVar
internal int start_pc;
internal int end_pc;
- internal void FindLvtEntry(ClassFile.Method.Code method, int instructionIndex)
+ internal void FindLvtEntry(ClassFile.Method method, int instructionIndex)
{
ClassFile.Method.LocalVariableTableEntry[] lvt = method.LocalVariableTableAttribute;
if(lvt != null)
@@ -1087,7 +1087,8 @@ class MethodAnalyzer
private static TypeWrapper DoubleArrayType;
private static TypeWrapper LongArrayType;
private ClassLoaderWrapper classLoader;
- private ClassFile.Method.Code method;
+ private ClassFile classFile;
+ private ClassFile.Method method;
private InstructionState[] state;
private ArrayList[] callsites;
private LocalVar[/*instructionIndex*/] localVars;
@@ -1106,9 +1107,10 @@ class MethodAnalyzer
LongArrayType = PrimitiveTypeWrapper.LONG.MakeArrayType(1);
}
- internal MethodAnalyzer(TypeWrapper wrapper, ClassFile.Method.Code method, ClassLoaderWrapper classLoader)
+ internal MethodAnalyzer(TypeWrapper wrapper, MethodWrapper mw, ClassFile classFile, ClassFile.Method method, ClassLoaderWrapper classLoader)
{
this.classLoader = classLoader;
+ this.classFile = classFile;
this.method = method;
state = new InstructionState[method.Instructions.Length];
callsites = new ArrayList[method.Instructions.Length];
@@ -1124,10 +1126,10 @@ class MethodAnalyzer
// start by computing the initial state, the stack is empty and the locals contain the arguments
state[0] = new InstructionState(method.MaxLocals, method.MaxStack);
int firstNonArgLocalIndex = 0;
- if(!method.Method.IsStatic)
+ if(!method.IsStatic)
{
// this reference. If we're a constructor, the this reference is uninitialized.
- if(method.Method.Name == "<init>")
+ if(method.Name == "<init>")
{
state[0].SetLocalType(firstNonArgLocalIndex++, VerifierTypeWrapper.UninitializedThis, -1);
}
@@ -1136,7 +1138,7 @@ class MethodAnalyzer
state[0].SetLocalType(firstNonArgLocalIndex++, wrapper, -1);
}
}
- TypeWrapper[] argTypeWrappers = method.Method.GetArgTypes(classLoader);
+ TypeWrapper[] argTypeWrappers = mw.GetParameters();
for(int i = 0; i < argTypeWrappers.Length; i++)
{
TypeWrapper type = argTypeWrappers[i];
@@ -1157,10 +1159,11 @@ class MethodAnalyzer
}
InstructionState s = state[0].Copy();
bool done = false;
+ ClassFile.Method.Instruction[] instructions = method.Instructions;
while(!done)
{
done = true;
- for(int i = 0; i < method.Instructions.Length; i++)
+ for(int i = 0; i < instructions.Length; i++)
{
if(state[i] != null && state[i].changed)
{
@@ -1172,7 +1175,7 @@ class MethodAnalyzer
// mark the exception handlers reachable from this instruction
for(int j = 0; j < method.ExceptionTable.Length; j++)
{
- if(method.ExceptionTable[j].start_pc <= method.Instructions[i].PC && method.ExceptionTable[j].end_pc > method.Instructions[i].PC)
+ if(method.ExceptionTable[j].start_pc <= instructions[i].PC && method.ExceptionTable[j].end_pc > instructions[i].PC)
{
// NOTE this used to be CopyLocalsAndSubroutines, but it doesn't (always) make
// sense to copy the subroutine state
@@ -1198,7 +1201,7 @@ class MethodAnalyzer
}
}
state[i].CopyTo(s);
- ClassFile.Method.Instruction instr = method.Instructions[i];
+ ClassFile.Method.Instruction instr = instructions[i];
switch(instr.NormalizedOpCode)
{
case NormalizedByteCode.__aload:
@@ -1378,17 +1381,17 @@ class MethodAnalyzer
s.PopObjectType();
break;
case NormalizedByteCode.__getstatic:
- s.PushType((GetFieldref(instr.Arg1)).GetFieldType(classLoader));
+ s.PushType((GetFieldref(instr.Arg1)).GetFieldType());
break;
case NormalizedByteCode.__putstatic:
- s.PopType(GetFieldref(instr.Arg1).GetFieldType(classLoader));
+ s.PopType(GetFieldref(instr.Arg1).GetFieldType());
break;
case NormalizedByteCode.__getfield:
- s.PopObjectType(GetFieldref(instr.Arg1).GetClassType(classLoader));
- s.PushType(GetFieldref(instr.Arg1).GetFieldType(classLoader));
+ s.PopObjectType(GetFieldref(instr.Arg1).GetClassType());
+ s.PushType(GetFieldref(instr.Arg1).GetFieldType());
break;
case NormalizedByteCode.__putfield:
- s.PopType(GetFieldref(instr.Arg1).GetFieldType(classLoader));
+ s.PopType(GetFieldref(instr.Arg1).GetFieldType());
// putfield is allowed to access the unintialized this
if(s.PeekType() == VerifierTypeWrapper.UninitializedThis)
{
@@ -1396,7 +1399,7 @@ class MethodAnalyzer
}
else
{
- s.PopObjectType(GetFieldref(instr.Arg1).GetClassType(classLoader));
+ s.PopObjectType(GetFieldref(instr.Arg1).GetClassType());
}
break;
case NormalizedByteCode.__ldc:
@@ -1419,7 +1422,7 @@ class MethodAnalyzer
s.PushType(CoreClasses.java.lang.String.Wrapper);
break;
case ClassFile.ConstantType.Class:
- if(method.Method.ClassFile.MajorVersion < 49)
+ if(classFile.MajorVersion < 49)
{
throw new VerifyError("Illegal type in constant pool");
}
@@ -1450,7 +1453,7 @@ class MethodAnalyzer
{
throw new VerifyError("Illegal call to internal method");
}
- TypeWrapper[] args = cpi.GetArgTypes(classLoader);
+ TypeWrapper[] args = cpi.GetArgTypes();
for(int j = args.Length - 1; j >= 0; j--)
{
s.PopType(args[j]);
@@ -1466,8 +1469,8 @@ class MethodAnalyzer
if(cpi.Name == "<init>")
{
TypeWrapper type = s.PopType();
- if((VerifierTypeWrapper.IsNew(type) && ((VerifierTypeWrapper)type).UnderlyingType != cpi.GetClassType(classLoader)) ||
- (type == VerifierTypeWrapper.UninitializedThis && cpi.GetClassType(classLoader) != wrapper.BaseTypeWrapper && cpi.GetClassType(classLoader) != wrapper) ||
+ if((VerifierTypeWrapper.IsNew(type) && ((VerifierTypeWrapper)type).UnderlyingType != cpi.GetClassType()) ||
+ (type == VerifierTypeWrapper.UninitializedThis && cpi.GetClassType() != wrapper.BaseTypeWrapper && cpi.GetClassType() != wrapper) ||
(!VerifierTypeWrapper.IsNew(type) && type != VerifierTypeWrapper.UninitializedThis))
{
// TODO oddly enough, Java fails verification for the class without
@@ -1493,7 +1496,7 @@ class MethodAnalyzer
if(instr.NormalizedOpCode != NormalizedByteCode.__invokeinterface)
{
TypeWrapper refType = s.PopObjectType();
- TypeWrapper targetType = cpi.GetClassType(classLoader);
+ TypeWrapper targetType = cpi.GetClassType();
if(!VerifierTypeWrapper.IsNullOrUnloadable(refType) &&
!targetType.IsUnloadable &&
!refType.IsAssignableTo(targetType))
@@ -1522,7 +1525,7 @@ class MethodAnalyzer
}
}
}
- TypeWrapper retType = cpi.GetRetType(classLoader);
+ TypeWrapper retType = cpi.GetRetType();
if(retType != PrimitiveTypeWrapper.VOID)
{
s.PushType(retType);
@@ -1832,19 +1835,18 @@ class MethodAnalyzer
s.PopObjectType();
break;
case NormalizedByteCode.__return:
- if(method.Method.GetRetType(classLoader) != PrimitiveTypeWrapper.VOID)
+ if(mw.ReturnType != PrimitiveTypeWrapper.VOID)
{
throw new VerifyError("Wrong return type in function");
}
break;
case NormalizedByteCode.__areturn:
- s.PopObjectType(method.Method.GetRetType(classLoader));
+ s.PopObjectType(mw.ReturnType);
break;
case NormalizedByteCode.__ireturn:
{
s.PopInt();
- TypeWrapper retType = method.Method.GetRetType(classLoader);
- if(!retType.IsIntOnStackPrimitive)
+ if(!mw.ReturnType.IsIntOnStackPrimitive)
{
throw new VerifyError("Wrong return type in function");
}
@@ -1852,21 +1854,21 @@ class MethodAnalyzer
}
case NormalizedByteCode.__lreturn:
s.PopLong();
- if(method.Method.GetRetType(classLoader) != PrimitiveTypeWrapper.LONG)
+ if(mw.ReturnType != PrimitiveTypeWrapper.LONG)
{
throw new VerifyError("Wrong return type in function");
}
break;
case NormalizedByteCode.__freturn:
s.PopFloat();
- if(method.Method.GetRetType(classLoader) != PrimitiveTypeWrapper.FLOAT)
+ if(mw.ReturnType != PrimitiveTypeWrapper.FLOAT)
{
throw new VerifyError("Wrong return type in function");
}
break;
case NormalizedByteCode.__dreturn:
s.PopDouble();
- if(method.Method.GetRetType(classLoader) != PrimitiveTypeWrapper.DOUBLE)
+ if(mw.ReturnType != PrimitiveTypeWrapper.DOUBLE)
{
throw new VerifyError("Wrong return type in function");
}
@@ -2014,7 +2016,7 @@ class MethodAnalyzer
break;
}
case NormalizedByteCode.__nop:
- if(i + 1 == method.Method.CodeAttribute.Instructions.Length)
+ if(i + 1 == instructions.Length)
{
throw new VerifyError("Falling off the end of the code");
}
@@ -2032,9 +2034,9 @@ class MethodAnalyzer
switch(instr.NormalizedOpCode)
{
case NormalizedByteCode.__lookupswitch:
- for(int j = 0; j < instr.Values.Length; j++)
+ for(int j = 0; j < instr.SwitchEntryCount; j++)
{
- state[method.PcIndexMap[instr.PC + instr.TargetOffsets[j]]] += s;
+ state[method.PcIndexMap[instr.PC + instr.GetSwitchTargetOffset(j)]] += s;
}
state[method.PcIndexMap[instr.PC + instr.DefaultOffset]] += s;
break;
@@ -2125,12 +2127,12 @@ class MethodAnalyzer
}
catch(VerifyError x)
{
- string opcode = method.Instructions[i].OpCode.ToString();
+ string opcode = instructions[i].OpCode.ToString();
if(opcode.StartsWith("__"))
{
opcode = opcode.Substring(2);
}
- x.SetInfo(method.Instructions[i].PC, method.Method.ClassFile.Name, method.Method.Name, method.Method.Signature, opcode);
+ x.SetInfo(instructions[i].PC, classFile.Name, method.Name, method.Signature, opcode);
Tracer.Info(Tracer.Verifier, x.ToString());
throw;
}
@@ -2152,14 +2154,14 @@ class MethodAnalyzer
if(JVM.Debug)
{
// if we're emitting debug info, we need to keep dead stores as well...
- for(int i = 0; i < method.Instructions.Length; i++)
+ for(int i = 0; i < instructions.Length; i++)
{
- if(IsStoreLocal(method.Instructions[i].NormalizedOpCode))
+ if(IsStoreLocal(instructions[i].NormalizedOpCode))
{
- if(!localByStoreSite.ContainsKey(i + ":" + method.Instructions[i].NormalizedArg1))
+ if(!localByStoreSite.ContainsKey(i + ":" + instructions[i].NormalizedArg1))
{
LocalVar v = new LocalVar();
- v.local = method.Instructions[i].NormalizedArg1;
+ v.local = instructions[i].NormalizedArg1;
v.type = GetRawStackTypeWrapper(i, 0);
v.FindLvtEntry(method, i);
locals.Add(v);
@@ -2214,25 +2216,25 @@ class MethodAnalyzer
}
}
}
- invokespecialLocalVars = new LocalVar[method.Instructions.Length][];
- localVars = new LocalVar[method.Instructions.Length];
+ invokespecialLocalVars = new LocalVar[instructions.Length][];
+ localVars = new LocalVar[instructions.Length];
for(int i = 0; i < localVars.Length; i++)
{
LocalVar v = null;
if(localStoreReaders[i] != null)
{
- Debug.Assert(IsLoadLocal(method.Instructions[i].NormalizedOpCode));
+ Debug.Assert(IsLoadLocal(instructions[i].NormalizedOpCode));
// lame way to look up the local variable for a load
// (by indirecting through a corresponding store)
foreach(int store in localStoreReaders[i].Keys)
{
- v = (LocalVar)localByStoreSite[store + ":" + method.Instructions[i].NormalizedArg1];
+ v = (LocalVar)localByStoreSite[store + ":" + instructions[i].NormalizedArg1];
break;
}
}
else
{
- if(method.Instructions[i].NormalizedOpCode == NormalizedByteCode.__invokespecial)
+ if(instructions[i].NormalizedOpCode == NormalizedByteCode.__invokespecial)
{
invokespecialLocalVars[i] = new LocalVar[method.MaxLocals];
for(int j = 0; j < invokespecialLocalVars[i].Length; j++)
@@ -2242,7 +2244,7 @@ class MethodAnalyzer
}
else
{
- v = (LocalVar)localByStoreSite[i + ":" + method.Instructions[i].NormalizedArg1];
+ v = (LocalVar)localByStoreSite[i + ":" + instructions[i].NormalizedArg1];
}
}
if(v != null)
@@ -2392,7 +2394,7 @@ class MethodAnalyzer
{
try
{
- ClassFile.ConstantPoolItemMI item = method.Method.ClassFile.GetMethodref(index);
+ ClassFile.ConstantPoolItemMI item = classFile.GetMethodref(index);
if(item != null)
{
return item;
@@ -2411,7 +2413,7 @@ class MethodAnalyzer
{
try
{
- ClassFile.ConstantPoolItemFieldref item = method.Method.ClassFile.GetFieldref(index);
+ ClassFile.ConstantPoolItemFieldref item = classFile.GetFieldref(index);
if(item != null)
{
return item;
@@ -2430,7 +2432,7 @@ class MethodAnalyzer
{
try
{
- return method.Method.ClassFile.GetConstantPoolConstantType(index);
+ return classFile.GetConstantPoolConstantType(index);
}
catch(IndexOutOfRangeException)
{
@@ -2451,7 +2453,7 @@ class MethodAnalyzer
{
try
{
- return method.Method.ClassFile.GetConstantPoolClass(index);
+ return classFile.GetConstantPoolClass(index);
}
catch(InvalidCastException)
{
@@ -2466,7 +2468,7 @@ class MethodAnalyzer
{
try
{
- return method.Method.ClassFile.GetConstantPoolClassType(index, classLoader);
+ return classFile.GetConstantPoolClassType(index);
}
catch(InvalidCastException)
{
diff --git a/runtime/vm.cs b/runtime/vm.cs
index 6042510a..52cb64f1 100644
--- a/runtime/vm.cs
+++ b/runtime/vm.cs
@@ -36,7 +36,6 @@ public class JVM
private static bool debug = false;
private static bool noJniStubs = false;
private static bool isStaticCompiler = false;
- private static IJniProvider jniProvider;
private static bool compilationPhase1;
private static string sourcePath;
@@ -108,38 +107,6 @@ public class JVM
}
}
- public static IJniProvider JniProvider
- {
- get
- {
- if(jniProvider == null)
- {
- Type provider;
- string providerAssembly = Environment.GetEnvironmentVariable("IKVM_JNI_PROVIDER");
- if(providerAssembly != null)
- {
- Tracer.Info(Tracer.Runtime, "Loading environment specified JNI provider: {0}", providerAssembly);
- provider = Assembly.LoadFrom(providerAssembly).GetType("JNI", true);
- }
- else
- {
- if(IsUnix)
- {
- Tracer.Info(Tracer.Runtime, "Loading JNI provider: IKVM.JNI.Mono");
- provider = Assembly.LoadWithPartialName("IKVM.JNI.Mono").GetType("JNI", true);
- }
- else
- {
- Tracer.Info(Tracer.Runtime, "Loading JNI provider: IKVM.JNI.CLR-Win32");
- provider = Assembly.LoadWithPartialName("IKVM.JNI.CLR-Win32").GetType("JNI", true);
- }
- }
- jniProvider = (IJniProvider)Activator.CreateInstance(provider);
- }
- return jniProvider;
- }
- }
-
private class CompilerClassLoader : ClassLoaderWrapper
{
private Hashtable classes;
@@ -1355,7 +1322,7 @@ public class JVM
ClassFile f;
try
{
- f = new ClassFile(classes[i], 0, classes[i].Length, null);
+ f = new ClassFile(classes[i], 0, classes[i].Length, null, true);
}
catch(UnsupportedClassVersionError x)
{