예제 #1
0
파일: module.cpp 프로젝트: guangwong/echojs
    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);
    }
예제 #2
0
  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));
  }
예제 #3
0
    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));
    }
예제 #4
0
    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));
    }
예제 #5
0
    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;
    }
예제 #6
0
    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);
    }
예제 #7
0
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;
}
예제 #8
0
파일: module.cpp 프로젝트: guangwong/echojs
    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);
    }
예제 #9
0
// ECMA262 15.3.4.3
static ejsval
_ejs_Function_prototype_apply (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    ejsval func = _this;

    /* 1. If IsCallable(func) is false, then throw a TypeError exception. */
    if (!EJSVAL_IS_CALLABLE(_this)) {
        printf ("throw TypeError, func is not callable\n");
        EJS_NOT_IMPLEMENTED();
    }

    ejsval thisArg = _ejs_undefined;
    ejsval argArray = _ejs_undefined;
    if (argc > 0) thisArg = args[0];
    if (argc > 1) argArray = args[1];

    /* 2. If argArray is null or undefined, then */
    if (EJSVAL_IS_UNDEFINED(argArray) || EJSVAL_IS_NULL(argArray)) {
        /*    a. Return the result of calling the [[Call]] internal method of func, providing thisArg as the this value */
        /*       and an empty list of arguments. */
        return _ejs_invoke_closure (func, thisArg, 0, NULL);
    }
    /* 3. If Type(argArray) is not Object, then throw a TypeError exception. */
    if (!EJSVAL_IS_OBJECT(argArray)) {
        printf ("throw TypeError, argArray is not an object\n");
        EJS_NOT_IMPLEMENTED();
    }
    EJSObject* argArray_ = EJSVAL_TO_OBJECT(argArray);

    /* 4. Let len be the result of calling the [[Get]] internal method of argArray with argument "length". */
    ejsval len = OP(argArray_,Get) (argArray, _ejs_atom_length, argArray);

    /* 5. Let n be ToUint32(len). */
    uint32_t n = (uint32_t)EJSVAL_TO_NUMBER(len);

    ejsval* argList;
    EJSBool argList_allocated = EJS_FALSE;

    if (EJSVAL_IS_DENSE_ARRAY(argArray)) {
        argList = EJSDENSEARRAY_ELEMENTS(argArray_);
    }
    else {
        /* 6. Let argList be an empty List. */
        argList = (ejsval*)malloc(sizeof(ejsval) * n);
        argList_allocated = EJS_TRUE;

        /* 7. Let index be 0. */
        int index = 0;

        /* 8. Repeat while index < n */
        while (index < n) {
            /*    a. Let indexName be ToString(index). */
            ejsval indexName = NUMBER_TO_EJSVAL(index);
            /*    b. Let nextArg be the result of calling the [[Get]] internal method of argArray with indexName as the  */
            /*       argument. */
            ejsval nextArg = OP(argArray_,Get)(argArray, indexName, argArray);
            /*    c. Append nextArg as the last element of argList. */
            argList[index] = nextArg;
            /*    d. Set index to index + 1. */
            ++index;
        }
    }

    /* 9. Return the result of calling the [[Call]] internal method of func, providing thisArg as the this value and */
    /*    argList as the list of arguments. */
    ejsval rv = EJSVAL_TO_FUNC(func) (EJSVAL_TO_ENV(func), thisArg, n, argList);

    if (argList_allocated)
        free (argList);
    return rv;
}