void MethodBuilder::setup() { std::vector<Type*> ftypes; ftypes.push_back(ls_->ptr_type("VM")); ftypes.push_back(ls_->ptr_type("CallFrame")); ftypes.push_back(ls_->ptr_type("Executable")); ftypes.push_back(ls_->ptr_type("Module")); ftypes.push_back(ls_->ptr_type("Arguments")); FunctionType* ft = FunctionType::get(ls_->ptr_type("Object"), ftypes, false); std::ostringstream ss; ss << std::string("_X_") << ls_->enclosure_name(info_.method()) << "#" << ls_->symbol_debug_str(info_.method()->name()) << "@" << ls_->add_jitted_method(); llvm::Function* func = Function::Create(ft, GlobalValue::ExternalLinkage, ss.str().c_str(), ls_->module()); Function::arg_iterator ai = func->arg_begin(); llvm::Value* vm = ai++; vm->setName("state"); llvm::Value* prev = ai++; prev->setName("previous"); exec = ai++; exec->setName("exec"); module = ai++; module->setName("mod"); llvm::Value* args = ai++; args->setName("args"); BasicBlock* block = BasicBlock::Create(ls_->ctx(), "entry", func); builder_.SetInsertPoint(block); info_.context().set_function(func); info_.set_vm(vm); info_.set_args(args); info_.set_previous(prev); info_.set_entry(block); alloc_frame("method_body"); check_arity(); // check_self_type(); initialize_frame(vmm_->stack_size); nil_stack(vmm_->stack_size, constant(cNil, obj_type)); import_args(); import_args_ = b().GetInsertBlock(); b().CreateBr(body_); b().SetInsertPoint(body_); }
object *call_proc(object *theproc, environ *env, object **args, int arglen) { CHECK_TYPE_PROC(theproc); if (theproc->val.proc.builtin) { return call_builtin1(theproc, args, arglen); } else { // Restore the environment that was available where the // function was defined. // Create new namespace for this invocation of the function. environ *new_env = new_environment(theproc->val.proc.closure); // Check function arity matches call check_arity(theproc, arglen); // Call function return ((FP) theproc->val.proc.func)(new_env, args, arglen); } }