Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1229,7 +1229,7 @@ endif
# depend on the first one.
$(firstword $(TEST_EXT_MODULE_OBJS)): $(TEST_EXT_MODULE_SRCS) | $(BUILD_PY)
$(VERB) cd $(TEST_DIR)/test_extension; time ../../$(BUILD_PY) setup.py build
$(VERB) cd $(TEST_DIR)/test_extension; ln -sf $(TEST_EXT_MODULE_NAMES:%=build/lib.linux2-2.7/%.pyston.so) .
$(VERB) cd $(TEST_DIR)/test_extension; ln -sf $(TEST_EXT_MODULE_NAMES:%=build/lib.linux-x86_64-2.7/%.pyston.so) .
$(VERB) touch -c $(TEST_EXT_MODULE_OBJS)
$(wordlist 2,9999,$(TEST_EXT_MODULE_OBJS)): $(firstword $(TEST_EXT_MODULE_OBJS))
$(firstword $(SHAREDMODS_OBJS)): $(SHAREDMODS_SRCS) | $(BUILD_PY)
Expand Down
64 changes: 43 additions & 21 deletions src/codegen/compvars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -489,14 +489,24 @@ CompilerVariable* UnknownType::getattr(IREmitter& emitter, const OpInfo& info, C

llvm::Value* rtn_val = NULL;

ExceptionStyle target_exception_style = CXX;
if (info.unw_info.capi_exc_dest)
target_exception_style = CAPI;

llvm::Value* llvm_func;
void* raw_func;
if (cls_only) {
assert(target_exception_style == CXX);
llvm_func = g.funcs.getclsattr;
raw_func = (void*)pyston::getclsattr;
} else {
llvm_func = g.funcs.getattr;
raw_func = (void*)pyston::getattr;
if (target_exception_style == CXX) {
llvm_func = g.funcs.getattr;
raw_func = (void*)pyston::getattr;
} else {
llvm_func = g.funcs.getattr_capi;
raw_func = (void*)pyston::getattr_capi;
}
}

bool do_patchpoint = ENABLE_ICGETATTRS;
Expand All @@ -507,15 +517,20 @@ CompilerVariable* UnknownType::getattr(IREmitter& emitter, const OpInfo& info, C
llvm_args.push_back(var->getValue());
llvm_args.push_back(ptr);

llvm::Value* uncasted = emitter.createIC(pp, raw_func, llvm_args, info.unw_info);
llvm::Value* uncasted = emitter.createIC(pp, raw_func, llvm_args, info.unw_info, target_exception_style);
rtn_val = emitter.getBuilder()->CreateIntToPtr(uncasted, g.llvm_value_type_ptr);
} else {
rtn_val = emitter.createCall2(info.unw_info, llvm_func, var->getValue(), ptr);
rtn_val = emitter.createCall2(info.unw_info, llvm_func, var->getValue(), ptr, target_exception_style);
}

if (target_exception_style == CAPI)
emitter.checkAndPropagateCapiException(info.unw_info, rtn_val, getNullPtr(g.llvm_value_type_ptr));

return new ConcreteCompilerVariable(UNKNOWN, rtn_val, true);
}

static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, llvm::Value* func, void* func_addr,
static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, llvm::Value* func,
ExceptionStyle target_exception_style, void* func_addr,
const std::vector<llvm::Value*>& other_args, ArgPassSpec argspec,
const std::vector<CompilerVariable*>& args,
const std::vector<BoxedString*>* keyword_names, ConcreteCompilerType* rtn_type) {
Expand Down Expand Up @@ -551,7 +566,6 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l
llvm_args.push_back(getNullPtr(g.llvm_value_type_ptr));
}

llvm::Value* mallocsave = NULL;
if (args.size() >= 4) {
llvm::Value* arg_array;

Expand Down Expand Up @@ -594,7 +608,7 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l

ICSetupInfo* pp = createCallsiteIC(info.getTypeRecorder(), args.size());

llvm::Value* uncasted = emitter.createIC(pp, func_addr, llvm_args, info.unw_info);
llvm::Value* uncasted = emitter.createIC(pp, func_addr, llvm_args, info.unw_info, target_exception_style);

assert(llvm::cast<llvm::FunctionType>(llvm::cast<llvm::PointerType>(func->getType())->getElementType())
->getReturnType() == g.llvm_value_type_ptr);
Expand All @@ -608,20 +622,19 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l
//}
// printf("%ld %ld\n", llvm_args.size(), args.size());
// printf("\n");
rtn = emitter.createCall(info.unw_info, func, llvm_args);
}

