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 _ejs_typedarray_new_from_array (EJSTypedArrayType element_type, ejsval arrayObj) { EJSObject *arr = EJSVAL_TO_OBJECT(arrayObj); int arrlen = EJSARRAY_LEN(arr); ejsval typedarr = _ejs_typedarray_new (element_type, arrlen); int i; void* data = _ejs_typedarray_get_data (EJSVAL_TO_OBJECT(typedarr)); // this is woefully underoptimized... for (i = 0; i < arrlen; i ++) { ejsval item = _ejs_object_getprop (arrayObj, NUMBER_TO_EJSVAL(i)); switch (element_type) { case EJS_TYPEDARRAY_INT8: ((int8_t*)data)[i] = (int8_t)EJSVAL_TO_NUMBER(item); break; case EJS_TYPEDARRAY_UINT8: ((uint8_t*)data)[i] = (uint8_t)EJSVAL_TO_NUMBER(item); break; case EJS_TYPEDARRAY_UINT8CLAMPED: EJS_NOT_IMPLEMENTED(); case EJS_TYPEDARRAY_INT16: ((int16_t*)data)[i] = (int16_t)EJSVAL_TO_NUMBER(item); break; case EJS_TYPEDARRAY_UINT16: ((uint16_t*)data)[i] = (uint16_t)EJSVAL_TO_NUMBER(item); break; case EJS_TYPEDARRAY_INT32: ((int32_t*)data)[i] = (int32_t)EJSVAL_TO_NUMBER(item); break; case EJS_TYPEDARRAY_UINT32: ((uint32_t*)data)[i] = (uint32_t)EJSVAL_TO_NUMBER(item); break; case EJS_TYPEDARRAY_FLOAT32: ((float*)data)[i] = (float)EJSVAL_TO_NUMBER(item); break; case EJS_TYPEDARRAY_FLOAT64: ((double*)data)[i] = (double)EJSVAL_TO_NUMBER(item); break; default: EJS_NOT_REACHED(); } } return typedarr; }
static ejsval _ejs_child_process_spawn (ejsval env, ejsval _this, uint32_t argc, ejsval* args) { char* argv0 = ucs2_to_utf8(EJSVAL_TO_FLAT_STRING(args[0])); EJSArray* argv_rest = (EJSArray*)EJSVAL_TO_OBJECT(args[1]); char **argv = (char**)calloc(sizeof(char*), EJSARRAY_LEN(argv_rest) + 2); argv[0] = argv0; for (uint32_t i = 0; i < EJSARRAY_LEN(argv_rest); i ++) argv[1+i] = ucs2_to_utf8(EJSVAL_TO_FLAT_STRING(ToString(EJSDENSEARRAY_ELEMENTS(argv_rest)[i]))); pid_t pid; switch (pid = fork()) { case -1: /* error */ perror("fork"); printf ("we should totally throw an exception here\n"); break; case 0: /* child */ execvp (argv0, argv); perror("execv"); EJS_NOT_REACHED(); break; default: /* parent */ { int stat; int wait_rv; do { wait_rv = waitpid(pid, &stat, 0); } while (wait_rv == -1 && errno == EINTR); if (wait_rv != pid) { perror ("waitpid"); printf ("we should totally throw an exception here\n"); } break; } } for (uint32_t i = 0; i < EJSARRAY_LEN(argv_rest)+1; i ++) free (argv[i]); free (argv); return _ejs_undefined; }
void _ejs_module_import_batch(ejsval fromImport, ejsval specifiers, ejsval toExport) { EJSObject* fromObj = EJSVAL_TO_OBJECT(fromImport); EJSObject* toObj = EJSVAL_TO_OBJECT(toExport); EJSArray* specArray = (EJSArray*)EJSVAL_TO_OBJECT(specifiers); ImportBatchData data; data.toObj = toObj; data.specifiers = EJSARRAY_LEN(specArray) == 0 ? NULL : specArray; _ejs_propertymap_foreach_property(&fromObj->map, import_batch_foreach, &data); }
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)); }
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 IRBuilder_createCall(ejsval env, ejsval _this, int argc, ejsval *args) { REQ_LLVM_VAL_ARG(0, callee); REQ_ARRAY_ARG(1, argv); FALLBACK_EMPTY_UTF8_ARG(2, name); std::vector<llvm::Value*> ArgsV; for (unsigned i = 0, e = EJSARRAY_LEN(argv); i != e; ++i) { ArgsV.push_back (Value_GetLLVMObj(EJSDENSEARRAY_ELEMENTS(argv)[i])); if (ArgsV.back() == 0) abort(); // XXX throw an exception here } return Call_new (_llvm_builder.CreateCall(callee, ArgsV, name)); }
ejsval StructType_create(ejsval env, ejsval _this, int argc, ejsval *args) { REQ_UTF8_ARG (0, name); REQ_ARRAY_ARG (1, elementTypes); std::vector<llvm::Type*> element_types; for (int i = 0; i < EJSARRAY_LEN(elementTypes); i ++) { element_types.push_back (Type_GetLLVMObj(EJSDENSEARRAY_ELEMENTS(elementTypes)[i])); } ejsval rv = StructType_new(llvm::StructType::create(llvm::getGlobalContext(), element_types, name)); free (name); return rv; }
static ejsval FunctionType_get (ejsval env, ejsval _this, int argc, ejsval *args) { REQ_LLVM_TYPE_ARG(0, returnType); REQ_ARRAY_ARG(1, argTypes); std::vector<llvm::Type*> arg_types; for (int i = 0; i < EJSARRAY_LEN(argTypes); i ++) { arg_types.push_back (Type_GetLLVMObj(EJSDENSEARRAY_ELEMENTS(argTypes)[i])); } llvm::FunctionType *FT = llvm::FunctionType::get(returnType, arg_types, false); EJSObject* result = FunctionType_alloc_instance(); _ejs_init_object (result, _ejs_FunctionType_proto, NULL); ((FunctionType*)result)->type = FT; return OBJECT_TO_EJSVAL(result); }
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); }