native support

This commit is contained in:
Julian Dolby 2017-06-24 18:45:54 +02:00
parent 2bca30af01
commit a31dd02ab2
16 changed files with 499 additions and 63 deletions

View File

@ -0,0 +1,24 @@
include Makefile.configuration
include ../../../com.ibm.wala.cast/source/c/Makefile.configuration
include ../../../com.ibm.wala.cast/source/c/Makefile.definitions
TEST_JNI_BRIDGE_HEADER = $(C_GENERATED)com_ibm_wala_cast_test_TestNativeTranslator.h
#
# rules
#
default: $(CAST_TEST_BIN)$(LIBPREFIX)xlator_test.$(DLLEXT)
$(TEST_JNI_BRIDGE_HEADER): $(CAST_TEST_BIN)com/ibm/wala/cast/test/TestNativeTranslator.class
$(JAVA_SDK)bin/javah -classpath "$(CAST_TEST_BIN)$(JAVAH_CLASS_PATH)" -d "$(JAVAH_GENERATED)" com.ibm.wala.cast.test.TestNativeTranslator
$(C_GENERATED)/smoke.o: $(TEST_JNI_BRIDGE_HEADER) smoke.cpp
$(CC) $(ALL_FLAGS) -o $@ -c smoke.cpp
$(CAST_TEST_BIN)$(LIBPREFIX)xlator_test.$(DLLEXT): $(C_GENERATED)/smoke.o
$(CC) $(CC_LDFLAGS) -Wl,-rpath -Wl,$(DOMO_AST_BIN) $(DOMO_AST_BIN)$(LIBPREFIX)cast.$(DLLEXT) $^ -o $@

View File

@ -0,0 +1,5 @@
# Path .class files of the com.ibm.domo.ast Java code (must end in /)
CAST_TEST_BIN = /Users/dolby/git/WALA/com.ibm.wala.cast.test/bin/

View File

@ -0,0 +1,20 @@
#include "CAstWrapper.h"
#include "com_ibm_wala_cast_test_TestNativeTranslator.h"
JNIEXPORT jobject JNICALL Java_com_ibm_wala_cast_test_TestNativeTranslator_inventAst
(JNIEnv *java_env, jclass cls, jobject ast)
{
TRY(exp, java_env)
CAstWrapper CAst(java_env, exp, ast);
THROW_ANY_EXCEPTION(exp);
return
CAst.makeNode(CAst.BINARY_EXPR,
CAst.OP_ADD,
CAst.makeConstant(1),
CAst.makeConstant(2));
CATCH()
return NULL;
}

View File

@ -0,0 +1,159 @@
package com.ibm.wala.cast.test;
import java.io.IOException;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import org.junit.Test;
import com.ibm.wala.cast.ir.translator.NativeTranslatorToCAst;
import com.ibm.wala.cast.tree.CAst;
import com.ibm.wala.cast.tree.CAstAnnotation;
import com.ibm.wala.cast.tree.CAstControlFlowMap;
import com.ibm.wala.cast.tree.CAstEntity;
import com.ibm.wala.cast.tree.CAstNode;
import com.ibm.wala.cast.tree.CAstNodeTypeMap;
import com.ibm.wala.cast.tree.CAstQualifier;
import com.ibm.wala.cast.tree.CAstSourcePositionMap;
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
import com.ibm.wala.cast.tree.CAstType;
import com.ibm.wala.cast.tree.impl.CAstImpl;
import com.ibm.wala.cast.tree.rewrite.CAstRewriter.CopyKey;
import com.ibm.wala.cast.tree.rewrite.CAstRewriter.RewriteContext;
import com.ibm.wala.cast.tree.rewrite.CAstRewriterFactory;
import com.ibm.wala.util.io.TemporaryFile;
public class TestNativeTranslator {
private static native CAstNode inventAst(SmokeXlator ast);
static {
System.loadLibrary("xlator_test");
}
private static class SmokeXlator extends NativeTranslatorToCAst {
protected SmokeXlator(CAst Ast, URL sourceURL) throws IOException {
super(Ast, sourceURL, TemporaryFile.urlToFile("temp", sourceURL).getAbsolutePath());
}
@Override
public <C extends RewriteContext<K>, K extends CopyKey<K>> void addRewriter(CAstRewriterFactory<C, K> factory,
boolean prepend) {
assert false;
}
@Override
public CAstEntity translateToCAst() {
return new CAstEntity() {
@Override
public int getKind() {
return CAstEntity.FUNCTION_ENTITY;
}
@Override
public String getName() {
return sourceURL.getFile();
}
@Override
public String getSignature() {
return "()";
}
@Override
public String[] getArgumentNames() {
return new String[0];
}
@Override
public CAstNode[] getArgumentDefaults() {
return new CAstNode[0];
}
@Override
public int getArgumentCount() {
return 0;
}
@Override
public Map<CAstNode, Collection<CAstEntity>> getAllScopedEntities() {
return Collections.emptyMap();
}
@Override
public Iterator<CAstEntity> getScopedEntities(CAstNode construct) {
return Collections.emptyIterator();
}
private CAstNode ast;
@Override
public CAstNode getAST() {
if (ast == null) {
ast = inventAst(SmokeXlator.this);
}
return ast;
}
@Override
public CAstControlFlowMap getControlFlow() {
// TODO Auto-generated method stub
return null;
}
@Override
public CAstSourcePositionMap getSourceMap() {
// TODO Auto-generated method stub
return null;
}
@Override
public Position getPosition() {
// TODO Auto-generated method stub
return null;
}
@Override
public CAstNodeTypeMap getNodeTypeMap() {
// TODO Auto-generated method stub
return null;
}
@Override
public Collection<CAstQualifier> getQualifiers() {
// TODO Auto-generated method stub
return null;
}
@Override
public CAstType getType() {
// TODO Auto-generated method stub
return null;
}
@Override
public Collection<CAstAnnotation> getAnnotations() {
// TODO Auto-generated method stub
return null;
}
};
}
}
private static final CAst ast = new CAstImpl();
@Test
public void testNativeCAst() throws IOException {
SmokeXlator xlator = new SmokeXlator(ast, getClass().getClassLoader().getResource("smoke.cpp"));
CAstNode ast = xlator.translateToCAst().getAST();
System.err.println(ast);
assert ast.getChildCount() == 3;
}
}