if (mallocsave) {
llvm::Value* l_free = embedConstantPtr(
(void*)free, llvm::FunctionType::get(g.void_, g.i8->getPointerTo(), false)->getPointerTo());
emitter.getBuilder()->CreateCall(l_free, mallocsave);
rtn = emitter.createCall(info.unw_info, func, llvm_args, target_exception_style);
}

for (int i = 0; i < args.size(); i++) {
converted_args[i]->decvref(emitter);
}

assert(rtn->getType() == rtn_type->llvmType());

if (target_exception_style == CAPI) {
emitter.checkAndPropagateCapiException(info.unw_info, rtn, getNullPtr(g.llvm_value_type_ptr));
}

return new ConcreteCompilerVariable(rtn_type, rtn, true);
}

Expand Down Expand Up @@ -650,7 +663,7 @@ CompilerVariable* UnknownType::call(IREmitter& emitter, const OpInfo& info, Conc

llvm::Value* llvm_argspec = llvm::ConstantInt::get(g.i32, argspec.asInt(), false);
other_args.push_back(llvm_argspec);
return _call(emitter, info, func, (void*)runtimeCall, other_args, argspec, args, keyword_names, UNKNOWN);
return _call(emitter, info, func, CXX, (void*)runtimeCall, other_args, argspec, args, keyword_names, UNKNOWN);
}

