/* ** Author(s): Miguel Calejo, Vera Pereira ** Contact: interprolog@declarativa.com, http://www.declarativa.com, http://www.xsb.com ** Copyright (C) XSB Inc., USA, 2001 ** Use and distribution, without any warranties, under the terms of the ** GNU Library General Public License, readable in http://www.fsf.org/copyleft/lgpl.html */ /* This file provides the implementation for the native methods of NativeEngine.java, as well as the XSB Prolog built-in used by InterProlog */ #include #include "com_xsb_interprolog_NativeEngine.h" #include #include #include #include // for interrupts: #include "sig_xsb.h" #include // extern int *asynint_ptr; extern void keyint_proc(int); /* The following include is necessary to get the macros and routine headers */ #include "xsb_config.h" #include "auxlry.h" #include "cell_xsb.h" #include "memory_xsb.h" #include "register.h" #include "flags_xsb.h" #include "heap_xsb.h" #include "subp.h" #include "cinterf.h" #include "error_xsb.h" #include "loader_xsb.h" #include "cinterf.h" JNIEnv *theEnv; jobject theObj; jboolean debug; JNIEXPORT jbyteArray JNICALL Java_com_xsb_interprolog_NativeEngine_get_1bytes (JNIEnv *env, jobject obj) { int i = 1; jbyteArray bytes; jsize size = p2p_arg(reg_term(1), 3); int newHead, newTail; jbyte *b; if (size == -1) { xsb_close_query(); return NULL; } b = (jbyte *) malloc(size); newHead = p2p_car(p2p_arg(reg_term(1), 2)); newTail = p2p_cdr(p2p_arg(reg_term(1), 2)); b[i-1] = p2c_int(newHead); while(is_nil(newTail) == 0) { newHead = p2p_car(newTail); b[i] = p2c_int(newHead); newTail = p2p_cdr(newTail); i++; } xsb_close_query(); bytes = (*env)->NewByteArray(env, size); (*env)->SetByteArrayRegion(env, bytes, 0, size, b); free(b); return bytes; } JNIEXPORT jint JNICALL Java_com_xsb_interprolog_NativeEngine_put_1bytes (JNIEnv *env, jobject obj, jbyteArray b, jint size, jint args, jstring jStr) { int head, tail, newVar, newVar2; int i = 1; int rc; //long T0 = clock(), T1, T2, T3, T4; jbyte *bytes; char *argString; //printf("C:Entering put_bytes - %d mS",T0); check_glstack_overflow(3, pcreg, (size+4)*8*sizeof(Cell)) ; bytes = (*env)->GetByteArrayElements(env, b, 0); //T1 = clock() - T0; //printf("C:got bytes array - %d mS",T1); argString = (*env)->GetStringUTFChars(env, jStr, 0); c2p_functor(argString, args, reg_term(1)); c2p_list(p2p_arg(reg_term(1),1)); if (args == 3) { newVar = p2p_arg(reg_term(1),2); newVar = p2p_new(); newVar2 = p2p_arg(reg_term(1),3); newVar2 = p2p_new(); } head = p2p_car(p2p_arg(reg_term(1),1)); tail = p2p_cdr(p2p_arg(reg_term(1),1)); if (bytes[0]<0) c2p_int((bytes[0]+256), head); else c2p_int(bytes[0], head); while (i < size) { c2p_list(tail); head = p2p_car(tail); tail = p2p_cdr(tail); if (bytes[i]<0) c2p_int((bytes[i]+256), head); else c2p_int(bytes[i], head); i++; } c2p_nil(tail); //T2 = clock() - T0 ; //printf("C:constructed Prolog list - %d mS",T2); theEnv = env; theObj = obj; rc = xsb_query(); //T3 = clock() - T0; //printf("C:Returned from Prolog - %d mS",T3); (*env)->ReleaseByteArrayElements(env, b, bytes, 0); (*env)->ReleaseStringUTFChars(env,jStr, argString); //T4 = clock() - T0; //printf("C:leaving put_bytes - %d mS\n",T4); return rc; } JNIEXPORT jint JNICALL Java_com_xsb_interprolog_NativeEngine_xsb_1close_1query (JNIEnv *env , jobject obj) { return xsb_close_query(); } JNIEXPORT jint JNICALL Java_com_xsb_interprolog_NativeEngine_xsb_1command_1string (JNIEnv *env, jobject obj, jstring jCommandString) { int rcode; char *CommandString = (*env)->GetStringUTFChars(env, jCommandString, 0); theEnv = env; theObj = obj; rcode=xsb_command_string(CommandString); (*env)->ReleaseStringUTFChars(env,jCommandString, CommandString); return rcode; } JNIEXPORT jint JNICALL Java_com_xsb_interprolog_NativeEngine_xsb_1init_1internal (JNIEnv *env, jobject obj, jstring jXSBPath) { int rcode; int myargc=2; char * myargv[2]; char *XSBPath = (*env)->GetStringUTFChars(env, jXSBPath, 0); if (debug==JNI_TRUE) printf("Entering Java_com_xsb_interprolog_NativeEngine_xsb_1init_1internal\n"); myargv[0] = XSBPath; myargv[1]="-n"; rcode=xsb_init(myargc,myargv); (*env)->ReleaseStringUTFChars(env,jXSBPath, XSBPath); if (debug==JNI_TRUE) printf("Exiting Java_com_xsb_interprolog_NativeEngine_xsb_1init_1internal\n"); return rcode; } JNIEXPORT void JNICALL Java_com_xsb_interprolog_NativeEngine_xsb_1interrupt (JNIEnv *env, jobject obj){ /* Do XSB's "interrupt" thing, by simulating a ctrl-C: */ // cf. keyint_proc(SIGINT) in subp.c; // *asynint_ptr |= KEYINT_MARK; keyint_proc(SIGINT); } JNIEXPORT void JNICALL Java_com_xsb_interprolog_NativeEngine_xsb_1setDebug (JNIEnv * env, jobject obj, jboolean d){ debug = d; } // the XSB Prolog built-in used in interprolog.P // arguments: +length, +byte list, -new byte list xsbBool interprolog_callback() { JNIEnv *env = theEnv; jobject obj = theObj; jclass cls; jmethodID mid; int i = 1, size, newHead, newTail; jbyte *b; jbyteArray newBytes, bytes; cls = (*env)->GetObjectClass(env, obj); if (cls == NULL) { printf("Could not find the class!\n"); return 0; } //printf("Got the class\n"); mid = (*env)->GetMethodID(env, cls, "callback", "([B)[B"); if (mid == NULL) { printf("Could not find the method!\n"); return 0; } //printf("Got the method\n"); size = p2c_int(reg_term(1)); b = (jbyte *) malloc(size); newHead = p2p_car(reg_term(2)); newTail = p2p_cdr(reg_term(2)); b[i-1] = p2c_int(newHead); while(is_nil(newTail) == 0) { newHead = p2p_car(newTail); b[i] = p2c_int(newHead); newTail = p2p_cdr(newTail); i++; } bytes = (*env)->NewByteArray(env, size); (*env)->SetByteArrayRegion(env, bytes, 0, size, b); // Calls the method with bytes, expecting the return in newBytes newBytes = (*env)->CallObjectMethod(env, obj, mid, bytes); size = (*env)->GetArrayLength(env, newBytes); b = (*env)->GetByteArrayElements(env, newBytes, 0); check_glstack_overflow(3, pcreg, size*8*sizeof(Cell)) ; c2p_list(reg_term(3)); newHead = p2p_car(reg_term(3)); newTail = p2p_cdr(reg_term(3)); if (b[0]<0) c2p_int((b[0]+256), newHead); else c2p_int(b[0], newHead); i = 1; while (i < size) { c2p_list(newTail); newHead = p2p_car(newTail); newTail = p2p_cdr(newTail); if (b[i]<0) c2p_int((b[i]+256), newHead); else c2p_int(b[i], newHead); i++; } c2p_nil(newTail); return 1; }