View File

@ -1,64 +1,7 @@
include Makefile.configuration
#
# in theory, these definitions should not need to be changed
#
ifeq (x$(PLATFORM),x)
PLATFORM=$(shell uname -s)
endif
C_GENERATED=$(DOMO_AST_BIN)libcast/
JAVAH_GENERATED=$(C_GENERATED)
ifeq ($(PLATFORM),windows)
CC=i686-mingw32-g++
else
CC=g++
endif
vpath %.cpp jni
JAVA_INCLUDES = -I$(JAVA_SDK)include
CAPA_INCLUDE_DIR = include/
CAPA_INCLUDES = -I$(CAPA_INCLUDE_DIR) -I$(C_GENERATED)
CAPA_JNI_BRIDGE_HEADER = $(C_GENERATED)com_ibm_wala_cast_ir_translator_NativeBridge.h
CAPA_JNI_XLATOR_HEADER = $(C_GENERATED)com_ibm_wala_cast_ir_translator_NativeTranslatorToCAst.h
CAPA_JNI_HEADERS = $(CAPA_JNI_BRIDGE_HEADER) $(CAPA_JNI_XLATOR_HEADER)
INCLUDES = $(CAPA_INCLUDES) $(JAVA_INCLUDES)
CAPA_SOURCES = $(notdir $(wildcard jni/*.cpp))
CAPA_OBJECTS = $(patsubst %.cpp,$(C_GENERATED)%.o,$(CAPA_SOURCES))
ifeq ($(PLATFORM),windows)
ALL_FLAGS = -gstabs+ $(TRACE) $(INCLUDES) -DBUILD_CAST_DLL
DLLEXT = dll
else
ifeq ($(PLATFORM),Darwin)
ALL_FLAGS = -gstabs+ $(TRACE) $(INCLUDES) -fPIC
DLLEXT = jnilib
else
ALL_FLAGS = -pthread -gstabs+ $(TRACE) $(INCLUDES) -fPIC
DLLEXT = so
endif
endif
ifeq ($(PLATFORM),windows)
CC_LDFLAGS = -shared -Wl,--add-stdcall-alias -Wl,-export-all-symbols
LIBPREFIX =
else
ifeq ($(PLATFORM),Darwin)
CC_LDFLAGS = -dynamiclib -Wl,-flat_namespace
LIBPREFIX = lib
else
CC_LDFLAGS = -pthread -shared
LIBPREFIX = lib
endif
endif
include Makefile.definitions
#
# rules

View File

@ -0,0 +1,18 @@
#
# global configuration. adjust for your system.
#
# The root of the java SDK to use (must end in /)
JAVA_SDK = /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/
# Path .class files of the com.ibm.domo.ast Java code (must end in /)
DOMO_AST_BIN = /Users/dolby/git/WALA/com.ibm.wala.cast/bin/
# Extra stuff needed in the classpath of javah (must start with path separator)
JAVAH_CLASS_PATH = :/Users/dolby/git/WALA/com.ibm.wala.cast/bin/
# enable debugging flags
TRACE =
# low-level JNI path
JNI_MD_DIR = darwin

View File

@ -0,0 +1,63 @@
#
# in theory, these definitions should not need to be changed
#
ifeq (x$(PLATFORM),x)
PLATFORM=$(shell uname -s)
endif
C_GENERATED=$(DOMO_AST_BIN)libcast/
JAVAH_GENERATED=$(C_GENERATED)
ifeq ($(PLATFORM),windows)
CC=i686-mingw32-g++
else
CC=g++
endif
vpath %.cpp jni
JAVA_INCLUDES = -I$(JAVA_SDK)include -I$(JAVA_SDK)include/$(JNI_MD_DIR) -DWALA_CLASSPATH="\"$(DOMO_AST_BIN)$(JAVAH_CLASS_PATH)\""
CAPA_INCLUDE_DIR = ../../../com.ibm.wala.cast/source/c/include/
CAPA_INCLUDES = -I$(CAPA_INCLUDE_DIR) -I$(C_GENERATED)
CAPA_JNI_BRIDGE_HEADER = $(C_GENERATED)com_ibm_wala_cast_ir_translator_NativeBridge.h
CAPA_JNI_XLATOR_HEADER = $(C_GENERATED)com_ibm_wala_cast_ir_translator_NativeTranslatorToCAst.h
CAPA_JNI_HEADERS = $(CAPA_JNI_BRIDGE_HEADER) $(CAPA_JNI_XLATOR_HEADER)
INCLUDES = $(CAPA_INCLUDES) $(JAVA_INCLUDES)
CAPA_SOURCES = $(notdir $(wildcard jni/*.cpp))
CAPA_OBJECTS = $(patsubst %.cpp,$(C_GENERATED)%.o,$(CAPA_SOURCES))
ifeq ($(PLATFORM),windows)
ALL_FLAGS = -g $(TRACE) $(INCLUDES) -DBUILD_CAST_DLL
DLLEXT = dll
else
ifeq ($(PLATFORM),Darwin)
ALL_FLAGS = -g $(TRACE) $(INCLUDES) -fPIC
DLLEXT = jnilib
else
ALL_FLAGS = -pthread -g $(TRACE) $(INCLUDES) -fPIC
DLLEXT = so
endif
endif
ifeq ($(PLATFORM),windows)
CC_LDFLAGS = -shared -Wl,--add-stdcall-alias -Wl,-export-all-symbols
LIBPREFIX =
else
ifeq ($(PLATFORM),Darwin)
CC_LDFLAGS = -dynamiclib -Wl,-flat_namespace
LIBPREFIX = lib
else
CC_LDFLAGS = -pthread -shared
LIBPREFIX = lib
endif
endif
CC_LDFLAGS += -L$(JAVA_SDK)jre/lib/server -ljvm
ALL_FLAGS += -std=c++11

View File

@ -4,6 +4,7 @@
#include <list>
#include "jni.h"
#include "Exceptions.h"
#include "launch.h"
using namespace std;
@ -53,6 +54,7 @@ private:
jclass CAstInterface;
jclass CAstPrinter;
jclass CAstSymbol;
jclass CAstType;
jclass NativeEntity;
jclass NativeClassEntity;
jclass NativeCodeEntity;

View File

@ -0,0 +1,10 @@
#ifndef _CAST_LAUNCH_H
#define _CAST_LAUNCH_H
#include "jni.h"
JNIEnv *launch();
void kill();
void run();
#endif

View File

@ -206,21 +206,21 @@ CAstWrapper::CAstWrapper(JNIEnv *env, Exceptions &ex, jobject xlator)
THROW_ANY_EXCEPTION(java_ex);
this->_getEntityName = env->GetMethodID(castEntity, "getName", "()Ljava/lang/String;");
CAstType = env->FindClass("com/ibm/wala/cast/tree/CAstType");
CAstSymbol = env->FindClass("com/ibm/wala/cast/tree/impl/CAstSymbolImpl");
THROW_ANY_EXCEPTION(java_ex);
this->castSymbolInit1 =
env->GetMethodID(CAstSymbol, "<init>", "(Ljava/lang/String;)V");
env->GetMethodID(CAstSymbol, "<init>", "(Ljava/lang/String;Lcom/ibm/wala/cast/tree/CAstType;)V");
THROW_ANY_EXCEPTION(java_ex);
this->castSymbolInit2 =
env->GetMethodID(CAstSymbol, "<init>", "(Ljava/lang/String;Z)V");
env->GetMethodID(CAstSymbol, "<init>", "(Ljava/lang/String;Lcom/ibm/wala/cast/tree/CAstType;Z)V");
THROW_ANY_EXCEPTION(java_ex);
this->castSymbolInit3 =
env->GetMethodID(CAstSymbol, "<init>", "(Ljava/lang/String;ZZ)V");
env->GetMethodID(CAstSymbol, "<init>", "(Ljava/lang/String;Lcom/ibm/wala/cast/tree/CAstType;ZZ)V");
THROW_ANY_EXCEPTION(java_ex);
this->castSymbolInit4 =
env->GetMethodID(CAstSymbol, "<init>", "(Ljava/lang/String;ZZLjava/lang/Object;)V");
env->GetMethodID(CAstSymbol, "<init>", "(Ljava/lang/String;Lcom/ibm/wala/cast/tree/CAstType;ZZLjava/lang/Object;)V");
THROW_ANY_EXCEPTION(java_ex);
}
#define _CPP_CONSTANTS

View File

@ -0,0 +1,44 @@
#include <jni.h>
#include <iostream>
#include <string>
#include "Exceptions.h"
#include "CAstWrapper.h"
using namespace std;
JavaVM *javaVM;
JNIEnv *launch() {
JavaVMOption jvmopt[1];
jvmopt[0].optionString = "-Djava.class.path=" WALA_CLASSPATH ":.";
JavaVMInitArgs vmArgs;
vmArgs.version = JNI_VERSION_1_2;
vmArgs.nOptions = 1;
vmArgs.options = jvmopt;
vmArgs.ignoreUnrecognized = JNI_TRUE;
// Create the JVM
JNIEnv *jniEnv;
long flag = JNI_CreateJavaVM(&javaVM, (void**)
&jniEnv, &vmArgs);
if (flag == JNI_ERR) {
cout << "Error creating VM. Exiting...\n";
return NULL;
}
return jniEnv;
}
void kill() {
javaVM->DestroyJavaVM();
}
void run() {
JNIEnv *java_env = launch();
TRY(exp, java_env)
CAstWrapper CAst(java_env, exp, NULL);
THROW_ANY_EXCEPTION(exp);
CATCH()
}

View File

@ -0,0 +1,43 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.cast.ir.translator;
import com.ibm.wala.cast.tree.CAst;
/**
* superclass for CAst parsers / translators making use of native code. performs
* initialization of the core CAst native library.
*/
public abstract class NativeBridge {
protected final CAst Ast;
protected static boolean isInitialized;
protected NativeBridge(CAst Ast) {
this.Ast = Ast;
}
/**
* initialize the CAst native library
*/
protected static native void initialize();
static {
isInitialized = false;
try {
initialize();
isInitialized = true;
} catch (Throwable e) {
// leave isInitialized as false
}
}
}

View File

@ -0,0 +1,105 @@
package com.ibm.wala.cast.ir.translator;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import com.ibm.wala.cast.tree.CAst;
import com.ibm.wala.cast.tree.CAstEntity;
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
import com.ibm.wala.cast.tree.impl.AbstractSourcePosition;
/**
* common functionality for any {@link TranslatorToCAst} making use of native code
*/
public abstract class NativeTranslatorToCAst
extends NativeBridge
implements TranslatorToCAst
{
protected final URL sourceURL;
protected final String sourceFileName;
protected NativeTranslatorToCAst(CAst Ast, URL sourceURL, String sourceFileName) {
super(Ast);
this.sourceURL = sourceURL;
this.sourceFileName = sourceFileName;
}
@SuppressWarnings("unused")
private String getLocalFile() {
return sourceFileName;
}
protected String getFile() {
return sourceURL.getFile();
}
@SuppressWarnings("unused")
private Position makeLocation(final int fl, final int fc, final int ll, final int lc) {
return new AbstractSourcePosition() {
@Override
public int getFirstLine() {
return fl;
}
@Override
public int getLastLine() {
return ll;
}
@Override
public int getFirstCol() {
return fc;
}
@Override
public int getLastCol() {
return lc;
}
@Override
public int getFirstOffset() {
return -1;
}
@Override
public int getLastOffset() {
return -1;
}
@Override
public URL getURL() {
return sourceURL;
}
public InputStream getInputStream() throws IOException {
return new FileInputStream(sourceFileName);
}
@Override
public String toString() {
String urlString = sourceURL.toString();
if (urlString.lastIndexOf(File.separator) == -1)
return "[" + fl + ":" + fc + "]->[" + ll + ":" + lc + "]";
else
return urlString.substring(urlString.lastIndexOf(File.separator) + 1) + "@[" + fl + ":" + fc + "]->[" + ll + ":" + lc
+ "]";
}
@Override
public Reader getReader() throws IOException {
return new InputStreamReader(getInputStream());
}
};
}
@Override
public abstract CAstEntity translateToCAst();
}