Exemplo n.º 1
0
static PageInfo*
alloc_page_from_arena(Arena *arena, size_t cell_size)
{
    void *page_data = (void*)ALIGN(arena->pos, PAGE_SIZE);
    if (arena->free_pages) {
        PageInfo* info = arena->free_pages;
        EJS_LIST_DETACH(info, arena->free_pages);
        info->cell_size = cell_size;
        info->num_cells = CELLS_OF_SIZE(cell_size);
        info->num_free_cells = info->num_cells;
        info->bump_ptr = info->page_start;
        memset (info->page_bitmap, CELL_FREE, info->num_cells * sizeof(BitmapCell));
        SPEW(3, _ejs_log ("alloc_page_from_arena from free pages for cell size %zd = %p\n", info->cell_size, info));
        return info;
    }
    else if (page_data < arena->end) {
        PageInfo* info = alloc_page_info_from_arena (arena, page_data, cell_size);
        int page_idx = arena->num_pages++;
        arena->pos = page_data + PAGE_SIZE;
        arena->pages[page_idx] = page_data;
        arena->page_infos[page_idx] = info;
        SPEW(3, _ejs_log ("alloc_page_from_arena from bump pointer for cell size %zd = %p\n", info->cell_size, info));
        return info;
    }
    else {
        return NULL;
    }
}
Exemplo n.º 2
0
ejsval
_ejs_invoke_closure (ejsval closure, ejsval _this, uint32_t argc, ejsval* args)
{
    if (!EJSVAL_IS_FUNCTION(closure)) {
#if DEBUG_LAST_LOOKUP
        extern jschar* last_lookup;
        if (last_lookup) {
            char *last_utf8 = ucs2_to_utf8(last_lookup);
            _ejs_log ("last property lookup was for: %s\n", last_utf8);
            free (last_utf8);
        }
#endif
        
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "object not a function");
    }

#if 0
    if (!EJSVAL_IS_NULL_OR_UNDEFINED(_this) && EJSVAL_IS_PRIMITIVE(_this)) {
        _this = ToObject(_this);
    }
#endif

    EJSFunction *fun = (EJSFunction*)EJSVAL_TO_OBJECT(closure);
    return fun->func (fun->env, _this, argc, args);
}
Exemplo n.º 3
0
void
_ejs_throw_nativeerror_utf8 (EJSNativeErrorType error_type, const char *message)
{
    ejsval exc = _ejs_nativeerror_new_utf8 (error_type, message);
    _ejs_log ("throwing exception with message %s\n", message);
    _ejs_throw (exc);
    EJS_NOT_REACHED();
}
Exemplo n.º 4
0
static ejsval
_ejs_DataView_impl (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    if (EJSVAL_IS_UNDEFINED(_this)) {
        _ejs_log ("DataView called as a function\n");
        EJS_NOT_IMPLEMENTED();
    }

    if (argc == 0 || !EJSVAL_IS_ARRAYBUFFER(args[0])) {
        _ejs_log ("arg0 not an ArrayBuffer object\n");
        EJS_NOT_IMPLEMENTED();
    }

    EJSDataView* view = (EJSDataView*)EJSVAL_TO_OBJECT(_this);
    EJSArrayBuffer* buff = (EJSArrayBuffer*)EJSVAL_TO_OBJECT(args[0]);

    uint32_t offset;
    uint32_t len;

    switch (argc) {
    case 1:
        offset = 0;
        len = buff->size;
        break;
    case 2:
        offset = EJSVAL_TO_NUMBER(args[1]);
        len = buff->size - offset;
        break;
    default:
        offset = EJSVAL_TO_NUMBER(args[1]);
        len = EJSVAL_TO_NUMBER(args[2]);
    }

    view->buffer = args[0];
    view->byteOffset = offset;
    view->byteLength = len;

    _ejs_object_define_value_property (_this, _ejs_atom_byteLength, DOUBLE_TO_EJSVAL_IMPL(view->byteLength), EJS_PROP_FLAGS_ENUMERABLE);
    _ejs_object_define_value_property (_this, _ejs_atom_byteOffset, DOUBLE_TO_EJSVAL_IMPL(view->byteOffset), EJS_PROP_FLAGS_ENUMERABLE);
    _ejs_object_define_value_property (_this, _ejs_atom_buffer, view->buffer, EJS_PROP_FLAGS_ENUMERABLE);

    return _this;
}
Exemplo n.º 5
0
static void*
alloc_from_os(size_t size, size_t align)
{
#if defined(WIN32)
    void *ptr = _aligned_malloc(size, align);
    memset((void *)ptr, 0x00, size);
    return ptr;
#else
    if (align == 0) {
        size = MAX(size, PAGE_SIZE);
        void* res = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, MAP_FD, 0);
        SPEW(2, _ejs_log ("mmap for 0 alignment = %p\n", res));
        return res == MAP_FAILED ? NULL : res;
    }

    void* res = mmap(NULL, size*2, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, MAP_FD, 0);
    if (res == MAP_FAILED) {
        return NULL;
    }

    SPEW(2, _ejs_log ("mmap returned %p\n", res));

    if (((uintptr_t)res % align) == 0) {
        // the memory was aligned, unmap the second half of our mapping
        // XXX should we just rejoice and add both halves?
        SPEW(2, _ejs_log ("already aligned\n"));
        munmap ((char *)res + size, size);
    }
    else {
        SPEW(2, _ejs_log ("not aligned\n"));
        // align res, and unmap the areas before/after the new mapping
        void *aligned_res = (void*)ALIGN(res, align);
        // the area before
        munmap (res, (uintptr_t)aligned_res - (uintptr_t)res);
        // the area after
        munmap ((char *)aligned_res+size, (uintptr_t)res+size*2 - (uintptr_t)((char *)aligned_res+size));
        res = aligned_res;
        SPEW(2, _ejs_log ("aligned ptr = %p\n", res));
    }
    return res;
