diff --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp index d33278ba6a23..533cc0650928 100644 --- a/clang/lib/CodeGen/CGCXXABI.cpp +++ b/clang/lib/CodeGen/CGCXXABI.cpp @@ -268,6 +268,10 @@ void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, Address ptr, llvm::Function* GetLen = llvm::Intrinsic::getDeclaration(&CGF.CGM.getModule(), llvm::Intrinsic::cheerp_get_array_len, {elemType}); numElements = CGF.Builder.CreateCall(GetLen, {allocPtr}); + llvm::Attribute ETAttr = + llvm::Attribute::get(GetLen->getContext(), llvm::Attribute::ElementType, + ptr.getElementType()); + llvm::cast(numElements)->addParamAttr(0, ETAttr); } else { // Derive a char* in the same address space as the pointer. ptr = CGF.Builder.CreateElementBitCast(ptr, CGF.Int8Ty); diff --git a/llvm/lib/CheerpWriter/PreExecute.cpp b/llvm/lib/CheerpWriter/PreExecute.cpp index b91205da5738..1ef78b881ba8 100644 --- a/llvm/lib/CheerpWriter/PreExecute.cpp +++ b/llvm/lib/CheerpWriter/PreExecute.cpp @@ -72,14 +72,14 @@ static char* most_derived_pointer(char* Addr) { } static GenericValue pre_execute_pointer_base(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE; char *p = (char *)(currentEE->GVTORP(Args[0])); return currentEE->RPTOGV(most_derived_pointer(p)); } static GenericValue pre_execute_pointer_offset(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { GenericValue G; ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE; char *p = (char *)(currentEE->GVTORP(Args[0])); @@ -89,7 +89,7 @@ static GenericValue pre_execute_pointer_offset(FunctionType *FT, } static GenericValue pre_execute_allocate_array(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE; size_t size=(size_t)(Args[1].IntVal.getLimitedValue()); @@ -123,7 +123,7 @@ static GenericValue pre_execute_allocate_array(FunctionType *FT, } static GenericValue pre_execute_allocate(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { size_t size=(size_t)(Args[1].IntVal.getLimitedValue()); ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE; void* ret = PreExecute::currentPreExecutePass->allocator->allocate(size); @@ -143,7 +143,7 @@ static GenericValue pre_execute_allocate(FunctionType *FT, } static GenericValue pre_execute_reallocate(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE; void *p = (void *)(currentEE->GVTORP(Args[0])); size_t size=(size_t)(Args[1].IntVal.getLimitedValue()); @@ -180,7 +180,7 @@ static GenericValue pre_execute_reallocate(FunctionType *FT, } static GenericValue pre_execute_deallocate(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { #ifdef DEBUG_PRE_EXECUTE ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE; void *p = (void *)(currentEE->GVTORP(Args[0])); @@ -196,10 +196,12 @@ static GenericValue pre_execute_deallocate(FunctionType *FT, } static GenericValue pre_execute_get_array_len(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE; const DataLayout& DL = currentEE->getDataLayout(); - Type* type = FT->getParamType(0)->getPointerElementType(); + assert(Attrs.hasParamAttr(0, Attribute::ElementType) && "ElementType attribute not present on call"); + Type* type = Attrs.getParamAttr(0, Attribute::ElementType).getValueAsType(); + size_t cookieWords = cheerp::TypeSupport::getArrayCookieSizeAsmJS(DL, type) / sizeof(uint32_t); uint32_t *cookie = static_cast(currentEE->GVTORP(Args[0])) - cookieWords; @@ -209,12 +211,12 @@ static GenericValue pre_execute_get_array_len(FunctionType *FT, } static GenericValue pre_execute_cast(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { return Args[0]; } static GenericValue pre_execute_memcpy(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE; // Support fully typed memcpy memcpy(currentEE->GVTORP(Args[0]), currentEE->GVTORP(Args[1]), @@ -226,7 +228,7 @@ static GenericValue pre_execute_memcpy(FunctionType *FT, } static GenericValue pre_execute_memmove(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE; // Support fully typed memmove memmove(currentEE->GVTORP(Args[0]), currentEE->GVTORP(Args[1]), @@ -238,7 +240,7 @@ static GenericValue pre_execute_memmove(FunctionType *FT, } static GenericValue pre_execute_memset(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE; // Support fully typed memset memset(currentEE->GVTORP(Args[0]), @@ -251,7 +253,7 @@ static GenericValue pre_execute_memset(FunctionType *FT, } static GenericValue pre_execute_umax(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { GenericValue GV; if(Args[0].IntVal.ugt(Args[1].IntVal)) GV.IntVal = Args[0].IntVal; @@ -261,7 +263,7 @@ static GenericValue pre_execute_umax(FunctionType *FT, } static GenericValue pre_execute_smax(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { GenericValue GV; if(Args[0].IntVal.sgt(Args[1].IntVal)) GV.IntVal = Args[0].IntVal; @@ -271,7 +273,7 @@ static GenericValue pre_execute_smax(FunctionType *FT, } static GenericValue pre_execute_abs(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { GenericValue GV; if(Args[0].IntVal.sgt(APInt(FT->getReturnType()->isIntegerTy(32) ? 32 : 64, 0))) GV.IntVal = Args[0].IntVal; @@ -281,7 +283,7 @@ static GenericValue pre_execute_abs(FunctionType *FT, } static GenericValue pre_execute_umin(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { GenericValue GV; if(Args[0].IntVal.ult(Args[1].IntVal)) GV.IntVal = Args[0].IntVal; @@ -291,7 +293,7 @@ static GenericValue pre_execute_umin(FunctionType *FT, } static GenericValue pre_execute_smin(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { GenericValue GV; if(Args[0].IntVal.slt(Args[1].IntVal)) GV.IntVal = Args[0].IntVal; @@ -396,7 +398,7 @@ static bool get_subobject_byte_offset(StructType* derivedType, uint32_t baseInde } static GenericValue pre_execute_downcast_current(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE; assert(currentEE->getCurrentCaller()); @@ -425,7 +427,7 @@ static GenericValue pre_execute_downcast_current(FunctionType *FT, } static GenericValue pre_execute_downcast(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { // We need to apply the offset in bytes using the bases metadata ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE; char* Addr = (char*)currentEE->GVTORP(Args[0]); @@ -459,7 +461,7 @@ static GenericValue pre_execute_downcast(FunctionType *FT, } static GenericValue pre_execute_virtualcast(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { // We need to apply the offset in bytes using the bases metadata ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE; char* Addr = (char*)currentEE->GVTORP(Args[0]); @@ -484,12 +486,12 @@ static GenericValue pre_execute_virtualcast(FunctionType *FT, } static GenericValue pre_execute_upcast(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { return Args[0]; } static GenericValue assertEqualImpl(FunctionType *FT, - ArrayRef Args) + ArrayRef Args, AttributeList Attrs) { ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE; bool success = Args[0].IntVal.getZExtValue(); @@ -505,7 +507,7 @@ static GenericValue assertEqualImpl(FunctionType *FT, } static GenericValue emptyFunction(FunctionType *FT, - ArrayRef Args) + ArrayRef Args, AttributeList Attrs) { return GenericValue(0); } diff --git a/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp b/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp index be3824af4cef..e97ad00ac498 100644 --- a/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp +++ b/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp @@ -59,7 +59,7 @@ using namespace llvm; namespace { -typedef GenericValue (*ExFunc)(FunctionType *, ArrayRef); +typedef GenericValue (*ExFunc)(FunctionType *, ArrayRef, AttributeList); typedef void (*RawFunc)(); struct Functions { @@ -274,6 +274,8 @@ GenericValue Interpreter::callExternalFunction(Function *F, TheInterpreter = this; auto &Fns = getFunctions(); + assert(ECStack.size() > 1); + ExecutionContext &CallerFrame = *(ECStack.end() - 2); std::unique_lock Guard(Fns.Lock); // Do a lookup to see if the function is in our cache... this should just be a @@ -283,7 +285,7 @@ GenericValue Interpreter::callExternalFunction(Function *F, if (ExFunc Fn = (FI == Fns.ExportedFunctions.end()) ? lookupFunction(F, LazyFunctionCreator) : FI->second) { Guard.unlock(); - return Fn(F->getFunctionType(), ArgVals); + return Fn(F->getFunctionType(), ArgVals, CallerFrame.Caller->getAttributes()); } #ifdef USE_LIBFFI @@ -331,7 +333,7 @@ GenericValue Interpreter::callExternalFunction(Function *F, // void atexit(Function*) static GenericValue lle_X_atexit(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList /*unused*/) { assert(Args.size() == 1); TheInterpreter->addAtExitHandler((Function*)GVTOP(Args[0])); GenericValue GV; @@ -340,13 +342,13 @@ static GenericValue lle_X_atexit(FunctionType *FT, } // void exit(int) -static GenericValue lle_X_exit(FunctionType *FT, ArrayRef Args) { +static GenericValue lle_X_exit(FunctionType *FT, ArrayRef Args, AttributeList /*unused*/) { TheInterpreter->exitCalled(Args[0]); return GenericValue(); } // void abort(void) -static GenericValue lle_X_abort(FunctionType *FT, ArrayRef Args) { +static GenericValue lle_X_abort(FunctionType *FT, ArrayRef Args, AttributeList /*unused*/) { //FIXME: should we report or raise here? //report_fatal_error("Interpreted program raised SIGABRT"); raise (SIGABRT); @@ -356,7 +358,7 @@ static GenericValue lle_X_abort(FunctionType *FT, ArrayRef Args) { // int sprintf(char *, const char *, ...) - a very rough implementation to make // output useful. static GenericValue lle_X_sprintf(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList /*unused*/) { char *OutputBuffer = (char *)GVTOP(Args[0]); const char *FmtStr = (const char *)GVTOP(Args[1]); unsigned ArgNo = 2; @@ -438,19 +440,19 @@ static GenericValue lle_X_sprintf(FunctionType *FT, // int printf(const char *, ...) - a very rough implementation to make output // useful. static GenericValue lle_X_printf(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { char Buffer[10000]; std::vector NewArgs; NewArgs.push_back(PTOGV((void*)&Buffer[0])); llvm::append_range(NewArgs, Args); - GenericValue GV = lle_X_sprintf(FT, NewArgs); + GenericValue GV = lle_X_sprintf(FT, NewArgs, Attrs); outs() << Buffer; return GV; } // int sscanf(const char *format, ...); static GenericValue lle_X_sscanf(FunctionType *FT, - ArrayRef args) { + ArrayRef args, AttributeList /*unused*/) { assert(args.size() < 10 && "Only handle up to 10 args to sscanf right now!"); char *Args[10]; @@ -464,7 +466,7 @@ static GenericValue lle_X_sscanf(FunctionType *FT, } // int scanf(const char *format, ...); -static GenericValue lle_X_scanf(FunctionType *FT, ArrayRef args) { +static GenericValue lle_X_scanf(FunctionType *FT, ArrayRef args, AttributeList /*unused*/) { assert(args.size() < 10 && "Only handle up to 10 args to scanf right now!"); char *Args[10]; @@ -480,20 +482,20 @@ static GenericValue lle_X_scanf(FunctionType *FT, ArrayRef args) { // int fprintf(FILE *, const char *, ...) - a very rough implementation to make // output useful. static GenericValue lle_X_fprintf(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList Attrs) { assert(Args.size() >= 2); char Buffer[10000]; std::vector NewArgs; NewArgs.push_back(PTOGV(Buffer)); NewArgs.insert(NewArgs.end(), Args.begin()+1, Args.end()); - GenericValue GV = lle_X_sprintf(FT, NewArgs); + GenericValue GV = lle_X_sprintf(FT, NewArgs, Attrs); fputs(Buffer, (FILE *) GVTOP(Args[0])); return GV; } static GenericValue lle_X_memset(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList /*unused*/) { int val = (int)Args[1].IntVal.getSExtValue(); size_t len = (size_t)Args[2].IntVal.getZExtValue(); memset((void *)GVTOP(Args[0]), val, len); @@ -505,7 +507,7 @@ static GenericValue lle_X_memset(FunctionType *FT, } static GenericValue lle_X_memcpy(FunctionType *FT, - ArrayRef Args) { + ArrayRef Args, AttributeList /*unused*/) { memcpy(GVTOP(Args[0]), GVTOP(Args[1]), (size_t)(Args[2].IntVal.getLimitedValue()));