From a31dd02ab28d9a5275908801866c2b4e8b0a820e Mon Sep 17 00:00:00 2001 From: Julian Dolby Date: Sat, 24 Jun 2017 18:45:54 +0200 Subject: [PATCH] native support --- com.ibm.wala.cast.test/harness-src/c/Makefile | 24 +++ .../harness-src/c/Makefile.configuration | 5 + .../harness-src/c/smoke.cpp | 20 +++ .../ibm/wala/cast/test/TestCAstPattern.java | 0 .../wala/cast/test/TestCAstTranslator.java | 0 .../wala/cast/test/TestCallGraphShape.java | 0 .../wala/cast/test/TestNativeTranslator.java | 159 ++++++++++++++++++ com.ibm.wala.cast/source/c/Makefile | 59 +------ .../source/c/Makefile.configuration | 18 ++ .../source/c/Makefile.definitions | 63 +++++++ .../source/c/include/CAstWrapper.h | 2 + com.ibm.wala.cast/source/c/include/launch.h | 10 ++ .../source/c/jni/CAstWrapper.cpp | 10 +- com.ibm.wala.cast/source/c/jni/launch.cpp | 44 +++++ .../wala/cast/ir/translator/NativeBridge.java | 43 +++++ .../ir/translator/NativeTranslatorToCAst.java | 105 ++++++++++++ 16 files changed, 499 insertions(+), 63 deletions(-) create mode 100644 com.ibm.wala.cast.test/harness-src/c/Makefile create mode 100644 com.ibm.wala.cast.test/harness-src/c/Makefile.configuration create mode 100644 com.ibm.wala.cast.test/harness-src/c/smoke.cpp rename com.ibm.wala.cast.test/harness-src/{ => java}/com/ibm/wala/cast/test/TestCAstPattern.java (100%) rename com.ibm.wala.cast.test/harness-src/{ => java}/com/ibm/wala/cast/test/TestCAstTranslator.java (100%) rename com.ibm.wala.cast.test/harness-src/{ => java}/com/ibm/wala/cast/test/TestCallGraphShape.java (100%) create mode 100644 com.ibm.wala.cast.test/harness-src/java/com/ibm/wala/cast/test/TestNativeTranslator.java create mode 100644 com.ibm.wala.cast/source/c/Makefile.configuration create mode 100644 com.ibm.wala.cast/source/c/Makefile.definitions create mode 100644 com.ibm.wala.cast/source/c/include/launch.h create mode 100644 com.ibm.wala.cast/source/c/jni/launch.cpp create mode 100644 com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/translator/NativeBridge.java create mode 100644 com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/translator/NativeTranslatorToCAst.java diff --git a/com.ibm.wala.cast.test/harness-src/c/Makefile b/com.ibm.wala.cast.test/harness-src/c/Makefile new file mode 100644 index 000000000..540c5210a --- /dev/null +++ b/com.ibm.wala.cast.test/harness-src/c/Makefile @@ -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 $@ + diff --git a/com.ibm.wala.cast.test/harness-src/c/Makefile.configuration b/com.ibm.wala.cast.test/harness-src/c/Makefile.configuration new file mode 100644 index 000000000..37642fa3e --- /dev/null +++ b/com.ibm.wala.cast.test/harness-src/c/Makefile.configuration @@ -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/ + + diff --git a/com.ibm.wala.cast.test/harness-src/c/smoke.cpp b/com.ibm.wala.cast.test/harness-src/c/smoke.cpp new file mode 100644 index 000000000..b4898502c --- /dev/null +++ b/com.ibm.wala.cast.test/harness-src/c/smoke.cpp @@ -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; +} diff --git a/com.ibm.wala.cast.test/harness-src/com/ibm/wala/cast/test/TestCAstPattern.java b/com.ibm.wala.cast.test/harness-src/java/com/ibm/wala/cast/test/TestCAstPattern.java similarity index 100% rename from com.ibm.wala.cast.test/harness-src/com/ibm/wala/cast/test/TestCAstPattern.java rename to com.ibm.wala.cast.test/harness-src/java/com/ibm/wala/cast/test/TestCAstPattern.java diff --git a/com.ibm.wala.cast.test/harness-src/com/ibm/wala/cast/test/TestCAstTranslator.java b/com.ibm.wala.cast.test/harness-src/java/com/ibm/wala/cast/test/TestCAstTranslator.java similarity index 100% rename from com.ibm.wala.cast.test/harness-src/com/ibm/wala/cast/test/TestCAstTranslator.java rename to com.ibm.wala.cast.test/harness-src/java/com/ibm/wala/cast/test/TestCAstTranslator.java diff --git a/com.ibm.wala.cast.test/harness-src/com/ibm/wala/cast/test/TestCallGraphShape.java b/com.ibm.wala.cast.test/harness-src/java/com/ibm/wala/cast/test/TestCallGraphShape.java similarity index 100% rename from com.ibm.wala.cast.test/harness-src/com/ibm/wala/cast/test/TestCallGraphShape.java rename to com.ibm.wala.cast.test/harness-src/java/com/ibm/wala/cast/test/TestCallGraphShape.java diff --git a/com.ibm.wala.cast.test/harness-src/java/com/ibm/wala/cast/test/TestNativeTranslator.java b/com.ibm.wala.cast.test/harness-src/java/com/ibm/wala/cast/test/TestNativeTranslator.java new file mode 100644 index 000000000..9238d47a3 --- /dev/null +++ b/com.ibm.wala.cast.test/harness-src/java/com/ibm/wala/cast/test/TestNativeTranslator.java @@ -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 , K extends CopyKey> void addRewriter(CAstRewriterFactory 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> getAllScopedEntities() { + return Collections.emptyMap(); + } + + @Override + public Iterator 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 getQualifiers() { + // TODO Auto-generated method stub + return null; + } + + @Override + public CAstType getType() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Collection 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; + } +} diff --git a/com.ibm.wala.cast/source/c/Makefile b/com.ibm.wala.cast/source/c/Makefile index 9b8cfd617..029b38249 100644 --- a/com.ibm.wala.cast/source/c/Makefile +++ b/com.ibm.wala.cast/source/c/Makefile @@ -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 diff --git a/com.ibm.wala.cast/source/c/Makefile.configuration b/com.ibm.wala.cast/source/c/Makefile.configuration new file mode 100644 index 000000000..4f1678f21 --- /dev/null +++ b/com.ibm.wala.cast/source/c/Makefile.configuration @@ -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 \ No newline at end of file diff --git a/com.ibm.wala.cast/source/c/Makefile.definitions b/com.ibm.wala.cast/source/c/Makefile.definitions new file mode 100644 index 000000000..15287ded2 --- /dev/null +++ b/com.ibm.wala.cast/source/c/Makefile.definitions @@ -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 + diff --git a/com.ibm.wala.cast/source/c/include/CAstWrapper.h b/com.ibm.wala.cast/source/c/include/CAstWrapper.h index ef4d83f81..e7b62e695 100644 --- a/com.ibm.wala.cast/source/c/include/CAstWrapper.h +++ b/com.ibm.wala.cast/source/c/include/CAstWrapper.h @@ -4,6 +4,7 @@ #include #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; diff --git a/com.ibm.wala.cast/source/c/include/launch.h b/com.ibm.wala.cast/source/c/include/launch.h new file mode 100644 index 000000000..1bd7da04f --- /dev/null +++ b/com.ibm.wala.cast/source/c/include/launch.h @@ -0,0 +1,10 @@ +#ifndef _CAST_LAUNCH_H +#define _CAST_LAUNCH_H + +#include "jni.h" + +JNIEnv *launch(); +void kill(); +void run(); + +#endif diff --git a/com.ibm.wala.cast/source/c/jni/CAstWrapper.cpp b/com.ibm.wala.cast/source/c/jni/CAstWrapper.cpp index 6da6e872d..59ed5f720 100644 --- a/com.ibm.wala.cast/source/c/jni/CAstWrapper.cpp +++ b/com.ibm.wala.cast/source/c/jni/CAstWrapper.cpp @@ -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, "", "(Ljava/lang/String;)V"); + env->GetMethodID(CAstSymbol, "", "(Ljava/lang/String;Lcom/ibm/wala/cast/tree/CAstType;)V"); THROW_ANY_EXCEPTION(java_ex); this->castSymbolInit2 = - env->GetMethodID(CAstSymbol, "", "(Ljava/lang/String;Z)V"); + env->GetMethodID(CAstSymbol, "", "(Ljava/lang/String;Lcom/ibm/wala/cast/tree/CAstType;Z)V"); THROW_ANY_EXCEPTION(java_ex); this->castSymbolInit3 = - env->GetMethodID(CAstSymbol, "", "(Ljava/lang/String;ZZ)V"); + env->GetMethodID(CAstSymbol, "", "(Ljava/lang/String;Lcom/ibm/wala/cast/tree/CAstType;ZZ)V"); THROW_ANY_EXCEPTION(java_ex); this->castSymbolInit4 = - env->GetMethodID(CAstSymbol, "", "(Ljava/lang/String;ZZLjava/lang/Object;)V"); + env->GetMethodID(CAstSymbol, "", "(Ljava/lang/String;Lcom/ibm/wala/cast/tree/CAstType;ZZLjava/lang/Object;)V"); THROW_ANY_EXCEPTION(java_ex); - } #define _CPP_CONSTANTS diff --git a/com.ibm.wala.cast/source/c/jni/launch.cpp b/com.ibm.wala.cast/source/c/jni/launch.cpp new file mode 100644 index 000000000..34409475b --- /dev/null +++ b/com.ibm.wala.cast/source/c/jni/launch.cpp @@ -0,0 +1,44 @@ +#include +#include +#include +#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() +} diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/translator/NativeBridge.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/translator/NativeBridge.java new file mode 100644 index 000000000..5ba688572 --- /dev/null +++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/translator/NativeBridge.java @@ -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 + } + } +} diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/translator/NativeTranslatorToCAst.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/translator/NativeTranslatorToCAst.java new file mode 100644 index 000000000..6388db0f7 --- /dev/null +++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/translator/NativeTranslatorToCAst.java @@ -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(); + +}