#endif
}
Exemplo n.º 6
0
void
_ejs_throw_nativeerror (EJSNativeErrorType error_type, ejsval message)
{
    ejsval exc = _ejs_nativeerror_new (error_type, message);

    char *message_utf8 = ucs2_to_utf8(EJSVAL_TO_FLAT_STRING(message));
    _ejs_log ("throwing exception with message %s\n", message_utf8);
    free (message_utf8);

    _ejs_throw (exc);
    EJS_NOT_REACHED();
}
Exemplo n.º 7
0
static void
finalize_object(GCObjectPtr p)
{
    GCObjectHeader* headerp = (GCObjectHeader*)p;
    if ((*headerp & EJS_SCAN_TYPE_OBJECT) != 0) {
        SPEW(2, _ejs_log ("finalizing object %p(%s)\n", p, CLASSNAME(p)));
        OP(p, finalize)((EJSObject*)p);
    }
    else if ((*headerp & EJS_SCAN_TYPE_CLOSUREENV) != 0) {
        SPEW(2, _ejs_log ("finalizing closureenv %p\n", p));
    }
    else if ((*headerp & EJS_SCAN_TYPE_PRIMSTR) != 0) {
        SPEW(1, {
                EJSPrimString* primstr = (EJSPrimString*)p;
                if (EJS_PRIMSTR_GET_TYPE(primstr) == EJS_STRING_FLAT) {
                    char* utf8 = ucs2_to_utf8(primstr->data.flat);
                    SPEW(2, _ejs_log ("finalizing flat primitive string %p(%s)\n", p, utf8));
                    free (utf8);
                }
                else {
                    SPEW(2, _ejs_log ("finalizing primitive string %p\n", p));
                }
            });
Exemplo n.º 8
0
static PageInfo*
alloc_new_page(size_t cell_size)
{
    SPEW(2, _ejs_log ("allocating new page for cell size %zd\n", cell_size));
    PageInfo *rv = NULL;
    for (int i = 0; i < num_arenas; i ++) {
        rv = alloc_page_from_arena(heap_arenas[i], cell_size);
        if (rv) {
            SPEW(2, _ejs_log ("  => %p", rv));
            return rv;
        }
    }

    // need a new arena
    SPEW(2, _ejs_log ("unable to find page in current arenas, allocating a new one"));
    LOCK_ARENAS();
    Arena* arena = arena_new();
    UNLOCK_ARENAS();
    if (arena == NULL)
        return NULL;
    rv = alloc_page_from_arena(arena, cell_size);
    SPEW(2, _ejs_log ("  => %p", rv));
    return rv;
}
Exemplo n.º 9
0
void _ejs_exception_throw(ejsval val)
{
    struct ejs_exception *exc =
        (struct ejs_exception*)__cxa_allocate_exception(sizeof(struct ejs_exception));

    exc->val = val;
    // need to root the exception until it's caught
    _ejs_gc_add_root(&exc->val);

    exc->tinfo = EJS_EHTYPE_ejsvalue;

    SPEW({
        _ejs_log ("EXCEPTIONS: throwing %p\n", exc);
        _ejs_dump_value (val);
    });
Exemplo n.º 10
0
static ejsval
_ejs_require_impl (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    if (argc < 1) {
        return _ejs_undefined;
    }

    ejsval arg = args[0];

    if (!EJSVAL_IS_STRING(arg)) {
        _ejs_log ("required called with non-string\n");
        return _ejs_null;
    }

    return _ejs_module_get(arg);
}
Exemplo n.º 11
0
_Unwind_Reason_Code
EJS_PERSONALITY(int version,
                _Unwind_Action actions,
                uint64_t exceptionClass,
                struct _Unwind_Exception *exceptionObject,
                struct _Unwind_Context *context)
{
    //SPEW(_ejs_log ("EXCEPTIONS: %s through frame [ip=%p sp=%p] "
    SPEW(_ejs_log ("EXCEPTIONS: through frame [ip=%p sp=%p] "
                   "for exception %p\n",
                   (void*)(_Unwind_GetIP(context)-1),
                   (void*)_Unwind_GetCFA(context), exceptionObject));

    // Let C++ handle the unwind itself.
    return CXX_PERSONALITY(version, actions, exceptionClass,
                           exceptionObject, context);
}
Exemplo n.º 12
0
ejsval
_ejs_invoke_closure (ejsval closure, ejsval _this, uint32_t argc, ejsval* args)
{
    if (!EJSVAL_IS_FUNCTION(closure)) {
#if DEBUG_LAST_LOOKUP
        extern jschar* last_lookup;
        if (last_lookup) {
            char *last_utf8 = ucs2_to_utf8(last_lookup);
            _ejs_log ("last property lookup was for: %s\n", last_utf8);
            free (last_utf8);
        }
#endif
        
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "object not a function");
    }

    if (!EJSVAL_IS_NULL_OR_UNDEFINED(_this) && EJSVAL_IS_PRIMITIVE(_this)) {
        _this = ToObject(_this);
    }

    EJSFunction *fun = (EJSFunction*)EJSVAL_TO_OBJECT(closure);
    return fun->func (fun->env, _this, argc, args);

#if not_anymore

    if (fun->bound_argc > 0) {
        ejsval* new_args = (ejsval*)malloc(sizeof(ejsval) * (fun->bound_argc + argc));
        memmove (new_args, fun->bound_args, sizeof(ejsval) * fun->bound_argc);
        memmove (&new_args[fun->bound_argc], args, argc);
        args = new_args;
        argc += fun->bound_argc;
    }

    DEBUG_FUNCTION_ENTER (closure);
    ejsval rv = fun->func (fun->env, fun->bound_this, argc, args);
    DEBUG_FUNCTION_EXIT (closure);

    if (fun->bound_argc > 0)
        free (args);
    return rv;
#endif
}
Exemplo n.º 13
0
ejsval
_ejs_module_get (ejsval arg)
{
    char* arg_utf8 = _ejs_string_to_utf8(EJSVAL_TO_STRING(arg));

    ejsval module EJSVAL_ALIGNMENT;
    if (require_builtin_module (arg_utf8, &module)) {
        free (arg_utf8);
        return module;
    }
    if (require_external_module (arg_utf8, &module)) {
        free (arg_utf8);
        return module;
    }
    if (require_user_module (arg_utf8, &module)) {
        free (arg_utf8);
        return module;
    }
    _ejs_log ("require('%s') failed: module not included in build.\n", arg_utf8);
    free(arg_utf8);
    return _ejs_null;
}
Exemplo n.º 14
0
static Arena*
arena_new()
{
    if (num_arenas == MAX_ARENAS-1)
        return NULL;

    SPEW(1, _ejs_log ("num_arenas = %d, max = %d\n", num_arenas, MAX_ARENAS));

    void* arena_start = alloc_from_os(ARENA_SIZE, ARENA_SIZE);
    if (arena_start == NULL)
        return NULL;

    Arena* new_arena = arena_start;

    memset (new_arena, 0, sizeof(Arena));

    new_arena->end = arena_start + ARENA_SIZE;
    new_arena->pos = (void*)ALIGN(arena_start + sizeof(Arena), PAGE_SIZE);

    LOCK_ARENAS();
    int insert_point = -1;
    for (int i = 0; i < num_arenas; i ++) {
        if (new_arena < heap_arenas[i]) {
            insert_point = i;
            break;
        }
    }
    if (insert_point == -1) insert_point = num_arenas;
    if (num_arenas-insert_point > 0)
        memmove (&heap_arenas[insert_point + 1], &heap_arenas[insert_point], (num_arenas-insert_point-1)*sizeof(Arena*));
    heap_arenas[insert_point] = new_arena;
    num_arenas++;
    UNLOCK_ARENAS();

    return new_arena;
}
Exemplo n.º 15
0
ejsval
_ejs_regexp_replace(ejsval str, ejsval search_re, ejsval replace)
{
    EJSRegExp* re = (EJSRegExp*)EJSVAL_TO_OBJECT(search_re);

    pcre16_extra extra;
    memset (&extra, 0, sizeof(extra));

    pcre16* code = (pcre16*)re->compiled_pattern;

    int capture_count;
    pcre16_fullinfo (code, NULL, PCRE_INFO_CAPTURECOUNT, &capture_count);

    int ovec_count = 3 * (1 + capture_count);
    int* ovec = malloc(sizeof(int) * ovec_count);
    int cur_off = 0;

    do {
        EJSPrimString *flat_str = _ejs_string_flatten (str);
        jschar *chars_str = flat_str->data.flat;

        int rv = pcre16_exec(code, &extra,
                             chars_str, flat_str->length, cur_off,
                             PCRE_NO_UTF16_CHECK, ovec, ovec_count);

        if (rv < 0)
            break;

        ejsval replaceval;

        if (EJSVAL_IS_FUNCTION(replace)) {
            ejsval substr_match = _ejs_string_new_substring (str, ovec[0], ovec[1] - ovec[0]);
            ejsval capture = _ejs_string_new_substring (str, ovec[2], ovec[3] - ovec[2]);

            _ejs_log ("substring match is %s\n", ucs2_to_utf8(_ejs_string_flatten(substr_match)->data.flat));
            _ejs_log ("capture is %s\n", ucs2_to_utf8(_ejs_string_flatten(capture)->data.flat));

            int argc = 3;
            ejsval args[3];

            args[0] = substr_match;
            args[1] = capture;
            args[2] = _ejs_undefined;

            replaceval = ToString(_ejs_invoke_closure (replace, _ejs_undefined, argc, args));
        }
        else {
            replaceval = ToString(replace);
        }

        if (ovec[0] == 0) {
            // we matched from the beginning of the string, so nothing from there to prepend
            str = _ejs_string_concat (replaceval, _ejs_string_new_substring (str, ovec[1], flat_str->length - ovec[1]));
        }
        else {
            str = _ejs_string_concatv (_ejs_string_new_substring (str, 0, ovec[0]),
                                       replaceval,
                                       _ejs_string_new_substring (str, ovec[1], flat_str->length - ovec[1]),
                                       _ejs_null);
        }

        cur_off = ovec[1];

        // if the RegExp object was created without a 'g' flag, only replace the first match
        if (!re->global)
            break;
    } while (EJS_TRUE);

    free (ovec);
    return str;
}