static ejsval Constant_getBoolValue (ejsval env, ejsval _this, int argc, ejsval *args) { REQ_BOOL_ARG (0, b); return Value_new (llvm::Constant::getIntegerValue(llvm::Type::getInt8Ty(llvm::getGlobalContext()), llvm::APInt(8, b?1:0))); }
ejsval IRBuilder_createResume(ejsval env, ejsval _this, int argc, ejsval *args) { REQ_LLVM_VAL_ARG(0, val); return Value_new (_llvm_builder.CreateResume(val)); }
static Value _evalForeach (Procedure self) { Exp exp = self->exp; Exp pairs = exp->u.ternary->a; Value collection = _EVAL(exp->u.ternary->b); if (!collection) return NULL; Value key = NULL, value = NULL; if (pairs->type == COMMA_EXP) { key = pairs->u.binary->a->u.value; value = pairs->u.binary->b->u.value; } else { value = pairs->u.value; } Assoc assoc = Value_pairs(collection, exp->type == IN_EXP); Assoc assocNode = assoc; Value result = Value_new(at_Array, NULL); int endIndex = 0; while (self->active && (assocNode = assocNode->next)) { self->active = 1; _set(self, key, assocNode->key); _set(self, value, assocNode->value); Value_set(result, Value_number(endIndex++), _EVAL(exp->u.ternary->c)); } Assoc_free(assoc); free(self); Value_set(result, at_TV_endIndex, Value_number(endIndex)); return result; }
// ================================================================================================ // _evalTrue, _evalWhile, _evalForeach, _evalBreak, _evalSwitch // ================================================================================================ static Value _evalTrue (Procedure self, Exp exp) { Value result = NULL, key = NULL, value = NULL; Exp iColon = NULL; real endIndex = 0; result = Value_new(at_True, NULL); while (exp) { TRAVERSEL_COMMA_EXP(exp, iColon); if (!iColon) continue; if (iColon->type == ASSIGN_EXP) { result->meta = at_Function; result->u.proc = Procedure_new(self, NULL, NULL, result, iColon->u.binary->b); } else { if (iColon->type != COLON_EXP && iColon->type != ACCESSOR_EXP) { key = Value_number(endIndex++); value = _EVAL(iColon); } else { key = _EVAL(iColon->u.binary->a); value = (iColon->type == ACCESSOR_EXP ? Value_functionAccessor(self, iColon->u.binary->b) : _EVAL(iColon->u.binary->b) ); if (Value_is(key, at_Number)) { endIndex = key->u.number + 1; } } Value_set(result, key, value); } } return result; }
ejsval IRBuilder_createBr(ejsval env, ejsval _this, int argc, ejsval *args) { REQ_LLVM_BB_ARG(0, dest); return Value_new (_llvm_builder.CreateBr(dest)); }
static ejsval Constant_getAggregateZero (ejsval env, ejsval _this, int argc, ejsval *args) { REQ_LLVM_TYPE_ARG (0, ty); return Value_new (llvm::ConstantAggregateZero::get(ty)); }
ejsval IRBuilder_createBitCast(ejsval env, ejsval _this, int argc, ejsval *args) { REQ_LLVM_VAL_ARG(0, V); REQ_LLVM_TYPE_ARG(1, dest_ty); FALLBACK_EMPTY_UTF8_ARG(2, name); return Value_new (_llvm_builder.CreateBitCast(V, dest_ty, name)); }
ejsval IRBuilder_createOr(ejsval env, ejsval _this, int argc, ejsval *args) { REQ_LLVM_VAL_ARG(0, lhs); REQ_LLVM_VAL_ARG(1, rhs); FALLBACK_EMPTY_UTF8_ARG(2, name); return Value_new (_llvm_builder.CreateOr(lhs, rhs, name)); }
static ejsval Constant_getIntegerValue (ejsval env, ejsval _this, int argc, ejsval *args) { REQ_LLVM_TYPE_ARG (0, ty); REQ_INT_ARG (1, v); if (argc == 2) { return Value_new (llvm::Constant::getIntegerValue(ty, llvm::APInt(ty->getPrimitiveSizeInBits(), v))); } else if (argc == 3 && EJSVAL_IS_NUMBER(args[2]) && ty->getPrimitiveSizeInBits() == 64) { uint64_t vhi = v; uint32_t vlo = (uint32_t)EJSVAL_TO_NUMBER(args[2]); return Value_new (llvm::Constant::getIntegerValue(ty, llvm::APInt(ty->getPrimitiveSizeInBits(), (int64_t)((vhi << 32) | vlo)))); } else abort(); // FIXME throw an exception }
ejsval IRBuilder_createGlobalStringPtr(ejsval env, ejsval _this, int argc, ejsval *args) { REQ_UTF8_ARG(0, val); FALLBACK_EMPTY_UTF8_ARG(1, name); return Value_new (_llvm_builder.CreateGlobalStringPtr(val, name)); }
ejsval IRBuilder_createCondBr(ejsval env, ejsval _this, int argc, ejsval *args) { REQ_LLVM_VAL_ARG(0, cond); REQ_LLVM_BB_ARG(1, thenPart); REQ_LLVM_BB_ARG(2, elsePart); return Value_new (_llvm_builder.CreateCondBr(cond, thenPart, elsePart)); }
ejsval IRBuilder_createICmpULt(ejsval env, ejsval _this, int argc, ejsval *args) { REQ_LLVM_VAL_ARG(0, left); REQ_LLVM_VAL_ARG(1, right); FALLBACK_EMPTY_UTF8_ARG(2, name); return Value_new (_llvm_builder.CreateICmpULT(left, right, name)); }
ejsval IRBuilder_createStructGetElementPointer(ejsval env, ejsval _this, int argc, ejsval *args) { REQ_LLVM_VAL_ARG(0, val); REQ_INT_ARG(1, idx); FALLBACK_EMPTY_UTF8_ARG(2, name); return Value_new (_llvm_builder.CreateStructGEP(val, idx, name)); }
ejsval IRBuilder_createExtractValue(ejsval env, ejsval _this, int argc, ejsval *args) { REQ_LLVM_VAL_ARG(0, val); REQ_INT_ARG(1, idx); FALLBACK_EMPTY_UTF8_ARG(2, name); return Value_new (_llvm_builder.CreateExtractValue(val, idx, name)); }
static inline void expose_VM(STATE, VALUE lobby) { VALUE vm = Value_new(state, ObjectType); Value_set(state, lobby, "VM", vm); // VM.primitives map DArray *prims = DArray_create(sizeof(VALUE), 10); VALUE primitives = Map_new(state, prims); Value_set(state, vm, "primitives", primitives); // Object DEFPRIM("to_s", Primitive_to_s); DEFPRIM("prototype", Primitive_prototype); DEFPRIM("or", Primitive_or); DEFPRIM("equals", Primitive_equals); DEFPRIM("is", Primitive_is); DEFPRIM("print", Primitive_print); DEFPRIM("puts", Primitive_puts); DEFPRIM("require", Primitive_require); DEFPRIM("clone", Primitive_clone); // Vector DEFPRIM("vector_[]", Primitive_Vector_at); DEFPRIM("vector_push", Primitive_Vector_push); DEFPRIM("vector_to_map", Primitive_Vector_to_map); DEFPRIM("vector_each", Primitive_Vector_each); DEFPRIM("vector_each_with_index", Primitive_Vector_each_with_index); // Number DEFPRIM("number_+", Primitive_Number_add); DEFPRIM("number_-", Primitive_Number_sub); DEFPRIM("number_*", Primitive_Number_mul); DEFPRIM("number_/", Primitive_Number_div); DEFPRIM("number_<", Primitive_Number_lt); DEFPRIM("number_>", Primitive_Number_gt); // String DEFPRIM("string_+", Primitive_String_concat); // Map DEFPRIM("map_each", Primitive_Map_each); // VM.types map DArray *ts = DArray_create(sizeof(VALUE), 10); VALUE types = Map_new(state, ts); Value_set(state, vm, "types", types); DEFVALUE("object", Object_bp); DEFVALUE("number", Number_bp); DEFVALUE("string", String_bp); DEFVALUE("vector", Vector_bp); DEFVALUE("map", Map_bp); DEFVALUE("closure", Closure_bp); }
ejsval IRBuilder_createSelect(ejsval env, ejsval _this, int argc, ejsval *args) { REQ_LLVM_VAL_ARG(0, C); REQ_LLVM_VAL_ARG(1, True); REQ_LLVM_VAL_ARG(2, False); FALLBACK_EMPTY_UTF8_ARG(3, name); return Value_new(_llvm_builder.CreateSelect(C, True, False, name)); }
void Runtime_init(STATE) { Object_bp = Value_new(state, ObjectType); Number_bp = Value_from_prototype(state, NumberType, Object_bp); String_bp = Value_from_prototype(state, StringType, Object_bp); Vector_bp = Value_from_prototype(state, VectorType, Object_bp); Map_bp = Value_from_prototype(state, MapType, Object_bp); Closure_bp = Value_from_prototype(state, ClosureType, Object_bp); // Init extern constants TrueObject = Value_new(state, TrueType); TrueObject->data.as_num = 1; FalseObject = Value_new(state, FalseType); FalseObject->data.as_num = 0; NilObject = Value_new(state, NilType); NilObject->data.as_num = 0; // These primitives cannot go in the prelude because they are used there. DEFNATIVE(Object_bp, "[]", Primitive_Map_get); DEFNATIVE(Object_bp, "[]=", Primitive_Map_set); }
static ejsval ConstantArray_get (ejsval env, ejsval _this, int argc, ejsval *args) { REQ_LLVM_TYPE_ARG(0, array_type); REQ_ARRAY_ARG(1, elements); std::vector< llvm::Constant*> element_constants; for (int i = 0; i < EJSARRAY_LEN(elements); i ++) { element_constants.push_back (static_cast<llvm::Constant*>(Value_GetLLVMObj(EJSDENSEARRAY_ELEMENTS(elements)[i]))); } return Value_new (llvm::ConstantArray::get(static_cast<llvm::ArrayType*>(array_type), element_constants)); }
static Value _evalWhile (Procedure self) { Exp exp = self->exp; Value cond = _EVAL(exp->u.binary->a); Value result = Value_new(at_Array, NULL); int endIndex = 0; while (self->active && (exp->type == WHILE_EXP && cond || exp->type == UNTIL_EXP && !cond)) { self->active = 1; Value_set(result, Value_number(endIndex++), _EVAL(exp->u.binary->b)); cond = _EVAL(exp->u.binary->a); } free(self); Value_set(result, at_TV_endIndex, Value_number(endIndex)); return result; }
ejsval IRBuilder_createPhi(ejsval env, ejsval _this, int argc, ejsval *args) { abort(); #if notyet REQ_LLVM_TYPE_ARG(0, ty); REQ_INT_ARG(1, incoming_values); FALLBACK_EMPTY_UTF8_ARG(2, name); ejsval rv = Value_new (_llvm_builder.CreatePHI(ty, incoming_values, name)); free (name); return rv; #endif }
ejsval IRBuilder_createInBoundsGetElementPointer(ejsval env, ejsval _this, int argc, ejsval *args) { REQ_LLVM_VAL_ARG(0, val); REQ_ARRAY_ARG(1, idxv); FALLBACK_EMPTY_UTF8_ARG(2, name); std::vector<llvm::Value*> IdxV; for (unsigned i = 0, e = EJSARRAY_LEN(idxv); i != e; ++i) { IdxV.push_back (Value_GetLLVMObj(EJSDENSEARRAY_ELEMENTS(idxv)[i])); if (IdxV.back() == 0) abort(); // XXX throw an exception here } return Value_new (_llvm_builder.CreateInBoundsGEP(val, IdxV, name)); }
ejsval Function_prototype_get_args(ejsval env, ejsval _this, int argc, ejsval *args) { Function* fun = ((Function*)EJSVAL_TO_OBJECT(_this)); int size = fun->llvm_fun->arg_size(); ejsval result = _ejs_array_new(0, EJS_FALSE); unsigned Idx = 0; for (llvm::Function::arg_iterator AI = fun->llvm_fun->arg_begin(); Idx != size; ++AI, ++Idx) { ejsval val = Value_new(AI); _ejs_array_push_dense (result, 1, &val); } return result; }
static Value _evalTo (Procedure self, ExpType type, Exp a, Exp b, Exp c) { Value va = _EVAL(a), vb = _EVAL(b), vc = _EVAL(c); if (!vc) { vc = Value_number(1); } if (!(Value_is(va, at_Number) && Value_is(vb, at_Number) && Value_is(vc, at_Number))) { yyerror("wrong to expression with NAN."); return NULL; } Value result = Value_new(at_Array, NULL); int endIndex = 0; real i = va->u.number; for (;i < vb->u.number || i == vb->u.number && type == TO_EXP; i += vc->u.number) { Value_set(result, Value_number(endIndex++), Value_number(i)); } Value_set(result, at_TV_endIndex, Value_number(endIndex)); return result; }
ejsval IRBuilder_createUnreachable(ejsval env, ejsval _this, int argc, ejsval *args) { return Value_new (_llvm_builder.CreateUnreachable()); }
ejsval IRBuilder_createRetVoid(ejsval env, ejsval _this, int argc, ejsval *args) { return Value_new(_llvm_builder.CreateRetVoid()); }
static ejsval Constant_getNull (ejsval env, ejsval _this, int argc, ejsval *args) { REQ_LLVM_TYPE_ARG (0, ty); return Value_new (llvm::Constant::getNullValue(ty)); }