ejsval Module_prototype_getOrInsertIntrinsic(ejsval env, ejsval _this, int argc, ejsval *args) { Module* module = ((Module*)EJSVAL_TO_OBJECT(_this)); REQ_UTF8_ARG(0, id); #if false REQ_ARRAY_ARG(1, paramTypes); std::vector< llvm::Type*> param_types; for (int i = 0; i < paramTypes->Length(); i ++) { param_types.push_back (Type_getLLVMObj(EJSARRAY_ELEMENTS(argTypes)[i])); } #endif llvm::Intrinsic::ID intrinsic_id; if (!strcmp (id.c_str(), "@llvm.gcroot")) { intrinsic_id = llvm::Intrinsic::gcroot; } else { abort(); } #if false llvm::Function* f = llvm::Intrinsic::getDeclaration (module->llvm_module, intrinsic_id, param_types); #else llvm::Function* f = llvm::Intrinsic::getDeclaration (module->llvm_module, intrinsic_id); #endif return Function_new (f); }
ejsval Module_prototype_getOrInsertFunction(ejsval env, ejsval _this, int argc, ejsval *args) { Module *module = ((Module*)EJSVAL_TO_OBJECT(_this)); REQ_UTF8_ARG(0, name); REQ_LLVM_TYPE_ARG(1, returnType); REQ_ARRAY_ARG(2, paramTypes); std::vector< llvm::Type*> param_types; for (int i = 0; i < EJSARRAY_LEN(paramTypes); i ++) { param_types.push_back (Type_GetLLVMObj(EJSDENSEARRAY_ELEMENTS(paramTypes)[i])); } llvm::FunctionType *FT = llvm::FunctionType::get(returnType, param_types, false); llvm::Function* f = static_cast< llvm::Function*>(module->llvm_module->getOrInsertFunction(name, FT)); // XXX this needs to come from the js call, since when we hoist anonymous methods we'll need to give them a private linkage. f->setLinkage (llvm::Function::ExternalLinkage); // XXX the args might not be identifiers but might instead be destructuring expressions. punt for now. #if notyet // Set names for all arguments. unsigned Idx = 0; for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size(); ++AI, ++Idx) AI->setName(Args[Idx]); #endif return Function_new (f); }
ejsval Module_prototype_getFunction(ejsval env, ejsval _this, int argc, ejsval *args) { Module *module = ((Module*)EJSVAL_TO_OBJECT(_this)); REQ_UTF8_ARG(0, name); llvm::Function* f = static_cast< llvm::Function*>(module->llvm_module->getFunction(name)); if (f) return Function_new (f); return _ejs_null; }
ejsval Module_prototype_getOrInsertExternalFunction(ejsval env, ejsval _this, int argc, ejsval *args) { Module *module = ((Module*)EJSVAL_TO_OBJECT(_this)); REQ_UTF8_ARG(0, name); REQ_LLVM_TYPE_ARG(1, returnType); REQ_ARRAY_ARG(2, paramTypes); std::vector< llvm::Type*> param_types; for (int i = 0; i < EJSARRAY_LEN(paramTypes); i ++) { param_types.push_back (Type_GetLLVMObj(EJSDENSEARRAY_ELEMENTS(paramTypes)[i])); } llvm::FunctionType *FT = llvm::FunctionType::get(returnType, param_types, false); llvm::Function* f = static_cast< llvm::Function*>(module->llvm_module->getOrInsertFunction(name, FT)); f->setLinkage (llvm::Function::ExternalLinkage); return Function_new (f); }
void Object_define_method(Object *object, bstring name, Instruction **instructions, int instructions_count, short arity) { Object *fn = Function_new(instructions, instructions_count, arity); Hashmap_set(object->slots, name, fn, tFunction); }
ejsval BasicBlock_prototype_get_parent(ejsval env, ejsval _this, int argc, ejsval *args) { BasicBlock* bb = ((BasicBlock*)EJSVAL_TO_OBJECT(_this)); return Function_new (bb->llvm_bb->getParent()); }
Expression* Expression_parse(const char** expr) { Expression* ret = NULL; Variable* var; Value* val; const char* equals = strchr(*expr, '='); if(equals == NULL) { /* No assignment, just a plain expression. */ return parseExpr(expr); } /* There is an assignment */ /* First, parse the right side of the assignment */ equals++; val = Value_parse(&equals, 0, 0); if(val->type == VAL_ERR) { /* A parse error occurred */ var = VarErr(Error_copy(val->err)); Value_free(val); return Expression_new(var); } if(val->type == VAL_END) { /* Empty input */ Value_free(val); var = VarErr(earlyEnd()); return Expression_new(var); } /* Now parse the left side */ char* name = nextToken(expr); if(name == NULL) { Value_free(val); var = VarErr(syntaxError("No variable to assign to.")); return Expression_new(var); } trimSpaces(expr); if(**expr == '(') { /* Defining a function */ (*expr)++; /* Array of argument names */ unsigned size = 2; char** args = fmalloc(size * sizeof(*args)); unsigned len = 0; /* Add each argument name to the array */ char* arg = nextToken(expr); if(arg == NULL && **expr != ')') { /* Invalid character */ Value_free(val); free(args); free(name); var = VarErr(badChar(**expr)); return Expression_new(var); } trimSpaces(expr); if(arg == NULL) { /* Empty parameter list means function with no args */ free(args); args = NULL; len = 0; } else { /* Loop through each argument in the list */ while(**expr == ',' || **expr == ')') { args[len++] = arg; if(**expr == ')') break; (*expr)++; /* Expand argument array if it's too small */ if(len >= size) { size *= 2; args = frealloc(args, size * sizeof(*args)); } arg = nextToken(expr); if(arg == NULL) { /* Invalid character */ Value_free(val); free(name); /* Free argument names and return */ unsigned i; for(i = 0; i < len; i++) { free(args[i]); } free(args); var = VarErr(badChar(**expr)); return Expression_new(var); } trimSpaces(expr); } } if(**expr != ')') { /* Invalid character inside argument name list */ Value_free(val); free(name); /* Free argument names and return */ unsigned i; for(i = 0; i < len; i++) { free(args[i]); } free(args); var = VarErr(badChar(**expr)); return Expression_new(var); } /* Skip closing parenthesis */ (*expr)++; trimSpaces(expr); if(**expr != '=') { Value_free(val); free(name); unsigned i; for(i = 0; i < len; i++) { free(args[i]); } free(args); var = VarErr(badChar(**expr)); return Expression_new(var); } /* Construct function and return it */ Function* func = Function_new(len, args, val); var = VarFunc(name, func); free(name); ret = Expression_new(var); } else { /* Defining a variable */ if(**expr != '=') { /* In-place manipulation */ BINTYPE bin = BinOp_nextType(expr, 0, 0); /* Still not an equals sign means invalid character */ if(**expr != '=') { Value_free(val); free(name); var = VarErr(badChar(**expr)); return Expression_new(var); } val = ValExpr(BinOp_new(bin, ValVar(name), val)); } var = VarValue(name, val); free(name); ret = Expression_new(var); } return ret; }