CompilerVariable* UnknownType::callattr(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var,
Expand Down Expand Up @@ -678,7 +691,8 @@ CompilerVariable* UnknownType::callattr(IREmitter& emitter, const OpInfo& info,
other_args.push_back(var->getValue());
other_args.push_back(embedRelocatablePtr(attr, g.llvm_boxedstring_type_ptr));
other_args.push_back(getConstantInt(flags.asInt(), g.i64));
return _call(emitter, info, func, (void*)pyston::callattr, other_args, flags.argspec, args, keyword_names, UNKNOWN);
return _call(emitter, info, func, CXX, (void*)pyston::callattr, other_args, flags.argspec, args, keyword_names,
UNKNOWN);
}

ConcreteCompilerVariable* UnknownType::nonzero(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var) {
Expand Down Expand Up @@ -1480,10 +1494,18 @@ class NormalObjectType : public ConcreteCompilerType {
if (canStaticallyResolveGetattrs()) {
Box* rtattr = typeLookup(cls, attr, nullptr);
if (rtattr == NULL) {
ExceptionStyle exception_style = info.unw_info.capi_exc_dest ? CAPI : CXX;
llvm::Value* raise_func = exception_style == CXX ? g.funcs.raiseAttributeErrorStr
: g.funcs.raiseAttributeErrorStrCapi;
llvm::CallSite call = emitter.createCall3(
info.unw_info, g.funcs.raiseAttributeErrorStr, embedRelocatablePtr(cls->tp_name, g.i8_ptr),
embedRelocatablePtr(attr->data(), g.i8_ptr), getConstantInt(attr->size(), g.i64));
call.setDoesNotReturn();
info.unw_info, raise_func, embedRelocatablePtr(cls->tp_name, g.i8_ptr),
embedRelocatablePtr(attr->data(), g.i8_ptr), getConstantInt(attr->size(), g.i64), exception_style);
if (exception_style == CAPI) {
emitter.checkAndPropagateCapiException(info.unw_info, getNullPtr(g.llvm_value_type_ptr),
getNullPtr(g.llvm_value_type_ptr));
} else {
call.setDoesNotReturn();
}
return undefVariable();
}

Expand Down Expand Up @@ -1623,8 +1645,8 @@ class NormalObjectType : public ConcreteCompilerType {

std::vector<llvm::Value*> other_args;

ConcreteCompilerVariable* rtn = _call(emitter, info, linked_function, cf->code, other_args, argspec, new_args,
keyword_names, cf->spec->rtn_type);
ConcreteCompilerVariable* rtn = _call(emitter, info, linked_function, cf->exception_style, cf->code, other_args,
argspec, new_args, keyword_names, cf->spec->rtn_type);
assert(rtn->getType() == cf->spec->rtn_type);
assert(rtn->getType() != UNDEF);

Expand Down
34 changes: 22 additions & 12 deletions src/codegen/irgen.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,19 @@ class IREmitter;
struct UnwindInfo {
public:
AST_stmt* current_stmt;
llvm::BasicBlock* exc_dest;

bool needsInvoke() { return exc_dest != NULL; }
llvm::BasicBlock* capi_exc_dest;
llvm::BasicBlock* cxx_exc_dest;

UnwindInfo(AST_stmt* current_stmt, llvm::BasicBlock* exc_dest) : current_stmt(current_stmt), exc_dest(exc_dest) {}
bool hasHandler() const { return cxx_exc_dest != NULL || capi_exc_dest != NULL; }

UnwindInfo(AST_stmt* current_stmt, llvm::BasicBlock* capi_exc_dest, llvm::BasicBlock* cxx_exc_dest)
: current_stmt(current_stmt), capi_exc_dest(capi_exc_dest), cxx_exc_dest(cxx_exc_dest) {}

// Risky! This means that we can't unwind from this location, and should be used in the
// rare case that there are language-specific reasons that the statement should not unwind
// (ex: loading function arguments into the appropriate scopes).
static UnwindInfo cantUnwind() { return UnwindInfo(NULL, NULL); }
static UnwindInfo cantUnwind() { return UnwindInfo(NULL, NULL, NULL); }
};

// TODO get rid of this
Expand Down Expand Up @@ -78,16 +81,23 @@ class IREmitter {

virtual llvm::Function* getIntrinsic(llvm::Intrinsic::ID) = 0;

virtual llvm::Value* createCall(UnwindInfo unw_info, llvm::Value* callee, const std::vector<llvm::Value*>& args)
virtual llvm::Value* createCall(const UnwindInfo& unw_info, llvm::Value* callee,
const std::vector<llvm::Value*>& args, ExceptionStyle target_exception_style = CXX)
= 0;
virtual llvm::Value* createCall(UnwindInfo unw_info, llvm::Value* callee) = 0;
virtual llvm::Value* createCall(UnwindInfo unw_info, llvm::Value* callee, llvm::Value* arg1) = 0;
virtual llvm::Value* createCall2(UnwindInfo unw_info, llvm::Value* callee, llvm::Value* arg1, llvm::Value* arg2)
virtual llvm::Value* createCall(const UnwindInfo& unw_info, llvm::Value* callee,
ExceptionStyle target_exception_style = CXX) = 0;
virtual llvm::Value* createCall(const UnwindInfo& unw_info, llvm::Value* callee, llvm::Value* arg1,
ExceptionStyle target_exception_style = CXX) = 0;
virtual llvm::Value* createCall2(const UnwindInfo& unw_info, llvm::Value* callee, llvm::Value* arg1,
llvm::Value* arg2, ExceptionStyle target_exception_style = CXX) = 0;
virtual llvm::Value* createCall3(const UnwindInfo& unw_info, llvm::Value* callee, llvm::Value* arg1,
llvm::Value* arg2, llvm::Value* arg3, ExceptionStyle target_exception_style = CXX)
= 0;
virtual llvm::Value* createCall3(UnwindInfo unw_info, llvm::Value* callee, llvm::Value* arg1, llvm::Value* arg2,
llvm::Value* arg3) = 0;
virtual llvm::Value* createIC(const ICSetupInfo* pp, void* func_addr, const std::vector<llvm::Value*>& args,
UnwindInfo unw_info) = 0;
const UnwindInfo& unw_info, ExceptionStyle target_exception_style = CXX) = 0;

virtual void checkAndPropagateCapiException(const UnwindInfo& unw_info, llvm::Value* returned_val,
llvm::Value* exc_val, bool double_check = false) = 0;

virtual Box* getIntConstant(int64_t n) = 0;
virtual Box* getFloatConstant(double d) = 0;
Expand Down Expand Up @@ -132,7 +142,7 @@ class OpInfo {
public:
const UnwindInfo unw_info;

OpInfo(EffortLevel effort, TypeRecorder* type_recorder, UnwindInfo unw_info)
OpInfo(EffortLevel effort, TypeRecorder* type_recorder, const UnwindInfo& unw_info)
: effort(effort), type_recorder(type_recorder), unw_info(unw_info) {}

TypeRecorder* getTypeRecorder() const { return type_recorder; }
Expand Down
14 changes: 5 additions & 9 deletions src/codegen/irgen/hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -716,8 +716,7 @@ void CompiledFunction::speculationFailed() {
}

CompiledFunction::CompiledFunction(llvm::Function* func, FunctionSpecialization* spec, void* code, EffortLevel effort,
ExceptionStyle::ExceptionStyle exception_style,
const OSREntryDescriptor* entry_descriptor)
ExceptionStyle exception_style, const OSREntryDescriptor* entry_descriptor)
: clfunc(NULL),
func(func),
spec(spec),
Expand Down Expand Up @@ -834,7 +833,7 @@ CLFunction* createRTFunction(int num_args, int num_defaults, bool takes_varargs,
}

CLFunction* boxRTFunction(void* f, ConcreteCompilerType* rtn_type, int num_args, const ParamNames& param_names,
ExceptionStyle::ExceptionStyle exception_style) {
ExceptionStyle exception_style) {
assert(!param_names.takes_param_names || num_args == param_names.args.size());
assert(param_names.vararg.str() == "");
assert(param_names.kwarg.str() == "");
Expand All @@ -843,8 +842,7 @@ CLFunction* boxRTFunction(void* f, ConcreteCompilerType* rtn_type, int num_args,
}

CLFunction* boxRTFunction(void* f, ConcreteCompilerType* rtn_type, int num_args, int num_defaults, bool takes_varargs,
bool takes_kwargs, const ParamNames& param_names,
ExceptionStyle::ExceptionStyle exception_style) {
bool takes_kwargs, const ParamNames& param_names, ExceptionStyle exception_style) {
assert(!param_names.takes_param_names || num_args == param_names.args.size());
assert(takes_varargs || param_names.vararg.str() == "");
assert(takes_kwargs || param_names.kwarg.str() == "");
Expand All @@ -855,8 +853,7 @@ CLFunction* boxRTFunction(void* f, ConcreteCompilerType* rtn_type, int num_args,
return cl_f;
}

void addRTFunction(CLFunction* cl_f, void* f, ConcreteCompilerType* rtn_type,
ExceptionStyle::ExceptionStyle exception_style) {
void addRTFunction(CLFunction* cl_f, void* f, ConcreteCompilerType* rtn_type, ExceptionStyle exception_style) {
std::vector<ConcreteCompilerType*> arg_types(cl_f->numReceivedArgs(), UNKNOWN);
return addRTFunction(cl_f, f, rtn_type, arg_types, exception_style);
}
Expand All @@ -867,8 +864,7 @@ static ConcreteCompilerType* processType(ConcreteCompilerType* type) {
}

void addRTFunction(CLFunction* cl_f, void* f, ConcreteCompilerType* rtn_type,
const std::vector<ConcreteCompilerType*>& arg_types,
ExceptionStyle::ExceptionStyle exception_style) {
const std::vector<ConcreteCompilerType*>& arg_types, ExceptionStyle exception_style) {
assert(arg_types.size() == cl_f->numReceivedArgs());
#ifndef NDEBUG
for (ConcreteCompilerType* t : arg_types)
Expand Down
2 changes: 2 additions & 0 deletions src/codegen/irgen/hooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm);
// will we always want to generate unique function names? (ie will this function always be reasonable?)
CompiledFunction* cfForMachineFunctionName(const std::string&);

extern "C" void capiExcCaughtInJit(AST_stmt* current_stmt, void* source_info);

extern "C" Box* exec(Box* boxedCode, Box* globals, Box* locals, FutureFlags caller_future_flags);
extern "C" Box* eval(Box* boxedCode, Box* globals, Box* locals);
extern "C" Box* compile(Box* source, Box* filename, Box* mode, Box** _args /* flags, dont_inherit */);
Expand Down
Loading