pax_global_header 0000666 0000000 0000000 00000000064 12470474244 0014522 g ustar 00root root 0000000 0000000 52 comment=8fbf5ed5535faf226357db6b982f18288859f140
jffi-1.2.7/ 0000775 0000000 0000000 00000000000 12470474244 0012447 5 ustar 00root root 0000000 0000000 jffi-1.2.7/.classpath 0000664 0000000 0000000 00000000605 12470474244 0014433 0 ustar 00root root 0000000 0000000
jffi-1.2.7/.gitignore 0000664 0000000 0000000 00000000217 12470474244 0014437 0 ustar 00root root 0000000 0000000 *.orig$
*.rej$
*~
nbproject/private
build
build.eclipse
dist
lib/nblibraries-private.properties
jni/libffi/doc/libffi.info$
/.settings/
target
jffi-1.2.7/.hgignore 0000664 0000000 0000000 00000000231 12470474244 0014246 0 ustar 00root root 0000000 0000000 \.orig$
\.orig\..*$
\.chg\..*$
\.rej$
\.conflict\~$
^nbproject/private
^build/.*$
^dist
^lib/nblibraries-private.properties
^jni/libffi/doc/libffi.info$
jffi-1.2.7/.project 0000664 0000000 0000000 00000001056 12470474244 0014120 0 ustar 00root root 0000000 0000000
jffi
org.eclipse.jdt.core.javabuilder
org.maven.ide.eclipse.maven2Builder
org.maven.ide.eclipse.maven2Nature
org.eclipse.jdt.core.javanature
jffi-1.2.7/.settings/ 0000775 0000000 0000000 00000000000 12470474244 0014365 5 ustar 00root root 0000000 0000000 jffi-1.2.7/.settings/org.eclipse.jdt.core.prefs 0000664 0000000 0000000 00000000422 12470474244 0021345 0 ustar 00root root 0000000 0000000 #Wed Dec 30 13:18:41 CET 2009
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.5
jffi-1.2.7/.settings/org.maven.ide.eclipse.prefs 0000664 0000000 0000000 00000000420 12470474244 0021501 0 ustar 00root root 0000000 0000000 #Wed Dec 30 15:17:24 CET 2009
activeProfiles=
eclipse.preferences.version=1
fullBuildGoals=process-test-resources
includeModules=false
resolveWorkspaceProjects=false
resourceFilterGoals=process-resources resources\:testResources
skipCompilerPlugin=true
version=1
jffi-1.2.7/.travis.yml 0000664 0000000 0000000 00000000102 12470474244 0014551 0 ustar 00root root 0000000 0000000 language: java
jdk:
- oraclejdk7
- openjdk6
script: ant test
jffi-1.2.7/COPYING.GPL 0000664 0000000 0000000 00000104513 12470474244 0014127 0 ustar 00root root 0000000 0000000 GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
jffi-1.2.7/COPYING.LESSER 0000664 0000000 0000000 00000016727 12470474244 0014513 0 ustar 00root root 0000000 0000000 GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
jffi-1.2.7/LICENSE 0000664 0000000 0000000 00000002260 12470474244 0013454 0 ustar 00root root 0000000 0000000 Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Alternatively, you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
version 3 for more details.
You should have received a copy of the GNU Lesser General Public License
version 3 along with this work. If not, see .
jffi-1.2.7/build.xml 0000664 0000000 0000000 00000033723 12470474244 0014300 0 ustar 00root root 0000000 0000000
Builds, tests, and runs the project jffi.
jffi-1.2.7/jni/ 0000775 0000000 0000000 00000000000 12470474244 0013227 5 ustar 00root root 0000000 0000000 jffi-1.2.7/jni/GNUmakefile 0000775 0000000 0000000 00000023737 12470474244 0015320 0 ustar 00root root 0000000 0000000 # -*- makefile -*-
BUILD_OS := $(strip $(shell uname -s | tr '[:upper:]' '[:lower:]'))
OS ?= $(BUILD_OS)
ifeq ($(OS),sunos)
OS = solaris
endif
# Default value of $OS on Windows is Windows_NT
ifeq ($(OS), Windows_NT)
# that's how we detect x64...
ifneq ($(findstring 64, $(BUILD_OS)),)
OS = win64
else
OS = win32
endif
endif
ifneq ($(findstring cygwin, $(BUILD_OS)),)
# cygwin is always x32
OS = win32
endif
CPU ?= $(shell uname -m | sed -e 's/i[345678]86/i386/')
MODEL = 32 # Default to 32bit compiles
PLATFORM = $(CPU)-$(OS)
JDK_HOME=$(shell if [ -d "$(JAVA_HOME)"/include ];then echo "$(JAVA_HOME)"; else echo "$(JAVA_HOME)"/..; fi)
# Set defaults to unix (linux/solaris/bsd)
PREFIX = lib
JNIEXT = so
export MACOSX_DEPLOYMENT_TARGET=10.4
CCACHE := $(strip $(realpath $(shell which ccache 2> /dev/null)))
SRC_DIR ?= $(shell pwd)/jni
JNI_DIR ?= $(SRC_DIR)
BUILD_DIR ?= $(shell pwd)/build
JFFI_SRC_DIR = $(SRC_DIR)/jffi
JFFI_BUILD_DIR = $(BUILD_DIR)/jffi
ifeq ($(USE_SYSTEM_LIBFFI),1)
LIBFFI_LIBS ?= $(shell pkg-config --libs libffi)
LIBFFI_CFLAGS ?= $(shell pkg-config --cflags libffi)
else
LIBFFI_SRC_DIR = $(SRC_DIR)/libffi
LIBFFI_BUILD_DIR = $(BUILD_DIR)/libffi-$(PLATFORM)
LIBFFI = $(LIBFFI_BUILD_DIR)/.libs/libffi_convenience.a
LIBFFI_LIBS = $(LIBFFI)
LIBFFI_CFLAGS = -I"$(LIBFFI_BUILD_DIR)"/include
endif
SRCS = $(wildcard $(JFFI_SRC_DIR)/*.c)
OBJS = $(patsubst %.c, $(JFFI_BUILD_DIR)/%.o, $(notdir $(SRCS)))
vpath %.h $(JFFI_SRC_DIR)
LIBNAME = jffi
#
# Compiler/linker flags from:
# http://weblogs.java.net/blog/kellyohair/archive/2006/01/compilation_of_1.html
JFLAGS = -fno-omit-frame-pointer -fno-strict-aliasing -DNDEBUG
OFLAGS = -O2 $(JFLAGS)
# MacOS headers aren't completely warning free, so turn them off
WERROR = -Werror
ifneq ($(OS),darwin)
WFLAGS += -Wundef $(WERROR)
endif
WFLAGS += -W -Wall -Wno-unused -Wno-parentheses
PICFLAGS = -fPIC
SOFLAGS = # Filled in for each OS specifically
FFI_MMAP_EXEC = -DFFI_MMAP_EXEC_WRIT
FFI_CC = $(CCACHE) $(CC)
FFI_LD = $(LD)
FFI_CFLAGS = $(FFI_MMAP_EXEC) $(OFLAGS)
STRIP ?= strip -S
JDK_INCLUDES = -I"$(JDK_HOME)/include" -I"$(JDK_HOME)/include/$(OS)"
IFLAGS = -I"$(BUILD_DIR)" -I"$(BUILD_DIR)"/jni -I$(SRC_DIR) -I"$(JFFI_SRC_DIR)"
CFLAGS += $(OFLAGS) $(WFLAGS) $(IFLAGS) $(PICFLAGS) $(JDK_INCLUDES) $(LIBFFI_CFLAGS)
CFLAGS += -D_REENTRANT -D_LARGEFILE64_SOURCE -D_GNU_SOURCE
ifeq ($(OS), win64)
override CPU = x86_64
JDK_INCLUDES=-I$(JNI_DIR)/win32/include -I$(JNI_DIR)/win32/include/win32
CC = x86_64-w64-mingw32-gcc -m64
PICFLAGS =
ifneq ($(findstring cygwin, $(BUILD_OS)),)
CC += -mno-cygwin
LDFLAGS += -mno-cygwin
endif
CFLAGS += -mwin32 -D_JNI_IMPLEMENTATION_
LDFLAGS += -Wl,--add-stdcall-alias
PICFLAGS=
SOFLAGS += -shared -static-libgcc
PREFIX =
JNIEXT=dll
AR = x86_64-w64-mingw32-ar
LD = x86_64-w64-mingw32-ld
STRIP = x86_64-w64-mingw32-strip --strip-debug
CONFIGURE_BUILD = x86_64-w64-mingw32
endif
ifeq ($(OS),cross-mingw32)
override OS = win32
override CPU = i386
JDK_INCLUDES=-I$(JNI_DIR)/win32/include -I$(JNI_DIR)/win32/include/win32
CC = i686-w64-mingw32-gcc
LD = i686-w64-mingw32-ld
STRIP = i686-w64-mingw32-strip --strip-debug
export RANLIB = i686-w64-mingw32-ranlib
CONFIGURE_HOST = i686-mingw32
CROSS_COMPILE=1
endif
ifeq ($(OS),cross-win64)
override CPU = x86_64
override OS = win64
JDK_INCLUDES=-I$(JNI_DIR)/win32/include -I$(JNI_DIR)/win32/include/win32
CC = x86_64-w64-mingw32-gcc
LD = x86_64-w64-mingw32-ld
STRIP = x86_64-w64-mingw32-strip --strip-debug
AR = x86_64-w64-mingw32-ar
LD = x86_64-w64-mingw32-ld
export RANLIB = x86_64-w64-mingw32-ranlib
CONFIGURE_HOST = x86_64-w64-mingw32
PICFLAGS =
CROSS_COMPILE=1
SOFLAGS += -shared -static-libgcc
PREFIX =
JNIEXT=dll
endif
ifneq ($(findstring cygwin,$(BUILD_OS)),)
OS = win32
JAVA_HOME := $(shell cygpath -u $(JAVA_HOME))
endif
ifeq ($(OS), win32)
ifneq ($(findstring cygwin, $(BUILD_OS)),)
CC += -mno-cygwin
LDFLAGS += -mno-cygwin
endif
CFLAGS += -mwin32 -D_JNI_IMPLEMENTATION_
# Linking against CRTMT.O is a workaround for GCC 4.4 bug
# that ignores __thread (which we really need for errno handling).
# See: http://n2.nabble.com/gcc-4-4-multi-threaded-exception-handling-thread-specifier-not-working-td3440749.html
ifeq ($(findstring -w64-,$(CC)),)
CRTMT.O = $(shell $(CC) -print-file-name=crtmt.o)
endif
LDFLAGS += -Wl,--add-stdcall-alias $(CRTMT.O)
PICFLAGS=
SOFLAGS += -shared -static-libgcc
PREFIX =
JNIEXT=dll
endif
ifeq ($(OS), darwin)
PLATFORM = darwin
ARCHES =
ifneq ($(findstring $(CPU), ppc powerpc),)
ARCHES += ppc
endif
ifneq ($(findstring $(CPU), i386 x86_64),)
ARCHES += i386 x86_64
endif
ifneq ($(realpath $(wildcard /Xcode3/usr/bin/gcc)),)
XCODE=/Xcode3
else
XCODE=$(shell xcode-select -print-path)
endif
ifneq ($(realpath $(wildcard $(XCODE)/usr/bin/gcc-4.0)),)
CC = $(XCODE)/usr/bin/gcc-4.0
else
CC = $(XCODE)/usr/bin/gcc
endif
UNIVERSAL_SDK = $(firstword $(strip $(realpath $(XCODE)/SDKs/MacOSX10.4u.sdk) $(realpath $(XCODE)/SDKs/MacOSX10.5.sdk)))
ifneq ($(UNIVERSAL_SDK),)
MACSDK = $(UNIVERSAL_SDK)
ifeq ($(findstring ppc, $(ARCHES)),)
ARCHES += ppc
endif
else
MACSDK = $(firstword $(strip $(wildcard $(XCODE)/SDKs/MacOSX10.*.sdk)) $(strip $(wildcard $(XCODE)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.*.sdk)))
endif
CFLAGS += -isysroot $(MACSDK) -DTARGET_RT_MAC_CFM=0
CFLAGS += -I$(MACSDK)/System/Library/Frameworks/JavaVM.framework/Headers
CFLAGS += $(foreach arch, $(ARCHES),-arch $(arch))
LDFLAGS = $(foreach arch, $(ARCHES),-arch $(arch)) -dynamiclib -framework JavaVM \
-Wl,-syslibroot,$(MACSDK) -mmacosx-version-min=10.6
JNIEXT = jnilib
#CFLAGS += -I$(MACSDK)/System/Library/Frameworks/Kernel.framework/Versions/A/Headers
CFLAGS += -fexceptions
FFI_CFLAGS += -isysroot $(MACSDK) -I$(MACSDK)/usr/include
PICFLAGS =
SOFLAGS =
#LIBS += $(JAVA_HOME)/jre/lib/libjsig.dylib
OBJS += $(JFFI_BUILD_DIR)/darwin-longjmp.o $(JFFI_BUILD_DIR)/darwin-trampoline.o
endif
ifeq ($(OS), linux)
SOFLAGS = -shared -static-libgcc -Wl,-soname,$(@F) -Wl,-O1
CFLAGS += -pthread
endif
ifeq ($(OS), solaris)
CC = gcc
CFLAGS += -D__EXTENSIONS__ -std=c99
LD = /usr/ccs/bin/ld
SOFLAGS = -shared -static-libgcc
LIBS += -ldl
STRIP = strip
endif
ifeq ($(OS), aix)
SOFLAGS = -shared -static-libgcc
CFLAGS += -pthread
LDFLAGS += -pthread
JNIEXT = a
STRIP = strip
endif
ifneq ($(findstring bsd, $(OS)),)
SOFLAGS = -shared -static-libgcc
CFLAGS += -pthread
LDFLAGS += -pthread
endif
ifeq ($(CPU), i386)
ifneq ($(findstring $(OS), linux),)
CFLAGS += -march=i586 -mtune=generic
endif
endif
ifeq ($(CPU), sparcv9)
MODEL=64
endif
ifneq ($(findstring $(CPU), x86_64 amd64 ppc64 powerpc64 s390x),)
MODEL = 64
endif
# On platforms (linux, solaris) that support both 32bit and 64bit, force building for one or the other
ifneq ($(strip $(findstring $(OS), solaris linux)),)
# Change the CC/LD instead of CFLAGS/LDFLAGS, incase other things in the flags
# makes the libffi build choke
CC += -m$(MODEL)
LD += -m$(MODEL)
endif
LIBJFFI = $(BUILD_DIR)/$(PREFIX)$(LIBNAME)-$(VERSION).$(JNIEXT)
LIBFFI_CONFIGURE = $(LIBFFI_SRC_DIR)/configure --disable-static \
--with-pic=yes --disable-dependency-tracking
ifdef CONFIGURE_HOST
LIBFFI_CONFIGURE += --host=$(CONFIGURE_HOST)
endif
ifdef CONFIGURE_BUILD
LIBFFI_CONFIGURE += --build=$(CONFIGURE_BUILD)
endif
all: $(LIBJFFI)
debug:
@echo OS="$(OS)"
@echo BUILD_OS="$(BUILD_OS)"
@echo CPU="$(CPU)"
@echo JAVA_HOME="$(JAVA_HOME)"
@echo JDK_HOME="$(JDK_HOME)"
@echo "PLATFORM=$(PLATFORM)"
@echo "JFFI_BUILD_DIR=$(JFFI_BUILD_DIR)"
@echo "OBJS=$(OBJS)"
$(LIBJFFI): $(OBJS) $(LIBFFI_LIBS)
$(CC) -o $@ $(LDFLAGS) $(SOFLAGS) $(OBJS) $(LIBFFI_LIBS) $(LIBS)
$(STRIP) $@
$(BUILD_DIR)/%.o : $(SRC_DIR)/%.c $(wildcard $(JFFI_SRC_DIR)/*.h)
@mkdir -p $(@D)
@$(CCACHE) $(CC) $(CFLAGS) -c $< -o $@
$(BUILD_DIR)/%.o : $(SRC_DIR)/%.S $(wildcard $(JFFI_SRC_DIR)/*.h)
@mkdir -p $(@D)
@$(CC) $(CFLAGS) -o $@ -c $<
$(OBJS) : $(LIBFFI_LIBS)
ifeq ($(OS), darwin)
build_ffi = \
mkdir -p $(BUILD_DIR)/libffi-darwin-$(1); \
(if [ ! -f $(BUILD_DIR)/libffi-darwin-$(1)/Makefile ]; then \
echo "Configuring libffi for $(1)"; \
cd $(BUILD_DIR)/libffi-darwin-$(1) && \
env CC="$(CCACHE) $(CC)" CFLAGS="-arch $(1) $(FFI_CFLAGS)" LDFLAGS="-arch $(1)" \
$(LIBFFI_CONFIGURE) --host=$(1)-apple-darwin > /dev/null; \
fi); \
env MACOSX_DEPLOYMENT_TARGET=10.4 $(MAKE) -C $(BUILD_DIR)/libffi-darwin-$(1)
$(LIBFFI):
@mkdir -p $(@D)
@for arch in $(ARCHES); do $(call build_ffi,$$arch);done
# Assemble into a FAT (i386, x86_64, ppc) library
@mkdir -p $(BUILD_DIR)/libffi/.libs
@env MACOSX_DEPLOYMENT_TARGET=10.4 /usr/bin/libtool -static -o $@ \
$(foreach arch, $(ARCHES),$(BUILD_DIR)/libffi-darwin-$(arch)/.libs/libffi_convenience.a)
@mkdir -p $(LIBFFI_BUILD_DIR)/include
$(RM) $(LIBFFI_BUILD_DIR)/include/ffi.h
@( \
printf "#if defined(__i386__)\n"; \
printf "#include \"libffi-darwin-i386/include/ffi.h\"\n"; \
printf "#elif defined(__x86_64__)\n"; \
printf "#include \"libffi-darwin-x86_64/include/ffi.h\"\n";\
printf "#elif defined(__ppc__)\n"; \
printf "#include \"libffi-darwin-ppc/include/ffi.h\"\n";\
printf "#endif\n";\
) > $(LIBFFI_BUILD_DIR)/include/ffi.h
@( \
printf "#if defined(__i386__)\n"; \
printf "#include \"libffi-darwin-i386/include/ffitarget.h\"\n"; \
printf "#elif defined(__x86_64__)\n"; \
printf "#include \"libffi-darwin-x86_64/include/ffitarget.h\"\n";\
printf "#elif defined(__ppc__)\n"; \
printf "#include \"libffi-darwin-ppc/include/ffitarget.h\"\n";\
printf "#endif\n";\
) > $(LIBFFI_BUILD_DIR)/include/ffitarget.h
else
$(LIBFFI):
@mkdir -p $(LIBFFI_BUILD_DIR)
@if [ ! -f $(LIBFFI_BUILD_DIR)/Makefile ]; then \
echo "Configuring libffi for $(PLATFORM)"; \
cd $(LIBFFI_BUILD_DIR) && env CC="$(FFI_CC)" LD="$(FFI_LD)" CFLAGS="$(FFI_CFLAGS)" \
$(LIBFFI_CONFIGURE) > /dev/null; \
fi
$(MAKE) -C $(LIBFFI_BUILD_DIR)
endif
clean::
# nothing to do - ant will delete the build dir
jffi-1.2.7/jni/jffi/ 0000775 0000000 0000000 00000000000 12470474244 0014145 5 ustar 00root root 0000000 0000000 jffi-1.2.7/jni/jffi/Array.c 0000664 0000000 0000000 00000022770 12470474244 0015377 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2007, 2008 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#include
#include
#include
#include
#include
#include "jffi.h"
#include "Exception.h"
#include "com_kenai_jffi_ObjectBuffer.h"
#include "Array.h"
#define ARGPRIM_MASK com_kenai_jffi_ObjectBuffer_PRIM_MASK
#define ARGTYPE_MASK com_kenai_jffi_ObjectBuffer_TYPE_MASK
#define ARGTYPE_SHIFT com_kenai_jffi_ObjectBuffer_TYPE_SHIFT
#define ARGFLAGS_MASK com_kenai_jffi_ObjectBuffer_FLAGS_MASK
static void
releaseHeapArray(JNIEnv* env, Array* array)
{
free(array->elems);
}
#define COPY_DATA(JTYPE, NTYPE, flags, obj, offset, length, array) do { \
if (IS_IN_ARRAY(flags)) { \
(*env)->Get##JTYPE##ArrayRegion(env, obj, offset, length, (NTYPE *) array->elems); \
if (unlikely((*env)->ExceptionCheck(env) != JNI_FALSE)) return NULL; \
} else if (unlikely((flags & ARRAY_CLEAR) != 0)) { \
memset(array->elems, 0, length * sizeof(NTYPE)); \
} \
} while (0)
#define SET_COPYOUT(JTYPE, array, flags) \
(array)->copyout = IS_OUT_ARRAY(flags) \
? (void (JNICALL *)(JNIEnv*, jobject, jsize, jsize, const void *))(*env)->Set##JTYPE##ArrayRegion \
: NULL
#define SET_COPYIN(JTYPE, array, flags) \
(array)->copyin = IS_IN_ARRAY(flags) \
? (void (JNICALL *)(JNIEnv*, jobject, jsize, jsize, void *))(*env)->Get##JTYPE##ArrayRegion \
: NULL
#define GET_ARRAY_BUFFER(JTYPE, NTYPE, flags, obj, offset, length, array) do { \
COPY_DATA(JTYPE, NTYPE, flags, obj, offset, length, array); \
SET_COPYOUT(JTYPE, array, flags); \
} while (0)
#define GET_ARRAY_HEAP(JTYPE, NTYPE, flags, obj, offset, length, array) do { \
int allocSize = sizeof(NTYPE) * (length + 1); \
(array)->elems = malloc(allocSize); \
if (unlikely((array)->elems == NULL)) { \
throwException(env, OutOfMemory, "failed to allocate native array of %d bytes", allocSize); \
return NULL; \
} \
COPY_DATA(JTYPE, NTYPE, flags, obj, offset, length, array); \
SET_COPYOUT(JTYPE, array, flags); \
} while(0)
void*
jffi_getArrayHeap(JNIEnv* env, jobject buf, jsize offset, jsize length, int type,
Array* array)
{
array->array = buf;
array->offset = offset;
array->length = length;
array->type = type;
array->copyin = NULL;
array->copyout = NULL;
array->release = releaseHeapArray;
/*
* Byte arrays are used for struct backing in both jaffl and jruby ffi, so
* are the most likely path.
*/
if (likely((type & ARGPRIM_MASK) == com_kenai_jffi_ObjectBuffer_BYTE)) {
GET_ARRAY_HEAP(Byte, jbyte, type, buf, offset, length, array);
// If the array was really a string, nul terminate it
if ((type & (ARRAY_NULTERMINATE | ARRAY_IN | ARRAY_OUT)) != ARRAY_OUT) {
*(((char *) array->elems) + length) = '\0';
}
} else {
switch (type & ARGPRIM_MASK) {
case com_kenai_jffi_ObjectBuffer_SHORT:
GET_ARRAY_HEAP(Short, jshort, type, buf, offset, length, array);
break;
case com_kenai_jffi_ObjectBuffer_INT:
GET_ARRAY_HEAP(Int, jint, type, buf, offset, length, array);
break;
case com_kenai_jffi_ObjectBuffer_LONG:
GET_ARRAY_HEAP(Long, jlong, type, buf, offset, length, array);
break;
case com_kenai_jffi_ObjectBuffer_FLOAT:
GET_ARRAY_HEAP(Float, jfloat, type, buf, offset, length, array);
break;
case com_kenai_jffi_ObjectBuffer_DOUBLE:
GET_ARRAY_HEAP(Double, jdouble, type, buf, offset, length, array);
break;
case com_kenai_jffi_ObjectBuffer_BOOLEAN:
GET_ARRAY_HEAP(Boolean, jboolean, type, buf, offset, length, array);
break;
case com_kenai_jffi_ObjectBuffer_CHAR:
GET_ARRAY_HEAP(Char, jchar, type, buf, offset, length, array);
break;
default:
throwException(env, IllegalArgument, "invalid array type: %#x\n", type);
return NULL;
}
}
return array->elems;
}
void*
jffi_getArrayBuffer(JNIEnv* env, jobject buf, jint offset, jint length, int type, struct Array* array, void* buffer)
{
array->array = buf;
array->elems = buffer;
array->offset = offset;
array->length = length;
array->type = type;
array->release = NULL;
array->copyin = NULL;
array->copyout = NULL;
switch (type & ARGPRIM_MASK) {
case com_kenai_jffi_ObjectBuffer_BYTE:
GET_ARRAY_BUFFER(Byte, jbyte, type, buf, offset, length, array);
// If the array was really a string, nul terminate it
if ((type & (ARRAY_NULTERMINATE | ARRAY_IN | ARRAY_OUT)) != ARRAY_OUT) {
*(((char *) array->elems) + length) = '\0';
}
break;
case com_kenai_jffi_ObjectBuffer_SHORT:
GET_ARRAY_BUFFER(Short, jshort, type, buf, offset, length, array);
break;
case com_kenai_jffi_ObjectBuffer_INT:
GET_ARRAY_BUFFER(Int, jint, type, buf, offset, length, array);
break;
case com_kenai_jffi_ObjectBuffer_LONG:
GET_ARRAY_BUFFER(Long, jlong, type, buf, offset, length, array);
break;
case com_kenai_jffi_ObjectBuffer_FLOAT:
GET_ARRAY_BUFFER(Float, jfloat, type, buf, offset, length, array);
break;
case com_kenai_jffi_ObjectBuffer_DOUBLE:
GET_ARRAY_BUFFER(Double, jdouble, type, buf, offset, length, array);
break;
case com_kenai_jffi_ObjectBuffer_BOOLEAN:
GET_ARRAY_BUFFER(Boolean, jboolean, type, buf, offset, length, array);
break;
case com_kenai_jffi_ObjectBuffer_CHAR:
GET_ARRAY_BUFFER(Char, jchar, type, buf, offset, length, array);
break;
default:
throwException(env, IllegalArgument, "Invalid array type: %#x\n", type);
return NULL;
}
return array->elems;
}
int
jffi_arraySize(int length, int type)
{
switch (type & ARGPRIM_MASK) {
case com_kenai_jffi_ObjectBuffer_BYTE:
return length * sizeof(jbyte);
case com_kenai_jffi_ObjectBuffer_SHORT:
return length * sizeof(jshort);
case com_kenai_jffi_ObjectBuffer_INT:
return length * sizeof(jint);
case com_kenai_jffi_ObjectBuffer_LONG:
return length * sizeof(jlong);
case com_kenai_jffi_ObjectBuffer_FLOAT:
return length * sizeof(jfloat);
case com_kenai_jffi_ObjectBuffer_DOUBLE:
return length * sizeof(jdouble);
case com_kenai_jffi_ObjectBuffer_BOOLEAN:
return length * sizeof(jboolean);
case com_kenai_jffi_ObjectBuffer_CHAR:
return length * sizeof(jchar);
default:
return length * 8;
}
}
static void
jffi_releaseCriticalArray(JNIEnv* env, Array *array)
{
(*env)->ReleasePrimitiveArrayCritical(env, array->array, array->elems, 0);
}
void*
jffi_getArrayCritical(JNIEnv* env, jobject buf, jsize offset, jsize length, int type, struct Array* array)
{
array->array = buf;
array->offset = offset;
array->length = length;
array->type = type;
array->copyin = NULL;
array->copyout = NULL;
array->elems = (*env)->GetPrimitiveArrayCritical(env, array->array, NULL);
if (unlikely(array->elems == NULL)) {
if (!(*env)->ExceptionCheck(env)) {
throwException(env, NullPointer, "failed to pin native array");
}
return NULL;
}
array->release = jffi_releaseCriticalArray;
return (char *) array->elems + offset;
}
void
jffi_releaseArrays(JNIEnv *env, Array* arrays, int arrayCount)
{
int aryIdx;
for (aryIdx = arrayCount - 1; aryIdx >= 0; aryIdx--) {
Array* array = &arrays[aryIdx];
if (IS_OUT_ARRAY(array->type) && array->copyout != NULL) {
if ((*env)->ExceptionCheck(env) == JNI_FALSE) {
(*array->copyout)(env, array->array, array->offset, array->length, array->elems);
}
}
if (unlikely(array->release != NULL)) {
(*array->release)(env, array);
}
}
}
jffi-1.2.7/jni/jffi/Array.h 0000664 0000000 0000000 00000007224 12470474244 0015401 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2007, 2008 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#ifndef jffi_Array_h
#define jffi_Array_h
//
// WARNING! Do not change the layout of this struct, it may be used from assembler
//
typedef struct Array {
void (JNICALL *copyin)(JNIEnv* env, jobject array, jsize start, jsize len, void *buf);
void (JNICALL *copyout)(JNIEnv* env, jobject array, jsize start, jsize len, const void *buf);
void (*release)(JNIEnv *env, struct Array *);
jobject array;
void* elems;
int offset;
int length;
int type;
int bytesize; // total size of array in bytes
} Array;
extern bool jffi_getInitArray(JNIEnv* env, jobject buf, jint offset, jint length, int type, struct Array* array);
extern void* jffi_getArrayBuffer(JNIEnv* env, jobject buf, jint offset, jint length, int type, struct Array* array, void* buffer);
extern void* jffi_getArrayHeap(JNIEnv* env, jobject buf, jint offset, jint length, int type, struct Array* array);
extern void* jffi_getArrayCritical(JNIEnv* env, jobject buf, jint offset, jint length, int type, struct Array* array);
extern int jffi_arraySize(int length, int type);
extern void jffi_releaseArrays(JNIEnv* env, Array* arrays, int arrayCount);
#include "com_kenai_jffi_ObjectBuffer.h"
#define OBJ_INDEX_MASK com_kenai_jffi_ObjectBuffer_INDEX_MASK
#define OBJ_INDEX_SHIFT com_kenai_jffi_ObjectBuffer_INDEX_SHIFT
#define ARRAY_NULTERMINATE com_kenai_jffi_ObjectBuffer_ZERO_TERMINATE
#define ARRAY_IN com_kenai_jffi_ObjectBuffer_IN
#define ARRAY_OUT com_kenai_jffi_ObjectBuffer_OUT
#define ARRAY_PINNED com_kenai_jffi_ObjectBuffer_PINNED
#define ARRAY_CLEAR com_kenai_jffi_ObjectBuffer_CLEAR
#define IS_PINNED_ARRAY(flags) \
(((flags) & (com_kenai_jffi_ObjectBuffer_ARRAY | com_kenai_jffi_ObjectBuffer_PINNED)) == (com_kenai_jffi_ObjectBuffer_ARRAY | com_kenai_jffi_ObjectBuffer_PINNED))
#define IS_UNPINNED_ARRAY(flags) \
(((flags) & (com_kenai_jffi_ObjectBuffer_ARRAY | com_kenai_jffi_ObjectBuffer_PINNED)) == com_kenai_jffi_ObjectBuffer_ARRAY)
#define IS_OUT_ARRAY(flags) (((flags) & (com_kenai_jffi_ObjectBuffer_ARRAY | ARRAY_IN | ARRAY_OUT)) != (com_kenai_jffi_ObjectBuffer_ARRAY | ARRAY_IN))
#define IS_IN_ARRAY(flags) (((flags) & (com_kenai_jffi_ObjectBuffer_ARRAY | ARRAY_IN | ARRAY_OUT)) != (com_kenai_jffi_ObjectBuffer_ARRAY | ARRAY_OUT))
#define RELEASE_ARRAYS(env, arrays, arrayCount) do { if (unlikely(arrayCount > 0)) jffi_releaseArrays(env, arrays, arrayCount); } while (0)
#endif /* jffi_Array_h */
jffi-1.2.7/jni/jffi/CallContext.c 0000664 0000000 0000000 00000017114 12470474244 0016535 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2008, 2009 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#include
#include
#include
#include
#if defined(__sun) || defined(_AIX)
# include
# include
#endif
#ifdef _WIN32
# include
#endif
#include
#include
#include "jffi.h"
#include "Exception.h"
#include "CallContext.h"
#include "com_kenai_jffi_Foreign.h"
#ifndef MAX
# define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
static inline int FFI_ALIGN(int v, int a) {
return ((((size_t) v) - 1) | (a - 1)) +1;
}
/*
* Class: com_kenai_jffi_Foreign
* Method: newCallContext
* Signature: (I[II)J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_newCallContext(JNIEnv* env, jobject self,
jlong returnType, jlongArray paramArray, jint flags)
{
CallContext* ctx = NULL;
jlong* paramTypes;
int paramCount, i, rawOffset = 0;
bool isFastInt = false, isFastLong = false;
ffi_type* ffiParamTypes;
int ffiStatus;
int abi;
paramCount = (*env)->GetArrayLength(env, paramArray);
ctx = calloc(1, sizeof(*ctx));
if (ctx == NULL) {
throwException(env, OutOfMemory, "Failed to allocate CallContext");
goto cleanup;
}
ctx->ffiParamTypes = calloc(MAX(1, paramCount), sizeof(ffi_type *));
if (ctx->ffiParamTypes == NULL) {
throwException(env, OutOfMemory, "Failed to allocate CallContext#ffiParamTypes");
goto cleanup;
}
ctx->rawParamOffsets = calloc(MAX(1, paramCount), sizeof(*ctx->rawParamOffsets));
if (ctx->rawParamOffsets == NULL) {
throwException(env, OutOfMemory, "Failed to allocate CallContext#rawParamOffsets");
goto cleanup;
}
paramTypes = alloca(paramCount * sizeof(jlong));
(*env)->GetLongArrayRegion(env, paramArray, 0, paramCount, paramTypes);
ctx->resultMask = (((ffi_type *) j2p(returnType))->size > 4) ? ~0UL : 0xffffffffUL;
#if defined(__i386__) || defined(__x86_64__)
isFastInt = true;
isFastLong = true;
switch (((ffi_type *) j2p(returnType))->type) {
case FFI_TYPE_INT:
case FFI_TYPE_SINT8:
case FFI_TYPE_UINT8:
case FFI_TYPE_SINT16:
case FFI_TYPE_UINT16:
case FFI_TYPE_SINT32:
case FFI_TYPE_UINT32:
#if defined(__i386__)
case FFI_TYPE_POINTER:
#endif
#if !defined(__x86_64__)
isFastLong = false;
#endif
break;
case FFI_TYPE_SINT64:
case FFI_TYPE_UINT64:
#if defined(__x86_64__)
case FFI_TYPE_POINTER:
#endif
isFastInt = false;
break;
case FFI_TYPE_VOID:
break;
default:
isFastInt = false;
isFastLong = false;
break;
}
#endif
for (i = 0; i < paramCount; ++i) {
ffi_type* type = (ffi_type *) j2p(paramTypes[i]);
if (type == NULL) {
throwException(env, IllegalArgument, "Invalid parameter type: %#x", paramTypes[i]);
goto cleanup;
}
ctx->ffiParamTypes[i] = type;
ctx->rawParamOffsets[i] = rawOffset;
rawOffset += FFI_ALIGN(type->size, FFI_SIZEOF_ARG);
#if defined(__i386__) || defined(__x86_64__)
switch (type->type) {
case FFI_TYPE_INT:
case FFI_TYPE_SINT8:
case FFI_TYPE_UINT8:
case FFI_TYPE_SINT16:
case FFI_TYPE_UINT16:
case FFI_TYPE_SINT32:
case FFI_TYPE_UINT32:
#if defined(__i386__)
case FFI_TYPE_POINTER:
#endif
#if !defined(__x86_64__)
isFastLong = false;
#endif
break;
case FFI_TYPE_SINT64:
case FFI_TYPE_UINT64:
#if defined(__x86_64__)
case FFI_TYPE_POINTER:
#endif
isFastInt = false;
break;
default:
isFastInt = false;
isFastLong = false;
break;
}
#endif
}
// On win32, we might need to set the abi to stdcall - but win64 only supports cdecl/default
#if defined(_WIN32) && !defined(_WIN64)
abi = (flags & com_kenai_jffi_Foreign_F_STDCALL) != 0 ? FFI_STDCALL : FFI_DEFAULT_ABI;
#else
abi = FFI_DEFAULT_ABI;
#endif
// Cannot bypass FFI unless ABI is cdecl
if (abi != FFI_DEFAULT_ABI) {
isFastInt = false;
isFastLong = false;
}
ffiStatus = ffi_prep_cif(&ctx->cif, abi, paramCount, (ffi_type *) j2p(returnType),
ctx->ffiParamTypes);
switch (ffiStatus) {
case FFI_OK:
break;
case FFI_BAD_TYPEDEF:
throwException(env, IllegalArgument, "Bad typedef");
goto cleanup;
case FFI_BAD_ABI:
throwException(env, Runtime, "Invalid ABI");
goto cleanup;
default:
throwException(env, Runtime, "Unknown FFI error");
}
ctx->rawParameterSize = rawOffset;
ctx->flags |= (flags & com_kenai_jffi_Foreign_F_NOERRNO) == 0 ? CALL_CTX_SAVE_ERRNO : 0;
ctx->flags |= isFastInt ? CALL_CTX_FAST_INT : 0;
ctx->flags |= isFastLong ? CALL_CTX_FAST_LONG : 0;
ctx->flags |= (flags & com_kenai_jffi_Foreign_F_PROTECT) != 0 ? CALL_CTX_FAULT_PROT : 0;
return p2j(ctx);
cleanup:
if (ctx != NULL) {
if (ctx->rawParamOffsets != NULL) {
free(ctx->rawParamOffsets);
}
if (ctx->ffiParamTypes != NULL) {
free(ctx->ffiParamTypes);
}
free(ctx);
}
return 0LL;
}
/*
* Class: com_kenai_jffi_Foreign
* Method: freeCallContext
* Signature: (J)V
*/
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_freeCallContext(JNIEnv* env, jobject self, jlong handle)
{
CallContext* ctx = (CallContext *) j2p(handle);
if (ctx != NULL) {
if (ctx->rawParamOffsets != NULL) {
free(ctx->rawParamOffsets);
}
if (ctx->ffiParamTypes != NULL) {
free(ctx->ffiParamTypes);
}
free(ctx);
}
}
/*
* Class: com_kenai_jffi_Foreign
* Method: getCallContextRawParameterSize
* Signature: (J)I
*/
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_getCallContextRawParameterSize(JNIEnv* env, jobject self, jlong handle)
{
CallContext* ctx = (CallContext *) j2p(handle);
return ctx->rawParameterSize;
}
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_setCallContextErrorFunction(JNIEnv* env, jobject self, jlong handle, jlong fn)
{
CallContext* ctx = (CallContext *) j2p(handle);
ctx->error_fn = j2p(fn);
}
jffi-1.2.7/jni/jffi/CallContext.h 0000664 0000000 0000000 00000003753 12470474244 0016546 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2008, 2009 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#ifndef JFFI_CALLCONTEXT_H
#define JFFI_CALLCONTEXT_H
#include
typedef struct CallContext {
/** IMPORTANT: keep ffi_cif as the first field */
ffi_cif cif;
int rawParameterSize;
ffi_type** ffiParamTypes;
int* rawParamOffsets;
bool saveErrno;
int flags;
long resultMask;
int (*error_fn)(void);
} CallContext;
extern void jffi_save_errno_ctx(CallContext* ctx);
#define CALL_CTX_SAVE_ERRNO (0x1)
#define CALL_CTX_FAST_INT (0x2)
#define CALL_CTX_FAST_LONG (0x4)
#define CALL_CTX_FAULT_PROT (0x8)
#define SAVE_ERRNO(ctx) do { \
if (unlikely((ctx->flags & CALL_CTX_SAVE_ERRNO) != 0)) { \
jffi_save_errno_ctx(ctx); \
} \
} while(0)
#endif /* JFFI_CALLCONTEXT_H */
jffi-1.2.7/jni/jffi/ClosureMagazine.c 0000664 0000000 0000000 00000032413 12470474244 0017404 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2007-2009 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#include
#include
#include
#include
#include
#include
#if defined(__sun) || defined(_AIX)
# include
# include
#endif
#ifdef _WIN32
# include
#endif
#include
#include "jffi.h"
#include "Exception.h"
#include "Type.h"
#include "CallContext.h"
#include "MemoryUtil.h"
#include "FaultProtect.h"
#include "com_kenai_jffi_Foreign.h"
#define THREAD_ATTACH_THRESHOLD (1000)
struct Closure;
typedef struct ClosureMagazine {
CallContext* callContext;
jmethodID methodID;
JavaVM* jvm;
void* code;
struct Closure* closures;
int nclosures;
int nextclosure;
int callWithPrimitiveParameters;
} Magazine;
typedef struct Closure {
void* code; /* the code address must be the first member of this struct; used by java */
jobject javaObject;
Magazine* magazine;
} Closure;
static bool closure_prep(ffi_cif* cif, void* code, Closure* closure, char* errbuf, size_t errbufsize);
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_newClosureMagazine(JNIEnv *env, jobject self, jlong ctxAddress, jobject closureMethod,
jboolean callWithPrimitiveParameters)
{
CallContext* ctx = (CallContext *) j2p(ctxAddress);
Closure* list = NULL;
Magazine* magazine = NULL;
caddr_t code = NULL;
char errmsg[256];
int i;
int trampolineSize, pageSize, nclosures;
trampolineSize = roundup(sizeof(ffi_closure), 8);
pageSize = jffi_getPageSize();
nclosures = pageSize / trampolineSize;
magazine = calloc(1, sizeof(*magazine));
list = calloc(nclosures, sizeof(*list));
code = jffi_allocatePages(1);
if (magazine == NULL || list == NULL || code == NULL) {
snprintf(errmsg, sizeof(errmsg), "failed to allocate a page. errno=%d (%s)", errno, strerror(errno));
goto error;
}
// Thread all the closure handles onto a list, and init each one
for (i = 0; i < nclosures; ++i) {
Closure* closure = &list[i];
closure->magazine = magazine;
closure->code = (code + (i * trampolineSize));
if (!closure_prep(&ctx->cif, closure->code, closure, errmsg, sizeof(errmsg))) {
goto error;
}
}
if (!jffi_makePagesExecutable(code, 1)) {
snprintf(errmsg, sizeof(errmsg), "failed to make page executable. errno=%d (%s)", errno, strerror(errno));
goto error;
}
magazine->methodID = (*env)->FromReflectedMethod(env, closureMethod);
if (magazine->methodID == NULL) {
throwException(env, IllegalArgument, "could not obtain reference to closure method");
goto error;
}
/* Track the allocated page + Closure memory area */
magazine->closures = list;
magazine->nextclosure = 0;
magazine->nclosures = nclosures;
magazine->code = code;
magazine->callWithPrimitiveParameters = callWithPrimitiveParameters;
(*env)->GetJavaVM(env, &magazine->jvm);
return p2j(magazine);
error:
free(list);
free(magazine);
if (code != NULL) {
jffi_freePages(code, 1);
}
throwException(env, Runtime, errmsg);
return 0L;
}
/*
* Class: com_kenai_jffi_Foreign
* Method: freeClosureMagazine
* Signature: (J)V
*/
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_freeClosureMagazine(JNIEnv *env, jobject self, jlong magAddress)
{
Magazine* magazine = (Magazine *) j2p(magAddress);
Closure* closure;
int i;
for (i = 0; i < magazine->nextclosure; ++i) {
(*env)->DeleteGlobalRef(env, magazine->closures[i].javaObject);
}
free(magazine->closures);
jffi_freePages(magazine->code, 1);
free(magazine);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: closureMagazineGet
* Signature: (JLjava/lang/Object;)J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_closureMagazineGet(JNIEnv *env, jobject self, jlong magAddress, jobject closureProxy)
{
Magazine* magazine = (Magazine *) j2p(magAddress);
if (magazine->nextclosure < magazine->nclosures) {
Closure* closure = &magazine->closures[magazine->nextclosure];
closure->javaObject = (*env)->NewGlobalRef(env, closureProxy);
if (closure->javaObject == NULL) {
throwException(env, IllegalArgument, "could not obtain reference to java object");
return 0L;
}
magazine->nextclosure++;
return p2j(closure);
}
return 0L;
}
static void
closure_begin(Closure* closure, JNIEnv** penv, bool* detach)
{
JavaVM* jvm = closure->magazine->jvm;
*detach = (*jvm)->GetEnv(jvm, (void **)penv, JNI_VERSION_1_4) != JNI_OK
&& (*jvm)->AttachCurrentThreadAsDaemon(jvm, (void **)penv, NULL) == JNI_OK;
#ifndef _WIN32
if (*detach && thread_data_get()->attach_count++ >= THREAD_ATTACH_THRESHOLD) {
thread_data_get()->attached_vm = jvm;
*detach = false;
}
#endif
if ((**penv)->ExceptionCheck(*penv)) {
(**penv)->ExceptionClear(*penv);
}
}
static void
closure_end(Closure* closure, JNIEnv* env, bool detach)
{
JavaVM* jvm = closure->magazine->jvm;
bool clearException = detach;
#ifndef _WIN32
if (thread_data_get()->attached_vm != NULL) {
clearException = true;
}
#endif
if (env != NULL && clearException) {
if ((*env)->ExceptionCheck(env)) {
(*env)->ExceptionClear(env);
}
}
if (detach) {
(*jvm)->DetachCurrentThread(jvm);
}
}
static void
closure_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
{
Closure* closure = (Closure *) user_data;
JNIEnv* env;
int i;
bool detach;
#if FAULT_PROTECT_ENABLED
ThreadData* td = thread_data_get();
FaultData* fdp;
#endif
closure_begin(closure, &env, &detach);
#if FAULT_PROTECT_ENABLED
fdp = td->fault_data;
td->fault_data = NULL;
#endif
if (closure->magazine->callWithPrimitiveParameters) {
// allocate one more than the parameter count (for the struct return value)
jvalue* jparams = alloca((cif->nargs + 1) * sizeof(jvalue));
for (i = 0; i < (int) cif->nargs; i++) {
jvalue* vp = &jparams[i];
vp->j = 0LL; // zero out any bits not filled below
switch (cif->arg_types[i]->type) {
case FFI_TYPE_SINT8:
case FFI_TYPE_UINT8:
vp->b = *(jbyte *) parameters[i];
break;
case FFI_TYPE_SINT16:
case FFI_TYPE_UINT16:
vp->s = *(jshort *) parameters[i];
break;
case FFI_TYPE_SINT32:
case FFI_TYPE_UINT32:
case FFI_TYPE_INT:
vp->i = *(jint *) parameters[i];
break;
case FFI_TYPE_SINT64:
case FFI_TYPE_UINT64:
vp->j = *(jlong *) parameters[i];
break;
case FFI_TYPE_FLOAT:
vp->i = *(jfloat *) parameters[i];
break;
case FFI_TYPE_DOUBLE:
vp->i = *(jdouble *) parameters[i];
break;
case FFI_TYPE_POINTER:
if (cif->arg_types[i]->size == 4) {
vp->i = (uintptr_t) *(void **) parameters[i];
} else {
vp->j = p2j(*(void **) parameters[i]);
}
break;
case FFI_TYPE_STRUCT:
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
case FFI_TYPE_LONGDOUBLE:
#endif
vp->j = p2j(parameters[i]);
break;
default:
memset(vp, 0, sizeof(*vp));
break;
}
}
switch (cif->rtype->type) {
case FFI_TYPE_VOID:
(*env)->CallVoidMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
*((ffi_sarg *) retval) = 0;
break;
case FFI_TYPE_SINT8:
*((ffi_sarg *) retval) = (*env)->CallByteMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
break;
case FFI_TYPE_SINT16:
*((ffi_sarg *) retval) = (*env)->CallShortMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
break;
case FFI_TYPE_SINT32:
case FFI_TYPE_INT:
*((ffi_sarg *) retval) = (*env)->CallIntMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
break;
case FFI_TYPE_UINT8:
*((ffi_arg *) retval) = (*env)->CallByteMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
break;
case FFI_TYPE_UINT16:
*((ffi_arg *) retval) = (*env)->CallShortMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
break;
case FFI_TYPE_UINT32:
*((ffi_arg *) retval) = (*env)->CallIntMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
break;
case FFI_TYPE_SINT64:
*((int64_t *) retval) = (*env)->CallLongMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
break;
case FFI_TYPE_UINT64:
*((uint64_t *) retval) = (*env)->CallLongMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
break;
case FFI_TYPE_POINTER:
if (cif->rtype->size == 4) {
*((ffi_arg *) retval) = (*env)->CallIntMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
} else {
*((ffi_arg *) retval) = (*env)->CallLongMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
}
break;
case FFI_TYPE_FLOAT:
*((float *) retval) = (*env)->CallFloatMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
break;
case FFI_TYPE_DOUBLE:
*((double *) retval) = (*env)->CallDoubleMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
break;
case FFI_TYPE_STRUCT:
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
case FFI_TYPE_LONGDOUBLE:
#endif
// stuff the retval in as the last parameter passed to the java method
jparams[cif->nargs].j = p2j(retval);
(*env)->CallVoidMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
break;
default:
memset(retval, 0, cif->rtype->size);
}
} else {
jvalue jparams[2];
jparams[0].j = p2j(retval);
jparams[1].j = p2j(parameters);
//
// Do the actual invoke - the java code will unmarshal the arguments
//
(*env)->CallVoidMethodA(env, closure->javaObject, closure->magazine->methodID, jparams);
}
if ((*env)->ExceptionCheck(env)) {
memset(retval, 0, cif->rtype->size);
}
#if FAULT_PROTECT_ENABLED
td->fault_data = fdp;
#endif
closure_end(closure, env, detach);
}
static bool
closure_prep(ffi_cif* cif, void* code, Closure* closure, char* errbuf, size_t errbufsize)
{
ffi_status status;
status = ffi_prep_closure(code, cif, closure_invoke, closure);
switch (status) {
case FFI_OK:
return true;
case FFI_BAD_ABI:
snprintf(errbuf, errbufsize, "Invalid ABI specified");
//throwException(env, IllegalArgument, "Invalid ABI specified");
return false;
case FFI_BAD_TYPEDEF:
snprintf(errbuf, errbufsize, "Invalid argument type specified");
//throwException(env, IllegalArgument, "Invalid argument type specified");
return false;
default:
snprintf(errbuf, errbufsize, "Unknown FFI error");
//throwException(env, IllegalArgument, "Unknown FFI error");
return false;
}
}
jffi-1.2.7/jni/jffi/Exception.c 0000664 0000000 0000000 00000004352 12470474244 0016253 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2008 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#include
#include
#include
#include "Exception.h"
void
jffi_throwExceptionByName(JNIEnv* env, const char* exceptionName, const char* fmt, ...)
{
va_list ap;
char buf[1024] = { 0 };
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
(*env)->PushLocalFrame(env, 10);
jclass exceptionClass = (*env)->FindClass(env, exceptionName);
if (exceptionClass != NULL) {
(*env)->ThrowNew(env, exceptionClass, buf);
}
(*env)->PopLocalFrame(env, NULL);
va_end(ap);
}
const char* jffi_IllegalArgumentException = "java/lang/IllegalArgumentException";
const char* jffi_NullPointerException = "java/lang/NullPointerException";
const char* jffi_OutOfBoundsException = "java/lang/IndexOutOfBoundsException";
const char* jffi_OutOfMemoryException = "java/lang/OutOfMemoryError";
const char* jffi_RuntimeException = "java/lang/RuntimeError";
const char* jffi_UnsatisfiedLinkException = "java/lang/UnsatisfiedLinkError";
jffi-1.2.7/jni/jffi/Exception.h 0000664 0000000 0000000 00000003627 12470474244 0016264 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2008 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#ifndef jffi_Exception_h
#define jffi_Exception_h
#ifdef __cplusplus
extern "C" {
#endif
#define throwException(env, name, fmt, a...) \
jffi_throwExceptionByName((env), jffi_##name##Exception, fmt, ##a)
extern const char* jffi_IllegalArgumentException;
extern const char* jffi_NullPointerException;
extern const char* jffi_OutOfBoundsException;
extern const char* jffi_OutOfMemoryException;
extern const char* jffi_RuntimeException;
extern const char* jffi_UnsatisfiedLinkException;
extern void jffi_throwExceptionByName(JNIEnv* env, const char* exceptionName, const char* fmt, ...);
#ifdef __cplusplus
}
#endif
#endif /* jffi_Exception_h */
jffi-1.2.7/jni/jffi/FastIntInvoke.c 0000664 0000000 0000000 00000015036 12470474244 0017042 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2009 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#include
#include
#include
#include
#include
#include "endian.h"
#include "jffi.h"
#include "Exception.h"
#include "CallContext.h"
#include "LastError.h"
#include "FaultProtect.h"
#include "com_kenai_jffi_Foreign.h"
#include "FastNumeric.h"
#if !FAULT_PROTECT_ENABLED
# define CALL(ctx, stmt) do { stmt; SAVE_ERRNO(ctx); } while(0)
#else
# define CALL(ctx, stmt) FAULTPROT_CTX(env, ctx, stmt, return 0)
#endif
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeVrI
* Signature: (J)I
*/
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_invokeI0(JNIEnv* env, jclass self, jlong ctxAddress, jlong function)
{
CallContext *ctx = (CallContext *) j2p(ctxAddress);
ffi_sarg retval;
CALL(ctx, invokeI0(ctx, j2p(function), &retval));
return (jint) retval;
}
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_invokeI1(JNIEnv* env, jclass self, jlong ctxAddress, jlong function,
jint arg1)
{
CallContext *ctx = (CallContext *) j2p(ctxAddress);
ffi_sarg retval;
CALL(ctx, invokeI1(ctx, j2p(function), &retval, arg1));
return (jint) retval;
}
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_invokeI2(JNIEnv*env, jobject self, jlong ctxAddress, jlong function,
jint arg1, jint arg2)
{
CallContext *ctx = (CallContext *) j2p(ctxAddress);
ffi_sarg retval;
CALL(ctx, invokeI2(ctx, j2p(function), &retval, arg1, arg2));
return (jint) retval;
}
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_invokeI3(JNIEnv*env, jobject self, jlong ctxAddress, jlong function,
jint arg1, jint arg2, jint arg3)
{
CallContext *ctx = (CallContext *) j2p(ctxAddress);
ffi_sarg retval;
CALL(ctx, invokeI3(ctx, j2p(function), &retval, arg1, arg2, arg3));
return (jint) retval;
}
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_invokeI4(JNIEnv*env, jobject self, jlong ctxAddress, jlong function,
jint arg1, jint arg2, jint arg3, jint arg4)
{
CallContext *ctx = (CallContext *) j2p(ctxAddress);
ffi_sarg retval;
CALL(ctx, invokeI4(ctx, j2p(function), &retval, arg1, arg2, arg3, arg4));
return (jint) retval;
}
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_invokeI5(JNIEnv*env, jobject self, jlong ctxAddress, jlong function,
jint arg1, jint arg2, jint arg3, jint arg4, jint arg5)
{
CallContext *ctx = (CallContext *) j2p(ctxAddress);
ffi_sarg retval;
CALL(ctx, invokeI5(ctx, j2p(function), &retval, arg1, arg2, arg3, arg4, arg5));
return (jint) retval;
}
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_invokeI6(JNIEnv*env, jobject self, jlong ctxAddress, jlong function,
jint arg1, jint arg2, jint arg3, jint arg4, jint arg5, jint arg6)
{
CallContext *ctx = (CallContext *) j2p(ctxAddress);
ffi_sarg retval;
CALL(ctx, invokeI6(ctx, j2p(function), &retval, arg1, arg2, arg3, arg4, arg5, arg6));
return (jint) retval;
}
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeVrI
* Signature: (J)I
*/
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_invokeI0NoErrno(JNIEnv* env, jclass self, jlong ctxAddress, jlong function)
{
CallContext *ctx = (CallContext *) j2p(ctxAddress);
ffi_sarg retval;
invokeI0(ctx, j2p(function), &retval);
return (jint) retval;
}
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_invokeI1NoErrno(JNIEnv* env, jclass self, jlong ctxAddress, jlong function,
jint arg1)
{
CallContext *ctx = (CallContext *) j2p(ctxAddress);
ffi_sarg retval;
invokeI1(ctx, j2p(function), &retval, arg1);
return (int) retval;
}
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_invokeI2NoErrno(JNIEnv*env, jobject self, jlong ctxAddress, jlong function,
jint arg1, jint arg2)
{
CallContext *ctx = (CallContext *) j2p(ctxAddress);
ffi_sarg retval;
invokeI2(ctx, j2p(function), &retval, arg1, arg2);
return (int) retval;
}
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_invokeI3NoErrno(JNIEnv*env, jobject self, jlong ctxAddress, jlong function,
jint arg1, jint arg2, jint arg3)
{
CallContext *ctx = (CallContext *) j2p(ctxAddress);
ffi_sarg retval;
invokeI3(ctx, j2p(function), &retval, arg1, arg2, arg3);
return (int) retval;
}
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_invokeI4NoErrno(JNIEnv*env, jobject self, jlong ctxAddress, jlong function,
jint arg1, jint arg2, jint arg3, jint arg4)
{
CallContext *ctx = (CallContext *) j2p(ctxAddress);
ffi_sarg retval;
invokeI4(ctx, j2p(function), &retval, arg1, arg2, arg3, arg4);
return (jint) retval;
}
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_invokeI5NoErrno(JNIEnv*env, jobject self, jlong ctxAddress, jlong function,
jint arg1, jint arg2, jint arg3, jint arg4, jint arg5)
{
CallContext *ctx = (CallContext *) j2p(ctxAddress);
ffi_sarg retval;
invokeI5(ctx, j2p(function), &retval, arg1, arg2, arg3, arg4, arg5);
return (jint) retval;
}
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_invokeI6NoErrno(JNIEnv*env, jobject self, jlong ctxAddress, jlong function,
jint arg1, jint arg2, jint arg3, jint arg4, jint arg5, jint arg6)
{
CallContext *ctx = (CallContext *) j2p(ctxAddress);
ffi_sarg retval;
invokeI6(ctx, j2p(function), &retval, arg1, arg2, arg3, arg4, arg5, arg6);
return (jint) retval;
}
jffi-1.2.7/jni/jffi/FastLongInvoke.c 0000664 0000000 0000000 00000016350 12470474244 0017207 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2009 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#include
#include
#ifdef __sun
# include
#endif
#include
#include
#include
#include "endian.h"
#include "jffi.h"
#include "Exception.h"
#include "CallContext.h"
#include "LastError.h"
#include "FaultProtect.h"
#include "com_kenai_jffi_Foreign.h"
#include "FastNumeric.h"
/* for return values <= sizeof(long), need to use an ffi_sarg sized return value */
#if BYTE_ORDER == BIG_ENDIAN
# define RETVAL(retval, ctx) ((ctx->cif.rtype)->size > sizeof(ffi_sarg) ? (retval).j : (retval).sarg)
#else
# define RETVAL(retval, ctx) ((retval).j)
#endif
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeVrL
* Signature: (J)J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeL0(JNIEnv* env, jobject self, jlong ctxAddress, jlong function)
{
CallContext* ctx = (CallContext *) j2p(ctxAddress);
FFIValue retval;
FAULTPROT_CTX(env, ctx, invokeL0(ctx, j2p(function), &retval), return 0);
return RETVAL(retval, ctx);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeVrL
* Signature: (J)J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeL0NoErrno(JNIEnv* env, jobject self, jlong ctxAddress, jlong function)
{
CallContext* ctx = (CallContext *) j2p(ctxAddress);
FFIValue retval;
FAULTPROT_CTX(env, ctx, invokeL0(ctx, j2p(function), &retval), return 0);
return RETVAL(retval, ctx);
}
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeL1(JNIEnv* env, jobject self, jlong ctxAddress, jlong function,
jlong arg1)
{
CallContext* ctx = (CallContext *) j2p(ctxAddress);
FFIValue retval;
FAULTPROT_CTX(env, ctx, invokeL1(ctx, j2p(function), &retval, arg1), return 0);
return RETVAL(retval, ctx);
}
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeL1NoErrno(JNIEnv* env, jobject self, jlong ctxAddress, jlong function,
jlong arg1)
{
CallContext* ctx = (CallContext *) j2p(ctxAddress);
FFIValue retval;
FAULTPROT_CTX(env, ctx, invokeL1(ctx, j2p(function), &retval, arg1), return 0);
return RETVAL(retval, ctx);
}
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeL2(JNIEnv* env, jobject self, jlong ctxAddress, jlong function,
jlong arg1, jlong arg2)
{
CallContext* ctx = (CallContext *) j2p(ctxAddress);
FFIValue retval;
FAULTPROT_CTX(env, ctx, invokeL2(ctx, j2p(function), &retval, arg1, arg2), return 0);
return RETVAL(retval, ctx);
}
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeL2NoErrno(JNIEnv* env, jobject self, jlong ctxAddress, jlong function,
jlong arg1, jlong arg2)
{
CallContext* ctx = (CallContext *) j2p(ctxAddress);
FFIValue retval;
FAULTPROT_CTX(env, ctx, invokeL2(ctx, j2p(function), &retval, arg1, arg2), return 0);
return RETVAL(retval, ctx);
}
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeL3(JNIEnv* env, jobject self, jlong ctxAddress, jlong function,
jlong arg1, jlong arg2, jlong arg3)
{
CallContext* ctx = (CallContext *) j2p(ctxAddress);
FFIValue retval;
FAULTPROT_CTX(env, ctx, invokeL3(ctx, j2p(function), &retval, arg1, arg2, arg3), return 0);
return RETVAL(retval, ctx);
}
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeL3NoErrno(JNIEnv* env, jobject self, jlong ctxAddress, jlong function,
jlong arg1, jlong arg2, jlong arg3)
{
CallContext* ctx = (CallContext *) j2p(ctxAddress);
FFIValue retval;
FAULTPROT_CTX(env, ctx, invokeL3(ctx, j2p(function), &retval, arg1, arg2, arg3), return 0);
return RETVAL(retval, ctx);
}
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeL4(JNIEnv* env, jobject self, jlong ctxAddress, jlong function,
jlong arg1, jlong arg2, jlong arg3, jlong arg4)
{
CallContext* ctx = (CallContext *) j2p(ctxAddress);
FFIValue retval;
FAULTPROT_CTX(env, ctx, invokeL4(ctx, j2p(function), &retval, arg1, arg2, arg3, arg4), return 0);
return RETVAL(retval, ctx);
}
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeL4NoErrno(JNIEnv* env, jobject self, jlong ctxAddress, jlong function,
jlong arg1, jlong arg2, jlong arg3, jlong arg4)
{
CallContext* ctx = (CallContext *) j2p(ctxAddress);
FFIValue retval;
FAULTPROT_CTX(env, ctx, invokeL4(ctx, j2p(function), &retval, arg1, arg2, arg3, arg4), return 0);
return RETVAL(retval, ctx);
}
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeL5(JNIEnv* env, jobject self, jlong ctxAddress, jlong function,
jlong arg1, jlong arg2, jlong arg3, jlong arg4, jlong arg5)
{
CallContext* ctx = (CallContext *) j2p(ctxAddress);
FFIValue retval;
FAULTPROT_CTX(env, ctx, invokeL5(ctx, j2p(function), &retval, arg1, arg2, arg3, arg4, arg5), return 0);
return RETVAL(retval, ctx);
}
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeL5NoErrno(JNIEnv* env, jobject self, jlong ctxAddress, jlong function,
jlong arg1, jlong arg2, jlong arg3, jlong arg4, jlong arg5)
{
CallContext* ctx = (CallContext *) j2p(ctxAddress);
FFIValue retval;
FAULTPROT_CTX(env, ctx, invokeL5(ctx, j2p(function), &retval, arg1, arg2, arg3, arg4, arg5), return 0);
return RETVAL(retval, ctx);
}
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeL6(JNIEnv* env, jobject self, jlong ctxAddress, jlong function,
jlong arg1, jlong arg2, jlong arg3, jlong arg4, jlong arg5, jlong arg6)
{
CallContext* ctx = (CallContext *) j2p(ctxAddress);
FFIValue retval;
FAULTPROT_CTX(env, ctx, invokeL6(ctx, j2p(function), &retval, arg1, arg2, arg3, arg4, arg5, arg6), return 0);
return RETVAL(retval, ctx);
}
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeL6NoErrno(JNIEnv* env, jobject self, jlong ctxAddress, jlong function,
jlong arg1, jlong arg2, jlong arg3, jlong arg4, jlong arg5, jlong arg6)
{
CallContext* ctx = (CallContext *) j2p(ctxAddress);
FFIValue retval;
FAULTPROT_CTX(env, ctx, invokeL6(ctx, j2p(function), &retval, arg1, arg2, arg3, arg4, arg5, arg6), return 0);
return RETVAL(retval, ctx);
}
jffi-1.2.7/jni/jffi/FastNumeric.h 0000664 0000000 0000000 00000006610 12470474244 0016541 0 ustar 00root root 0000000 0000000 #ifndef JFFI_FASTNUMERIC_H
#define JFFI_FASTNUMERIC_H
#if (defined(__i386__) || defined(__x86_64__)) && defined(__GNUC__)
# define INT_BYPASS_FFI
#endif
#if defined(__x86_64__) && defined(__GNUC__)
# define LONG_BYPASS_FFI
#endif
# if defined(__x86_64) || defined(__amd64)
# define CLEAR_VARARGS ({__asm__ __volatile__("xorq %%rax, %%rax" ::: "rax");})
# else
# define CLEAR_VARARGS do { } while(0)
# endif
#if defined(INT_BYPASS_FFI)
# define invokeI0(ctx, fn, retval) do { \
CLEAR_VARARGS; *(retval) = ((jint (*)()) (fn))(); \
} while (0)
# define invokeI1(ctx, fn, retval, arg1) do { \
CLEAR_VARARGS; *(retval) = ((jint (*)(jint)) (fn))(arg1); \
} while (0)
# define invokeI2(ctx, fn, retval, arg1, arg2) do { \
CLEAR_VARARGS; *(retval) = ((jint (*)(jint, jint)) (fn))((arg1), (arg2)); \
} while (0)
# define invokeI3(ctx, fn, retval, arg1, arg2, arg3) do { \
CLEAR_VARARGS; *(retval) = ((jint (*)(jint, jint, jint)) (fn))(arg1, arg2, arg3); \
} while (0)
# define invokeI4(ctx, fn, retval, arg1, arg2, arg3, arg4) do { \
CLEAR_VARARGS; *(retval) = ((jint (*)(jint, jint, jint, jint)) (fn))(arg1, arg2, arg3, arg4); \
} while (0)
# define invokeI5(ctx, fn, retval, arg1, arg2, arg3, arg4, arg5) do { \
CLEAR_VARARGS; *(retval) = ((jint (*)(jint, jint, jint, jint, jint)) (fn))(arg1, arg2, arg3, arg4, arg5); \
} while (0)
# define invokeI6(ctx, fn, retval, arg1, arg2, arg3, arg4, arg5, arg6) do { \
CLEAR_VARARGS; *(retval) = ((jint (*)(jint, jint, jint, jint, jint, jint)) (fn))(arg1, arg2, arg3, arg4, arg5, arg6); \
} while (0)
#else /* non-i386, non-x86_64 */
# define invokeI0 ffi_call0
# define invokeI1 ffi_call1
# define invokeI2 ffi_call2
# define invokeI3 ffi_call3
# define invokeI4 ffi_call4
# define invokeI5 ffi_call5
# define invokeI6 ffi_call6
#endif
#if defined(LONG_BYPASS_FFI)
# define invokeL0(ctx, fn, retval) do { \
CLEAR_VARARGS; (retval)->j = ((jlong (*)()) (fn))(); \
} while (0)
# define invokeL1(ctx, fn, retval, arg1) do { \
CLEAR_VARARGS; (retval)->j = ((jlong (*)(jlong)) (fn))(arg1); \
} while (0)
# define invokeL2(ctx, fn, retval, arg1, arg2) do { \
CLEAR_VARARGS; (retval)->j = ((jlong (*)(jlong, jlong)) (fn))((arg1), (arg2)); \
} while (0)
# define invokeL3(ctx, fn, retval, arg1, arg2, arg3) do { \
CLEAR_VARARGS; (retval)->j = ((jlong (*)(jlong, jlong, jlong)) (fn))(arg1, arg2, arg3); \
} while (0)
# define invokeL4(ctx, fn, retval, arg1, arg2, arg3, arg4) do { \
CLEAR_VARARGS; (retval)->j = ((jlong (*)(jlong, jlong, jlong, jlong)) (fn))(arg1, arg2, arg3, arg4); \
} while (0)
# define invokeL5(ctx, fn, retval, arg1, arg2, arg3, arg4, arg5) do { \
CLEAR_VARARGS; (retval)->j = ((jlong (*)(jlong, jlong, jlong, jlong, jlong)) (fn))(arg1, arg2, arg3, arg4, arg5); \
} while (0)
# define invokeL6(ctx, fn, retval, arg1, arg2, arg3, arg4, arg5, arg6) do { \
CLEAR_VARARGS; (retval)->j = ((jlong (*)(jlong, jlong, jlong, jlong, jlong, jlong)) (fn))(arg1, arg2, arg3, arg4, arg5, arg6); \
} while (0)
#else /* non-i386, non-x86_64 */
# define invokeL0 ffi_call0
# define invokeL1 ffi_call1
# define invokeL2 ffi_call2
# define invokeL3 ffi_call3
# define invokeL4 ffi_call4
# define invokeL5 ffi_call5
# define invokeL6 ffi_call6
#endif
#endif /* JFFI_FASTNUMERIC_H */ jffi-1.2.7/jni/jffi/FastNumericInvoker.c 0000664 0000000 0000000 00000036361 12470474244 0020100 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2009 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#include
#include
#ifdef __sun
# include
#endif
#include
#include
#include
#include "endian.h"
#include "jffi.h"
#include "Exception.h"
#include "CallContext.h"
#include "Array.h"
#include "LastError.h"
#include "FaultProtect.h"
#include "com_kenai_jffi_Foreign.h"
#include "FastNumeric.h"
/* for return values <= sizeof(long), need to use an ffi_sarg sized return value */
#if BYTE_ORDER == BIG_ENDIAN
# define RETVAL(retval, ctx) ((ctx->cif.rtype)->size > sizeof(ffi_sarg) ? (retval).j : (retval).sarg)
#else
# define RETVAL(retval, ctx) ((retval).j)
#endif
#define MAX_STACK_ARRAY (1024)
#define OBJIDX(flags) ((flags & com_kenai_jffi_ObjectBuffer_INDEX_MASK) >> com_kenai_jffi_ObjectBuffer_INDEX_SHIFT)
#define OBJTYPE(flags) ((flags) & com_kenai_jffi_ObjectBuffer_TYPE_MASK)
#define IS_ARRAY(flags) \
((OBJTYPE(flags) & ~com_kenai_jffi_ObjectBuffer_PRIM_MASK) == com_kenai_jffi_ObjectBuffer_ARRAY)
#define IS_BUFFER(flags) \
((OBJTYPE(flags) & ~com_kenai_jffi_ObjectBuffer_PRIM_MASK) == com_kenai_jffi_ObjectBuffer_BUFFER)
typedef struct Pinned {
jobject object;
int offset;
int length;
int flags;
} Pinned;
typedef struct ObjectParam {
jobject object;
int offset;
int length;
int flags;
} ObjectParam;
static jlong call1(JNIEnv* env, CallContext* ctx, void* function,
jlong n1);
static jlong call2(JNIEnv* env, CallContext* ctx, void* function,
jlong n1, jlong n2);
static jlong call3(JNIEnv* env, CallContext* ctx, void* function,
jlong n1, jlong n2, jlong n3);
static jlong call4(JNIEnv* env, CallContext* ctx, void* function,
jlong n1, jlong n2, jlong n3, jlong n4);
static jlong call5(JNIEnv* env, CallContext* ctx, void* function,
jlong n1, jlong n2, jlong n3, jlong n4, jlong n5);
static jlong call6(JNIEnv* env, CallContext* ctx, void* function,
jlong n1, jlong n2, jlong n3, jlong n4, jlong n5, jlong n6);
static bool pin_arrays(JNIEnv* env, Pinned* pinned, int pinnedCount,
Array* arrays, int *arrayCount, jlong* v);
static bool object_to_ptr(JNIEnv* env, jobject obj, int off, int len, int f, jlong* vp,
Array* arrays, int* arrayCount, Pinned* pinned, int* pinnedCount);
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeVrL
* Signature: (J)J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeN0(JNIEnv* env, jobject self, jlong ctxAddress, jlong function)
{
CallContext* ctx = (CallContext *) j2p(ctxAddress);
FFIValue retval;
FAULTPROT_CTX(env, ctx, if (0) {
#if defined(LONG_BYPASS_FFI)
} else if (likely((ctx->flags & CALL_CTX_FAST_LONG) != 0)) {
invokeL0(ctx, j2p(function), &retval);
#endif
#if defined(INT_BYPASS_FFI)
} else if (likely((ctx->flags & CALL_CTX_FAST_INT) != 0)) {
invokeI0(ctx, j2p(function), &retval.j);
#endif
} else {
ffi_call0(ctx, j2p(function), &retval);
}, return 0);
return RETVAL(retval, ctx);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeLrL
* Signature: (JJ)J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeN1(JNIEnv* env, jobject self, jlong ctxAddress, jlong function, jlong arg1)
{
return call1(env, (CallContext *) j2p(ctxAddress), j2p(function), arg1);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeLLrL
* Signature: (JJJ)J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeN2(JNIEnv* env, jobject self, jlong ctxAddress, jlong function, jlong arg1, jlong arg2)
{
return call2(env, (CallContext *) j2p(ctxAddress), j2p(function), arg1, arg2);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeLLLrL
* Signature: (JJJJ)J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeN3(JNIEnv* env, jobject self, jlong ctxAddress, jlong function,
jlong arg1, jlong arg2, jlong arg3)
{
return call3(env, (CallContext *) j2p(ctxAddress), j2p(function), arg1, arg2, arg3);
}
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeN4(JNIEnv* env, jobject self, jlong ctxAddress, jlong function,
jlong arg1, jlong arg2, jlong arg3, jlong arg4)
{
return call4(env, (CallContext *) j2p(ctxAddress), j2p(function), arg1, arg2, arg3, arg4);
}
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeN5(JNIEnv* env, jobject self, jlong ctxAddress, jlong function,
jlong arg1, jlong arg2, jlong arg3, jlong arg4, jlong arg5)
{
return call5(env, (CallContext *) j2p(ctxAddress), j2p(function), arg1, arg2, arg3, arg4, arg5);
}
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeN6(JNIEnv* env, jobject self, jlong ctxAddress, jlong function,
jlong arg1, jlong arg2, jlong arg3, jlong arg4, jlong arg5, jlong arg6)
{
return call6(env, (CallContext *) j2p(ctxAddress), j2p(function), arg1, arg2, arg3, arg4, arg5, arg6);
}
static jlong
call1(JNIEnv* env, CallContext* ctx, void* function, jlong n1)
{
FFIValue retval;
FAULTPROT_CTX(env, ctx, if (0) {
#if defined(LONG_BYPASS_FFI)
} else if (likely((ctx->flags & CALL_CTX_FAST_LONG) != 0)) {
invokeL1(ctx, function, &retval, n1);
#endif
#if defined(INT_BYPASS_FFI)
} else if (likely((ctx->flags & CALL_CTX_FAST_INT) != 0)) {
invokeI1(ctx, function, &retval.j, (jint) n1);
#endif
} else {
ffi_call1(ctx, function, &retval, n1);
}, return 0);
return RETVAL(retval, ctx);
}
static jlong
call2(JNIEnv* env, CallContext* ctx, void* function, jlong n1, jlong n2)
{
FFIValue retval;
FAULTPROT_CTX(env, ctx, if (0) {
#if defined(LONG_BYPASS_FFI)
} else if (likely((ctx->flags & CALL_CTX_FAST_LONG) != 0)) {
invokeL2(ctx, function, &retval, n1, n2);
#endif
#if defined(INT_BYPASS_FFI)
} else if (likely((ctx->flags & CALL_CTX_FAST_INT) != 0)) {
invokeI2(ctx, function, &retval.j, (jint) n1, (jint) n2);
#endif
} else {
ffi_call2(ctx, function, &retval, n1, n2);
}, return 0);
return RETVAL(retval, ctx);
}
static jlong
call3(JNIEnv* env, CallContext* ctx, void* function, jlong n1, jlong n2, jlong n3)
{
FFIValue retval;
FAULTPROT_CTX(env, ctx, if (0) {
#if defined(LONG_BYPASS_FFI)
} else if (likely((ctx->flags & CALL_CTX_FAST_LONG) != 0)) {
invokeL3(ctx, function, &retval, n1, n2, n3);
#endif
#if defined(INT_BYPASS_FFI)
} else if (likely((ctx->flags & CALL_CTX_FAST_INT) != 0)) {
invokeI3(ctx, function, &retval.j, (jint) n1, (jint) n2, (jint) n3);
#endif
} else {
ffi_call3(ctx, function, &retval, n1, n2, n3);
}, return 0);
return RETVAL(retval, ctx);
}
static jlong
call4(JNIEnv* env, CallContext* ctx, void* function, jlong n1, jlong n2, jlong n3, jlong n4)
{
FFIValue retval;
FAULTPROT_CTX(env, ctx, if (0) {
#if defined(LONG_BYPASS_FFI)
} else if (likely((ctx->flags & CALL_CTX_FAST_LONG) != 0)) {
invokeL4(ctx, function, &retval, n1, n2, n3, n4);
#endif
#if defined(INT_BYPASS_FFI)
} else if (likely((ctx->flags & CALL_CTX_FAST_INT) != 0)) {
invokeI4(ctx, function, &retval.j, (jint) n1, (jint) n2, (jint) n3, (jint) n4);
#endif
} else {
ffi_call4(ctx, function, &retval, n1, n2, n3, n4);
}, return 0);
return RETVAL(retval, ctx);
}
static jlong
call5(JNIEnv* env, CallContext* ctx, void* function,
jlong n1, jlong n2, jlong n3, jlong n4, jlong n5)
{
FFIValue retval;
FAULTPROT_CTX(env, ctx, if (0) {
#if defined(LONG_BYPASS_FFI)
} else if (likely((ctx->flags & CALL_CTX_FAST_LONG) != 0)) {
invokeL5(ctx, function, &retval, n1, n2, n3, n4, n5);
#endif
#if defined(INT_BYPASS_FFI)
} else if (likely((ctx->flags & CALL_CTX_FAST_INT) != 0)) {
invokeI5(ctx, function, &retval.j, (jint) n1, (jint) n2, (jint) n3, (jint) n4, (jint) n5);
#endif
} else {
ffi_call5(ctx, function, &retval, n1, n2, n3, n4, n5);
}, return 0);
return RETVAL(retval, ctx);
}
static jlong
call6(JNIEnv* env, CallContext* ctx, void* function,
jlong n1, jlong n2, jlong n3, jlong n4, jlong n5, jlong n6)
{
FFIValue retval;
FAULTPROT_CTX(env, ctx, if (0) {
#if defined(LONG_BYPASS_FFI)
} else if (likely((ctx->flags & CALL_CTX_FAST_LONG) != 0)) {
invokeL6(ctx, function, &retval, n1, n2, n3, n4, n5, n6);
#endif
#if defined(INT_BYPASS_FFI)
} else if (likely((ctx->flags & CALL_CTX_FAST_INT) != 0)) {
invokeI6(ctx, function, &retval.j, (jint) n1, (jint) n2, (jint) n3, (jint) n4, (jint) n5, (jint) n6);
#endif
} else {
ffi_call6(ctx, function, &retval, n1, n2, n3, n4, n5, n6);
}, return 0);
return RETVAL(retval, ctx);
}
static bool
pin_arrays(JNIEnv* env, Pinned* pinned, int pinnedCount,
Array* arrays, int *arrayCount, jlong* v)
{
int aryIdx;
for (aryIdx = 0; aryIdx < pinnedCount; aryIdx++) {
Pinned* p = &pinned[aryIdx];
Array* ary = &arrays[*arrayCount];
void* addr = jffi_getArrayCritical(env, p->object, p->offset, p->length, p->flags, ary);
if (unlikely(addr == NULL)) {
return false;
}
v[OBJIDX(p->flags)] = p2j(addr);
(*arrayCount)++;
}
return true;
}
static bool
object_to_ptr(JNIEnv* env, jobject obj, int off, int len, int f, jlong* vp,
Array* arrays, int* arrayCount, Pinned* pinned, int* pinnedCount)
{
if (unlikely(obj == NULL)) {
throwException(env, NullPointer, "null object for parameter %d", OBJIDX(f));
return false;
} else if (unlikely(IS_PINNED_ARRAY(f))) {
Pinned* p = &pinned[(*pinnedCount)++];
p->object = obj;
p->offset = off;
p->length = len;
p->flags = f;
*vp = 0LL;
} else if (IS_ARRAY(f)) {
*vp = p2j(jffi_getArrayHeap(env, obj, off, len, f, &arrays[*arrayCount]));
if (unlikely(*vp == 0L)) {
return false;
}
(*arrayCount)++;
} else if (IS_BUFFER((f))) {
caddr_t addr = (caddr_t) (*env)->GetDirectBufferAddress(env, obj);
if (unlikely(addr == NULL)) {
throwException(env, NullPointer,
"could not get direct buffer address for parameter %d", OBJIDX(f));
return false;
}
*vp = p2j(addr + off);
} else {
throwException(env, IllegalArgument, "unsupported object type for parameter %d: %#x", OBJIDX(f), f);
return false;
}
return true;
}
#define N1 n1
#define N2 N1, n2
#define N3 N2, n3
#define N4 N3, n4
#define N5 N4, n5
#define N6 N5, n6
#define INIT(n) \
const int MAX_PARAM_INDEX = (n) - 1; \
CallContext* ctx = (CallContext *) j2p(ctxAddress); \
Array arrays[(n)]; \
Pinned pinned[(n)]; \
int arrayCount = 0, pinnedCount = 0; \
jlong retval = 0; \
jlong v[] = { N##n }
#define END \
error: \
RELEASE_ARRAYS(env, arrays, arrayCount); \
return retval
#define ADDOBJ(obj, off, len, flags) do { \
int idx = OBJIDX(flags); \
if (unlikely(idx < 0 || idx > MAX_PARAM_INDEX)) { \
throwException(env, OutOfBounds, "invalid object parameter index %d (expected 0..%d)", \
idx, MAX_PARAM_INDEX); \
goto error; \
} \
if (likely(IS_UNPINNED_ARRAY(flags) && len < MAX_STACK_ARRAY)) { \
void* ptr = alloca(jffi_arraySize((len) + 1, (flags))); \
if (unlikely(jffi_getArrayBuffer(env, obj, off, len, flags, &arrays[arrayCount], ptr) == NULL)) { \
goto error; \
} \
v[idx] = p2j(ptr); \
arrayCount++; \
} else if (!object_to_ptr(env, obj, off, len, flags, &v[idx], arrays, &arrayCount, pinned, &pinnedCount)) { \
goto error; \
} \
} while (0)
#define PIN_ARRAYS do { \
if (unlikely(pinnedCount > 0)) { \
if (!pin_arrays(env, pinned, pinnedCount, arrays, &arrayCount, v)) goto error; \
} \
} while(0)
#define CALL(n, args...) \
PIN_ARRAYS; \
retval = call##n(env, ctx, j2p(function), args); \
END
#define CALL1 CALL(1, v[0])
#define CALL2 CALL(2, v[0], v[1])
#define CALL3 CALL(3, v[0], v[1], v[2])
#define CALL4 CALL(4, v[0], v[1], v[2], v[3])
#define CALL5 CALL(5, v[0], v[1], v[2], v[3], v[4])
#define CALL6 CALL(6, v[0], v[1], v[2], v[3], v[4], v[5])
#define IMPL(n) \
INIT(n); \
int objIdx; \
for (objIdx = 0; objIdx < nobjects; objIdx++) { \
ADDOBJ(objects[objIdx].object, objects[objIdx].offset, objects[objIdx].length, \
objects[objIdx].flags); \
} \
CALL##n;
#define DEF_N(x) jlong n##x
#define DEF_N1 DEF_N(1)
#define DEF_N2 DEF_N1, DEF_N(2)
#define DEF_N3 DEF_N2, DEF_N(3)
#define DEF_N4 DEF_N3, DEF_N(4)
#define DEF_N5 DEF_N4, DEF_N(5)
#define DEF_N6 DEF_N5, DEF_N(6)
#define DEFINVOKE(n) \
static jlong invoke##n(JNIEnv* env, jobject self, jlong ctxAddress, jlong function, DEF_N##n, ObjectParam* objects, int nobjects) \
{ \
IMPL(n); \
}
DEFINVOKE(1)
DEFINVOKE(2)
DEFINVOKE(3)
DEFINVOKE(4)
DEFINVOKE(5)
DEFINVOKE(6)
#define DEF_O(x) jobject o##x, jint o##x##flags, jint o##x##off, jint o##x##len
#define DEF_O1 DEF_O(1)
#define DEF_O2 DEF_O1, DEF_O(2)
#define DEF_O3 DEF_O2, DEF_O(3)
#define DEF_O4 DEF_O3, DEF_O(4)
#define DEF_O5 DEF_O4, DEF_O(5)
#define DEF_O6 DEF_O5, DEF_O(6)
#define DEF_N(x) jlong n##x
#define DEF_N1 DEF_N(1)
#define DEF_N2 DEF_N1, DEF_N(2)
#define DEF_N3 DEF_N2, DEF_N(3)
#define DEF_N4 DEF_N3, DEF_N(4)
#define DEF_N5 DEF_N4, DEF_N(5)
#define DEF_N6 DEF_N5, DEF_N(6)
#define OBJ(x) { o##x, o##x##off, o##x##len, o##x##flags }
#define OBJ1 OBJ(1)
#define OBJ2 OBJ1, OBJ(2)
#define OBJ3 OBJ2, OBJ(3)
#define OBJ4 OBJ3, OBJ(4)
#define OBJ5 OBJ4, OBJ(5)
#define OBJ6 OBJ5, OBJ(6)
#define DEFJNI(n, o) \
JNIEXPORT jlong JNICALL \
Java_com_kenai_jffi_Foreign_invokeN##n##O##o(JNIEnv* env, jobject self, jlong ctxAddress, jlong function, DEF_N##n, DEF_O##o) \
{ \
ObjectParam objects[] = { OBJ##o }; \
return invoke##n(env, self, ctxAddress, function, N##n, objects, o); \
}
DEFJNI(1, 1)
DEFJNI(2, 1)
DEFJNI(2, 2)
DEFJNI(3, 1)
DEFJNI(3, 2)
DEFJNI(3, 3)
DEFJNI(4, 1)
DEFJNI(4, 2)
DEFJNI(4, 3)
DEFJNI(4, 4)
DEFJNI(5, 1)
DEFJNI(5, 2)
DEFJNI(5, 3)
DEFJNI(5, 4)
DEFJNI(5, 5)
DEFJNI(6, 1)
DEFJNI(6, 2)
DEFJNI(6, 3)
DEFJNI(6, 4)
DEFJNI(6, 5)
DEFJNI(6, 6)
jffi-1.2.7/jni/jffi/FaultProtect.c 0000664 0000000 0000000 00000012117 12470474244 0016727 0 ustar 00root root 0000000 0000000 #include "FaultProtect.h"
#if FAULT_PROTECT_ENABLED
#include
#include
#include
#include
#include
#include
#include
#include
#include "jffi.h"
#include "Exception.h"
#ifdef __APPLE__
# define SKIP_FRAME_COUNT (2)
#endif
struct sigaction jffi_sigsegv_chain;
struct sigaction jffi_sigbus_chain;
void
fill_in_backtrace(FaultData* fdp)
{
unw_context_t uc;
unw_cursor_t c;
int i, boff;
memset(&uc, 0, sizeof(uc));
memset(&c, 0, sizeof(c));
if (unw_getcontext(&uc) < 0) {
abort();
}
if (unw_init_local(&c, &uc) < 0) {
abort();
}
// Skip the signal handler, and the signal trampoline
for (i = 0; i < SKIP_FRAME_COUNT; i++) {
if (unw_step(&c) <= 0) {
break;
}
}
memset(fdp->frame, 0, sizeof(fdp->frame));
fdp->frame_count = 0;
boff = 0;
do {
char fn[256];
unw_word_t off, ip;
Dl_info dli;
unw_proc_info_t pi;
unw_get_reg (&c, UNW_REG_IP, &ip);
fdp->frame[fdp->frame_count].addr = (uintptr_t) ip;
fdp->frame[fdp->frame_count].procname = (uintptr_t) &fdp->backtrace_buf[boff];
unw_get_proc_name(&c, (char *) fdp->frame[fdp->frame_count].procname, sizeof(fdp->backtrace_buf) - boff, &off);
unw_get_proc_info(&c, &pi);
boff += strlen((char *) fdp->frame[fdp->frame_count].procname) + 1;
fdp->frame[fdp->frame_count].libname = (uintptr_t) &fdp->backtrace_buf[boff];
dladdr((void *)(uintptr_t) ip, &dli);
strcpy((char *) (uintptr_t) fdp->frame[fdp->frame_count].libname, dli.dli_fname);
boff += strlen((char *) fdp->frame[fdp->frame_count].libname) + 1;
fdp->frame_count++;
} while (unw_step(&c) > 0);
}
static void
jffi_fault(void)
{
ThreadData* td = (ThreadData *) pthread_getspecific(jffi_threadDataKey);
FaultData* fdp = td->fault_data;
td->fault_data = NULL;
fill_in_backtrace(fdp);
jffi_longjmp(fdp->buf, fdp->sig);
// If we get here, we could not unwind the stack - restore the old signal handler, and let it re-fault
switch (fdp->sig) {
case SIGBUS:
sigaction(fdp->sig, &jffi_sigbus_chain, NULL);
break;
case SIGSEGV:
sigaction(fdp->sig, &jffi_sigsegv_chain, NULL);
break;
}
}
static void
jffi_fault_handler(ThreadData* td, int sig, siginfo_t* si, ucontext_t* uctx)
{
extern int _jffi_fault_trampoline;
FaultData* fdp = td->fault_data;
int i, boff;
fdp->mcontext = *uctx->uc_mcontext;
fdp->sig = sig;
#ifdef __x86_64__
uctx->uc_mcontext->__ss.__rax = (uintptr_t) &jffi_fault;
uctx->uc_mcontext->__ss.__rdx = uctx->uc_mcontext->__ss.__rip;
uctx->uc_mcontext->__ss.__rip = (uintptr_t) &_jffi_fault_trampoline;
uctx->uc_mcontext->__ss.__rflags = 0;
#elif defined(__i386__)
uctx->uc_mcontext->ss.eax = (uintptr_t) &jffi_fault;
uctx->uc_mcontext->ss.edx = uctx->uc_mcontext->ss.eip;
uctx->uc_mcontext->ss.eip = &_jffi_fault_trampoline;
uctx->uc_mcontext->ss.eflags = 0;
#else
# error "architecture not supported"
#endif
}
void
jffi_sigsegv(int sig, siginfo_t *si, void *uctx)
{
ThreadData* td = (ThreadData *) pthread_getspecific(jffi_threadDataKey);
if (td == NULL || td->fault_data == NULL) {
(*jffi_sigsegv_chain.sa_sigaction)(sig, si, uctx);
} else {
jffi_fault_handler(td, sig, si, (ucontext_t *) uctx);
}
}
void
jffi_sigbus(int sig, siginfo_t *si, void *uctx)
{
ThreadData* td = (ThreadData *) pthread_getspecific(jffi_threadDataKey);
if (td == NULL || td->fault_data == NULL) {
(*jffi_sigbus_chain.sa_sigaction)(sig, si, uctx);
} else {
jffi_fault_handler(td, sig, si, (ucontext_t *) uctx);
}
}
void
jffi_faultException(JNIEnv* env, struct FaultData_* f, int val)
{
jclass exceptionClass = (*env)->FindClass(env, "com/kenai/jffi/FaultException");
if (exceptionClass != NULL) {
jmethodID constructor = (*env)->GetMethodID(env, exceptionClass, "", "(I[J[J[J)V");
if (constructor != NULL) {
jlongArray addresses = (*env)->NewLongArray(env, f->frame_count);
jlongArray procnames = (*env)->NewLongArray(env, f->frame_count);
jlongArray libnames = (*env)->NewLongArray(env, f->frame_count);
int i;
for (i = 0; i < f->frame_count; i++) {
jlong ip = f->frame[i].addr;
jlong procname = f->frame[i].procname;
jlong libname = f->frame[i].libname;
(*env)->SetLongArrayRegion(env, addresses, i, 1, &ip);
(*env)->SetLongArrayRegion(env, procnames, i, 1, &procname);
(*env)->SetLongArrayRegion(env, libnames, i, 1, &libname);
}
jobject exc = (*env)->NewObject(env, exceptionClass, constructor, val, addresses, procnames, libnames);
if (exc != NULL) (*env)->Throw(env, (jthrowable) exc);
}
(*env)->DeleteLocalRef(env, exceptionClass);
} else {
throwException(env, NullPointer, "fault");
}
}
#endif
jffi-1.2.7/jni/jffi/FaultProtect.h 0000664 0000000 0000000 00000006720 12470474244 0016737 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2012 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#ifndef JFFI_FAULTPROTECT_H
#define JFFI_FAULTPROTECT_H
#include
#include
#include
#if defined(__APPLE__) && (defined(__x86_64__) || defined(__i386__)) && 0
# define FAULT_PROTECT_ENABLED (1)
#else
# define FAULT_PROTECT_ENABLED (0)
#endif
typedef struct FaultData_ FaultData;
#if FAULT_PROTECT_ENABLED
extern struct sigaction jffi_sigsegv_chain;
extern struct sigaction jffi_sigbus_chain;
extern void jffi_sigsegv(int sig, siginfo_t *si, void *uctx);
extern void jffi_sigbus(int sig, siginfo_t *si, void *uctx);
#include
#include
struct FaultData_ {
jmp_buf buf;
int sig;
_STRUCT_MCONTEXT mcontext;
struct {
uintptr_t addr;
uintptr_t procname;
uintptr_t libname;
} frame[128];
int frame_count;
char backtrace_buf[1024];
};
extern int jffi_setjmp(struct FaultData_ *);
extern void jffi_longjmp(jmp_buf env, int val);
extern void jffi_faultException(JNIEnv* env, struct FaultData_ *, int val);
#if defined(__amd64) || defined(__x86_64__)
# if defined (__APPLE__)
# define JB_SP 1
# define JB_RP 0
# define UNW_REG_EH UNW_X86_64_RAX
# endif
#else
# define JB_SP 1
# define JB_RP 0
# define UNW_REG_EH UNW_X86_EAX
#endif
#define FAULTPROT_CTX(env, ctx, stmt, fail) do { \
if (likely((ctx->flags & (CALL_CTX_SAVE_ERRNO | CALL_CTX_FAULT_PROT)) == 0)) { \
stmt; \
} else if (likely((ctx->flags & CALL_CTX_FAULT_PROT) == 0)) { \
stmt; \
jffi_save_errno_ctx(ctx); \
} else { \
JNIEnv* volatile env_ = env; \
FaultData fd; \
int val; \
\
if (unlikely((val = jffi_setjmp(&fd)) != 0)) { \
jffi_faultException(env_, &fd, val); \
fail; \
} else { \
ThreadData* td = thread_data_get(); \
td->fault_data = &fd; \
stmt; \
td->fault_data = NULL; \
jffi_save_errno_td(td, ctx); \
} \
} \
} while(0)
#else /* fault protection not enabled */
struct FaultData_ { long dummy; };
# define FAULTPROT_CTX(env, ctx, stmt, fail) do { \
stmt; \
SAVE_ERRNO(ctx); \
} while(0)
#endif
#endif /* JFFI_FAULTPROTECT_H */
jffi-1.2.7/jni/jffi/Foreign.c 0000664 0000000 0000000 00000016220 12470474244 0015703 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2008-2010 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#include
#ifndef _WIN32
# include
#endif
#include
#include
#include "Exception.h"
#include "com_kenai_jffi_Foreign.h"
#include "com_kenai_jffi_Version.h"
#include "jffi.h"
#include "FaultProtect.h"
#ifndef _WIN32
pthread_key_t jffi_threadDataKey;
static void thread_data_free(void *ptr);
#endif
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *vm, void *reserved)
{
#ifndef _WIN32
struct sigaction sa;
pthread_key_create(&jffi_threadDataKey, thread_data_free);
#if FAULT_PROTECT_ENABLED
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = jffi_sigsegv;
sa.sa_flags = SA_SIGINFO;
sigaction(SIGSEGV, &sa, &jffi_sigsegv_chain);
sa.sa_sigaction = jffi_sigbus;
sigaction(SIGBUS, &sa, &jffi_sigbus_chain);
#endif
#endif
return JNI_VERSION_1_4;
}
JNIEXPORT void JNICALL
JNI_OnUnload(JavaVM *jvm, void *reserved)
{
#ifndef _WIN32
pthread_key_delete(jffi_threadDataKey);
#endif
}
#ifndef _WIN32
ThreadData*
jffi_thread_data_init()
{
ThreadData* td = calloc(1, sizeof(*td));
pthread_setspecific(jffi_threadDataKey, td);
return td;
}
static void
thread_data_free(void *ptr)
{
ThreadData* td = (ThreadData *) ptr;
if (td->attached_vm != NULL) {
(*td->attached_vm)->DetachCurrentThread(td->attached_vm);
}
free(ptr);
}
#endif /* !_WIN32 */
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_getVersion(JNIEnv* env, jobject self)
{
return (com_kenai_jffi_Version_MAJOR << 16)
| (com_kenai_jffi_Version_MINOR << 8)
| (com_kenai_jffi_Version_MICRO);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: init
* Signature: ()V
*
* Initialize any class/method/field ids
*/
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_init(JNIEnv* env, jobject self)
{
}
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_getJNIVersion(JNIEnv* env, jobject self)
{
return (*env)->GetVersion(env);
}
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_getJavaVM(JNIEnv *env, jobject self)
{
JavaVM* vm;
(*env)->GetJavaVM(env, &vm);
return p2j(vm);
}
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_fatalError(JNIEnv * env, jobject self, jstring msg)
{
const char* str = (*env)->GetStringUTFChars(env, msg, NULL);
(*env)->FatalError(env, str);
(*env)->ReleaseStringUTFChars(env, msg, str);
}
JNIEXPORT jclass JNICALL
Java_com_kenai_jffi_Foreign_defineClass__Ljava_lang_String_2Ljava_lang_Object_2_3BII(JNIEnv *env,
jobject self, jstring jname, jobject loader, jbyteArray jbuf, jint off, jint len)
{
const char* name = NULL;
jbyte* buf = NULL;
jclass retval = NULL;
name = (*env)->GetStringUTFChars(env, jname, NULL);
if (name == NULL) {
throwException(env, NullPointer, "Invalid name parameter");
goto cleanup;
}
buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
if (buf == NULL) {
throwException(env, NullPointer, "Invalid buffer parameter");
goto cleanup;
}
retval = (*env)->DefineClass(env, name, loader, buf + off, len);
cleanup:
if (buf != NULL) {
(*env)->ReleaseByteArrayElements(env, jbuf, buf, JNI_ABORT);
}
if (name != NULL) {
(*env)->ReleaseStringUTFChars(env, jname, name);
}
return retval;
}
JNIEXPORT jclass JNICALL
Java_com_kenai_jffi_Foreign_defineClass__Ljava_lang_String_2Ljava_lang_Object_2Ljava_nio_ByteBuffer_2(JNIEnv *env,
jobject self, jstring jname, jobject loader, jobject jbuf)
{
const char* name = NULL;
jclass retval = NULL;
name = (*env)->GetStringUTFChars(env, jname, NULL);
if (name == NULL) {
throwException(env, NullPointer, "Invalid name parameter");
goto cleanup;
}
if (jbuf == NULL) {
throwException(env, NullPointer, "Invalid buffer parameter");
goto cleanup;
}
retval = (*env)->DefineClass(env, name, loader,
(*env)->GetDirectBufferAddress(env, jbuf),
(*env)->GetDirectBufferCapacity(env, jbuf));
cleanup:
if (name != NULL) {
(*env)->ReleaseStringUTFChars(env, jname, name);
}
return retval;
}
JNIEXPORT jobject JNICALL
Java_com_kenai_jffi_Foreign_allocObject(JNIEnv *env, jobject self, jclass klass)
{
return (*env)->AllocObject(env, klass);
}
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_registerNatives(JNIEnv *env, jobject self, jclass clazz,
jlong methods, jint nmethods)
{
return (*env)->RegisterNatives(env, clazz, j2p(methods), nmethods);
}
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_unregisterNatives(JNIEnv *env, jobject self, jclass clazz)
{
return (*env)->UnregisterNatives(env, clazz);
}
/*
* Determine the cpu type at compile time - useful for MacOSX where the jvm
* reports os.arch as 'universal'
*/
#if defined(__i386__) || defined(__i386)
# define CPU "i386"
#elif defined(__x86_64__) || defined(__x86_64) || defined(__amd64)
# define CPU "x86_64"
#elif defined(__ppc64__) || defined(__powerpc64__)
# define CPU "ppc64"
#elif defined(__ppc__) || defined(__powerpc__) || defined(__powerpc)
# define CPU "ppc"
/* Need to check for __sparcv9 first, because __sparc will be defined either way
. */
#elif defined(__sparcv9__) || defined(__sparcv9)
# define CPU "sparcv9"
#elif defined(__sparc__) || defined(__sparc)
# define CPU "sparc"
#elif defined(__arm__) || defined(__arm)
# define CPU "arm"
#elif defined(__ia64__) || defined(__ia64)
# define CPU "ia64"
#elif defined(__mips__) || defined(__mips)
# define CPU "mips"
#elif defined(__s390__)
# define CPU "s390"
#else
# define CPU "unknown"
#endif
/*
* Class: com_kenai_jffi_Foreign
* Method: getArch
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL
Java_com_kenai_jffi_Foreign_getArch(JNIEnv *env, jobject self)
{
return (*env)->NewStringUTF(env, CPU);
}
JNIEXPORT jboolean JNICALL
Java_com_kenai_jffi_Foreign_isFaultProtectionEnabled(JNIEnv *env , jclass klass)
{
return FAULT_PROTECT_ENABLED ? JNI_TRUE : JNI_FALSE;
}
jffi-1.2.7/jni/jffi/Internals.c 0000664 0000000 0000000 00000003611 12470474244 0016251 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2010 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#include
#include
#include "Exception.h"
#include "com_kenai_jffi_Foreign.h"
#include "LastError.h"
#include "CallContext.h"
#include "jffi.h"
/*
* Class: com_kenai_jffi_Foreign
* Method: getSaveErrnoFunction
* Signature: ()J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_getSaveErrnoFunction(JNIEnv *env, jobject self)
{
return p2j(jffi_save_errno);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: getSaveErrnoFunction
* Signature: ()J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_getSaveErrnoCtxFunction(JNIEnv *env, jobject self)
{
return p2j(jffi_save_errno_ctx);
}
jffi-1.2.7/jni/jffi/Invoke.c 0000664 0000000 0000000 00000042504 12470474244 0015551 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2008-2010 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#include
#include
#if defined (__sun) || defined(_AIX)
# include
#endif
#ifdef _WIN32
# include
#endif
#include
#include
#include
#include "jffi.h"
#include "Exception.h"
#include "CallContext.h"
#include "Array.h"
#include "LastError.h"
#include "FaultProtect.h"
#include "com_kenai_jffi_Foreign.h"
#define PARAM_SIZE (8)
#define MAX_STACK_ARRAY (1024)
typedef struct Pinned {
jobject object;
jsize offset;
jsize length;
int type;
} Pinned;
# define COPY_ARGS(ctx, src, ffiArgs) do { \
int idx; \
for (idx = 0; idx < (int) ctx->cif.nargs; ++idx) { \
if (unlikely(ctx->cif.arg_types[idx]->type == FFI_TYPE_STRUCT)) { \
ffiArgs[idx] = *(void **) &src[idx * PARAM_SIZE]; \
} else { \
ffiArgs[idx] = &src[idx * PARAM_SIZE]; \
} \
} \
} while (0)
# define ARG_BUFFER_SIZE(ctx) ((ctx)->cif.nargs * PARAM_SIZE)
static void
invokeArrayWithObjects_(JNIEnv* env, jlong ctxAddress, jlong function, jbyteArray paramBuffer,
jint objectCount, jint* infoBuffer, jobject* objectBuffer, void* retval);
/*
* Class: com_kenai_jffi_Foreign
* Method: isRawParameterPackingEnabled
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL
Java_com_kenai_jffi_Foreign_isRawParameterPackingEnabled(JNIEnv* env, jobject self)
{
return JNI_FALSE;
}
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeArrayInt32
* Signature: (J[B)I
*/
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_invokeArrayReturnInt(JNIEnv* env, jclass self, jlong ctxAddress, jlong function,
jbyteArray paramBuffer)
{
FFIValue retval;
invokeArrayWithObjects_(env, ctxAddress, function, paramBuffer, 0, NULL, NULL, &retval);
return_int(retval);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeArrayInt64
* Signature: (J[B)J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeArrayReturnLong(JNIEnv* env, jclass self, jlong ctxAddress, jlong function,
jbyteArray paramBuffer)
{
FFIValue retval;
invokeArrayWithObjects_(env, ctxAddress, function, paramBuffer, 0, NULL, NULL, &retval);
return retval.s64;
}
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeArrayFloat
* Signature: (J[B)F
*/
JNIEXPORT jfloat JNICALL
Java_com_kenai_jffi_Foreign_invokeArrayReturnFloat(JNIEnv* env, jclass self, jlong ctxAddress, jlong function,
jbyteArray paramBuffer)
{
FFIValue retval;
invokeArrayWithObjects_(env, ctxAddress, function, paramBuffer, 0, NULL, NULL, &retval);
return retval.f;
}
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeArrayDouble
* Signature: (J[B)D
*/
JNIEXPORT jdouble JNICALL
Java_com_kenai_jffi_Foreign_invokeArrayReturnDouble(JNIEnv* env, jclass self, jlong ctxAddress, jlong function,
jbyteArray paramBuffer)
{
FFIValue retval;
invokeArrayWithObjects_(env, ctxAddress, function, paramBuffer, 0, NULL, NULL, &retval);
return retval.d;
}
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeArrayReturnStruct
* Signature: (J[B[B)V
*/
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_invokeArrayReturnStruct(JNIEnv* env, jclass self, jlong ctxAddress, jlong function,
jbyteArray paramBuffer, jbyteArray returnBuffer, jint offset)
{
CallContext* ctx = (CallContext *) j2p(ctxAddress);
jbyte* retval = alloca(ctx->cif.rtype->size);
invokeArrayWithObjects_(env, ctxAddress, function, paramBuffer, 0, NULL, NULL, retval);
(*env)->SetByteArrayRegion(env, returnBuffer, offset, ctx->cif.rtype->size, retval);
}
static void
invokeArrayWithObjects_(JNIEnv* env, jlong ctxAddress, jlong function, jbyteArray paramBuffer,
jint objectCount, jint* infoBuffer, jobject* objectBuffer, void* retval)
{
CallContext* ctx = (CallContext *) j2p(ctxAddress);
void **ffiArgs = { NULL };
Array *arrays = NULL;
Pinned *pinned = NULL;
int i, arrayCount = 0, pinnedCount = 0, paramBytes = 0;
if (unlikely(objectCount > 0)) {
arrays = alloca(objectCount * sizeof(Array));
pinned = alloca(objectCount * sizeof(Pinned));
}
if (ctx->cif.nargs > 0) {
jbyte* tmpBuffer = alloca(ARG_BUFFER_SIZE(ctx));
(*env)->GetByteArrayRegion(env, paramBuffer, 0, ARG_BUFFER_SIZE(ctx), tmpBuffer);
ffiArgs = alloca(ctx->cif.nargs * sizeof(void *));
COPY_ARGS(ctx, tmpBuffer, ffiArgs);
}
for (i = 0; i < objectCount; ++i) {
int type = infoBuffer[i * 3];
jsize offset = infoBuffer[(i * 3) + 1];
jsize length = infoBuffer[(i * 3) + 2];
jobject object = objectBuffer[i];
int idx = (type & com_kenai_jffi_ObjectBuffer_INDEX_MASK) >> com_kenai_jffi_ObjectBuffer_INDEX_SHIFT;
void* ptr;
switch (type & com_kenai_jffi_ObjectBuffer_TYPE_MASK & ~com_kenai_jffi_ObjectBuffer_PRIM_MASK) {
case com_kenai_jffi_ObjectBuffer_ARRAY:
if (unlikely(object == NULL)) {
throwException(env, NullPointer, "null object for parameter %d", idx);
goto cleanup;
}
if (unlikely((type & com_kenai_jffi_ObjectBuffer_PINNED) != 0)) {
// Record the pinned array, but the actual pinning will be done just before the ffi_call
Pinned* p = &pinned[pinnedCount++];
p->object = object;
p->offset = offset;
p->length = length;
p->type = type;
ptr = NULL;
} else if (likely(length < MAX_STACK_ARRAY)) {
ptr = alloca(jffi_arraySize(length + 1, type));
if (unlikely(jffi_getArrayBuffer(env, object, offset, length, type,
&arrays[arrayCount], ptr) == NULL)) {
goto cleanup;
}
++arrayCount;
} else {
ptr = jffi_getArrayHeap(env, object, offset, length, type, &arrays[arrayCount]);
if (unlikely(ptr == NULL)) {
goto cleanup;
}
++arrayCount;
}
break;
case com_kenai_jffi_ObjectBuffer_BUFFER:
if (unlikely(object == NULL)) {
throwException(env, NullPointer, "null object for parameter %d", idx);
goto cleanup;
}
ptr = (*env)->GetDirectBufferAddress(env, object);
if (unlikely(ptr == NULL)) {
throwException(env, NullPointer, "null direct buffer address for parameter %d", idx);
goto cleanup;
}
ptr = ((char *) ptr + offset);
break;
case com_kenai_jffi_ObjectBuffer_JNI:
switch (type & com_kenai_jffi_ObjectBuffer_TYPE_MASK) {
case com_kenai_jffi_ObjectBuffer_JNIENV:
ptr = env;
break;
case com_kenai_jffi_ObjectBuffer_JNIOBJECT:
ptr = (void *) object;
break;
default:
throwException(env, IllegalArgument, "Unsupported object type: %#x",
type & com_kenai_jffi_ObjectBuffer_TYPE_MASK);
goto cleanup;
}
break;
default:
throwException(env, IllegalArgument, "Unsupported object type: %#x",
type & com_kenai_jffi_ObjectBuffer_TYPE_MASK);
goto cleanup;
}
if (likely(ctx->cif.arg_types[idx]->type == FFI_TYPE_POINTER)) {
*((void **) ffiArgs[idx]) = ptr;
} else {
ffiArgs[idx] = ptr;
}
}
//
// Pin all the arrays just before calling the native function.
//
// Although hotspot allows it, other JVMs do not allow JNI operations
// once any array has been pinned, so pinning must be done last, just before
// the native function is called.
//
for (i = 0; i < pinnedCount; i++) {
Pinned* p = &pinned[i];
Array* ary = &arrays[arrayCount];
int idx = (p->type & com_kenai_jffi_ObjectBuffer_INDEX_MASK) >> com_kenai_jffi_ObjectBuffer_INDEX_SHIFT;
void* ptr = jffi_getArrayCritical(env, p->object, p->offset, p->length, p->type, &arrays[arrayCount]);
if (unlikely(ptr == NULL)) {
goto cleanup;
}
if (likely(ctx->cif.arg_types[idx]->type == FFI_TYPE_POINTER)) {
*((void **) ffiArgs[idx]) = ptr;
} else {
ffiArgs[idx] = ptr;
}
++arrayCount;
}
FAULTPROT_CTX(env, ctx, ffi_call(&ctx->cif, FFI_FN(j2p(function)), retval, ffiArgs), );
cleanup:
/* Release any array backing memory */
RELEASE_ARRAYS(env, arrays, arrayCount);
}
static void
invokeArrayWithObjects(JNIEnv* env, jlong ctxAddress, jlong function, jbyteArray paramBuffer,
jint objectCount, jintArray objectInfo, jobjectArray objectArray, void* retval)
{
jint* infoBuffer = alloca(objectCount * sizeof(jint) * 3);
jobject* objectBuffer = alloca(objectCount * sizeof(jobject));
int i;
(*env)->GetIntArrayRegion(env, objectInfo, 0, objectCount * 3, infoBuffer);
for (i = 0; i < objectCount; ++i) {
objectBuffer[i] = (*env)->GetObjectArrayElement(env, objectArray, i);
}
invokeArrayWithObjects_(env, ctxAddress, function, paramBuffer, objectCount, infoBuffer, objectBuffer, retval);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeArrayWithObjectsInt32
* Signature: (J[B[I[Ljava/lang/Object;)I
*/
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_invokeArrayWithObjectsInt32(JNIEnv* env, jobject self,
jlong ctxAddress, jlong function, jbyteArray paramBuffer, jint objectCount, jintArray objectInfo, jobjectArray objectArray)
{
FFIValue retval;
invokeArrayWithObjects(env, ctxAddress, function, paramBuffer, objectCount, objectInfo, objectArray, &retval);
return_int(retval);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeArrayO1Int32
* Signature: (J[BILjava/lang/Object;I)I
*/
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_invokeArrayO1Int32(JNIEnv* env, jobject self, jlong ctxAddress, jlong function,
jbyteArray paramBuffer, jobject o1, jint o1info, jint o1off, jint o1len)
{
FFIValue retval;
jint info[] = { o1info, o1off, o1len };
jobject objects[] = { o1 };
invokeArrayWithObjects_(env, ctxAddress, function, paramBuffer, 1, info, objects, &retval);
return_int(retval);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeArrayO2Int32
* Signature: (J[BLjava/lang/Object;IIILjava/lang/Object;III)I
*/
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_invokeArrayO2Int32(JNIEnv* env, jobject self, jlong ctxAddress, jlong function,
jbyteArray paramBuffer, jobject o1, jint o1info, jint o1off, jint o1len,
jobject o2, jint o2info, jint o2off, jint o2len)
{
FFIValue retval;
jint info[] = { o1info, o1off, o1len, o2info, o2off, o2len };
jobject objects[] = { o1, o2 };
invokeArrayWithObjects_(env, ctxAddress, function, paramBuffer, 2, info, objects, &retval);
return_int(retval);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeArrayWithObjectsInt64
* Signature: (J[BI[I[Ljava/lang/Object;)J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeArrayWithObjectsInt64(JNIEnv* env, jobject self,
jlong ctxAddress, jlong function, jbyteArray paramBuffer, jint objectCount, jintArray objectInfo, jobjectArray objectArray)
{
FFIValue retval;
invokeArrayWithObjects(env, ctxAddress, function, paramBuffer, objectCount, objectInfo, objectArray, &retval);
return retval.s64;
}
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeArrayO1Int64
* Signature: (J[BLjava/lang/Object;III)J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeArrayO1Int64(JNIEnv* env, jobject self, jlong ctxAddress, jlong function,
jbyteArray paramBuffer, jobject o1, jint o1info, jint o1off, jint o1len)
{
FFIValue retval;
jint info[] = { o1info, o1off, o1len };
jobject objects[] = { o1 };
invokeArrayWithObjects_(env, ctxAddress, function, paramBuffer, 1, info, objects, &retval);
return retval.j;
}
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeArrayO2Int64
* Signature: (J[BLjava/lang/Object;IIILjava/lang/Object;III)J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_invokeArrayO2Int64(JNIEnv* env, jobject self, jlong ctxAddress, jlong function,
jbyteArray paramBuffer, jobject o1, jint o1info, jint o1off, jint o1len,
jobject o2, jint o2info, jint o2off, jint o2len)
{
FFIValue retval;
jint info[] = { o1info, o1off, o1len, o2info, o2off, o2len };
jobject objects[] = { o1, o2 };
invokeArrayWithObjects_(env, ctxAddress, function, paramBuffer, 2, info, objects, &retval);
return retval.j;
}
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeArrayWithObjectsFloat
* Signature: (J[BI[I[Ljava/lang/Object;)F
*/
JNIEXPORT jfloat JNICALL
Java_com_kenai_jffi_Foreign_invokeArrayWithObjectsFloat(JNIEnv* env, jobject self,
jlong ctxAddress, jlong function, jbyteArray paramBuffer, jint objectCount, jintArray objectInfo, jobjectArray objectArray)
{
FFIValue retval;
invokeArrayWithObjects(env, ctxAddress, function, paramBuffer, objectCount, objectInfo, objectArray, &retval);
return retval.f;
}
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeArrayWithObjectsDouble
* Signature: (J[BI[I[Ljava/lang/Object;)D
*/
JNIEXPORT jdouble JNICALL
Java_com_kenai_jffi_Foreign_invokeArrayWithObjectsDouble(JNIEnv* env, jobject self,
jlong ctxAddress, jlong function, jbyteArray paramBuffer, jint objectCount, jintArray objectInfo, jobjectArray objectArray)
{
FFIValue retval;
invokeArrayWithObjects(env, ctxAddress, function, paramBuffer, objectCount, objectInfo, objectArray, &retval);
return retval.d;
}
/*
* Class: com_kenai_jffi_Foreign
* Method: invokeArrayWithObjectsReturnStruct
* Signature: (J[BI[I[Ljava/lang/Object;[BI)V
*/
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_invokeArrayWithObjectsReturnStruct(JNIEnv* env, jobject self,
jlong ctxAddress, jlong function, jbyteArray paramBuffer, jint objectCount, jintArray objectInfo,
jobjectArray objectArray, jbyteArray returnBuffer, jint returnBufferOffset)
{
CallContext* ctx = (CallContext *) j2p(ctxAddress);
jbyte* retval = alloca(ctx->cif.rtype->size);
invokeArrayWithObjects(env, ctxAddress, function, paramBuffer, objectCount, objectInfo, objectArray, retval);
(*env)->SetByteArrayRegion(env, returnBuffer, returnBufferOffset, ctx->cif.rtype->size, retval);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: invokePointerParameterArray
* Signature: (JJ[J)V
*/
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_invokePointerParameterArray(JNIEnv *env, jobject self, jlong ctxAddress, jlong function,
jlong returnBuffer, jlongArray parameterArray)
{
CallContext* ctx = (CallContext *) j2p(ctxAddress);
int parameterCount;
jlong* params = NULL;
void** ffiArgs = NULL;
int i;
if (unlikely(ctxAddress == 0LL)) {
throwException(env, NullPointer, "context address is null");
return;
}
if (unlikely(returnBuffer == 0LL)) {
throwException(env, NullPointer, "result buffer is null");
return;
}
if (unlikely(parameterArray == NULL)) {
throwException(env, NullPointer, "parameter array is null");
return;
}
parameterCount = (*env)->GetArrayLength(env, parameterArray);
if (parameterCount > 0) {
params = alloca(parameterCount * sizeof(jlong));
ffiArgs = alloca(parameterCount * sizeof(void *));
(*env)->GetLongArrayRegion(env, parameterArray, 0, parameterCount, params);
for (i = 0; i < parameterCount; ++i) {
ffiArgs[i] = j2p(params[i]);
}
}
ffi_call(&ctx->cif, FFI_FN(j2p(function)), j2p(returnBuffer), ffiArgs);
}
jffi-1.2.7/jni/jffi/LastError.c 0000664 0000000 0000000 00000005755 12470474244 0016242 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2008, 2009 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#include
#include
#ifdef _WIN32
# include
#endif
#include
#include "LastError.h"
#include "CallContext.h"
#if defined(_WIN32)
static __thread int last_error = 0;
#endif
/*
* Class: com_kenai_jffi_Foreign
* Method: getLastError
* Signature: ()I
*/
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_getLastError(JNIEnv* env, jobject self)
{
#ifdef _WIN32
// printf("Getting ERRNO: %d on thread %d\n", last_error, (int)GetCurrentThreadId());
return last_error;
#else
return thread_data_get()->error;
#endif
}
/*
* Class: com_kenai_jffi_Foreign
* Method: setLastError
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_setLastError(JNIEnv* env, jobject self, jint value)
{
#ifdef _WIN32
// printf("Setting ERRNO: %d on thread %d\n", value, (int)GetCurrentThreadId());
SetLastError(value);
last_error = value;
#else
thread_data_get()->error = errno = value;
#endif
}
void
jffi_save_errno(void)
{
#ifdef _WIN32
last_error = GetLastError();
// printf("JFFI Saving ERRNO: %d on thread %d\n", last_error, (int)GetCurrentThreadId());
#else
thread_data_get()->error = errno;
#endif
}
void
jffi_save_errno_ctx(CallContext* ctx)
{
#ifdef _WIN32
if (unlikely(ctx->error_fn != NULL)) {
last_error = (*ctx->error_fn)();
} else {
last_error = GetLastError();
}
#else
if (unlikely(ctx->error_fn != NULL)) {
thread_data_get()->error = (*ctx->error_fn)();
} else {
thread_data_get()->error = errno;
}
#endif
}
#ifndef _WIN32
void
jffi_save_errno_td(ThreadData* td, CallContext* ctx)
{
if (unlikely(ctx->error_fn != NULL)) {
td->error = (*ctx->error_fn)();
} else {
td->error = errno;
}
}
#endif
jffi-1.2.7/jni/jffi/LastError.h 0000664 0000000 0000000 00000003015 12470474244 0016232 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2008, 2009 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#ifndef JFFI_LASTERRROR_H
#define JFFI_LASTERRROR_H
#include "jffi.h"
#include "CallContext.h"
extern void jffi_save_errno(void);
#ifndef _WIN32
extern void jffi_save_errno_td(ThreadData* td, CallContext* ctx);
#endif
#endif /* JFFI_LASTERRROR_H */
jffi-1.2.7/jni/jffi/Library.c 0000664 0000000 0000000 00000014141 12470474244 0015716 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2008-2010 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#include
#include
#include
#include
#include
#if defined(_WIN32) || defined(__WIN32__)
# include
# include
#else
# include
#endif
#if defined (__sun) || defined(_AIX)
# include
#endif
#include
#include
#include "jffi.h"
#include "Exception.h"
#include "com_kenai_jffi_Foreign.h"
#if defined(_WIN32) || defined(__WIN32__)
static void* dl_open(const char* name, int flags);
static void dl_error(char* buf, int size);
#define dl_sym(handle, name) GetProcAddress(handle, name)
#define dl_close(handle) FreeLibrary(handle)
enum { RTLD_LAZY=1, RTLD_NOW, RTLD_GLOBAL, RTLD_LOCAL };
#else
# define dl_open(name, flags) dlopen(name, flags != 0 ? flags : (RTLD_LAZY | RTLD_LOCAL))
# define dl_error(buf, size) do { \
const char *e = dlerror(); snprintf(buf, size, "%s", e ? e : "unknown"); \
} while(0)
# define dl_sym(handle, name) dlsym(handle, name)
# define dl_close(handle) dlclose(handle)
#ifndef RTLD_LOCAL
# define RTLD_LOCAL 8
#endif
#endif
static int getMultibyteString(JNIEnv* env, char* dst, jstring jstr, int n);
static int getWideString(JNIEnv* env, wchar_t* dst, jstring jstr, int n);
/*
* Class: com_kenai_jffi_Foreign
* Method: dlopen
* Signature: (Ljava/lang/String;I)J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_dlopen(JNIEnv* env, jobject self, jstring jPath, jint jFlags)
{
#ifdef _WIN32
if (jPath == NULL) {
return p2j(GetModuleHandle(NULL));
} else {
wchar_t path[PATH_MAX];
getWideString(env, path, jPath, sizeof(path) / sizeof(path[0]));
return p2j(LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH));
}
#else
char path_[PATH_MAX];
const char* path = NULL; // Handle dlopen(NULL, flags);
void* handle = NULL;
int flags = 0;
#define F(x) (jFlags & com_kenai_jffi_Foreign_RTLD_##x) != 0 ? RTLD_##x : 0;
flags |= F(LAZY);
flags |= F(GLOBAL);
flags |= F(LOCAL);
flags |= F(NOW);
#undef F
#ifdef _AIX
flags |= RTLD_MEMBER; // Needed for AIX
#endif
if (jPath != NULL) {
path = path_;
getMultibyteString(env, path_, jPath, sizeof(path_));
}
handle = dl_open(path, flags);
if (handle == NULL) {
char errbuf[1024] = { 0 };
dl_error(errbuf, sizeof(errbuf) - 1);
throwException(env, UnsatisfiedLink, "%s", errbuf);
}
return p2j(handle);
#endif
}
/*
* Class: com_googlecode_jffi_NativeLibrary
* Method: dlclose
* Signature: (J)V
*/
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_dlclose(JNIEnv* env, jclass cls, jlong handle)
{
dl_close(j2p(handle));
}
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_dlsym(JNIEnv* env, jclass cls, jlong handle, jstring jstr)
{
char sym[1024];
void* addr;
getMultibyteString(env, sym, jstr, sizeof(sym));
#ifndef _WIN32
dlerror(); // clear any errors
#endif
addr = dl_sym(j2p(handle), sym);
if (addr == NULL) {
char errbuf[1024] = { 0 };
dl_error(errbuf, sizeof(errbuf) - 1);
throwException(env, UnsatisfiedLink, "%s", errbuf);
}
return p2j(addr);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: dlerror
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL
Java_com_kenai_jffi_Foreign_dlerror(JNIEnv* env, jobject self)
{
char errbuf[1024] = { 0 };
dl_error(errbuf, sizeof(errbuf) - 1);
return (*env)->NewStringUTF(env, errbuf);
}
#if defined(_WIN32) || defined(__WIN32__)
static void*
dl_open(const char* name, int flags)
{
if (name == NULL) {
return GetModuleHandle(NULL);
} else {
return LoadLibraryEx(name, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
}
}
static void
dl_error(char* buf, int size)
{
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
0, buf, size, NULL);
}
#endif
static int
getWideString(JNIEnv* env, wchar_t* dst, jstring src, int n)
{
const jchar* jstr = NULL;
int len, i;
if (src != NULL) {
jstr = (*env)->GetStringChars(env, src, NULL);
}
len = (*env)->GetStringLength(env, src);
if (len > (n - 1)) len = n - 1;
for (i = 0; i < len; ++i) {
dst[i] = (wchar_t) jstr[i];
}
dst[len] = (wchar_t) 0;
if (jstr != NULL) {
(*env)->ReleaseStringChars(env, src, jstr);
}
return len;
}
static int
getMultibyteString(JNIEnv* env, char* dst, jstring src, int n)
{
wchar_t* wstr = NULL;
const jchar* jstr = NULL;
int len, i;
if (src != NULL) {
jstr = (*env)->GetStringChars(env, src, NULL);
}
len = (*env)->GetStringLength(env, src);
wstr = alloca(sizeof(wchar_t) * (len + 1));
for (i = 0; i < len; ++i) {
wstr[i] = (wchar_t) jstr[i];
}
wstr[len] = (wchar_t) 0;
if (jstr != NULL) {
(*env)->ReleaseStringChars(env, src, jstr);
}
return wcstombs(dst, wstr, n);
}
jffi-1.2.7/jni/jffi/LongDouble.c 0000664 0000000 0000000 00000011530 12470474244 0016343 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2007, 2008 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#include
#include
#ifdef __sun
# include
#endif
#include
#include
#include
#include "jffi.h"
#include "Exception.h"
#include "com_kenai_jffi_Foreign.h"
static void
jffi_encodeLongDouble(JNIEnv *env, long double ld, jbyteArray array, jint arrayOffset, jint arrayLength)
{
if (arrayLength != sizeof(ld)) {
throwException(env, Runtime, "array size != sizeof(long double)");
return;
}
(*env)->SetByteArrayRegion(env, array, arrayOffset, arrayLength, (jbyte *) &ld);
}
static long double
jffi_decodeLongDouble(JNIEnv *env, jbyteArray array, jint arrayOffset, jint arrayLength)
{
long double ld;
if (arrayLength != sizeof(ld)) {
throwException(env, Runtime, "array size != sizeof(long double)");
return 0.0;
}
(*env)->GetByteArrayRegion(env, array, arrayOffset, arrayLength, (jbyte *) &ld);
return ld;
}
/*
* Class: com_kenai_jffi_Foreign
* Method: longDoubleFromEngineeringString
* Signature: (Ljava/lang/String;[BII)V
*/
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_longDoubleFromString(JNIEnv *env, jobject self, jstring str,
jbyteArray array, jint arrayOffset, jint arrayLength)
{
long double ld;
char* tmp;
jsize len;
len = (*env)->GetStringUTFLength(env, str);
tmp = alloca(len + 1);
(*env)->GetStringUTFRegion(env, str, 0, len, tmp);
ld = strtold(tmp, NULL);
jffi_encodeLongDouble(env, ld, array, arrayOffset, arrayLength);
}
static inline jstring
jffi_longDoubleToString(JNIEnv *env,
jbyteArray array, jint arrayOffset, jint arrayLength, const char * const fmt)
{
char tmp[256];
sprintf(tmp, fmt, jffi_decodeLongDouble(env, array, arrayOffset, arrayLength));
return (*env)->NewStringUTF(env, tmp);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: longDoubleToEngineeringString
* Signature: ([BII)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL
Java_com_kenai_jffi_Foreign_longDoubleToEngineeringString(JNIEnv *env, jobject self,
jbyteArray array, jint arrayOffset, jint arrayLength)
{
return jffi_longDoubleToString(env, array, arrayOffset, arrayLength, "%.35Le");
}
/*
* Class: com_kenai_jffi_Foreign
* Method: longDoubleToPlainString
* Signature: ([BII)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL
Java_com_kenai_jffi_Foreign_longDoubleToPlainString(JNIEnv *env, jobject self,
jbyteArray array, jint arrayOffset, jint arrayLength)
{
return jffi_longDoubleToString(env, array, arrayOffset, arrayLength, "%.35Lf");
}
/*
* Class: com_kenai_jffi_Foreign
* Method: longDoubleToString
* Signature: ([BII)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL
Java_com_kenai_jffi_Foreign_longDoubleToString(JNIEnv *env, jobject self,
jbyteArray array, jint arrayOffset, jint arrayLength)
{
return jffi_longDoubleToString(env, array, arrayOffset, arrayLength, "%.35Lg");
}
/*
* Class: com_kenai_jffi_Foreign
* Method: longDoubleFromDouble
* Signature: (D[BII)V
*/
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_longDoubleFromDouble(JNIEnv *env, jobject self, jdouble doubleValue,
jbyteArray array, jint arrayOffset, jint arrayLength)
{
jffi_encodeLongDouble(env, doubleValue, array, arrayOffset, arrayLength);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: longDoubleToDouble
* Signature: ([BII)D
*/
JNIEXPORT jdouble JNICALL
Java_com_kenai_jffi_Foreign_longDoubleToDouble(JNIEnv *env, jobject self,
jbyteArray array, jint arrayOffset, jint arrayLength)
{
return jffi_decodeLongDouble(env, array, arrayOffset, arrayLength);
}
jffi-1.2.7/jni/jffi/Memory.c 0000664 0000000 0000000 00000011552 12470474244 0015565 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2008, 2009 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#include
#include
#ifndef _WIN32
# include
#else
# include
# include
# include
#endif
#include
#include "Exception.h"
#include "LastError.h"
#include "com_kenai_jffi_Foreign.h"
#include "jffi.h"
/*
* Class: com_kenai_jffi_Foreign
* Method: pageSize
* Signature: ()J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_pageSize(JNIEnv *env, jobject self)
{
#ifndef _WIN32
return sysconf(_SC_PAGESIZE);
#else
SYSTEM_INFO si;
GetSystemInfo(&si);
return si.dwPageSize;
#endif
}
#ifndef _WIN32
static int PROT(int p);
static int FLAGS(int f);
/*
* Class: com_kenai_jffi_Foreign
* Method: mmap
* Signature: (JJIIIJ)J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_mmap(JNIEnv *env, jobject self, jlong addr, jlong len,
jint prot, jint flags, jint fd, jlong off)
{
caddr_t result;
result = mmap(j2p(addr), len, PROT(prot), FLAGS(flags), fd, off);
if (unlikely(result == (caddr_t) -1)) {
jffi_save_errno();
return -1;
}
return p2j(result);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: munmap
* Signature: (JJ)I
*/
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_munmap(JNIEnv *env, jobject self, jlong addr, jlong len)
{
int result = munmap(j2p(addr), len);
if (unlikely(result != 0)) {
jffi_save_errno();
return -1;
}
return 0;
}
/*
* Class: com_kenai_jffi_Foreign
* Method: mprotect
* Signature: (JJI)I
*/
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_mprotect(JNIEnv *env, jobject self, jlong addr, jlong len, jint prot)
{
int result = mprotect(j2p(addr), len, PROT(prot));
if (unlikely(result != 0)) {
jffi_save_errno();
return -1;
}
return 0;
}
static int
PROT(int p)
{
int n = 0;
n |= ((p & com_kenai_jffi_Foreign_PROT_NONE) != 0) ? PROT_NONE : 0;
n |= ((p & com_kenai_jffi_Foreign_PROT_READ) != 0) ? PROT_READ : 0;
n |= ((p & com_kenai_jffi_Foreign_PROT_WRITE) != 0) ? PROT_WRITE : 0;
n |= ((p & com_kenai_jffi_Foreign_PROT_EXEC) != 0) ? PROT_EXEC : 0;
return n;
}
static int
FLAGS(int j)
{
int m = 0;
#define M(x) m |= ((j & com_kenai_jffi_Foreign_MAP_##x) != 0) ? MAP_##x : 0
M(FIXED);
M(SHARED);
M(PRIVATE);
#ifdef MAP_NORESERVE
M(NORESERVE);
#endif
M(ANON);
#ifdef MAP_ALIGN
M(ALIGN);
#endif
#ifdef MAP_TEXT
M(TEXT);
#endif
return m;
}
#else /* _WIN32 */
/*
* Class: com_kenai_jffi_Foreign
* Method: VirtualAlloc
* Signature: (JIII)J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_VirtualAlloc(JNIEnv *env, jobject self, jlong addr, jint size, jint flags, jint prot)
{
void* ptr = VirtualAlloc(j2p(addr), size, flags, prot);
if (unlikely(ptr == NULL)) {
jffi_save_errno();
return 0;
}
return p2j(ptr);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: VirtualFree
* Signature: (JI)Z
*/
JNIEXPORT jboolean JNICALL
Java_com_kenai_jffi_Foreign_VirtualFree(JNIEnv *env, jobject self, jlong addr, jint size, jint flags)
{
if (!VirtualFree(j2p(addr), size, flags)) {
jffi_save_errno();
return JNI_FALSE;
}
return JNI_TRUE;
}
/*
* Class: com_kenai_jffi_Foreign
* Method: VirtualProtect
* Signature: (JII)Z
*/
JNIEXPORT jboolean JNICALL
Java_com_kenai_jffi_Foreign_VirtualProtect(JNIEnv *env, jobject self, jlong addr, jint size, jint prot)
{
DWORD oldprot;
if (!VirtualProtect(j2p(addr), size, prot, &oldprot)) {
jffi_save_errno();
return JNI_FALSE;
}
return JNI_TRUE;
}
#endif /* !_WIN32 */
jffi-1.2.7/jni/jffi/MemoryIO.c 0000664 0000000 0000000 00000032244 12470474244 0016016 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2007 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
#include "jffi.h"
#include "FaultProtect.h"
#include "com_kenai_jffi_Foreign.h"
#if FAULT_PROTECT_ENABLED
# define PROT(stmt, rval) do { \
JNIEnv* volatile env_ = env; \
FaultData fd; \
int val; \
if (unlikely((val = jffi_setjmp(&fd)) != 0)) { \
jffi_faultException(env_, &fd, val); \
return rval; \
} else { \
ThreadData* td = thread_data_get(); \
td->fault_data = &fd; \
stmt; \
td->fault_data = NULL; \
} \
} while (0)
#else
# define PROT(stmt, rval) do { stmt; } while(0)
#endif
#ifndef MIN
# define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
static void putArrayChecked(JNIEnv* env, jlong address, jobject obj, jint offset, jint length, int typeSize,
void (JNICALL *get)(JNIEnv *env, jobject array, jsize start, jsize l, void *buf));
static void getArrayChecked(JNIEnv* env, jlong address, jobject obj, jint offset, jint length, int typeSize,
void (JNICALL *put)(JNIEnv *env, jobject array, jsize start, jsize l, const void *buf));
#define GET(JTYPE, NTYPE) JNIEXPORT NTYPE JNICALL \
Java_com_kenai_jffi_Foreign_get##JTYPE(JNIEnv* env, jobject self, jlong address) \
{ NTYPE tmp; memcpy(&tmp, j2p(address), sizeof(tmp)); return tmp; } \
JNIEXPORT NTYPE JNICALL \
Java_com_kenai_jffi_Foreign_get##JTYPE##Checked(JNIEnv* env, jobject self, jlong address) \
{ NTYPE tmp; PROT(memcpy(&tmp, j2p(address), sizeof(tmp)), 0); return tmp; }
#define PUT(JTYPE, NTYPE) \
JNIEXPORT void JNICALL \
Java_com_kenai_jffi_Foreign_put##JTYPE(JNIEnv *env, jobject self, jlong address, NTYPE value) \
{ memcpy(j2p(address), &value, sizeof(value)); } \
JNIEXPORT void JNICALL \
Java_com_kenai_jffi_Foreign_put##JTYPE##Checked(JNIEnv *env, jobject self, jlong address, NTYPE value) \
{ PROT(memcpy(j2p(address), &value, sizeof(value)),); }
#define COPY(JTYPE, NTYPE) \
JNIEXPORT void JNICALL \
Java_com_kenai_jffi_Foreign_put##JTYPE##Array(JNIEnv* env, jobject unsafe, jlong address, jobject obj, jint offset, jint length) \
{ \
(*env)->Get##JTYPE##ArrayRegion(env, obj, offset, length, (NTYPE *) j2p(address)); \
} \
JNIEXPORT void JNICALL \
Java_com_kenai_jffi_Foreign_put##JTYPE##ArrayChecked(JNIEnv* env, jobject unsafe, jlong address, jobject obj, jint offset, jint length) \
{ \
putArrayChecked(env, address, obj, offset, length, sizeof(NTYPE), \
(void (JNICALL *)(JNIEnv *env, jobject array, jsize start, jsize l, void *buf)) (*env)->Get##JTYPE##ArrayRegion); \
} \
JNIEXPORT void JNICALL \
Java_com_kenai_jffi_Foreign_get##JTYPE##Array(JNIEnv* env, jobject unsafe, jlong address, jobject obj, jint offset, jint length) \
{ \
(*env)->Set##JTYPE##ArrayRegion(env, obj, offset, length, (NTYPE *) j2p(address)); \
} \
JNIEXPORT void JNICALL \
Java_com_kenai_jffi_Foreign_get##JTYPE##ArrayChecked(JNIEnv* env, jobject unsafe, jlong address, jobject obj, jint offset, jint length) \
{ \
getArrayChecked(env, address, obj, offset, length, sizeof(NTYPE), \
(void (JNICALL *)(JNIEnv *env, jobject array, jsize start, jsize l, const void *)) (*env)->Set##JTYPE##ArrayRegion); \
}
static inline void
copy(void* dst, const void* src, int len)
{
int i;
for (i = 0; i < len; i++) *((char *) dst + i) = *((const char *) src + i);
}
static void
putArrayChecked(JNIEnv* env, jlong address, jobject obj, jint offset, jint length, int typeSize,
void (JNICALL *get)(JNIEnv *env, jobject array, jsize start, jsize l, void *buf))
{
jint copyOff = 0;
PROT(while (copyOff < length) {
jbyte tmp[4096];
int copyLen = MIN((int) sizeof(tmp) / typeSize, length - copyOff);
(*get)(env, obj, offset + copyOff, copyLen, tmp);
copy(j2p(address + (copyOff * typeSize)), tmp, copyLen * typeSize);
copyOff += copyLen;
},);
}
static void
getArrayChecked(JNIEnv* env, jlong address, jobject obj, jint offset, jint length, int typeSize,
void (JNICALL *put)(JNIEnv *env, jobject array, jsize start, jsize l, const void *buf))
{
jint copyOff = 0;
PROT(while (copyOff < length) {
jbyte tmp[4096];
int copyLen = MIN((int) sizeof(tmp) / typeSize, length - copyOff);
copy(tmp, j2p(address + (copyOff * typeSize)), copyLen * typeSize);
(*put)(env, obj, offset + copyOff, copyLen, tmp);
copyOff += copyLen;
},);
}
#define UNSAFE(J, N) GET(J, N) PUT(J, N) COPY(J, N)
UNSAFE(Byte, jbyte);
UNSAFE(Char, jchar);
UNSAFE(Boolean, jboolean);
UNSAFE(Short, jshort);
UNSAFE(Int, jint);
UNSAFE(Long, jlong);
UNSAFE(Float, jfloat);
UNSAFE(Double, jdouble);
/*
* Class: com_googlecode_jffi_JNIUnsafe
* Method: getAddress
* Signature: (J)J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_getAddress(JNIEnv* ev, jobject self, jlong address)
{
void* tmp;
memcpy(&tmp, j2p(address), sizeof(tmp));
return p2j(tmp);
}
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_getAddressChecked(JNIEnv* env, jobject self, jlong address)
{
void* tmp;
PROT(memcpy(&tmp, j2p(address), sizeof(tmp)), 0);
return p2j(tmp);
}
/*
* Class: com_googlecode_jffi_JNIUnsafe
* Method: putAddress
* Signature: (JJ)V
*/
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_putAddress(JNIEnv* env, jobject self, jlong address, jlong value)
{
void* tmp = j2p(value);
memcpy(j2p(address), &tmp, sizeof(tmp));
}
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_putAddressChecked(JNIEnv* env, jobject self, jlong address, jlong value)
{
void* tmp = j2p(value);
PROT(memcpy(j2p(address), &tmp, sizeof(tmp)),);
}
/*
* Class: com_googlecode_jffi_Unsafe_JNIUnsafe
* Method: setMemory
* Signature: (JJB)V
*/
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_setMemory(JNIEnv* env, jobject self, jlong address, jlong size, jbyte value)
{
memset(j2p(address), value, size);
}
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_setMemoryChecked(JNIEnv* env, jobject self, jlong address, jlong size, jbyte value)
{
PROT(memset(j2p(address), value, size),);
}
/*
* Class: com_googlecode_jffi_lowlevel_Unsafe_JNIUnsafe
* Method: copyMemory
* Signature: (JJJ)V
*/
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_copyMemory(JNIEnv* env, jobject self, jlong src, jlong dst, jlong size)
{
memcpy(j2p(dst), j2p(src), size);
}
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_copyMemoryChecked(JNIEnv* env, jobject self, jlong src, jlong dst, jlong size)
{
PROT(memcpy(j2p(dst), j2p(src), size),);
}
/*
* Class: com_googlecode_jffi_lowlevel_Unsafe
* Method: memchr
* Signature: (JIJ)I
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_memchr(JNIEnv* env, jobject self, jlong address, jint c, jlong maxlen)
{
return p2j(memchr(j2p(address), c, maxlen));
}
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_memchrChecked(JNIEnv* env, jobject self, jlong address, jint c, jlong maxlen)
{
PROT(return p2j(memchr(j2p(address), c, maxlen)), 0);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: memmove
* Signature: (JJJ)V
*/
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_memmove(JNIEnv* env, jobject self, jlong dst, jlong src, jlong size)
{
memmove(j2p(dst), j2p(src), size);
}
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_memmoveChecked(JNIEnv* env, jobject self, jlong dst, jlong src, jlong size)
{
PROT(memmove(j2p(dst), j2p(src), size),);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: memcpy
* Signature: (JJJ)V
*/
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_memcpy(JNIEnv* env, jobject self, jlong dst, jlong src, jlong size)
{
memcpy(j2p(dst), j2p(src), size);
}
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_memcpyChecked(JNIEnv* env, jobject self, jlong dst, jlong src, jlong size)
{
PROT(memcpy(j2p(dst), j2p(src), size), );
}
/*
* Class: com_kenai_jffi_Foreign
* Method: strlen
* Signature: (J)J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_strlen(JNIEnv* env, jobject self, jlong address)
{
return (jlong) strlen(j2p(address));
}
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_strlenChecked(JNIEnv* env, jobject self, jlong address)
{
PROT(return (jlong) strlen(j2p(address)), 0);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: getUTF8StringAsBytes
* Signature: (J)[B
*/
JNIEXPORT jbyteArray JNICALL
Java_com_kenai_jffi_Foreign_getZeroTerminatedByteArray__J(JNIEnv* env, jobject self, jlong address)
{
const char* str = (const char*) j2p(address);
int len = strlen(str);
jbyteArray bytes = (*env)->NewByteArray(env, len);
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte *) str);
return bytes;
}
JNIEXPORT jbyteArray JNICALL
Java_com_kenai_jffi_Foreign_getZeroTerminatedByteArrayChecked__J(JNIEnv* env, jobject self, jlong address)
{
const char* str = (const char*) j2p(address);
int len;
// Just protecting the strlen against segfault should be sufficient
PROT(len = strlen(str), NULL);
jbyteArray bytes = (*env)->NewByteArray(env, len);
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte *) str);
return bytes;
}
/*
* Class: com_kenai_jffi_Foreign
* Method: getZeroTerminatedByteArray
* Signature: (JI)[B
*/
JNIEXPORT jbyteArray JNICALL
Java_com_kenai_jffi_Foreign_getZeroTerminatedByteArray__JI(JNIEnv* env, jobject self, jlong address, jint maxlen)
{
const char *str = (const char*) j2p(address), *zp;
jsize len = ((zp = memchr(str, 0, maxlen)) != NULL) ? zp - str : maxlen;
jbyteArray bytes = (*env)->NewByteArray(env, len);
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte *) str);
return bytes;
}
JNIEXPORT jbyteArray JNICALL
Java_com_kenai_jffi_Foreign_getZeroTerminatedByteArrayChecked__JI(JNIEnv* env, jobject self, jlong address, jint maxlen)
{
const char *str = (const char*) j2p(address), *zp;
jsize len;
PROT(zp = memchr(str, 0, maxlen), NULL);
len = zp != NULL ? zp - str : maxlen;
jbyteArray bytes = (*env)->NewByteArray(env, len);
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte *) str);
return bytes;
}
/*
* Class: com_kenai_jffi_Foreign
* Method: putZeroTerminatedByteArray
* Signature: (J[BII)V
*/
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_putZeroTerminatedByteArray(JNIEnv *env, jobject self,
jlong address, jbyteArray data, jint offset, jint length)
{
(*env)->GetByteArrayRegion(env, data, offset, length, (jbyte *)j2p(address));
*((char *) (uintptr_t) address + length) = '\0';
}
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_putZeroTerminatedByteArrayChecked(JNIEnv *env, jobject self,
jlong address, jbyteArray data, jint offset, jint length)
{
char* cp = (char *) (uintptr_t) address;
PROT({ *cp = 0; *(cp + length) ='\0';},);
(*env)->GetByteArrayRegion(env, data, offset, length, (jbyte *)j2p(address));
}
/*
* Class: com_kenai_jffi_Foreign
* Method: allocateMemory
* Signature: (JZ)J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_allocateMemory(JNIEnv* env, jobject self, jlong size, jboolean clear)
{
void* memory = malloc(size);
if (memory != NULL && clear != JNI_FALSE) {
memset(memory, 0, size);
}
return p2j(memory);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: freeMemory
* Signature: (J)V
*/
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_freeMemory(JNIEnv* env, jobject self, jlong address)
{
free(j2p(address));
}
/*
* Class: com_kenai_jffi_Foreign
* Method: newDirectByteBuffer
* Signature: (I)Ljava/nio/ByteBuffer;
*/
JNIEXPORT jobject JNICALL
Java_com_kenai_jffi_Foreign_newDirectByteBuffer(JNIEnv* env, jobject self, jlong address, jint capacity)
{
return (*env)->NewDirectByteBuffer(env, j2p(address), capacity);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: getDirectBufferAddress
* Signature: (Lcom/kenai/jffi/Closure/Buffer;)J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_getDirectBufferAddress(JNIEnv* env, jobject self, jobject buffer)
{
return p2j((*env)->GetDirectBufferAddress(env, buffer));
}
jffi-1.2.7/jni/jffi/MemoryUtil.c 0000664 0000000 0000000 00000005006 12470474244 0016420 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2007, 2008, 2009 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#include
#include
#ifndef _WIN32
# include
#endif
#include
#include
#include
#include
#ifndef _WIN32
# include
#else
# include
#endif
#include
#include "MemoryUtil.h"
int
jffi_getPageSize(void)
{
#ifdef _WIN32
SYSTEM_INFO si;
GetSystemInfo(&si);
return si.dwPageSize;
#else
return sysconf(_SC_PAGESIZE);
#endif
}
void*
jffi_allocatePages(int npages)
{
#ifdef _WIN32
return VirtualAlloc(NULL, npages * jffi_getPageSize(), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
#else
caddr_t memory = mmap(NULL, npages * jffi_getPageSize(), PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
return (memory != (caddr_t) -1) ? memory : NULL;
#endif
}
bool
jffi_freePages(void *addr, int npages)
{
#ifdef _WIN32
return VirtualFree(addr, 0, MEM_RELEASE);
#else
return munmap(addr, npages * jffi_getPageSize()) == 0;
#endif
}
bool
jffi_makePagesExecutable(void* memory, int npages)
{
#ifdef _WIN32
DWORD oldProtect;
return VirtualProtect(memory, npages * jffi_getPageSize(), PAGE_EXECUTE_READ, &oldProtect);
#else
return mprotect(memory, npages * jffi_getPageSize(), PROT_READ | PROT_EXEC) == 0;
#endif
}
jffi-1.2.7/jni/jffi/MemoryUtil.h 0000664 0000000 0000000 00000003055 12470474244 0016427 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2009 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#ifndef JFFI_MEMORY_H
#define JFFI_MEMORY_H
#ifdef __cplusplus
extern "C" {
#endif
int jffi_getPageSize(void);
void* jffi_allocatePages(int npages);
bool jffi_freePages(void *addr, int npages);
bool jffi_makePagesExecutable(void* memory, int npages);
#ifdef __cplusplus
}
#endif
#endif
jffi-1.2.7/jni/jffi/Struct.c 0000664 0000000 0000000 00000012616 12470474244 0015603 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2009 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#include
#include
#include
#if defined(__sun) || defined(_AIX)
# include
#endif
#ifdef _WIN32
# include
#endif
#include
#include
#include "com_kenai_jffi_Foreign.h"
#include "jffi.h"
#include "Exception.h"
#ifndef MAX
# define MAX(x,y) ((x) > (y) ? (x) : (y))
#endif
#define FFI_ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1)
/*
* Class: com_kenai_jffi_Foreign
* Method: newStruct
* Signature: ([J)J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_newStruct(JNIEnv* env, jobject self, jlongArray typeArray, jboolean isUnion)
{
ffi_type* s = NULL;
int fieldCount;
jlong* fieldTypes;
int i;
if (typeArray == NULL) {
throwException(env, NullPointer, "types array cannot be null");
return 0L;
}
fieldCount = (*env)->GetArrayLength(env, typeArray);
if (fieldCount < 1) {
throwException(env, IllegalArgument, "No fields specified");
return 0L;
}
s = calloc(1, sizeof(*s));
if (s == NULL) {
throwException(env, OutOfMemory, "failed to allocate memory");
return 0L;
}
//
// Need to terminate the list of field types with a NULL, so allocate 1 extra
//
s->elements = calloc(fieldCount + 1, sizeof(ffi_type *));
if (s->elements == NULL) {
throwException(env, OutOfMemory, "failed to allocate memory");
goto error;
}
// Copy out all the field descriptors
fieldTypes = alloca(fieldCount * sizeof(jlong));
(*env)->GetLongArrayRegion(env, typeArray, 0, fieldCount, fieldTypes);
s->type = FFI_TYPE_STRUCT;
s->size = 0;
s->alignment = 0;
for (i = 0; i < fieldCount; ++i) {
ffi_type* elem = (ffi_type *) j2p(fieldTypes[i]);
if (elem == NULL) {
throwException(env, IllegalArgument, "type for field %d is NULL", i);
goto error;
}
if (elem->size == 0) {
throwException(env, IllegalArgument, "type for field %d has size 0", i);
goto error;
}
s->elements[i] = elem;
if (!isUnion) {
s->size = FFI_ALIGN(s->size, elem->alignment) + elem->size;
} else {
s->size = MAX(s->size, elem->size);
}
s->alignment = MAX(s->alignment, elem->alignment);
}
if (s->size == 0) {
throwException(env, Runtime, "struct size is zero");
goto error;
}
// Include tail padding
s->size = FFI_ALIGN(s->size, s->alignment);
return p2j(s);
error:
if (s != NULL) {
if (s->elements != NULL) {
free(s->elements);
}
free(s);
}
return 0L;
}
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_newArray(JNIEnv* env, jobject self, jlong type, jint length)
{
ffi_type* elem = (ffi_type *) j2p(type);
ffi_type* s = NULL;
int i;
if (elem == NULL) {
throwException(env, NullPointer, "element type cannot be null");
return 0L;
}
if (elem->size == 0) {
throwException(env, IllegalArgument, "element type size 0");
return 0L;
}
if (length < 1) {
throwException(env, IllegalArgument, "array length == 0");
return 0L;
}
s = calloc(1, sizeof(*s));
if (s == NULL) {
throwException(env, OutOfMemory, "failed to allocate memory");
return 0L;
}
s->type = FFI_TYPE_STRUCT;
s->alignment = elem->alignment;
s->size = length * elem->size;
// Need to terminate the list of field types with a NULL, so allocate 1 extra
s->elements = calloc(length + 1, sizeof(ffi_type *));
if (s->elements == NULL) {
throwException(env, OutOfMemory, "failed to allocate memory");
free(s);
return 0L;
}
for (i = 0; i < length; ++i) {
s->elements[i] = elem;
}
return p2j(s);
}
/*
* Class: com_kenai_jffi_Foreign
* Method: freeStruct
* Signature: (J)V
*/
JNIEXPORT void JNICALL
Java_com_kenai_jffi_Foreign_freeAggregate(JNIEnv* env, jobject self, jlong handle)
{
ffi_type* s = (ffi_type *) j2p(handle);
if (s != NULL) {
free(s->elements);
free(s);
}
}
jffi-1.2.7/jni/jffi/Type.c 0000664 0000000 0000000 00000007634 12470474244 0015244 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2008, 2009 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#include
#include
#include
#include "com_kenai_jffi_Foreign.h"
#include "jffi.h"
static ffi_type*
typeToFFI(int type)
{
switch (type) {
case com_kenai_jffi_Foreign_TYPE_VOID: return &ffi_type_void;
case com_kenai_jffi_Foreign_TYPE_FLOAT:return &ffi_type_float;
case com_kenai_jffi_Foreign_TYPE_DOUBLE: return &ffi_type_double;
case com_kenai_jffi_Foreign_TYPE_LONGDOUBLE: return &ffi_type_longdouble;
case com_kenai_jffi_Foreign_TYPE_UINT8: return &ffi_type_uint8;
case com_kenai_jffi_Foreign_TYPE_SINT8: return &ffi_type_sint8;
case com_kenai_jffi_Foreign_TYPE_UINT16: return &ffi_type_uint16;
case com_kenai_jffi_Foreign_TYPE_SINT16: return &ffi_type_sint16;
case com_kenai_jffi_Foreign_TYPE_UINT32: return &ffi_type_uint32;
case com_kenai_jffi_Foreign_TYPE_SINT32: return &ffi_type_sint32;
case com_kenai_jffi_Foreign_TYPE_UINT64: return &ffi_type_uint64;
case com_kenai_jffi_Foreign_TYPE_SINT64: return &ffi_type_sint64;
case com_kenai_jffi_Foreign_TYPE_POINTER: return &ffi_type_pointer;
case com_kenai_jffi_Foreign_TYPE_UCHAR: return &ffi_type_uchar;
case com_kenai_jffi_Foreign_TYPE_SCHAR: return &ffi_type_schar;
case com_kenai_jffi_Foreign_TYPE_USHORT: return &ffi_type_ushort;
case com_kenai_jffi_Foreign_TYPE_SSHORT: return &ffi_type_sshort;
case com_kenai_jffi_Foreign_TYPE_UINT: return &ffi_type_uint;
case com_kenai_jffi_Foreign_TYPE_SINT: return &ffi_type_sint;
case com_kenai_jffi_Foreign_TYPE_ULONG: return &ffi_type_ulong;
case com_kenai_jffi_Foreign_TYPE_SLONG: return &ffi_type_slong;
}
return NULL;
}
/*
* Class: com_kenai_jffi_Foreign
* Method: lookupType
* Signature: (I)J
*/
JNIEXPORT jlong JNICALL
Java_com_kenai_jffi_Foreign_lookupBuiltinType(JNIEnv* env, jobject self, jint type)
{
return p2j(typeToFFI(type));
}
/*
* Class: com_kenai_jffi_Foreign
* Method: getTypeSize
* Signature: (J)I
*/
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_getTypeSize(JNIEnv* env, jobject self, jlong handle)
{
return ((ffi_type *) j2p(handle))->size;
}
/*
* Class: com_kenai_jffi_Foreign
* Method: getTypeAlign
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_com_kenai_jffi_Foreign_getTypeAlign(JNIEnv* env, jobject self, jlong handle)
{
return ((ffi_type *) j2p(handle))->alignment;
}
/*
* Class: com_kenai_jffi_Foreign
* Method: getTypeType
* Signature: (J)I
*/
JNIEXPORT jint JNICALL
Java_com_kenai_jffi_Foreign_getTypeType(JNIEnv* env, jobject self, jlong handle)
{
return ((ffi_type *) j2p(handle))->type;
}
jffi-1.2.7/jni/jffi/Type.h 0000664 0000000 0000000 00000002545 12470474244 0015245 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2008, 2009 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#ifndef JFFI_TYPE_H
#define JFFI_TYPE_H
#include
#endif /* JFFI_TYPE_H */
jffi-1.2.7/jni/jffi/darwin-longjmp.S 0000664 0000000 0000000 00000003202 12470474244 0017216 0 ustar 00root root 0000000 0000000 /* libunwind - a platform-independent unwind library
Copyright (C) 2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang
This file is part of libunwind.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#ifdef __APPLE__
# define FN(x) _##x
#else
# define FN(x) x
#endif
#if defined(__amd64) || defined(__x86_64__)
.globl FN(_jffi_longjmp_cont)
FN(_jffi_longjmp_cont):
push %rax /* push target IP as return address */
mov %rdx, %rax /* set up return-value */
retq
#elif defined(__i386__)
.globl FN(_jffi_longjmp_cont)
FN(_jffi_longjmp_cont):
push %eax /* push target IP as return address */
mov %ecx, %eax /* set up return-value */
ret
#endif
jffi-1.2.7/jni/jffi/darwin-trampoline.S 0000664 0000000 0000000 00000003147 12470474244 0017732 0 ustar 00root root 0000000 0000000 /* libunwind - a platform-independent unwind library
Copyright (C) 2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang
This file is part of libunwind.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#ifdef __APPLE__
# define FN(x) _##x
#else
# define FN(x) x
#endif
#if defined(__amd64) || defined(__x86_64__)
.globl FN(_jffi_fault_trampoline)
FN(_jffi_fault_trampoline):
and $0xfffffffffffffff0, %rsp
push %rdx
jmp *%rax
#elif defined(__i386__)
.globl FN(_jffi_fault_trampoline)
FN(_jffi_fault_trampoline):
and $0xfffffff0, %esp
push %edx /* push target IP as return address */
jmp *%eax
#endif
jffi-1.2.7/jni/jffi/deprecated.c 0000664 0000000 0000000 00000003500 12470474244 0016407 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2009 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
#include "jffi.h"
#include "com_kenai_jffi_Foreign.h"
/*
* This version of getZeroTerminatedByteArray is deprecated and only here for
* binary backwards compatibility.
*/
JNIEXPORT jbyteArray JNICALL
Java_com_kenai_jffi_Foreign_getZeroTerminatedByteArray__JJ(JNIEnv* env, jobject self, jlong address, jlong maxlen)
{
return Java_com_kenai_jffi_Foreign_getZeroTerminatedByteArray__JI(env, self, address, (jint) maxlen);
}
jffi-1.2.7/jni/jffi/endian.h 0000664 0000000 0000000 00000004177 12470474244 0015565 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2009 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#ifndef JFFI_ENDIAN_H
#define JFFI_ENDIAN_H
#include
#include
#ifdef __linux__
# include_next
#endif
#ifdef __sun
# include
# define LITTLE_ENDIAN 1234
# define BIG_ENDIAN 4321
# if defined(_BIG_ENDIAN)
# define BYTE_ORDER BIG_ENDIAN
# elif defined(_LITTLE_ENDIAN)
# define BYTE_ORDER LITTLE_ENDIAN
# else
# error "Cannot determine endian-ness"
# endif
#endif
#if defined(_AIX) && !defined(BYTE_ORDER)
# define LITTLE_ENDIAN 1234
# define BIG_ENDIAN 4321
# if defined(__BIG_ENDIAN__)
# define BYTE_ORDER BIG_ENDIAN
# elif defined(__LITTLE_ENDIAN__)
# define BYTE_ORDER LITTLE_ENDIAN
# else
# error "Cannot determine endian-ness"
# endif
#endif
#if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN) || !defined(BIG_ENDIAN)
# error "Cannot determine the endian-ness of this platform"
#endif
#endif /* JFFI_ENDIAN_H */
jffi-1.2.7/jni/jffi/jffi.h 0000664 0000000 0000000 00000014143 12470474244 0015237 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2007, 2008 Wayne Meissner
*
* This file is part of jffi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Alternatively, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this work. If not, see .
*/
#ifndef jffi_jffi_h
#define jffi_jffi_h
#include
#include
#include
#include
#ifndef _WIN32
# include
#endif
#include "endian.h"
#include
#include
#ifdef __cplusplus
extern "C" {
#endif
#ifndef roundup
# define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
#endif
#ifdef _WIN32
typedef char* caddr_t;
#endif
#ifdef __GNUC__
# define likely(x) __builtin_expect((x), 1)
# define unlikely(x) __builtin_expect((x), 0)
#else
# define likely(x) (x)
# define unlikely(x) (x)
#endif
/**
* Convert a C pointer into a java long
*/
static inline jlong
p2j(void *p)
{
return (jlong)(uintptr_t) p;
}
/**
* Convert a java long into a C pointer
*/
static inline void*
j2p(jlong j)
{
return (void *)(uintptr_t) j;
}
#ifndef __cplusplus
static inline
jboolean loadClass(JNIEnv* env, const char *name, jclass *classp)
{
jclass tmp = (*env)->FindClass(env, name);
if (tmp == NULL) {
return JNI_FALSE;
}
*classp = (jclass)(*env)->NewGlobalRef(env, tmp);
return JNI_TRUE;
}
#endif
typedef union FFIValue {
int8_t s8;
uint8_t u8;
int16_t s16;
uint16_t u16;
int32_t s32;
uint32_t u32;
int64_t s64;
uint64_t u64;
jint i;
jlong j;
long l;
float f;
double d;
void* p;
ffi_sarg sarg;
ffi_arg arg;
} FFIValue;
#ifndef _WIN32
typedef struct ThreadData {
int error;
int attach_count;
JavaVM* attached_vm;
struct FaultData_* fault_data;
} ThreadData;
extern pthread_key_t jffi_threadDataKey;
extern ThreadData* jffi_thread_data_init();
static inline ThreadData*
thread_data_get()
{
ThreadData* td = (ThreadData *) pthread_getspecific(jffi_threadDataKey);
return likely(td != NULL) ? td : jffi_thread_data_init();
}
#endif /* !_WIN32 */
#if BYTE_ORDER == LITTLE_ENDIAN
# define return_int(retval) return ((retval).i)
# define ARGPTR(argp, type) (argp)
#elif BYTE_ORDER == BIG_ENDIAN
# define return_int(retval) return ((retval).l & 0xFFFFFFFFL)
# define ARGPTR(argp, type) (((caddr_t) (argp)) + sizeof(*argp) - (type)->size)
#else
# error "Unsupported BYTE_ORDER"
#endif
# define ffi_call0(ctx, fn, retval) do { \
FFIValue arg0; \
void* ffiValues[] = { &arg0 }; \
ffi_call(&(ctx)->cif, FFI_FN((fn)), (retval), ffiValues); \
} while (0)
# define ffi_call1(ctx, fn, retval, arg1) do { \
void* ffiValues[] = { ARGPTR(&(arg1), (ctx)->cif.arg_types[0]) }; \
ffi_call(&(ctx)->cif, FFI_FN((fn)), (retval), ffiValues); \
} while (0)
# define ffi_call2(ctx, fn, retval, arg1, arg2) do {\
void* ffiValues[] = { \
ARGPTR(&arg1, (ctx)->cif.arg_types[0]), \
ARGPTR(&arg2, (ctx)->cif.arg_types[1]) \
}; \
ffi_call(&(ctx)->cif, FFI_FN((fn)), (retval), ffiValues); \
} while (0)
# define ffi_call3(ctx, fn, retval, arg1, arg2, arg3) do { \
void* ffiValues[] = { \
ARGPTR(&arg1, (ctx)->cif.arg_types[0]), \
ARGPTR(&arg2, (ctx)->cif.arg_types[1]), \
ARGPTR(&arg3, (ctx)->cif.arg_types[2]) \
}; \
ffi_call(&(ctx)->cif, FFI_FN((fn)), (retval), ffiValues); \
} while (0)
# define ffi_call4(ctx, fn, retval, arg1, arg2, arg3, arg4) do { \
void* ffiValues[] = { \
ARGPTR(&arg1, (ctx)->cif.arg_types[0]), \
ARGPTR(&arg2, (ctx)->cif.arg_types[1]), \
ARGPTR(&arg3, (ctx)->cif.arg_types[2]), \
ARGPTR(&arg4, (ctx)->cif.arg_types[3]) \
}; \
ffi_call(&(ctx)->cif, FFI_FN((fn)), (retval), ffiValues); \
} while (0)
# define ffi_call5(ctx, fn, retval, arg1, arg2, arg3, arg4, arg5) do { \
void* ffiValues[] = { \
ARGPTR(&arg1, (ctx)->cif.arg_types[0]), \
ARGPTR(&arg2, (ctx)->cif.arg_types[1]), \
ARGPTR(&arg3, (ctx)->cif.arg_types[2]), \
ARGPTR(&arg4, (ctx)->cif.arg_types[3]), \
ARGPTR(&arg5, (ctx)->cif.arg_types[4]) \
}; \
ffi_call(&(ctx)->cif, FFI_FN((fn)), (retval), ffiValues); \
} while (0)
# define ffi_call6(ctx, fn, retval, arg1, arg2, arg3, arg4, arg5, arg6) do { \
void* ffiValues[] = { \
ARGPTR(&arg1, (ctx)->cif.arg_types[0]), \
ARGPTR(&arg2, (ctx)->cif.arg_types[1]), \
ARGPTR(&arg3, (ctx)->cif.arg_types[2]), \
ARGPTR(&arg4, (ctx)->cif.arg_types[3]), \
ARGPTR(&arg5, (ctx)->cif.arg_types[4]), \
ARGPTR(&arg6, (ctx)->cif.arg_types[5]) \
}; \
ffi_call(&(ctx)->cif, FFI_FN((fn)), (retval), ffiValues); \
} while (0)
#if defined(__APPLE__)
# define debug(fmt, a...) dprintf(STDERR_FILENO, fmt "\n", ##a)
#else
# define debug(fmt, a...) do { \
char tmp[1024]; \
write(STDERR_FILENO, tmp, snprintf(tmp, sizeof(tmp), fmt "\n", ##a)); \
} while(0)
#endif
#ifdef __cplusplus
}
#endif
#endif /* jffi_jffi_h */
jffi-1.2.7/jni/jffi/longjmp.c 0000664 0000000 0000000 00000006565 12470474244 0015773 0 ustar 00root root 0000000 0000000 /* libunwind - a platform-independent unwind library
Copyright (C) 2003-2004 Hewlett-Packard Co
Contributed by David Mosberger-Tang
This file is part of libunwind.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#undef _FORTIFY_SOURCE
#include
#include
#include
#include
#include
#include
#include "jffi.h"
#include "FaultProtect.h"
#if FAULT_PROTECT_ENABLED
#include
#ifdef __APPLE__
#if defined(__x86_64__)
# define SP_OFF 16
#else
# define SP_OFF 12
#endif
#elif defined __FreeBSD__
# define SP_OFF (sizeof(unw_word_t))
#else
# define SP_OFF 0
#endif
void
jffi_longjmp (jmp_buf env, int val)
{
extern int _jffi_longjmp_cont;
unw_context_t uc;
unw_cursor_t c;
unw_word_t sp, ip, bp = 0;
uintptr_t *wp = (uintptr_t *) env;
int i, setjmp_frame;
if (unw_getcontext (&uc) < 0 || unw_init_local (&c, &uc) < 0) {
debug("failed to get context");
abort ();
}
#ifdef __x86_86__
# define UNW_REG_BP UNW_X86_64_RBP
#else
# define UNW_REG_BP UNW_X86_EBP
#endif
setjmp_frame = 0;
do {
char name[256];
unw_proc_info_t pi;
unw_word_t off;
if (unw_get_reg (&c, UNW_REG_BP, &bp) < 0) {
abort();
}
if (unw_get_reg (&c, UNW_REG_SP, &sp) < 0) {
abort();
}
if (unw_get_reg (&c, UNW_REG_IP, &ip) < 0) {
abort();
}
unw_get_proc_name(&c, name, sizeof(name), &off);
unw_get_proc_info(&c, &pi);
// debug("frame %s ip=%llx sp=%llx bp=%llx wp[RP]=%p wp[SP]=%p, pi.start_ip=%llx, pi.end_ip=%llx",
// name, (long long) ip, (long long) sp, (long long) bp, (void *) wp[JB_RP], (void *) wp[JB_SP],
// pi.start_ip, pi.end_ip);
if (wp[JB_SP] > sp || wp[JB_RP] < pi.start_ip || wp[JB_RP] > pi.end_ip) continue;
/* found the right frame: */
// debug("found frame to jump back to");
assert (UNW_NUM_EH_REGS >= 2);
if (unw_set_reg (&c, UNW_REG_EH + 0, wp[JB_RP]) < 0
|| unw_set_reg (&c, UNW_REG_EH + 1, val) < 0
|| unw_set_reg (&c, UNW_REG_IP, (unw_word_t) (uintptr_t) &_jffi_longjmp_cont))
abort ();
unw_resume (&c);
// should not reach here
abort ();
} while (unw_step (&c) > 0);
// debug("failed to find correct frame to jmp to");
}
#endif /* FAULT_PROTECT_ENABLED */
jffi-1.2.7/jni/jffi/queue.h 0000664 0000000 0000000 00000043307 12470474244 0015451 0 ustar 00root root 0000000 0000000 /* $OpenBSD: queue.h,v 1.32 2007/04/30 18:42:34 pedro Exp $ */
/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
/*
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)queue.h 8.5 (Berkeley) 8/20/94
*/
#ifndef _JFFI_QUEUE_H_
#define _JFFI_QUEUE_H_
/*
* This file defines five types of data structures: singly-linked lists,
* lists, simple queues, tail queues, and circular queues.
*
*
* A singly-linked list is headed by a single forward pointer. The elements
* are singly linked for minimum space and pointer manipulation overhead at
* the expense of O(n) removal for arbitrary elements. New elements can be
* added to the list after an existing element or at the head of the list.
* Elements being removed from the head of the list should use the explicit
* macro for this purpose for optimum efficiency. A singly-linked list may
* only be traversed in the forward direction. Singly-linked lists are ideal
* for applications with large datasets and few or no removals or for
* implementing a LIFO queue.
*
* A list is headed by a single forward pointer (or an array of forward
* pointers for a hash table header). The elements are doubly linked
* so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before
* or after an existing element or at the head of the list. A list
* may only be traversed in the forward direction.
*
* A simple queue is headed by a pair of pointers, one the head of the
* list and the other to the tail of the list. The elements are singly
* linked to save space, so elements can only be removed from the
* head of the list. New elements can be added to the list before or after
* an existing element, at the head of the list, or at the end of the
* list. A simple queue may only be traversed in the forward direction.
*
* A tail queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or
* after an existing element, at the head of the list, or at the end of
* the list. A tail queue may be traversed in either direction.
*
* A circle queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or after
* an existing element, at the head of the list, or at the end of the list.
* A circle queue may be traversed in either direction, but has a more
* complex end of list detection.
*
* For details on the use of these macros, see the queue(3) manual page.
*/
#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
#define _Q_INVALIDATE(a) (a) = ((void *)-1)
#else
#define _Q_INVALIDATE(a)
#endif
/*
* Singly-linked List definitions.
*/
#define SLIST_HEAD(name, type) \
struct name { \
struct type *slh_first; /* first element */ \
}
#define SLIST_HEAD_INITIALIZER(head) \
{ NULL }
#define SLIST_ENTRY(type) \
struct { \
struct type *sle_next; /* next element */ \
}
/*
* Singly-linked List access methods.
*/
#define SLIST_FIRST(head) ((head)->slh_first)
#define SLIST_END(head) NULL
#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
#define SLIST_FOREACH(var, head, field) \
for((var) = SLIST_FIRST(head); \
(var) != SLIST_END(head); \
(var) = SLIST_NEXT(var, field))
#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
for ((varp) = &SLIST_FIRST((head)); \
((var) = *(varp)) != SLIST_END(head); \
(varp) = &SLIST_NEXT((var), field))
/*
* Singly-linked List functions.
*/
#define SLIST_INIT(head) { \
SLIST_FIRST(head) = SLIST_END(head); \
}
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
(elm)->field.sle_next = (slistelm)->field.sle_next; \
(slistelm)->field.sle_next = (elm); \
} while (0)
#define SLIST_INSERT_HEAD(head, elm, field) do { \
(elm)->field.sle_next = (head)->slh_first; \
(head)->slh_first = (elm); \
} while (0)
#define SLIST_REMOVE_NEXT(head, elm, field) do { \
(elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \
} while (0)
#define SLIST_REMOVE_HEAD(head, field) do { \
(head)->slh_first = (head)->slh_first->field.sle_next; \
} while (0)
#define SLIST_REMOVE(head, elm, type, field) do { \
if ((head)->slh_first == (elm)) { \
SLIST_REMOVE_HEAD((head), field); \
} else { \
struct type *curelm = (head)->slh_first; \
\
while (curelm->field.sle_next != (elm)) \
curelm = curelm->field.sle_next; \
curelm->field.sle_next = \
curelm->field.sle_next->field.sle_next; \
_Q_INVALIDATE((elm)->field.sle_next); \
} \
} while (0)
/*
* List definitions.
*/
#define LIST_HEAD(name, type) \
struct name { \
struct type *lh_first; /* first element */ \
}
#define LIST_HEAD_INITIALIZER(head) \
{ NULL }
#define LIST_ENTRY(type) \
struct { \
struct type *le_next; /* next element */ \
struct type **le_prev; /* address of previous next element */ \
}
/*
* List access methods
*/
#define LIST_FIRST(head) ((head)->lh_first)
#define LIST_END(head) NULL
#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
#define LIST_FOREACH(var, head, field) \
for((var) = LIST_FIRST(head); \
(var)!= LIST_END(head); \
(var) = LIST_NEXT(var, field))
/*
* List functions.
*/
#define LIST_INIT(head) do { \
LIST_FIRST(head) = LIST_END(head); \
} while (0)
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
(listelm)->field.le_next->field.le_prev = \
&(elm)->field.le_next; \
(listelm)->field.le_next = (elm); \
(elm)->field.le_prev = &(listelm)->field.le_next; \
} while (0)
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.le_prev = (listelm)->field.le_prev; \
(elm)->field.le_next = (listelm); \
*(listelm)->field.le_prev = (elm); \
(listelm)->field.le_prev = &(elm)->field.le_next; \
} while (0)
#define LIST_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
(head)->lh_first = (elm); \
(elm)->field.le_prev = &(head)->lh_first; \
} while (0)
#define LIST_REMOVE(elm, field) do { \
if ((elm)->field.le_next != NULL) \
(elm)->field.le_next->field.le_prev = \
(elm)->field.le_prev; \
*(elm)->field.le_prev = (elm)->field.le_next; \
_Q_INVALIDATE((elm)->field.le_prev); \
_Q_INVALIDATE((elm)->field.le_next); \
} while (0)
#define LIST_REPLACE(elm, elm2, field) do { \
if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
(elm2)->field.le_next->field.le_prev = \
&(elm2)->field.le_next; \
(elm2)->field.le_prev = (elm)->field.le_prev; \
*(elm2)->field.le_prev = (elm2); \
_Q_INVALIDATE((elm)->field.le_prev); \
_Q_INVALIDATE((elm)->field.le_next); \
} while (0)
/*
* Simple queue definitions.
*/
#define SIMPLEQ_HEAD(name, type) \
struct name { \
struct type *sqh_first; /* first element */ \
struct type **sqh_last; /* addr of last next element */ \
}
#define SIMPLEQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).sqh_first }
#define SIMPLEQ_ENTRY(type) \
struct { \
struct type *sqe_next; /* next element */ \
}
/*
* Simple queue access methods.
*/
#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
#define SIMPLEQ_END(head) NULL
#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
#define SIMPLEQ_FOREACH(var, head, field) \
for((var) = SIMPLEQ_FIRST(head); \
(var) != SIMPLEQ_END(head); \
(var) = SIMPLEQ_NEXT(var, field))
/*
* Simple queue functions.
*/
#define SIMPLEQ_INIT(head) do { \
(head)->sqh_first = NULL; \
(head)->sqh_last = &(head)->sqh_first; \
} while (0)
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
(head)->sqh_last = &(elm)->field.sqe_next; \
(head)->sqh_first = (elm); \
} while (0)
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.sqe_next = NULL; \
*(head)->sqh_last = (elm); \
(head)->sqh_last = &(elm)->field.sqe_next; \
} while (0)
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
(head)->sqh_last = &(elm)->field.sqe_next; \
(listelm)->field.sqe_next = (elm); \
} while (0)
#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
(head)->sqh_last = &(head)->sqh_first; \
} while (0)
/*
* Tail queue definitions.
*/
#define TAILQ_HEAD(name, type) \
struct name { \
struct type *tqh_first; /* first element */ \
struct type **tqh_last; /* addr of last next element */ \
}
#define TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first }
#define TAILQ_ENTRY(type) \
struct { \
struct type *tqe_next; /* next element */ \
struct type **tqe_prev; /* address of previous next element */ \
}
/*
* tail queue access methods
*/
#define TAILQ_FIRST(head) ((head)->tqh_first)
#define TAILQ_END(head) NULL
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
#define TAILQ_LAST(head, headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last))
/* XXX */
#define TAILQ_PREV(elm, headname, field) \
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
#define TAILQ_EMPTY(head) \
(TAILQ_FIRST(head) == TAILQ_END(head))
#define TAILQ_FOREACH(var, head, field) \
for((var) = TAILQ_FIRST(head); \
(var) != TAILQ_END(head); \
(var) = TAILQ_NEXT(var, field))
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
for((var) = TAILQ_LAST(head, headname); \
(var) != TAILQ_END(head); \
(var) = TAILQ_PREV(var, headname, field))
/*
* Tail queue functions.
*/
#define TAILQ_INIT(head) do { \
(head)->tqh_first = NULL; \
(head)->tqh_last = &(head)->tqh_first; \
} while (0)
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
(head)->tqh_first->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(head)->tqh_first = (elm); \
(elm)->field.tqe_prev = &(head)->tqh_first; \
} while (0)
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.tqe_next = NULL; \
(elm)->field.tqe_prev = (head)->tqh_last; \
*(head)->tqh_last = (elm); \
(head)->tqh_last = &(elm)->field.tqe_next; \
} while (0)
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
(elm)->field.tqe_next->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(listelm)->field.tqe_next = (elm); \
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
} while (0)
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
(elm)->field.tqe_next = (listelm); \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
} while (0)
#define TAILQ_REMOVE(head, elm, field) do { \
if (((elm)->field.tqe_next) != NULL) \
(elm)->field.tqe_next->field.tqe_prev = \
(elm)->field.tqe_prev; \
else \
(head)->tqh_last = (elm)->field.tqe_prev; \
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
_Q_INVALIDATE((elm)->field.tqe_prev); \
_Q_INVALIDATE((elm)->field.tqe_next); \
} while (0)
#define TAILQ_REPLACE(head, elm, elm2, field) do { \
if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
(elm2)->field.tqe_next->field.tqe_prev = \
&(elm2)->field.tqe_next; \
else \
(head)->tqh_last = &(elm2)->field.tqe_next; \
(elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
*(elm2)->field.tqe_prev = (elm2); \
_Q_INVALIDATE((elm)->field.tqe_prev); \
_Q_INVALIDATE((elm)->field.tqe_next); \
} while (0)
/*
* Circular queue definitions.
*/
#define CIRCLEQ_HEAD(name, type) \
struct name { \
struct type *cqh_first; /* first element */ \
struct type *cqh_last; /* last element */ \
}
#define CIRCLEQ_HEAD_INITIALIZER(head) \
{ CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
#define CIRCLEQ_ENTRY(type) \
struct { \
struct type *cqe_next; /* next element */ \
struct type *cqe_prev; /* previous element */ \
}
/*
* Circular queue access methods
*/
#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
#define CIRCLEQ_LAST(head) ((head)->cqh_last)
#define CIRCLEQ_END(head) ((void *)(head))
#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
#define CIRCLEQ_EMPTY(head) \
(CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
#define CIRCLEQ_FOREACH(var, head, field) \
for((var) = CIRCLEQ_FIRST(head); \
(var) != CIRCLEQ_END(head); \
(var) = CIRCLEQ_NEXT(var, field))
#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
for((var) = CIRCLEQ_LAST(head); \
(var) != CIRCLEQ_END(head); \
(var) = CIRCLEQ_PREV(var, field))
/*
* Circular queue functions.
*/
#define CIRCLEQ_INIT(head) do { \
(head)->cqh_first = CIRCLEQ_END(head); \
(head)->cqh_last = CIRCLEQ_END(head); \
} while (0)
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
(elm)->field.cqe_next = (listelm)->field.cqe_next; \
(elm)->field.cqe_prev = (listelm); \
if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \
(head)->cqh_last = (elm); \
else \
(listelm)->field.cqe_next->field.cqe_prev = (elm); \
(listelm)->field.cqe_next = (elm); \
} while (0)
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
(elm)->field.cqe_next = (listelm); \
(elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \
(head)->cqh_first = (elm); \
else \
(listelm)->field.cqe_prev->field.cqe_next = (elm); \
(listelm)->field.cqe_prev = (elm); \
} while (0)
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
(elm)->field.cqe_next = (head)->cqh_first; \
(elm)->field.cqe_prev = CIRCLEQ_END(head); \
if ((head)->cqh_last == CIRCLEQ_END(head)) \
(head)->cqh_last = (elm); \
else \
(head)->cqh_first->field.cqe_prev = (elm); \
(head)->cqh_first = (elm); \
} while (0)
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.cqe_next = CIRCLEQ_END(head); \
(elm)->field.cqe_prev = (head)->cqh_last; \
if ((head)->cqh_first == CIRCLEQ_END(head)) \
(head)->cqh_first = (elm); \
else \
(head)->cqh_last->field.cqe_next = (elm); \
(head)->cqh_last = (elm); \
} while (0)
#define CIRCLEQ_REMOVE(head, elm, field) do { \
if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \
(head)->cqh_last = (elm)->field.cqe_prev; \
else \
(elm)->field.cqe_next->field.cqe_prev = \
(elm)->field.cqe_prev; \
if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \
(head)->cqh_first = (elm)->field.cqe_next; \
else \
(elm)->field.cqe_prev->field.cqe_next = \
(elm)->field.cqe_next; \
_Q_INVALIDATE((elm)->field.cqe_prev); \
_Q_INVALIDATE((elm)->field.cqe_next); \
} while (0)
#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \
CIRCLEQ_END(head)) \
(head).cqh_last = (elm2); \
else \
(elm2)->field.cqe_next->field.cqe_prev = (elm2); \
if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \
CIRCLEQ_END(head)) \
(head).cqh_first = (elm2); \
else \
(elm2)->field.cqe_prev->field.cqe_next = (elm2); \
_Q_INVALIDATE((elm)->field.cqe_prev); \
_Q_INVALIDATE((elm)->field.cqe_next); \
} while (0)
#endif /* !_JFFI_QUEUE_H_ */
jffi-1.2.7/jni/jffi/setjmp.c 0000664 0000000 0000000 00000000705 12470474244 0015615 0 ustar 00root root 0000000 0000000 #include "FaultProtect.h"
#if FAULT_PROTECT_ENABLED
#include
#include
#include
#include
#include
#include "jffi.h"
#include "Exception.h"
int
jffi_setjmp(FaultData* f)
{
void **wp = (void **) f->buf;
wp[JB_SP] = __builtin_frame_address (0);
wp[JB_RP] = (void *) __builtin_return_address (0);
// debug("saved state: sp=%p, rp=%p", wp[JB_SP], wp[JB_RP]);
return 0;
}
#endif
jffi-1.2.7/libtest/ 0000775 0000000 0000000 00000000000 12470474244 0014115 5 ustar 00root root 0000000 0000000 jffi-1.2.7/libtest/Benchmark.c 0000664 0000000 0000000 00000005177 12470474244 0016165 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2007 Wayne Meissner. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include
#include
void returnVoid() {
}
void returnVoidI(int arg) {
}
int returnInt() {
return 0;
}
int returnIntI(int arg) {
return arg;
}
typedef int8_t s8;
typedef uint8_t u8;
typedef int16_t s16;
typedef uint16_t u16;
typedef int32_t s32;
typedef uint32_t u32;
typedef int64_t s64;
typedef uint64_t u64;
typedef float f32;
typedef double f64;
typedef void v;
typedef char* S;
typedef void* P;
#define B6(R, T1, T2, T3, T4, T5, T6) R bench_##T1##T2##T3##T4##T5##T6##_##R(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6) {}
#define B5(R, T1, T2, T3, T4, T5) R bench_##T1##T2##T3##T4##T5##_##R(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) {}
#define B4(R, T1, T2, T3, T4) R bench_##T1##T2##T3##T4##_##R(T1 a1, T2 a2, T3 a3, T4 a4) {}
#define B3(R, T1, T2, T3) R bench_##T1##T2##T3##_##R(T1 a1, T2 a2, T3 a3) {}
#define B2(R, T1, T2) R bench_##T1##T2##_##R(T1 a1, T2 a2) {}
#define B1(R, T1) R bench_##T1##_##R(T1 a1) {}
#define BrV(T) B1(v, T); B2(v, T, T); B3(v, T, T, T); B4(v, T, T, T, T); B5(v, T, T, T, T, T); B6(v, T, T, T, T, T, T);
BrV(u32);
BrV(s32);
BrV(s64);
BrV(u64);
BrV(f32);
BrV(f64);
BrV(S);
BrV(P);
jffi-1.2.7/libtest/BufferTest.c 0000664 0000000 0000000 00000004207 12470474244 0016335 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2007 Wayne Meissner
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define MEMSET(buf, value, size) do { \
int i; for (i = 0; i < size; ++i) buf[i] = value; \
} while(0)
#define MEMCPY(dst, src, size) do { \
int i; for (i = 0; i < size; ++i) dst[i] = src[i]; \
} while(0)
#define FILL(JTYPE, CTYPE) \
void fill##JTYPE##Buffer(CTYPE* buf, CTYPE value, int size) { MEMSET(buf, value, size); }
#define COPY(JTYPE, CTYPE) \
void copy##JTYPE##Buffer(CTYPE* dst, CTYPE* src, int size) { MEMCPY(dst, src, size); }
#define FUNC(JTYPE, CTYPE) \
FILL(JTYPE, CTYPE); \
COPY(JTYPE, CTYPE)
FUNC(Byte, char);
FUNC(Short, short);
FUNC(Int, int);
FUNC(Long, long long);
FUNC(Float, float);
FUNC(Double, double);
jffi-1.2.7/libtest/ClosureTest.c 0000664 0000000 0000000 00000012567 12470474244 0016550 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2007 Wayne Meissner. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include
#ifndef _WIN32
# include
#endif
void testClosureVrV(void (*closure)(void))
{
(*closure)();
}
char testClosureVrB(char (*closure)(void))
{
return (*closure)();
}
short testClosureVrS(short (*closure)(void))
{
return (*closure)();
}
int testClosureVrI(int (*closure)(void))
{
return (*closure)();
}
long long testClosureVrL(long long (*closure)(void))
{
return (*closure)();
}
float testClosureVrF(float (*closure)(void))
{
return (*closure)();
}
double testClosureVrD(double (*closure)(void))
{
return (*closure)();
}
void* testClosureVrP(void* (*closure)(void))
{
return (*closure)();
}
void testClosureBrV(void (*closure)(char), char a1)
{
(*closure)(a1);
}
void testClosureSrV(void (*closure)(short), short a1)
{
(*closure)(a1);
}
void testClosureIrV(void (*closure)(int), int a1)
{
(*closure)(a1);
}
void testClosureLrV(void (*closure)(long long), long long a1)
{
(*closure)(a1);
}
void testClosureFrV(void (*closure)(float), float a1)
{
(*closure)(a1);
}
void testClosureDrV(void (*closure)(double), double a1)
{
(*closure)(a1);
}
void testOptionalClosureBrV(void (*closure)(char), char a1)
{
if (closure) {
(*closure)(a1);
}
}
struct ThreadVrV {
void (*closure)(void);
int count;
};
static void *
threadVrV(void *arg)
{
struct ThreadVrV* t = (struct ThreadVrV *) arg;
int i;
for (i = 0; i < t->count; i++) {
(*t->closure)();
}
return NULL;
}
void testThreadedClosureVrV(void (*closure)(void), int n)
{
#ifndef _WIN32
pthread_t t;
struct ThreadVrV arg;
arg.closure = closure;
arg.count = n;
pthread_create(&t, NULL, threadVrV, &arg);
pthread_join(t, NULL);
#else
int i;
for (i = 0; i < t->count; i++) {
(*closure)();
}
#endif
}
struct s8f32s32 {
char s8;
float f32;
int s32;
};
// Takes a struct argument
void testClosureTrV(void (*closure)(struct s8f32s32 s), struct s8f32s32* s)
{
(*closure)(*s);
}
// Returns a struct value
struct s8f32s32 testClosureVrT(struct s8f32s32 (*closure)())
{
return (*closure)();
}
typedef int (*returnTypeClosure_t)(int) ;
typedef returnTypeClosure_t (*lookupClosure_t)();
int testReturnsClosure(lookupClosure_t lookup, int val)
{
returnTypeClosure_t func = lookup ? (*lookup)() : NULL;
return func ? (*func)(val) : 0;
}
static int multiplyByTwo(int value)
{
return value * 2;
}
returnTypeClosure_t testReturnsFunctionPointer()
{
return multiplyByTwo;
}
typedef int (*argumentClosure_t)(int);
typedef int (*withArgumentClosure_t)(argumentClosure_t, int);
int testArgumentClosure(withArgumentClosure_t closure_with, argumentClosure_t closure_arg, int val)
{
return (*closure_with)(closure_arg, val);
}
//
// These macros produce functions of the form:
// testClosureBIrV(void (*closure)(char, int), char a1, int a2) {}
//
#define C2_(J1, J2, N1, N2) \
void testClosure##J1##J2##rV(void (*closure)(N1, N2), N1 a1, N2 a2) \
{ \
(*closure)(a1, a2); \
}
#define C2(J, N) \
C2_(B, J, char, N) \
C2_(S, J, short, N) \
C2_(I, J, int, N) \
C2_(L, J, long long, N) \
C2_(F, J, float, N) \
C2_(D, J, double, N) \
C2(B, char);
C2(S, short);
C2(I, int);
C2(L, long long);
C2(F, float);
C2(D, double);
#define C3_(J1, J2, J3, N1, N2, N3) \
void testClosure##J1##J2##J3##rV(void (*closure)(N1, N2, N3), N1 a1, N2 a2, N3 a3) \
{ \
(*closure)(a1, a2, a3); \
}
#define C3(J, N) \
C3_(B, J, B, char, N, char) \
C3_(S, J, S, short, N, short) \
C3_(I, J, I, int, N, int) \
C3_(L, J, L, long long, N, long long) \
C3_(F, J, F, float, N, float) \
C3_(D, J, D, double, N, double) \
C3(B, char);
C3(S, short);
C3(I, int);
C3(L, long long);
C3(F, float);
C3(D, double);
C3_(B, S, I, char, short, int);
C3_(B, S, L, char, short, long long);
C3_(L, S, B, long long, short, char);
C3_(L, B, S, long long, char, short);
jffi-1.2.7/libtest/EnumTest.c 0000664 0000000 0000000 00000004176 12470474244 0016035 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2007 Wayne Meissner. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
int test_untagged_enum(int val) {
return val;
}
int test_untagged_typedef_enum(int val) {
return val;
}
typedef enum {c1, c2, c3, c4} enum_type1;
enum_type1 test_tagged_typedef_enum1(enum_type1 val) {
return val;
}
typedef enum {c5 = 42, c6, c7, c8} enum_type2;
enum_type2 test_tagged_typedef_enum2(enum_type2 val) {
return val;
}
typedef enum {c9 = 42, c10, c11 = 4242, c12} enum_type3;
enum_type3 test_tagged_typedef_enum3(enum_type3 val) {
return val;
}
typedef enum {c13 = 42, c14 = 4242, c15 = 424242, c16 = 42424242} enum_type4;
enum_type4 test_tagged_typedef_enum4(enum_type4 val) {
return val;
}
jffi-1.2.7/libtest/GNUmakefile 0000664 0000000 0000000 00000011271 12470474244 0016171 0 ustar 00root root 0000000 0000000 # -*- makefile -*-
BUILD_OS := $(strip $(shell uname -s | tr '[:upper:]' '[:lower:]'))
OS ?= $(BUILD_OS)
# Default value of $OS on Windows is Windows_NT
ifeq ($(OS), Windows_NT)
# that's how we detect x64...
ifneq ($(findstring 64, $(BUILD_OS)),)
OS = win64
else
OS = win32
endif
endif
CPU = $(shell uname -m | sed -e 's/i[345678]86/i386/')
MODEL = 32 # Default to 32bit compiles
PLATFORM = $(CPU)-$(OS)
ifeq ($(OS), sunos)
OS = solaris
endif
ifneq ($(findstring cygwin,$(BUILD_OS)),)
# cygwin is always x32 for now
OS = win32
endif
SRC_DIR = libtest
BUILD_DIR ?= build
TEST_BUILD_DIR = $(BUILD_DIR)/libtest
# Set defaults to unix (linux/solaris/bsd)
PREFIX = lib
LIBEXT = so
LIBNAME = $(PREFIX)test.$(LIBEXT)
export MACOSX_DEPLOYMENT_TARGET=10.4
CCACHE := $(strip $(realpath $(shell which ccache 2> /dev/null)))
TEST_SRCS = $(wildcard $(SRC_DIR)/*.c)
TEST_OBJS := $(patsubst $(SRC_DIR)/%.c, $(TEST_BUILD_DIR)/%.o, $(TEST_SRCS))
#
# Compiler/linker flags from:
# http://weblogs.java.net/blog/kellyohair/archive/2006/01/compilation_of_1.html
JFLAGS = -fno-omit-frame-pointer -fno-strict-aliasing
OFLAGS = -O2 $(JFLAGS)
WFLAGS = -W -Werror -Wall -Wno-unused -Wno-parentheses
PICFLAGS = -fPIC
SOFLAGS = -shared -Wl,-O1
LDFLAGS += $(SOFLAGS)
IFLAGS = -I"$(BUILD_DIR)"
CFLAGS = $(OFLAGS) $(WFLAGS) $(IFLAGS) $(PICFLAGS) -D_REENTRANT
ifeq ($(OS), win64)
override CPU = x86_64
JDK_INCLUDES=-I$(JNI_DIR)/win32/include -I$(JNI_DIR)/win32/include/win32
CC = x86_64-w64-mingw32-gcc -m64
PICFLAGS =
ifneq ($(findstring cygwin, $(BUILD_OS)),)
CC += -mno-cygwin
LDFLAGS += -mno-cygwin
endif
CFLAGS += -mwin32 -D_JNI_IMPLEMENTATION_
LDFLAGS += -Wl,--add-stdcall-alias
PICFLAGS=
SOFLAGS += -shared -static-libgcc
PREFIX =
LIBEXT = dll
endif
ifeq ($(OS), win32)
CC += -mno-cygwin -mwin32
LDFLAGS += -mno-cygwin -Wl,--add-stdcall-alias
PREFIX =
PICFLAGS =
LIBEXT = dll
endif
ifeq ($(OS), darwin)
ARCHFLAGS =
ifneq ($(findstring $(CPU), ppc powerpc),)
ARCHES += ppc
endif
ifneq ($(findstring $(CPU), i386 x86_64),)
ARCHES += i386 x86_64
endif
ifneq ($(realpath $(wildcard /Xcode3/usr/bin/gcc)),)
XCODE=/Xcode3
else
XCODE=$(shell xcode-select -print-path)
endif
ifneq ($(realpath $(wildcard $(XCODE)/usr/bin/gcc-4.0)),)
CC = $(XCODE)/usr/bin/gcc-4.0
else
CC = $(XCODE)/usr/bin/gcc
endif
ifneq ($(realpath $(wildcard $(XCODE)/SDKs/MacOSX10.4?.sdk)),)
MACSDK = $(XCODE)/SDKs/MacOSX10.4u.sdk
ifeq ($(findstring ppc, $(ARCHES)),)
ARCHES += ppc
endif
else
MACSDK = $(firstword $(strip $(wildcard $(XCODE)/SDKs/MacOSX10.*.sdk)) $(strip $(wildcard $(XCODE)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.*.sdk)))
endif
ARCHFLAGS = $(foreach arch, $(ARCHES),-arch $(arch))
CFLAGS += $(ARCHFLAGS) -isysroot $(MACSDK) -DTARGET_RT_MAC_CFM=0
CFLAGS += -fno-common
LDFLAGS = $(ARCHFLAGS) -dynamiclib -Wl,-syslibroot,$(MACSDK) -mmacosx-version-min=10.4
LDFLAGS += $(foreach arch, $(ARCHES),-arch $(arch))
# link against the universal libraries on ppc machines
LDFLAGS += -L$(MACSDK)/usr/lib
LIBEXT = dylib
FFI_CFLAGS += -isysroot $(MACSDK)
PICFLAGS =
SOFLAGS =
endif
ifeq ($(OS), linux)
SOFLAGS += -Wl,-soname,$(LIBNAME)
endif
ifeq ($(OS), solaris)
CC = gcc
CFLAGS += -std=c99
LD = /usr/ccs/bin/ld
SOFLAGS = -shared -static-libgcc
endif
ifeq ($(OS), aix)
LIBEXT = a
SOFLAGS = -shared -static-libgcc
PICFLAGS += -pthread
endif
ifneq ($(findstring bsd, $(OS)),)
SOFLAGS = -shared -static-libgcc
CFLAGS += -pthread
LDFLAGS += -pthread
endif
ifneq ($(findstring cygwin, $(OS)),)
CFLAGS += -mno-cygwin -mwin32
LDFLAGS += -mno-cygwin -Wl,--add-stdcall-alias
LIBEXT = dll
PREFIX =
PICFLAGS =
endif
ifneq ($(findstring mingw, $(OS)),)
LIBEXT = dll
PICFLAGS=
endif
ifeq ($(CPU), sparcv9)
MODEL = 64
endif
ifeq ($(CPU), amd64)
MODEL = 64
endif
ifeq ($(CPU), x86_64)
MODEL = 64
endif
ifeq ($(CPU), s390x)
MODEL = 64
endif
ifeq ($(CPU), ppc64)
MODEL = 64
endif
# On platforms (linux, solaris) that support both 32bit and 64bit, force building for one or the other
ifneq ($(strip $(findstring $(OS), solaris)),)
# Change the CC/LD instead of CFLAGS/LDFLAGS, incase other things in the flags
# makes the libffi build choke
CC += -m$(MODEL)
LD += -m$(MODEL)
endif
LIBTEST = $(BUILD_DIR)/$(LIBNAME)
all: $(LIBTEST)
$(TEST_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
@mkdir -p $(@D)
$(CCACHE) $(CC) $(CFLAGS) -c $< -o $@
$(LIBTEST): $(TEST_OBJS)
$(CC) -o $@ $(LDFLAGS) $(TEST_OBJS) -lm
clean::
# nothing to do - ant will delete the build dir
debug::
@echo OS="$(OS)"
@echo BUILD_OS="$(BUILD_OS)"
@echo JAVA_HOME="$(JAVA_HOME)"
@echo JDK_HOME="$(JDK_HOME)"
@echo "SRCS=$(TEST_SRCS)"
jffi-1.2.7/libtest/GlobalVariable.c 0000664 0000000 0000000 00000001267 12470474244 0017135 0 ustar 00root root 0000000 0000000 #include
#include
typedef int8_t s8;
typedef uint8_t u8;
typedef int16_t s16;
typedef uint16_t u16;
typedef int32_t s32;
typedef uint32_t u32;
typedef int64_t s64;
typedef uint64_t u64;
typedef signed long sL;
typedef unsigned long uL;
typedef float f32;
typedef double f64;
#if !defined(__OpenBSD__)
typedef unsigned long ulong;
#endif
typedef void* pointer;
typedef void* P;
#define GVAR(T) \
extern T gvar_##T; \
T gvar_##T = (T) -1; \
T gvar_##T##_get() { return gvar_##T; }; \
void gvar_##T##_set(T v) { gvar_##T = v; }
GVAR(s8);
GVAR(u8);
GVAR(s16);
GVAR(u16);
GVAR(s32);
GVAR(u32);
GVAR(s64);
GVAR(u64);
GVAR(long);
GVAR(ulong);
GVAR(pointer);
jffi-1.2.7/libtest/LastErrorTest.c 0000664 0000000 0000000 00000003371 12470474244 0017042 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2008 Wayne Meissner. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(_WIN32) || defined(__WIN32__)
# include
#else
# include
#endif
int setLastError(int error) {
#if defined(_WIN32) || defined(__WIN32__)
SetLastError(error);
#else
errno = error;
#endif
return -1;
}
jffi-1.2.7/libtest/NumberTest.c 0000664 0000000 0000000 00000012053 12470474244 0016352 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2007 Wayne Meissner. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include
#include
#include
#include
typedef int8_t s8;
typedef uint8_t u8;
typedef int16_t s16;
typedef uint16_t u16;
typedef int32_t s32;
typedef uint32_t u32;
typedef int64_t s64;
typedef uint64_t u64;
typedef signed long sL;
typedef unsigned long uL;
typedef float f32;
typedef double f64;
typedef long double f128;
#if !defined(__OpenBSD__)
typedef unsigned long ulong;
#endif
#define ADD(T) T add_##T(T arg1, T arg2) { return arg1 + arg2; }
#define SUB(T) T sub_##T(T arg1, T arg2) { return arg1 - arg2; }
#define MUL(T) T mul_##T(T arg1, T arg2) { return arg1 * arg2; }
#define DIV(T) T div_##T(T arg1, T arg2) { return arg1 / arg2; }
#define RET(T) T ret_##T(T arg1) { return arg1; }
#define SET(T) static T T##_;void set_##T(T arg1) { T##_ = arg1; }
#define GET(T) T get_##T() { return T##_; }
typedef char* ptr;
#define TEST(T) ADD(T) SUB(T) MUL(T) DIV(T) RET(T) SET(T) GET(T)
TEST(s8);
TEST(u8);
TEST(s16);
TEST(u16);
TEST(s32);
TEST(u32);
TEST(s64);
TEST(u64);
TEST(float);
TEST(double);
TEST(f128);
TEST(long);
TEST(ulong);
#define ADD2(R, T1, T2) R add_##T1##T2##_##R(T1 arg1, T2 arg2) { return arg1 + arg2; }
#define SUB2(R, T1, T2) R sub_##T1##T2##_##R(T1 arg1, T2 arg2) { return arg1 - arg2; }
#define MUL2(R, T1, T2) R mul_##T1##T2##_##R(T1 arg1, T2 arg2) { return arg1 * arg2; }
#define DIV2(R, T1, T2) R div_##T1##T2##_##R(T1 arg1, T2 arg2) { return arg1 / arg2; }
#define T2__(R, T1, T2) ADD2(R, T1, T2) SUB2(R, T1, T2) MUL2(R, T1, T2) DIV2(R, T1, T2)
#define T2_(R, T1) \
T2__(R, T1, s8) T2__(R, T1, u8) \
T2__(R, T1, s16) T2__(R, T1, u16) \
T2__(R, T1, s32) T2__(R, T1, u32) \
T2__(R, T1, sL) T2__(R, T1, uL) \
T2__(R, T1, s64) T2__(R, T1, u64) \
#define TEST2(R) \
T2_(R, s8) T2_(R, u8) T2_(R, s16) T2_(R, u16) T2_(R, s32) T2_(R, u32) \
T2_(R, sL) T2_(R, uL) T2_(R, s64) T2_(R, u64)
#ifdef notyet
TEST2(s32)
TEST2(u32)
TEST2(s64)
TEST2(u64)
#endif
#define ADD3(R, T1, T2, T3) R add_##T1##T2##T3##_##R(T1 arg1, T2 arg2, T3 arg3) { return arg1 + arg2 + arg3; }
#define pack_f32(buf, v) do { *(float *)(buf) = v; } while(0)
#define pack_f64(buf, v) do { *(double *)(buf) = v; } while(0)
#define pack_f128(buf, v) do { *(long double *)(buf) = v; } while(0)
#define pack_int(buf, v) do { *(buf) = v; } while(0)
#define pack_s8 pack_int
#define pack_u8 pack_int
#define pack_s16 pack_int
#define pack_u16 pack_int
#define pack_s32 pack_int
#define pack_u32 pack_int
#define pack_s64 pack_int
#define pack_u64 pack_int
#define pack_sL pack_int
#define pack_uL pack_int
#define PACK3(R, T1, T2, T3) void pack_##T1##T2##T3##_##R(T1 arg1, T2 arg2, T3 arg3, R* r) { \
pack_##T1(&r[0], arg1); \
pack_##T2(&r[1], arg2); \
pack_##T3(&r[2], arg3); \
}
#define T3___(R, T1, T2, T3) PACK3(R, T1, T2, T3) /* SUB2(R, T1, T2) MUL2(R, T1, T2) DIV2(R, T1, T2) */
#define T3__(R, T1, T2) \
T3___(R, T1, T2, s8) T3___(R, T1, T2, u8) \
T3___(R, T1, T2, s16) T3___(R, T1, T2, u16) \
T3___(R, T1, T2, s32) T3___(R, T1, T2, u32) \
T3___(R, T1, T2, sL) T3___(R, T1, T2, uL) \
T3___(R, T1, T2, s64) T3___(R, T1, T2, u64) \
T3___(R, T1, T2, f32) T3___(R, T1, T2, f64) \
#define T3_(R, T1) \
T3__(R, T1, s8) T3__(R, T1, u8) \
T3__(R, T1, s16) T3__(R, T1, u16) \
T3__(R, T1, s32) T3__(R, T1, u32) \
T3__(R, T1, sL) T3__(R, T1, uL) \
T3__(R, T1, s64) T3__(R, T1, u64) \
T3__(R, T1, f32) T3__(R, T1, f64) \
#define TEST3(R) \
T3_(R, s8) T3_(R, u8) T3_(R, s16) T3_(R, u16) T3_(R, s32) T3_(R, u32) \
T3_(R, sL) T3_(R, uL) T3_(R, s64) T3_(R, u64) T3_(R, f32) T3_(R, f64)
TEST3(s64)
jffi-1.2.7/libtest/PointerTest.c 0000664 0000000 0000000 00000010143 12470474244 0016540 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2007 Wayne Meissner. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include
#include
#include
#include
#include
#include
typedef void* ptr;
typedef void* pointer;
#ifdef _WIN32
typedef char* caddr_t;
#endif
#define RET(T) T ptr_ret_##T(void* arg1, int offset) { \
T tmp; memcpy(&tmp, (caddr_t) arg1 + offset, sizeof(tmp)); return tmp; \
}
#define SET(T) void ptr_set_##T(void* arg1, int offset, T value) { \
memcpy((caddr_t) arg1 + offset, &value, sizeof(value)); \
}
#define TEST(T) SET(T) RET(T)
TEST(int8_t);
TEST(int16_t);
TEST(int32_t);
TEST(int64_t);
TEST(float);
TEST(double);
TEST(pointer);
void*
ptr_return_array_element(void **ptrArray, int arrayIndex)
{
return ptrArray[arrayIndex];
}
void
ptr_set_array_element(void **ptrArray, int arrayIndex, void *value)
{
ptrArray[arrayIndex] = value;
}
void*
ptr_malloc(int size)
{
return calloc(1, size);
}
void
ptr_free(void* ptr)
{
free(ptr);
}
void*
ptr_from_address(uintptr_t addr)
{
return (void *) addr;
}
unsigned long
invokeO(unsigned long *ptr)
{
unsigned long ret = *ptr;
*ptr = 0xdeadbeefUL;
return ret;
}
unsigned long
invokeON(unsigned long *ptr, unsigned long val)
{
unsigned long ret = *ptr;
*ptr = val;
return ret;
}
unsigned long
invokeNO(unsigned long val, unsigned long *ptr)
{
unsigned long ret = *ptr;
*ptr = val;
return ret;
}
unsigned long
invokeOO(unsigned long *p1, unsigned long *p2)
{
unsigned long ret = *p1 + *p2;
unsigned long tmp = *p1;
*p1 = *p2;
*p2 = tmp;
return ret;
}
unsigned long
invokeONN(unsigned long *ptr, unsigned long n1, unsigned long n2)
{
unsigned long ret = *ptr;
ptr[0] = n1;
ptr[1] = n2;
return ret;
}
unsigned long
invokeOON(unsigned long *p1, unsigned long *p2, unsigned long n1)
{
unsigned long ret = *p1;
*p1 = n1;
*p2 = n1;
return ret;
}
unsigned long
invokeNNO(unsigned long n1, unsigned long n2, unsigned long *ptr)
{
unsigned long ret = *ptr;
ptr[0] = n1;
ptr[1] = n2;
return ret;
}
unsigned long
invokeNON(unsigned long n1, unsigned long *ptr, unsigned long n2)
{
unsigned long ret = *ptr;
ptr[0] = n1;
ptr[1] = n2;
return ret;
}
unsigned long
invokeNOO(unsigned long n1, unsigned long *p1, unsigned long *p2)
{
unsigned long ret = *p1;
*p1 = n1;
*p2 = n1;
return ret;
}
unsigned long
invokeOOO(unsigned long *p1, unsigned long *p2, unsigned long *p3)
{
unsigned long ret = *p1;
*p1 = *p3;
*p2 = *p3;
*p3 = ret;
return ret;
}
#define N3O1 p1[0] = n1; p1[1] = n2; p1[2] = n3
#define N3O2 p1[0] = n1; p1[1] = n2; p1[2] = n3
jffi-1.2.7/libtest/ReferenceTest.c 0000664 0000000 0000000 00000004077 12470474244 0017027 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2007 Wayne Meissner. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include
#define REF(T) void ref_##T(T arg, T* result) { *result = arg; }
#define ADD(T) void ref_add_##T(T arg1, T arg2, T* result) { *result = arg1 + arg2; }
#define SUB(T) void ref_sub_##T(T arg1, T arg2, T* result) { *result = arg1 - arg2; }
#define MUL(T) void ref_mul_##T(T arg1, T arg2, T* result) { *result = arg1 * arg2; }
#define DIV(T) void ref_div_##T(T arg1, T arg2, T* result) { *result = arg1 / arg2; }
#define TEST(T) ADD(T) SUB(T) MUL(T) DIV(T) REF(T)
TEST(int8_t);
TEST(int16_t);
TEST(int32_t);
TEST(int64_t);
TEST(float);
TEST(double);
jffi-1.2.7/libtest/StringTest.c 0000664 0000000 0000000 00000003441 12470474244 0016371 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2007 Wayne Meissner. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include
int
string_equals(const char* s1, const char* s2)
{
return strcmp(s1, s2) == 0;
}
void
string_set(char* s1, const char* s2)
{
strcpy(s1, s2);
}
void
string_concat(char* dst, const char* src)
{
strcat(dst, src);
}
void
string_dummy(char* dummy)
{
}
jffi-1.2.7/libtest/StructTest.c 0000664 0000000 0000000 00000010747 12470474244 0016416 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2007 Wayne Meissner. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include
#include
#include
#include
#include
typedef char s8;
typedef short s16;
typedef int s32;
typedef long long s64;
typedef float f32;
typedef double f64;
typedef struct bugged_struct {
unsigned char visible;
unsigned int x;
unsigned int y;
short rx;
short ry;
unsigned char order;
unsigned char size;
} bugged_struct_t;
unsigned int
bugged_struct_size() {
return sizeof(bugged_struct_t);
}
struct test1 {
char b;
short s;
int i;
long long j;
long l;
float f;
double d;
char string[32];
};
struct struct_with_array {
char c;
int a[5];
};
struct nested {
int i;
};
struct container {
char first;
struct nested s;
};
int
struct_align_nested_struct(struct container* a) { return a->s.i; }
void*
struct_field_array(struct struct_with_array* s) { return &s->a; }
struct container*
struct_make_container_struct(int i)
{
static struct container cs;
memset(&cs, 0, sizeof(cs));
cs.first = 1;
cs.s.i = i;
return &cs;
}
#define T(x, type) \
type struct_field_##type(struct test1* t) { return t->x; } \
struct type##_align { char first; type value; }; \
type struct_align_##type(struct type##_align* a) { return a->value; }
T(b, s8);
T(s, s16);
T(i, s32);
T(j, s64);
T(f, f32);
T(d, f64);
T(l, long);
void
struct_set_string(struct test1* t, char* s)
{
strcpy(t->string, s);
}
struct test1*
struct_make_struct(char b, short s, int i, long long ll, float f, double d)
{
static struct test1 t;
memset(&t, 0, sizeof(t));
t.b = b;
t.s = s;
t.i = i;
t.j = ll;
t.f = f;
t.d = d;
return &t;
}
typedef int (*add_cb)(int a1, int a2);
typedef int (*sub_cb)(int a1, int a2);
struct test2 {
add_cb add_callback;
sub_cb sub_callback;
};
int
struct_call_add_cb(struct test2* t, int a1, int a2)
{
return t->add_callback(a1, a2);
}
int
struct_call_sub_cb(struct test2* t, int a1, int a2)
{
return t->sub_callback(a1, a2);
}
struct struct_with_array*
struct_make_struct_with_array(int a_0, int a_1, int a_2, int a_3, int a_4)
{
static struct struct_with_array s;
memset(&s, 0, sizeof(s));
s.a[0] = a_0;
s.a[1] = a_1;
s.a[2] = a_2;
s.a[3] = a_3;
s.a[4] = a_4;
return &s;
}
struct s8s32 {
char s8;
int s32;
};
struct s8s32
struct_return_s8s32()
{
struct s8s32 s;
s.s8 = 0x7f;
s.s32 = 0x12345678;
return s;
}
struct s8s32
struct_s8s32_set(char s8, int s32)
{
struct s8s32 s;
s.s8 = s8;
s.s32 = s32;
return s;
}
int
struct_s8s32_get_s8(struct s8s32 s)
{
return s.s8;
}
int
struct_s8s32_get_s32(struct s8s32 s)
{
return s.s32;
}
// Pass a struct and an int arg, ensure the int arg is passed correctly
int
struct_s8s32_s32_ret_s32(struct s8s32 s, int s32)
{
return s32;
}
// Pass a struct and a long long arg, ensure the long long arg is passed correctly
long long
struct_s8s32_s64_ret_s64(struct s8s32 s, long long s64)
{
return s64;
}
jffi-1.2.7/libtest/VariadicTest.c 0000664 0000000 0000000 00000002334 12470474244 0016645 0 ustar 00root root 0000000 0000000
#include
#include
#include
#include
#include
typedef int8_t s8;
typedef uint8_t u8;
typedef int16_t s16;
typedef uint16_t u16;
typedef int32_t s32;
typedef uint32_t u32;
typedef int64_t s64;
typedef uint64_t u64;
typedef signed long sL;
typedef unsigned long uL;
typedef float F;
typedef double D;
void pack_varargs(s64* buf, const char* fmt, ...)
{
va_list ap;
int c;
double d;
va_start(ap, fmt);
while ((c = *fmt++)) {
switch (c) {
case 'c':
case 's':
case 'i':
*buf++ = va_arg(ap, s32);
break;
case 'l':
*buf++ = va_arg(ap, long);
break;
case 'j':
*buf++ = va_arg(ap, s64);
break;
case 'f':
case 'd':
d = va_arg(ap, double);
memcpy(buf++, &d, sizeof(d));
break;
case 'C':
case 'S':
case 'I':
*buf++ = va_arg(ap, u32);
break;
case 'L':
*buf++ = va_arg(ap, unsigned long);
break;
}
}
va_end(ap);
}
jffi-1.2.7/pom.xml 0000664 0000000 0000000 00000014667 12470474244 0014002 0 ustar 00root root 0000000 0000000
4.0.0
org.sonatype.oss
oss-parent
7
com.github.jnr
jffi
jar
1.2.7
jffi
Java Foreign Function Interface
http://github.com/jnr/jffi
The Apache Software License, Version 2.0
http://www.apache.org/licenses/LICENSE-2.0.txt
repo
scm:git:git@github.com:jnr/jffi.git
scm:git:git@github.com:jnr/jffi.git
git@github.com:jnr/jffi.git
wmeissner
Wayne Meissner
wmeissner@gmail.com
junit
junit
4.8.2
test
true
true
UTF-8
1.6
1.6
make
linux-profile
linux
freebsd-profile
freebsd
gmake
org.apache.maven.plugins
maven-release-plugin
2.2
@{project.version}
org.apache.maven.plugins
maven-antrun-plugin
1.6
build-native-library
generate-sources
${project.build.directory}/java
run
process-test-resources
run
org.apache.maven.plugins
maven-assembly-plugin
2.2
src/main/assembly/native.xml
true
true
native-assemble
package
single
jffi-1.2.7/src/ 0000775 0000000 0000000 00000000000 12470474244 0013236 5 ustar 00root root 0000000 0000000 jffi-1.2.7/src/main/ 0000775 0000000 0000000 00000000000 12470474244 0014162 5 ustar 00root root 0000000 0000000 jffi-1.2.7/src/main/assembly/ 0000775 0000000 0000000 00000000000 12470474244 0016001 5 ustar 00root root 0000000 0000000 jffi-1.2.7/src/main/assembly/native.xml 0000664 0000000 0000000 00000001012 12470474244 0020003 0 ustar 00root root 0000000 0000000
native
jar
false
${project.build.directory}/jni
/jni
**/*.dll
**/*.so
**/*.jnilib
**/*.dylib
**/*.a