[libinline-java-perl] 270/398: new extension for PerlNatives
Jonas Smedegaard
dr at jones.dk
Thu Feb 26 11:43:13 UTC 2015
This is an automated email from the git hooks/post-receive script.
js pushed a commit to tag 0.55
in repository libinline-java-perl.
commit 1663542c3106d17055a7562c409080ddceee7085
Author: patrick_leb <>
Date: Sun Jan 18 03:23:25 2004 +0000
new extension for PerlNatives
---
Java/Natives/Makefile.PL | 12 +++
Java/Natives/Natives.pm | 7 ++
Java/Natives/Natives.xs | 229 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 248 insertions(+)
diff --git a/Java/Natives/Makefile.PL b/Java/Natives/Makefile.PL
new file mode 100644
index 0000000..1f82949
--- /dev/null
+++ b/Java/Natives/Makefile.PL
@@ -0,0 +1,12 @@
+use ExtUtils::MakeMaker ;
+
+use strict ;
+
+WriteMakefile(
+ NAME => 'Inline::Java::Natives',
+ VERSION_FROM => 'Natives.pm',
+ INC => join(' ', @main::I),
+ LIBS => [join(' ', @main::L) . " -ljvm"],
+ # CCFLAGS => '-D_REENTRANT',
+) ;
+
diff --git a/Java/Natives/Natives.pm b/Java/Natives/Natives.pm
new file mode 100644
index 0000000..8430c0b
--- /dev/null
+++ b/Java/Natives/Natives.pm
@@ -0,0 +1,7 @@
+package Inline::Java::Natives ;
+
+use strict ;
+
+$Inline::Java::Natives::VERSION = '0.45' ;
+
+1 ;
diff --git a/Java/Natives/Natives.xs b/Java/Natives/Natives.xs
new file mode 100644
index 0000000..b376c9c
--- /dev/null
+++ b/Java/Natives/Natives.xs
@@ -0,0 +1,229 @@
+#include "stdlib.h"
+#include "string.h"
+#include "stdio.h"
+#include "stdarg.h"
+
+
+/* Include the JNI header file */
+#include "jni.h"
+
+
+void throw_ije(JNIEnv *env, char *msg){
+ jclass ije ;
+
+ ije = (*(env))->FindClass(env, "org/perl/inline/java/InlineJavaException") ;
+ if ((*(env))->ExceptionCheck(env)){
+ (*(env))->ExceptionDescribe(env) ;
+ (*(env))->ExceptionClear(env) ;
+ (*(env))->FatalError(env, "Can't find class InlineJavaException: exiting...") ;
+ }
+ (*(env))->ThrowNew(env, ije, msg) ;
+}
+
+
+/*
+ Here we simply check if an exception is pending an re-throw it
+*/
+int check_exception_from_java(JNIEnv *env){
+ jthrowable exc ;
+ int ret = 0 ;
+
+ exc = (*(env))->ExceptionOccurred(env) ;
+ if (exc != NULL){
+ /* (*(env))->ExceptionDescribe(env) ; */
+ (*(env))->ExceptionClear(env) ;
+ if ((*(env))->Throw(env, exc)){
+ (*(env))->FatalError(env, "Throw if InlineJava*Exception failed: exiting...") ;
+ }
+ ret = 1 ;
+ }
+
+ return ret ;
+}
+
+
+jobject create_primitive_object(JNIEnv *env, char f, char *cls_name, jvalue val){
+ jclass arg_cls ;
+ jmethodID mid ;
+ jobject ret = NULL ;
+ char sign[64] ;
+
+ arg_cls = (*(env))->FindClass(env, cls_name) ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+ sprintf(sign, "(%c)V", f) ;
+ mid = (*(env))->GetMethodID(env, arg_cls, "<init>", sign) ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+ ret = (*(env))->NewObjectA(env, arg_cls, mid, &val) ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+
+ return ret ;
+}
+
+
+jobject extract_va_arg(JNIEnv *env, va_list *list, char f){
+ jobject ret = NULL ;
+ jvalue val ;
+ int fi ;
+ jfloat *ff ;
+
+ /*
+ A bit of voodoo going on for J and F, but the rest I think is pretty
+ kosher...
+ */
+ switch(f){
+ case 'B':
+ val.i = (jbyte)va_arg(*list, jint) ;
+ ret = create_primitive_object(env, f, "java/lang/Byte", val) ;
+ break ;
+ case 'S':
+ val.i = (jshort)va_arg(*list, jint) ;
+ ret = create_primitive_object(env, f, "java/lang/Short", val) ;
+ break ;
+ case 'I':
+ val.i = (jint)va_arg(*list, jint) ;
+ ret = create_primitive_object(env, f, "java/lang/Integer", val) ;
+ break ;
+ case 'J':
+ val.d = (jdouble)va_arg(*list, jdouble) ;
+ ret = create_primitive_object(env, f, "java/lang/Long", val) ;
+ break ;
+ case 'F':
+ /* Seems float is not properly promoted to double... */
+ fi = (int)va_arg(*list, int) ;
+ ff = (float *)&fi ;
+ val.f = *ff ;
+ ret = create_primitive_object(env, f, "java/lang/Float", val) ;
+ break ;
+ case 'D':
+ val.d = (jdouble)va_arg(*list, jdouble) ;
+ ret = create_primitive_object(env, f, "java/lang/Double", val) ;
+ break ;
+ case 'Z':
+ val.i = (jint)va_arg(*list, jint) ;
+ ret = create_primitive_object(env, f, "java/lang/Boolean", val) ;
+ break ;
+ case 'C':
+ val.i = (jchar)va_arg(*list, jint) ;
+ ret = create_primitive_object(env, f, "java/lang/Character", val) ;
+ break ;
+ }
+
+ return ret ;
+}
+
+
+/*
+ This is the generic native function that callback java to call the proper
+ perl method.
+*/
+jobject JNICALL generic_perl_native(JNIEnv *env, jobject obj, ...){
+ va_list list ;
+ jclass cls ;
+ jmethodID mid ;
+ jstring jfmt ;
+ char *fmt ;
+ int fmt_len ;
+ jclass obj_cls ;
+ jobjectArray obj_array ;
+ jobject arg ;
+ int i ;
+ jobject ret = NULL ;
+
+ cls = (*(env))->GetObjectClass(env, obj) ;
+ mid = (*(env))->GetMethodID(env, cls, "LookupMethod", "()Ljava/lang/String;") ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+
+ /* Call obj.LookupMethod to get the format string */
+ jfmt = (*(env))->CallObjectMethod(env, obj, mid) ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+
+ fmt = (char *)((*(env))->GetStringUTFChars(env, jfmt, NULL)) ;
+ fmt_len = strlen(fmt) ;
+
+ obj_cls = (*(env))->FindClass(env, "java/lang/Object") ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+
+ obj_array = (*(env))->NewObjectArray(env, fmt_len, obj_cls, NULL) ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+
+ (*(env))->SetObjectArrayElement(env, obj_array, 0, obj) ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+ va_start(list, obj) ;
+ for (i = 1 ; i < fmt_len ; i++){
+ if (fmt[i] != 'L'){
+ arg = extract_va_arg(env, &list, fmt[i]) ;
+ if (arg == NULL){
+ return NULL ;
+ }
+ }
+ else{
+ arg = (jobject)va_arg(list, jobject) ;
+ }
+ (*(env))->SetObjectArrayElement(env, obj_array, i, arg) ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+ }
+ va_end(list) ;
+
+ /* Call obj.InvokePerlMethod and grab the returned object and return it */
+ mid = (*(env))->GetMethodID(env, cls, "InvokePerlMethod", "([Ljava/lang/Object;)Ljava/lang/Object;") ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+
+ ret = (*(env))->CallObjectMethod(env, obj, mid, obj_array) ;
+ if (check_exception_from_java(env)){
+ return NULL ;
+ }
+
+ return ret ;
+}
+
+
+/*
+ This function is used to register the specified native method and associate it with our magic
+ method that trap and redirects all the Perl native calls.
+*/
+JNIEXPORT void JNICALL Java_org_perl_inline_java_InlineJavaPerlNatives_RegisterMethod(JNIEnv *env, jobject obj, jclass cls, jstring name, jstring signature){
+ JNINativeMethod nm ;
+
+ /* Register the function */
+ nm.name = (char *)((*(env))->GetStringUTFChars(env, name, NULL)) ;
+ nm.signature = (char *)((*(env))->GetStringUTFChars(env, signature, NULL)) ;
+ nm.fnPtr = generic_perl_native ;
+
+ (*(env))->RegisterNatives(env, cls, &nm, 1) ;
+ (*(env))->ReleaseStringUTFChars(env, name, nm.name) ;
+ (*(env))->ReleaseStringUTFChars(env, signature, nm.signature) ;
+ if (check_exception_from_java(env)){
+ return ;
+ }
+}
+
+
+
+/*****************************************************************************/
+
+
+
+void boot_Inline__Java__Natives(){
+}
+
+
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libinline-java-perl.git
More information about the Pkg-perl-cvs-commits
mailing list