refactoring to bring reusable CAst translation code out of the PHP and JavaScript translators, and into the generic Cast projects. Also, adapted native code to compile on Mac OS X Tiger
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@2017 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
457799ac9a
commit
9d980f3901
|
@ -13,7 +13,7 @@ include Makefile.configuration
|
|||
|
||||
# 2006/08/03 Naoshi Tabuchi: tabee@jp.ibm.com
|
||||
# Recent versions of Cygwin's uname return "Cygwin", instead of "cygwin."
|
||||
PLATFORM=$(shell uname -o | sed -e 's/C/c/')
|
||||
PLATFORM=$(shell uname -s | sed -e 's/C/c/')
|
||||
|
||||
C_GENERATED=$(DOMO_AST_BIN)libcast/
|
||||
|
||||
|
@ -37,7 +37,9 @@ JAVA_INCLUDES = -I$(JAVA_SDK)include -I$(JAVA_SDK)$(PLATFORM_JNI_DIR) -I$(JAVA_S
|
|||
CAPA_INCLUDE_DIR = include/
|
||||
CAPA_INCLUDES = -I$(CAPA_INCLUDE_DIR) -I$(C_GENERATED)
|
||||
|
||||
CAPA_JNI_HEADER = $(C_GENERATED)com_ibm_wala_cast_ir_translator_NativeBridge.h
|
||||
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)
|
||||
|
||||
|
@ -48,9 +50,14 @@ ifeq ($(PLATFORM),cygwin)
|
|||
ALL_FLAGS = /WL /MD /EHsc /D ZTS /D YY_NO_UNISTD_H /D _USE_32BIT_TIME_T /D __WIN32__ /D WIN32 /D BUILD_CAST_DLL $(INCLUDES)
|
||||
DLLEXT = dll
|
||||
else
|
||||
ALL_FLAGS = -pthread -gstabs+ $(TRACE) $(INCLUDES) -fpic
|
||||
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),cygwin)
|
||||
CC_OUTFLAG = /Fo
|
||||
|
@ -58,6 +65,13 @@ ifeq ($(PLATFORM),cygwin)
|
|||
CC_LDFLAGS = /LDd /MD
|
||||
LIBPREFIX =
|
||||
POSTPROCESS = && cd $(DOMO_AST_BIN) && mt /manifest $(LIBPREFIX)cast.$(DLLEXT).manifest /outputresource:"$(LIBPREFIX)cast.$(DLLEXT);\#2"
|
||||
else
|
||||
ifeq ($(PLATFORM),Darwin)
|
||||
CC_OUTFLAG = -o
|
||||
CC_LDFLAGS = -dynamiclib -Wl,-flat_namespace
|
||||
LD_OUTFLAG = -o
|
||||
LIBPREFIX = lib
|
||||
POSTPROCESS =
|
||||
else
|
||||
CC_OUTFLAG = -o
|
||||
CC_LDFLAGS = -pthread -shared
|
||||
|
@ -65,6 +79,7 @@ else
|
|||
LIBPREFIX = lib
|
||||
POSTPROCESS =
|
||||
endif
|
||||
endif
|
||||
|
||||
#
|
||||
# rules
|
||||
|
@ -75,15 +90,18 @@ default: $(DOMO_AST_BIN)$(LIBPREFIX)cast.$(DLLEXT)
|
|||
bindir:
|
||||
mkdir -p $(C_GENERATED)
|
||||
|
||||
$(CAPA_JNI_HEADER): $(DOMO_AST_BIN)com/ibm/wala/cast/ir/translator/NativeBridge.class bindir
|
||||
$(CAPA_JNI_BRIDGE_HEADER): $(DOMO_AST_BIN)com/ibm/wala/cast/ir/translator/NativeBridge.class bindir
|
||||
$(JAVA_SDK)bin/javah -classpath "$(DOMO_AST_BIN)$(JAVAH_CLASS_PATH)" -d "$(JAVAH_GENERATED)" com.ibm.wala.cast.ir.translator.NativeBridge
|
||||
|
||||
$(CAPA_OBJECTS): $(C_GENERATED)%.o: %.cpp $(CAPA_JNI_HEADER) bindir
|
||||
$(CAPA_JNI_XLATOR_HEADER): $(DOMO_AST_BIN)com/ibm/wala/cast/ir/translator/NativeTranslatorToCAst.class bindir
|
||||
$(JAVA_SDK)bin/javah -classpath "$(DOMO_AST_BIN)$(JAVAH_CLASS_PATH)" -d "$(JAVAH_GENERATED)" com.ibm.wala.cast.ir.translator.NativeTranslatorToCAst
|
||||
|
||||
$(CAPA_OBJECTS): $(C_GENERATED)%.o: %.cpp $(CAPA_JNI_HEADERS) bindir
|
||||
echo $(CAPA_OBJECTS)
|
||||
$(CC) $(ALL_FLAGS) $(CC_OUTFLAG)$@ -c $<
|
||||
|
||||
$(DOMO_AST_BIN)$(LIBPREFIX)cast.$(DLLEXT): $(CAPA_OBJECTS)
|
||||
$(CC) $(CC_LDFLAGS) $^ $(LD_OUTFLAG)$@ $(POSTPROCESS)
|
||||
$(CC) $(CC_LDFLAGS) $^ $(LD_OUTFLAG) $@ $(POSTPROCESS)
|
||||
|
||||
clean:
|
||||
rm -rf $(DOMO_AST_BIN)$(LIBPREFIX)cast.$(DLLEXT) $(C_GENERATED) hs_err_pid*
|
||||
|
|
|
@ -28,29 +28,35 @@ class DLLEXPORT CAstWrapper {
|
|||
/**
|
||||
* This class is a simple wrapper that provides a C++ object veneer
|
||||
* over JNI calls to a CAst object in Javaland. This wrapper is used
|
||||
* by the grammar rules of the bison grammar that defines PHP to build
|
||||
* a CAst tree in Javaland.
|
||||
* by native code to build a CAst tree in Javaland.
|
||||
*/
|
||||
class CAstWrapper {
|
||||
#endif
|
||||
|
||||
|
||||
protected:
|
||||
jobject Ast;
|
||||
JNIEnv *env;
|
||||
Exceptions &java_ex;
|
||||
jobject xlator;
|
||||
jobject Ast;
|
||||
jclass HashSet;
|
||||
jclass LinkedList;
|
||||
jmethodID hashSetInit;
|
||||
jmethodID hashSetAdd;
|
||||
jclass LinkedList;
|
||||
jmethodID linkedListInit;
|
||||
jmethodID linkedListAdd;
|
||||
jfieldID astField;
|
||||
|
||||
private:
|
||||
jclass CAstNode;
|
||||
jclass CAstInterface;
|
||||
jclass CAstPrinter;
|
||||
jclass CAstSymbol;
|
||||
jclass NativeEntity;
|
||||
jclass NativeCodeEntity;
|
||||
jclass NativeFieldEntity;
|
||||
jclass NativeBridge;
|
||||
jclass NativeTranslatorToCAst;
|
||||
jmethodID castPrint;
|
||||
jmethodID makeNode0;
|
||||
jmethodID makeNode1;
|
||||
|
@ -81,7 +87,14 @@ private:
|
|||
jmethodID castSymbolInit2;
|
||||
jmethodID castSymbolInit3;
|
||||
jmethodID castSymbolInit4;
|
||||
|
||||
jmethodID addScopedEntity;
|
||||
jmethodID entityGetType;
|
||||
jmethodID fieldEntityInit;
|
||||
jmethodID _makeLocation;
|
||||
jmethodID setNodePosition;
|
||||
jmethodID setPosition;
|
||||
jmethodID codeSetGotoTarget;
|
||||
jmethodID codeSetLabelledGotoTarget;
|
||||
jobject callReference;
|
||||
|
||||
public:
|
||||
|
@ -187,6 +200,30 @@ public:
|
|||
jobject makeSymbol(const char *, bool, bool, jobject);
|
||||
|
||||
void log(jobject);
|
||||
|
||||
void addChildEntity(jobject, jobject, jobject);
|
||||
|
||||
void setGotoTarget(jobject, jobject, jobject);
|
||||
|
||||
void setGotoTarget(jobject, jobject, jobject, bool);
|
||||
|
||||
void setGotoTarget(jobject, jobject, jobject, jobject);
|
||||
|
||||
void setAstNodeLocation(jobject, jobject, jobject);
|
||||
|
||||
void setLocation(jobject, jobject);
|
||||
|
||||
jobject makeLocation(int, int, int, int);
|
||||
|
||||
jobject makeFieldEntity(jobject, jobject, bool, list<jobject> *);
|
||||
|
||||
jobject getEntityAst(jobject);
|
||||
|
||||
virtual void setEntityAst(jobject, jobject);
|
||||
|
||||
jobject getEntityType(jobject);
|
||||
|
||||
void die(const char *);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -67,8 +67,8 @@ private:
|
|||
public:
|
||||
Exceptions(JNIEnv *java_env, jmp_buf& c_env);
|
||||
|
||||
void throwException(char *file_name, int line_number);
|
||||
void throwAnyException(char *file_name, int line_number);
|
||||
void throwException(char *file_name, int line_number, char *c_message);
|
||||
void throwException(const char *file_name, int line_number);
|
||||
void throwAnyException(const char *file_name, int line_number);
|
||||
void throwException(const char *file_name, int line_number, const char *c_message);
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
}
|
||||
|
||||
#else
|
||||
#error "bad use of CAst constants
|
||||
#error "bad use of CAst constants"
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <string.h>
|
||||
#include <CAstWrapper.h>
|
||||
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER) || defined(__APPLE__)
|
||||
#define strndup(s,n) strdup(s)
|
||||
#endif
|
||||
|
||||
|
@ -15,6 +15,9 @@
|
|||
#define __CTN "com/ibm/wala/cast/tree/CAst"
|
||||
#define __CTS __SIG( __CTN )
|
||||
|
||||
#define __CEN "com/ibm/wala/cast/tree/CAstEntity"
|
||||
#define __CES __SIG( __CEN )
|
||||
|
||||
#define __CNN "com/ibm/wala/cast/tree/CAstNode"
|
||||
#define __CNS __SIG( __CNN )
|
||||
|
||||
|
@ -46,13 +49,52 @@ static const char *doubleSig = "(D)" __CNS;
|
|||
static const char *floatSig = "(F)" __CNS;
|
||||
static const char *objectSig = "(" __OBJS ")" __CNS;
|
||||
|
||||
CAstWrapper::CAstWrapper(JNIEnv *env, Exceptions &ex, jobject Ast)
|
||||
: java_ex(ex), env(env), Ast(Ast)
|
||||
|
||||
#define XLATOR_PKG "com/ibm/wala/cast/ir/translator/"
|
||||
|
||||
#define XLATOR_CLS_NAME "NativeTranslatorToCAst"
|
||||
|
||||
#define XLATOR_CLS(cls) XLATOR_PKG XLATOR_CLS_NAME "$" cls
|
||||
|
||||
static const char *XlatorCls = XLATOR_PKG XLATOR_CLS_NAME;
|
||||
|
||||
static const char *EntityCls = XLATOR_CLS("NativeEntity");
|
||||
static const char *CodeEntityCls = XLATOR_CLS("NativeCodeEntity");
|
||||
static const char *ScriptCls = XLATOR_CLS("NativeScriptEntity");
|
||||
static const char *FieldCls = XLATOR_CLS("NativeFieldEntity");
|
||||
|
||||
CAstWrapper::CAstWrapper(JNIEnv *env, Exceptions &ex, jobject xlator)
|
||||
: java_ex(ex), env(env), xlator(xlator)
|
||||
{
|
||||
this->CAstNode = env->FindClass( __CNN );
|
||||
this->CAstInterface = env->FindClass( __CTN );
|
||||
this->HashSet = env->FindClass("java/util/HashSet");
|
||||
this->LinkedList = env->FindClass("java/util/LinkedList");
|
||||
this->NativeBridge =
|
||||
env->FindClass("com/ibm/wala/cast/ir/translator/NativeBridge");
|
||||
this->NativeTranslatorToCAst =
|
||||
env->FindClass("com/ibm/wala/cast/ir/translator/NativeTranslatorToCAst");
|
||||
|
||||
jfieldID castFieldID = env->GetFieldID(NativeBridge, "Ast", "Lcom/ibm/wala/cast/tree/CAst;");
|
||||
this->Ast = env->GetObjectField(xlator, castFieldID);
|
||||
|
||||
jclass xlatorCls = env->FindClass( XlatorCls );
|
||||
this->_makeLocation = env->GetMethodID(xlatorCls, "makeLocation", "(IIII)Lcom/ibm/wala/cast/tree/CAstSourcePositionMap$Position;");
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
|
||||
this->NativeEntity = env->FindClass(EntityCls);
|
||||
this->addScopedEntity = env->GetMethodID(NativeEntity, "addScopedEntity", "(Lcom/ibm/wala/cast/tree/CAstNode;Lcom/ibm/wala/cast/tree/CAstEntity;)V");
|
||||
this->entityGetType = env->GetMethodID(NativeEntity, "getType", "()Lcom/ibm/wala/cast/tree/CAstType;");
|
||||
|
||||
this->NativeCodeEntity = env->FindClass(CodeEntityCls);
|
||||
this->astField = env->GetFieldID(NativeCodeEntity, "Ast", "Lcom/ibm/wala/cast/tree/CAstNode;");
|
||||
this->codeSetGotoTarget = env->GetMethodID(NativeCodeEntity, "setGotoTarget", "(Lcom/ibm/wala/cast/tree/CAstNode;Lcom/ibm/wala/cast/tree/CAstNode;)V");
|
||||
this->codeSetLabelledGotoTarget = env->GetMethodID(NativeCodeEntity, "setLabelledGotoTarget", "(Lcom/ibm/wala/cast/tree/CAstNode;Lcom/ibm/wala/cast/tree/CAstNode;Ljava/lang/Object;)V");
|
||||
this->setNodePosition = env->GetMethodID(NativeCodeEntity, "setNodePosition", "(Lcom/ibm/wala/cast/tree/CAstNode;Lcom/ibm/wala/cast/tree/CAstSourcePositionMap$Position;)V");
|
||||
this->setPosition = env->GetMethodID(NativeEntity, "setPosition", "(Lcom/ibm/wala/cast/tree/CAstSourcePositionMap$Position;)V");
|
||||
|
||||
this->NativeFieldEntity = env->FindClass(FieldCls);
|
||||
this->fieldEntityInit = env->GetMethodID(NativeFieldEntity, "<init>", "(Lcom/ibm/wala/cast/ir/translator/NativeTranslatorToCAst;Ljava/lang/String;Ljava/util/Set;Z" __CES ")V");
|
||||
|
||||
this->makeNode0 = env->GetMethodID(CAstInterface, __MN, zeroSig);
|
||||
this->makeNode1 = env->GetMethodID(CAstInterface, __MN, oneSig);
|
||||
|
@ -540,3 +582,73 @@ jobject
|
|||
return s;
|
||||
}
|
||||
|
||||
void CAstWrapper::addChildEntity(jobject parent, jobject n, jobject child)
|
||||
{
|
||||
env->CallVoidMethod(parent, addScopedEntity, n, child);
|
||||
}
|
||||
|
||||
void CAstWrapper::setGotoTarget(jobject entity, jobject from, jobject to) {
|
||||
env->CallVoidMethod(entity, codeSetGotoTarget, from, to);
|
||||
}
|
||||
|
||||
void CAstWrapper::setGotoTarget(jobject entity, jobject from, jobject to, bool label) {
|
||||
jobject javaLabel;
|
||||
jclass boolean = env->FindClass("java/lang/Boolean");
|
||||
if (label) {
|
||||
jfieldID trueId =
|
||||
env->GetStaticFieldID(boolean, "TRUE", "Ljava/lang/Boolean;");
|
||||
javaLabel = env->GetStaticObjectField(boolean, trueId);
|
||||
} else {
|
||||
jfieldID falseId =
|
||||
env->GetStaticFieldID(boolean, "FALSE", "Ljava/lang/Boolean;");
|
||||
javaLabel = env->GetStaticObjectField(boolean, falseId);
|
||||
}
|
||||
setGotoTarget(entity, from, to, javaLabel);
|
||||
}
|
||||
|
||||
void CAstWrapper::setGotoTarget(jobject entity, jobject from, jobject to, jobject label) {
|
||||
env->CallVoidMethod(entity, codeSetLabelledGotoTarget, from, to, label);
|
||||
}
|
||||
|
||||
void CAstWrapper::setLocation(jobject entity, jobject loc) {
|
||||
env->CallVoidMethod(entity, setPosition, loc);
|
||||
}
|
||||
|
||||
void CAstWrapper::setAstNodeLocation(jobject entity, jobject astNode, jobject loc) {
|
||||
env->CallVoidMethod(entity, setNodePosition, astNode, loc);
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeLocation(int fl, int fc, int ll, int lc) {
|
||||
return env->CallObjectMethod(xlator, _makeLocation, fl, fc, ll, lc);
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeFieldEntity(jobject declaringClass, jobject name, bool isStatic, list<jobject> *modifiers) {
|
||||
|
||||
jobject entity = env->NewObject(NativeFieldEntity, fieldEntityInit, xlator, getConstantValue(name), makeSet(modifiers), isStatic, declaringClass);
|
||||
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
return entity;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::getEntityAst(jobject entity) {
|
||||
jobject result = env->GetObjectField(entity, astField);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
LOG(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void CAstWrapper::setEntityAst(jobject entity, jobject ast) {
|
||||
env->SetObjectField(entity, astField, ast);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
}
|
||||
|
||||
jobject CAstWrapper::getEntityType(jobject entity) {
|
||||
jobject result = env->CallObjectMethod(entity, entityGetType);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
return result;
|
||||
}
|
||||
|
||||
void CAstWrapper::die(const char *message) {
|
||||
THROW(java_ex, message);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,11 +19,11 @@ Exceptions::Exceptions(JNIEnv *java_env, jmp_buf& c_env) :
|
|||
"(Ljava/lang/String;Ljava/lang/Throwable;)V");
|
||||
}
|
||||
|
||||
void Exceptions::throwAnyException(char *file_name, int line_number) {
|
||||
void Exceptions::throwAnyException(const char *file_name, int line_number) {
|
||||
if (_java_env->ExceptionCheck()) throwException(file_name, line_number);
|
||||
}
|
||||
|
||||
void Exceptions::throwException(char *file_name, int line_number) {
|
||||
void Exceptions::throwException(const char *file_name, int line_number) {
|
||||
jthrowable real_ex = _java_env->ExceptionOccurred();
|
||||
_java_env->ExceptionClear();
|
||||
|
||||
|
@ -52,7 +52,7 @@ void Exceptions::throwException(char *file_name, int line_number) {
|
|||
}
|
||||
|
||||
void
|
||||
Exceptions::throwException(char *file_name, int line_number, char *c_message) {
|
||||
Exceptions::throwException(const char *file_name, int line_number, const char *c_message) {
|
||||
#ifdef _MSC_VER
|
||||
int msglen = strlen(file_name) + strlen(c_message) + 1024;
|
||||
char* msg = (char*)_alloca(msglen);
|
||||
|
|
|
@ -10,6 +10,9 @@ Java_com_ibm_wala_cast_ir_translator_NativeBridge_initialize(
|
|||
JNIEnv *env,
|
||||
jclass cls)
|
||||
{
|
||||
|
||||
fprintf(stderr, "got here\n");
|
||||
|
||||
TRY(exp, env)
|
||||
|
||||
jclass CAstNode = env->FindClass( "com/ibm/wala/cast/tree/CAstNode" );
|
||||
|
|
|
@ -81,7 +81,9 @@ import com.ibm.wala.util.graph.impl.SparseNumberedGraph;
|
|||
/**
|
||||
* @author Julian Dolby TODO: document me.
|
||||
*/
|
||||
public abstract class AstTranslator extends CAstVisitor implements ArrayOpHandler {
|
||||
public abstract class AstTranslator extends CAstVisitor
|
||||
implements ArrayOpHandler, TranslatorToIR
|
||||
{
|
||||
|
||||
protected abstract boolean useDefaultInitValues();
|
||||
|
||||
|
|
|
@ -10,8 +10,16 @@
|
|||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.translator;
|
||||
|
||||
import com.ibm.wala.cast.tree.*;
|
||||
|
||||
public class NativeBridge {
|
||||
|
||||
protected final CAst Ast;
|
||||
|
||||
protected NativeBridge(CAst Ast) {
|
||||
this.Ast = Ast;
|
||||
}
|
||||
|
||||
protected static native void initialize();
|
||||
|
||||
/*
|
||||
|
|
|
@ -0,0 +1,307 @@
|
|||
package com.ibm.wala.cast.ir.translator;
|
||||
|
||||
import com.ibm.wala.cast.ir.translator.NativeBridge;
|
||||
import com.ibm.wala.cast.tree.*;
|
||||
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
||||
import com.ibm.wala.cast.tree.impl.*;
|
||||
import com.ibm.wala.cast.tree.visit.*;
|
||||
import com.ibm.wala.cast.util.*;
|
||||
import com.ibm.wala.util.collections.*;
|
||||
import com.ibm.wala.util.debug.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
|
||||
public abstract class NativeTranslatorToCAst extends NativeBridge {
|
||||
|
||||
protected abstract class NativeEntity implements CAstEntity {
|
||||
private Position sourcePosition;
|
||||
|
||||
private final Map scopedEntities =
|
||||
new HashMap();
|
||||
|
||||
public Map getAllScopedEntities() {
|
||||
return scopedEntities;
|
||||
}
|
||||
|
||||
public String getSignature() {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setPosition(Position pos) {
|
||||
sourcePosition = pos;
|
||||
}
|
||||
|
||||
public Position getPosition() {
|
||||
return sourcePosition;
|
||||
}
|
||||
|
||||
public Iterator getScopedEntities(CAstNode construct) {
|
||||
if (scopedEntities.containsKey(construct)) {
|
||||
return ((Set)scopedEntities.get(construct)).iterator();
|
||||
} else {
|
||||
return EmptyIterator.instance();
|
||||
}
|
||||
}
|
||||
|
||||
private void addScopedEntity(CAstNode construct, CAstEntity child) {
|
||||
if (!scopedEntities.containsKey(construct)) {
|
||||
scopedEntities.put(construct, new HashSet(1));
|
||||
}
|
||||
|
||||
((Set)scopedEntities.get(construct)).add( child );
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract class NativeCodeEntity extends NativeEntity {
|
||||
protected final CAstSourcePositionRecorder src =
|
||||
new CAstSourcePositionRecorder();
|
||||
protected final CAstControlFlowRecorder cfg =
|
||||
new CAstControlFlowRecorder(src);
|
||||
protected final CAstNodeTypeMapRecorder types =
|
||||
new CAstNodeTypeMapRecorder();
|
||||
|
||||
protected final CAstType type;
|
||||
|
||||
protected CAstNode Ast;
|
||||
|
||||
protected NativeCodeEntity(CAstType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public CAstNode getAST() {
|
||||
return Ast;
|
||||
}
|
||||
|
||||
public CAstType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public CAstControlFlowMap getControlFlow() {
|
||||
return cfg;
|
||||
}
|
||||
|
||||
public CAstSourcePositionMap getSourceMap() {
|
||||
return src;
|
||||
}
|
||||
|
||||
public CAstNodeTypeMap getNodeTypeMap() {
|
||||
return types;
|
||||
}
|
||||
|
||||
public void setGotoTarget(CAstNode from, CAstNode to) {
|
||||
setLabelledGotoTarget(from, to, null);
|
||||
}
|
||||
|
||||
public void setLabelledGotoTarget(CAstNode from, CAstNode to, Object label) {
|
||||
if (! cfg.isMapped(from)) {
|
||||
cfg.map(from, from);
|
||||
}
|
||||
if (! cfg.isMapped(to)) {
|
||||
cfg.map(to, to);
|
||||
}
|
||||
cfg.add(from, to, label);
|
||||
}
|
||||
|
||||
public void setNodePosition(CAstNode n, Position pos) {
|
||||
src.setPosition(n, pos);
|
||||
}
|
||||
|
||||
public void setNodeType(CAstNode n, CAstType type) {
|
||||
types.add(n, type);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract class NativeDataEntity extends NativeEntity {
|
||||
public CAstNode getAST() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public CAstControlFlowMap getControlFlow() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public CAstSourcePositionMap getSourceMap() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public CAstNodeTypeMap getNodeTypeMap() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String[] getArgumentNames() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
public CAstNode[] getArgumentDefaults() {
|
||||
return new CAstNode[0];
|
||||
}
|
||||
|
||||
public int getArgumentCount() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected class NativeFieldEntity extends NativeDataEntity {
|
||||
private final String name;
|
||||
private final Set modifiers;
|
||||
private final CAstEntity declaringClass;
|
||||
|
||||
public NativeFieldEntity(String name, Set modifiers, boolean isStatic, CAstEntity declaringClass) {
|
||||
this.name = name;
|
||||
this.declaringClass = declaringClass;
|
||||
|
||||
this.modifiers = new HashSet();
|
||||
if (modifiers != null) {
|
||||
this.modifiers.addAll(modifiers);
|
||||
}
|
||||
if (isStatic) {
|
||||
this.modifiers.add(CAstQualifier.STATIC);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "field " + name + " of " + declaringClass.getName();
|
||||
}
|
||||
|
||||
public int getKind() {
|
||||
return FIELD_ENTITY;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public CAstType getType() {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
public Collection getQualifiers() {
|
||||
return modifiers;
|
||||
}
|
||||
}
|
||||
|
||||
protected class NativeClassEntity extends NativeDataEntity {
|
||||
private final CAstType.Class type;
|
||||
|
||||
public NativeClassEntity(CAstType.Class type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "class " + type.getName();
|
||||
}
|
||||
|
||||
public int getKind() {
|
||||
return TYPE_ENTITY;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return type.getName();
|
||||
}
|
||||
|
||||
public CAstType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Collection getQualifiers() {
|
||||
return type.getQualifiers();
|
||||
}
|
||||
};
|
||||
|
||||
protected class NativeScriptEntity extends NativeCodeEntity {
|
||||
private final File file;
|
||||
|
||||
public NativeScriptEntity(File file, CAstType type) {
|
||||
super(type);
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public NativeScriptEntity(String file, CAstType type) {
|
||||
this(new File(file), type);
|
||||
}
|
||||
|
||||
public int getKind() {
|
||||
return SCRIPT_ENTITY;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "script " + file.getName();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "script " + file.getName();
|
||||
}
|
||||
|
||||
public String[] getArgumentNames() {
|
||||
return new String[]{ "script object" };
|
||||
}
|
||||
|
||||
public CAstNode[] getArgumentDefaults() {
|
||||
return new CAstNode[0];
|
||||
}
|
||||
|
||||
public int getArgumentCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Collection getQualifiers() {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
};
|
||||
|
||||
protected final URL sourceURL;
|
||||
|
||||
protected final String sourceFileName;
|
||||
|
||||
protected NativeTranslatorToCAst(CAst Ast,
|
||||
URL sourceURL,
|
||||
String sourceFileName)
|
||||
{
|
||||
super(Ast);
|
||||
this.sourceURL = sourceURL;
|
||||
this.sourceFileName = sourceFileName;
|
||||
}
|
||||
|
||||
private String getLocalFile() {
|
||||
return sourceFileName;
|
||||
}
|
||||
|
||||
private String getFile() {
|
||||
return sourceURL.getFile();
|
||||
}
|
||||
|
||||
private Position makeLocation(final int fl,
|
||||
final int fc,
|
||||
final int ll,
|
||||
final int lc)
|
||||
{
|
||||
return new AbstractSourcePosition() {
|
||||
public int getFirstLine() { return fl; }
|
||||
public int getLastLine() { return ll; }
|
||||
public int getFirstCol() { return fc; }
|
||||
public int getLastCol() { return lc; }
|
||||
public URL getURL() { return sourceURL; }
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return new FileInputStream(sourceFileName);
|
||||
}
|
||||
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+"]";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public abstract CAstEntity translateToCAst();
|
||||
|
||||
}
|
|
@ -13,12 +13,10 @@ package com.ibm.wala.cast.ir.translator;
|
|||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.classLoader.ModuleEntry;
|
||||
import com.ibm.wala.cast.tree.*;
|
||||
|
||||
public interface TranslatorToIR {
|
||||
|
||||
void translate(ModuleEntry S, String N) throws IOException;
|
||||
|
||||
void translate(Set modules) throws IOException;
|
||||
void translate(CAstEntity S, String N);
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
package com.ibm.wala.cast.loader;
|
||||
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.ipa.cha.*;
|
||||
import com.ibm.wala.types.*;
|
||||
import com.ibm.wala.util.Atom;
|
||||
import com.ibm.wala.util.collections.*;
|
||||
import com.ibm.wala.util.debug.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public abstract class CAstAbstractLoader implements IClassLoader {
|
||||
|
||||
protected final Map<TypeName,IClass> types = HashMapFactory.make();
|
||||
|
||||
protected final IClassHierarchy cha;
|
||||
|
||||
protected final IClassLoader parent;
|
||||
|
||||
public CAstAbstractLoader(IClassHierarchy cha, IClassLoader parent) {
|
||||
this.cha = cha;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public CAstAbstractLoader(IClassHierarchy cha) {
|
||||
this(cha, null);
|
||||
}
|
||||
|
||||
public IClass lookupClass(String className, IClassHierarchy cha) {
|
||||
Assertions._assert(this.cha == cha);
|
||||
return (IClass) types.get(TypeName.string2TypeName(className));
|
||||
}
|
||||
|
||||
public IClass lookupClass(TypeName className) {
|
||||
return (IClass) types.get(className);
|
||||
}
|
||||
|
||||
public Iterator<IClass> iterateAllClasses() {
|
||||
return types.values().iterator();
|
||||
}
|
||||
|
||||
public int getNumberOfClasses() {
|
||||
return types.size();
|
||||
}
|
||||
|
||||
public Atom getName() {
|
||||
return getReference().getName();
|
||||
}
|
||||
|
||||
public int getNumberOfMethods() {
|
||||
int i = 0;
|
||||
for (Iterator cls = types.values().iterator(); cls.hasNext();) {
|
||||
for (Iterator ms = ((IClass) cls.next()).getDeclaredMethods().iterator();
|
||||
ms.hasNext(); )
|
||||
{
|
||||
i++;
|
||||
ms.next();
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public String getSourceFileName(IClass klass) {
|
||||
return klass.getSourceFileName();
|
||||
}
|
||||
|
||||
public IClassLoader getParent() {
|
||||
assert parent != null;
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void removeAll(Collection toRemove) {
|
||||
Set<TypeName> keys = HashSetFactory.make();
|
||||
|
||||
for (Iterator<Map.Entry<TypeName,IClass>> EE = types.entrySet().iterator(); EE.hasNext();) {
|
||||
Map.Entry<TypeName,IClass> E = EE.next();
|
||||
if (toRemove.contains(E.getValue())) {
|
||||
keys.add(E.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
for (Iterator KK = keys.iterator(); KK.hasNext();) {
|
||||
types.remove(KK.next());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
package com.ibm.wala.cast.loader;
|
||||
|
||||
import com.ibm.wala.cast.ir.translator.*;
|
||||
import com.ibm.wala.cast.tree.*;
|
||||
import com.ibm.wala.cast.tree.impl.*;
|
||||
import com.ibm.wala.cast.util.*;
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.ipa.cha.*;
|
||||
import com.ibm.wala.types.*;
|
||||
import com.ibm.wala.util.debug.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
|
||||
public abstract class CAstAbstractNativeLoader extends CAstAbstractLoader {
|
||||
|
||||
public CAstAbstractNativeLoader(IClassHierarchy cha, IClassLoader parent) {
|
||||
super(cha, parent);
|
||||
}
|
||||
|
||||
public CAstAbstractNativeLoader(IClassHierarchy cha) {
|
||||
this(cha, null);
|
||||
}
|
||||
|
||||
protected abstract NativeTranslatorToCAst
|
||||
getTranslatorToCAst(CAst ast, URL sourceURL, String localFileName);
|
||||
|
||||
protected abstract TranslatorToIR initTranslator();
|
||||
|
||||
protected void finishTranslation() {
|
||||
|
||||
}
|
||||
|
||||
public void init(final Set modules) {
|
||||
final CAst ast = new CAstImpl();
|
||||
|
||||
final TranslatorToIR xlatorToIR = initTranslator();
|
||||
|
||||
class TranslatorNestingHack {
|
||||
|
||||
private void init(ModuleEntry moduleEntry) {
|
||||
if (moduleEntry.isModuleFile()) {
|
||||
init(moduleEntry.asModule());
|
||||
} else if (moduleEntry instanceof SourceFileModule) {
|
||||
File f = ((SourceFileModule) moduleEntry).getFile();
|
||||
String fn = f.toString();
|
||||
|
||||
try {
|
||||
NativeTranslatorToCAst xlatorToCAst =
|
||||
getTranslatorToCAst(ast, new URL("file://" + f), fn);
|
||||
|
||||
CAstEntity fileEntity = xlatorToCAst.translateToCAst();
|
||||
|
||||
Trace.println(CAstPrinter.print(fileEntity));
|
||||
|
||||
xlatorToIR.translate(fileEntity, fn);
|
||||
} catch (MalformedURLException e) {
|
||||
Trace.println("unpected problems with " + f);
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
} else if (moduleEntry instanceof SourceURLModule) {
|
||||
java.net.URL url = ((SourceURLModule) moduleEntry).getURL();
|
||||
String fileName = ((SourceURLModule) moduleEntry).getName();
|
||||
String localFileName = fileName.replace('/', '_');
|
||||
|
||||
try {
|
||||
File F = TemporaryFile.streamToFile(localFileName,
|
||||
((SourceURLModule) moduleEntry).getInputStream());
|
||||
|
||||
final NativeTranslatorToCAst xlatorToCAst =
|
||||
getTranslatorToCAst(ast, url, localFileName);
|
||||
|
||||
CAstEntity fileEntity = xlatorToCAst.translateToCAst();
|
||||
|
||||
Trace.println(CAstPrinter.print(fileEntity));
|
||||
|
||||
xlatorToIR.translate(fileEntity, fileName);
|
||||
|
||||
F.delete();
|
||||
} catch (IOException e) {
|
||||
Trace.println("unpected problems with " + fileName);
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void init(Module module) {
|
||||
for (Iterator mes = module.getEntries(); mes.hasNext();) {
|
||||
init((ModuleEntry) mes.next());
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
for (Iterator mes = modules.iterator(); mes.hasNext();) {
|
||||
init((Module) mes.next());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(new TranslatorNestingHack()).init();
|
||||
|
||||
for (Iterator ts = types.keySet().iterator(); ts.hasNext();) {
|
||||
TypeName tn = (TypeName) ts.next();
|
||||
try {
|
||||
Trace.println("found type " + tn + " : " + types.get(tn) + " < "
|
||||
+ ((IClass) types.get(tn)).getSuperclass());
|
||||
} catch (Exception e) {
|
||||
System.err.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
finishTranslation();
|
||||
}
|
||||
|
||||
}
|
|
@ -33,6 +33,8 @@ public interface CAstType {
|
|||
|
||||
public interface Class extends Reference {
|
||||
boolean isInterface();
|
||||
|
||||
Collection getQualifiers();
|
||||
}
|
||||
|
||||
public interface Array extends Reference {
|
||||
|
|
Loading…
Reference in New Issue