ValueP ExternalCallingFunctionValue::call(SgFunctionType *fnType, const vector<ValueP> &args) const { if (fnType->get_argument_list()->get_arguments().size() != args.size()) { throw InterpError("ExternalCalling: function's formal parameter list length differs from actual parameter list length"); } RoseFFI ffi; if (!ffi.prepare(fnType)) { throw InterpError("Could not prepare the function type " + fnType->unparseToString()); } ffi.call(fnPtr, args); return ValueP(); // TODO: get return value }
ffi_type *getFFIType(SgType *t) { t = t->stripTypedefsAndModifiers(); switch (t->variantT()) { case V_SgTypeBool: return &ffi_type_uchar; case V_SgTypeChar: return &ffi_type_schar; case V_SgTypeDouble: return &ffi_type_double; case V_SgTypeFloat: return &ffi_type_float; case V_SgTypeInt: return &ffi_type_sint; case V_SgTypeLongDouble: return &ffi_type_longdouble; case V_SgTypeLong: return &ffi_type_slong; case V_SgTypeLongLong: return &ffi_type_sint64; /* NOTE: inaccurate */ case V_SgTypeShort: return &ffi_type_sshort; case V_SgTypeUnsignedChar: return &ffi_type_uchar; case V_SgTypeUnsignedInt: return &ffi_type_uint; case V_SgTypeUnsignedLongLong: return &ffi_type_uint64; /* NOTE: inaccurate */ case V_SgTypeUnsignedLong: return &ffi_type_ulong; case V_SgTypeUnsignedShort: return &ffi_type_ushort; case V_SgTypeVoid: return &ffi_type_void; case V_SgClassType: return getFFIClassType(isSgClassType(t)); case V_SgArrayType: return &ffi_type_pointer; case V_SgPointerType: return &ffi_type_pointer; default: throw InterpError("Encountered unsupported type: " + t->class_name()); } }
ffi_type *getFFIClassType(SgClassType *ct) { const StructLayoutInfo &sli = typeLayout(ct); ffi_type **fieldTypes = new ffi_type*[sli.fields.size()]; allocatedTypeArrays.push_back(fieldTypes); for (size_t i = 0; i < sli.fields.size(); i++) { SgNode *decl = sli.fields[i].decl; if (SgInitializedName *in = isSgInitializedName(decl)) { fieldTypes[i] = getFFIType(in->get_type()); } else if (SgBaseClass *bc = isSgBaseClass(decl)) { fieldTypes[i] = getFFIType(bc->get_base_class()->get_type()); } else { throw InterpError("Encountered unsupported field decl: " + decl->class_name()); } } ffi_type *ctType = new ffi_type; allocatedTypes.push_back(ctType); ctType->elements = fieldTypes; return ctType; }
void serialize(void *data, ValueP val) { Value *valP = val.get(); if (PointerValue *ptrVal = dynamic_cast<PointerValue *>(valP)) { void **pdata = static_cast<void **>(data); ValueP target = ptrVal->getTarget(); if (target.get() == NULL) { *pdata = NULL; } else { *pdata = getPtr(target); } } else if (CharValue *charVal = dynamic_cast<CharValue *>(valP)) { char *pdata = static_cast<char *>(data); *pdata = charVal->getConcreteValueChar(); } else if (IntValue *intVal = dynamic_cast<IntValue *>(valP)) { char *pdata = static_cast<char *>(data); *pdata = intVal->getConcreteValueInt(); } // TODO: other primtypes else if (BaseCompoundValue *compVal = dynamic_cast<BaseCompoundValue *>(valP)) { struct SerializeField : FieldVisitor { RoseFFI *ffi; void *data; SerializeField(RoseFFI *ffi, void *data) : ffi(ffi), data(data) {} void operator()(long offset, ValueP prim) { if (offset >= 0) { void *dataOfs = static_cast<void *>(static_cast<char *>(data) + offset); ffi->serialize(dataOfs, prim); } } }; SerializeField sf(this, data); compVal->forEachPrim(sf); } else { throw InterpError(string("Unable to serialize a ") + typeid(*valP).name()); } }
ValueP ExternalCallingStackFrame::externEvalFunctionRefExp(SgFunctionSymbol *sym) { string symName = sym->get_name().getString(); for (vector<void *>::const_iterator sharedLib = sharedLibraries.begin(); sharedLib != sharedLibraries.end(); ++sharedLib) { void (*fnPtr)() = reinterpret_cast<void(*)()>(dlsym(*sharedLib, symName.c_str())); if (fnPtr != NULL) { return ValueP(new ExternalCallingFunctionValue(symName, fnPtr, PTemp, shared_from_this())); } } throw InterpError("Could not find the function symbol " + symName + " in the current list of shared libraries"); }
vector<void *> buildLibraryList(SgProject *prj) { vector<void *> libs; void *libc = dlopen("libc.so.6", RTLD_NOW | RTLD_GLOBAL); if (NULL==libc) libc = dlopen("libc.dylib", RTLD_NOW | RTLD_GLOBAL); // Mac OS X if (NULL==libc) throw InterpError(string("Couldn't load libc: ") + dlerror()); libs.push_back(libc); // libs.push_back(RTLD_DEFAULT); return libs; }
static BOOL InterpretKal(FILE *fpFile, LPSTR lpFileName, LPSTR lpComment, BOOL bMode, ATOMID idAsk) { LPEXP lpExp; GLOBALHANDLE hExp = KppMakeTempExp(READ_EXP_SIZE, (LPLPSTR) &lpExp); WORD wDummy = EXP_NORMAL_MODE; DWORD dwInputLineNumberSave; ITEMID idExpStackElemSave; BOOL bExpStackSave, bRet = TRUE; ATOMID idFileName = KppAddAtom(lpFileName); BOOL bSaveInterp = bInterpreterOn; LPSTR lpSaveFile = lpFileBeingInterpreted; BOOL bFirst = TRUE; ATOMID idOldAsk = KppGetOverrideMode(); SaveFileTimeStamp(idFileName, fpFile, NULL); if (!hExp) return ERROR; /* Clear the key */ INIT_INTERRUPT; /* prepare the parser */ idExpStackElemSave = KppGetExpStackElem(); bExpStackSave = KppGetExpStackState(); dwInputLineNumberSave = KppGetInputLineNumber(); KppSetInputLineNumber(1); KppSetExpStackState(FALSE); /* Attempt reading the Application Comment */ Read_KAL_App_Comment(fpFile, lpComment); /* while not end of file */ UnwindProtect(cleanup); KppSetOverrideMode(idAsk); while (!feof(fpFile)) { unsigned long lBegin = ftell(fpFile); if (IS_INTERRUPTED) { if (!KppInvokeEscapeFn()) { KppPostKappaErrorMessageCB(); if (InterpError(lpFileName) == IDNO) { bRet = FALSE; break; } } } SetFileBeingInterpreted(lpFileName); if (!KppFillExpNew3(lpExp, 0, fpFile, NULL, NULL, EXP_NORMAL_MODE, &wDummy, READ_EXP_SIZE, bFirst ? (long *) &lBegin : NULL)) { PostKappaMessage(); if (InterpError(lpFileName) == IDNO) { bRet = FALSE; break; } else continue; } if (bMode) KppInterpretationEchoCB((LPSTR) lpExp, 0, 0); SetInterpretationFlag(TRUE); KppSetItemSkipped(FALSE); if (!Kpp_EvalExp(lpExp)) { if (!TrapImageSlotError()) { KppPostKappaErrorMessageCB(); if (InterpError(lpFileName) == IDNO) { SetInterpretationFlag(FALSE); bRet = FALSE; break; } } else KppClearTraceStack(); } else if (!KppGetItemSkipped()) KppSetItemFileInfo(lpExp, idFileName, lBegin, ftell(fpFile)); SetInterpretationFlag(TRUE); if (bMode) KppInterpretationEchoCB((LPSTR) lpExp, RETURNFLAGS, RETURNVALUE); bFirst = FALSE; } cleanup: KppSetOverrideMode(idOldAsk); KppSetExpStackElem(idExpStackElemSave); KppSetExpStackState(bExpStackSave); KppSetInputLineNumber(dwInputLineNumberSave); KppReleaseTempExp(hExp, TRUE); SetInterpretationFlag(bSaveInterp); SetFileBeingInterpreted(lpSaveFile); EndProtect(); return bRet; }