Exemple #1
0
void hlt_execution_context_delete(hlt_execution_context* ctx)
{
    hlt_exception* excpt = 0;

    // Do this first, it may still need the context.
    hlt_timer_mgr_expire(ctx->tmgr, 0, &excpt, ctx);
    GC_DTOR(ctx->tmgr, hlt_timer_mgr, ctx);

    __hlt_globals_dtor(ctx);

    GC_DTOR(ctx->excpt, hlt_exception, ctx);

    if ( ctx->fiber )
        hlt_fiber_delete(ctx->fiber, ctx);

    if ( ctx->pstate )
        __hlt_profiler_state_delete(ctx->pstate);

    if ( ctx->tcontext ) {
        GC_DTOR_GENERIC(&ctx->tcontext, ctx->tcontext_type, ctx);
    }

    __hlt_fiber_pool_delete(ctx->fiber_pool);

    if ( ctx->nullbuffer )
        __hlt_memory_nullbuffer_delete(ctx->nullbuffer, ctx);

    hlt_free(ctx);
}
Exemple #2
0
static void __dtor_state(__parser_state* state, hlt_execution_context* ctx)
{
    for ( ; state; state = state->next ) {
        GC_DTOR(state->parser, hlt_BinPACHilti_Parser, ctx);
        GC_DTOR_GENERIC(&state->pobj, state->parser->type_info, ctx);
        GC_DTOR(state->data, hlt_bytes, ctx);
        GC_DTOR(state->resume, hlt_exception, ctx);
    }
}
Exemple #3
0
static void __finish_parser(binpac_sink* sink, __parser_state* state, hlt_exception** excpt, hlt_execution_context* ctx)
{
    if ( state->data && state->resume ) {
        hlt_bytes_freeze(state->data, 1, excpt, ctx);

        // TODO: Not sure if we need this wrapping with fiber/excpt here
        // (neither in main write function).
        hlt_fiber* saved_fiber = ctx->fiber;
        ctx->fiber = 0;
        hlt_exception* sink_excpt = 0;

        // We may trigger a safepoint so make sure we refcount our locoal.
        GC_CCTOR(sink, binpac_sink, ctx);
        __cctor_state(state, ctx);

        (state->parser->resume_func_sink)(state->resume, &sink_excpt, ctx);

        GC_DTOR(sink, binpac_sink, ctx);
        __dtor_state(state, ctx);

        GC_CLEAR(state->resume, hlt_exception, ctx);
        __hlt_context_clear_exception(ctx);
        ctx->fiber = saved_fiber;

        // TODO: Not quite sure why the yield exception can occur here, but
        // we ignore it.
        //
        // Update: Actually I think I do: when two separate filters (like
        // first for a sink and then for the unit connected to it) filter the
        // same data, the frozen flags doesn't get propagated.
        //
        // We forbid that for now and hope it won't be used ...
        //
        // sink-unit-filter.pac2 tests for this but is currently disabled ...
        if ( sink_excpt && sink_excpt->type == &hlt_exception_yield ) {
            assert(false);
        }

        else if ( sink_excpt && sink_excpt->type == &binpac_exception_parserdisabled ) {
            // Disabled, nothing to do.
            DBG_LOG("binpac-sinks", "- final writing to sink %p disabled for parser %p", sink, state->pobj);
            GC_DTOR(sink_excpt, hlt_exception, ctx);
        }

        else
            *excpt = sink_excpt;
    }

    __unlink_state(sink, state, ctx);
}
Exemple #4
0
int __spicy_global_state_done()
{
    if ( ! __globals->initialized )
        return 0;

    if ( __globals->finished )
        return 0;

    GC_DTOR(__globals->parsers, hlt_list, hlt_global_execution_context());
    GC_DTOR(__globals->mime_types, hlt_map, hlt_global_execution_context());

    __globals->finished = 1;

    return 1;
}
Exemple #5
0
int main()
{
    hlt_execution_context* ctx = 0;
    hlt_exception* excpt = 0;
    hlt_string s;

    hlt_init();
    ctx = hlt_global_execution_context();

    hlt_port a;

    a = hlt_port_from_asciiz("80/tcp", &excpt, ctx);
    s = hlt_object_to_string(&hlt_type_info_hlt_port, &a, 0, &excpt, ctx);
    hlt_string_print(stdout, s, 1, &excpt, ctx);
    assert(! excpt);

    a = hlt_port_from_asciiz("53/udp", &excpt, ctx);
    s = hlt_object_to_string(&hlt_type_info_hlt_port, &a, 0, &excpt, ctx);
    hlt_string_print(stdout, s, 1, &excpt, ctx);
    assert(! excpt);

    a = hlt_port_from_asciiz("can't parse", &excpt, ctx);
    assert(excpt);

    GC_DTOR(excpt, hlt_exception, ctx);

    return 0;
}
Exemple #6
0
void hlt_match_token_state_dtor(hlt_type_info* ti, hlt_match_token_state* t, hlt_execution_context* ctx)
{
    if ( t->re )
        // Will be set to zero once match_state_done is called.
        jrx_match_state_done(&t->ms);

    GC_DTOR(t->re, hlt_regexp, ctx);
}
Exemple #7
0
void binpachilti_sink_add_filter(binpac_sink* sink, hlt_enum ftype, hlt_exception** excpt, hlt_execution_context* ctx)
{
    binpac_filter* old_filter = sink->filter;
    sink->filter = binpachilti_filter_add(sink->filter, ftype, excpt, ctx);
    GC_CCTOR(sink->filter, binpac_filter, ctx);
    GC_DTOR(old_filter, binpac_filter, ctx);

    DBG_LOG("binpac-sinks", "attached filter %s to sink %p", sink->filter->def->name, sink);
}
Exemple #8
0
void hlt_regexp_dtor(hlt_type_info* ti, hlt_regexp* re, hlt_execution_context* ctx)
{
    for ( int i = 0; i < re->num; i++ )
        GC_DTOR(re->patterns[i], hlt_string, ctx);

    hlt_free(re->patterns);

    if ( re->num > 0 )
        jrx_regfree(&re->regexp);
}
Exemple #9
0
static void __connect_one(binpac_sink* sink, hlt_bytes* mtype, hlt_bytes* mtype_full, int8_t try_mode, void* cookie, hlt_exception** excpt, hlt_execution_context* ctx)
{
    if ( ! __binpac_globals_get()->mime_types )
        return;

    __mime_parser** current = hlt_map_get_default(__binpac_globals_get()->mime_types, &hlt_type_info_hlt_bytes, &mtype, &hlt_type_info___mime_parser, 0, excpt, ctx);

    if ( ! current )
        return;

    __mime_parser* mparser = *current;
    for ( __mime_parser* mp = mparser; mp; mp = mp->next ) {
        assert(mp->parser->new_func);

        // The C stub for the ctor function may mess with our yield/resume
        // information. We need to restore that afterwards.
        hlt_fiber* saved_fiber = ctx->fiber;
        __hlt_thread_mgr_blockable* saved_blockable = ctx->blockable;

        // We may trigger a safepoint so make sure we refcount our locoal.
        GC_CCTOR(sink, binpac_sink, ctx);
        GC_CCTOR(mtype, hlt_bytes, ctx);
        GC_CCTOR(mtype_full, hlt_bytes, ctx);

        void* pobj = mp->parser->new_func(sink, mtype, try_mode, cookie, excpt, ctx);
        assert(pobj);

        GC_DTOR(sink, binpac_sink, ctx);
        GC_DTOR(mtype, hlt_bytes, ctx);
        GC_DTOR(mtype_full, hlt_bytes, ctx);

        ctx->fiber = saved_fiber;
        ctx->blockable = saved_blockable;

        _binpachilti_sink_connect_intern(sink, mp->parser->type_info, &pobj, mp->parser, mtype_full, excpt, ctx);
    }
}
Exemple #10
0
static void __add_parser(hlt_bytes* mt, binpac_parser* parser, hlt_exception** excpt, hlt_execution_context* ctx)
{
    __mime_parser* mp = GC_NEW_REF(__mime_parser, ctx);
    GC_INIT(mp->parser, parser, hlt_BinPACHilti_Parser, ctx);
    mp->next = 0;

    // Deep-copy the pointers, the map needs that.

    __mime_parser** cmp = hlt_malloc(sizeof(__mime_parser*));
    hlt_bytes**     cmt = hlt_malloc(sizeof(hlt_bytes*));
    *cmt = mt;
    *cmp = mp;

    __mime_parser** current = hlt_map_get_default(__binpac_globals_get()->mime_types, &hlt_type_info_hlt_bytes, cmt, &hlt_type_info___mime_parser, 0, excpt, ctx);

    if ( current ) {
        mp->next = *current;
        GC_CCTOR(mp->next, __mime_parser, ctx);
    }

    hlt_map_insert(__binpac_globals_get()->mime_types, &hlt_type_info_hlt_bytes, cmt, &hlt_type_info___mime_parser, cmp, excpt, ctx);

    GC_DTOR(mp, __mime_parser, ctx);

    hlt_free(cmp);
    hlt_free(cmt);

#ifdef DEBUG
    hlt_string s = hlt_string_decode(mt, Hilti_Charset_ASCII, excpt, ctx);

    char* r1 = hlt_string_to_native(s, excpt, ctx);
    char* r2 = hlt_string_to_native(parser->name, excpt, ctx);

    DBG_LOG("binpac-sinks", "MIME type %s registered for parser %s", r1, r2);

    hlt_free(r1);
    hlt_free(r2);
#endif
}
Exemple #11
0
static int8_t __deliver_chunk(binpac_sink* sink, hlt_bytes* data, uint64_t rseq, uint64_t rupper, void* user, hlt_exception** excpt, hlt_execution_context* ctx)
{
    if ( ! data ) {
        // A gap.
        DBG_LOG("binpac-sinks", "hit gap with sink %p at rseq %" PRIu64, sink, rseq);

        if ( sink->cur_rseq != rupper ) {
            __report_gap(sink, rseq, (rupper - rseq), user, excpt, ctx);
            sink->cur_rseq = rupper;

            if ( sink->auto_trim )
                // We trim just up to the gap here, excluding the gap itself. This
                // will prevent future data beyond the gap from being delivered until
                // we explicitly skip over it.
                __trim(sink, rseq, user, excpt, ctx);
        }

        return 0;
    }

    DBG_LOG("binpac-sinks", "starting to deliver to sink %p at rseq %" PRIu64, sink, rseq);

    // If the HILTI function that we'll call suspends, it will change the
    // yield/resume fields. We need to reset them when we leave this
    // function.

    hlt_fiber* saved_fiber = ctx->fiber;
    __hlt_thread_mgr_blockable* saved_blockable = ctx->blockable;

    ctx->fiber = 0;
    ctx->blockable = 0;

    binpac_dbg_deliver(sink, data, 0, excpt, ctx);

    if ( sink->filter ) {
        hlt_bytes* decoded = binpachilti_filter_decode(sink->filter, data, excpt, ctx); // &noref!

        if ( ! decoded )
            goto exit;

        data = decoded;
    }

    sink->size += hlt_bytes_len(data, excpt, ctx);

    if ( *excpt )
        goto exit;

    if ( ! sink->head ) {
        DBG_LOG("binpac-sinks", "done delivering to sink %p, no parser connected", sink);
        goto exit;
    }

    // data at +1 here.

    __parser_state* s = sink->head;

    // Now pass it onto parsers.
    while ( s ) {

        if ( s->disconnected )
            continue;

        hlt_exception* sink_excpt = 0;

        if ( ! s->data ) {
            // First chunk.
            DBG_LOG("binpac-sinks", "- start delivering to sink %p for parser %p", sink, s->pobj);
            s->data = hlt_bytes_copy(data, excpt, ctx);
            GC_CCTOR(s->data, hlt_bytes, ctx);

            if ( hlt_bytes_is_frozen(data, excpt, ctx) )
                hlt_bytes_freeze(s->data, 1, excpt, ctx);

            // We may trigger a safepoint so make sure we refcount our locoal.
            GC_CCTOR(sink, binpac_sink, ctx);
            GC_CCTOR(data, hlt_bytes, ctx);
            __cctor_state(s, ctx);

            (s->parser->parse_func_sink)(s->pobj, s->data, user, &sink_excpt, ctx);

            GC_DTOR(sink, binpac_sink, ctx);
            GC_DTOR(data, hlt_bytes, ctx);
            __dtor_state(s, ctx);
        }

        else {
            if ( ! s->resume ) {
                // Parsing has already finished for this parser. We ignore this here,
                // as otherwise we'd have to throw an exception and thus abort the
                // other parsers as well.
                s = s->next;
                continue;
            }

            DBG_LOG("binpac-sinks", "- resuming delivering to sink %p for parser %p", sink, s->pobj);

            // Subsequent chunk, resume.
            hlt_bytes_append(s->data, data, excpt, ctx);

            if ( hlt_bytes_is_frozen(data, excpt, ctx) )
                hlt_bytes_freeze(s->data, 1, excpt, ctx);

            // We may trigger a safepoint so make sure we refcount our locoal.
            GC_CCTOR(sink, binpac_sink, ctx);
            GC_CCTOR(data, hlt_bytes, ctx);
            __cctor_state(s, ctx);

            (s->parser->resume_func_sink)(s->resume, &sink_excpt, ctx);

            GC_DTOR(sink, binpac_sink, ctx);
            GC_DTOR(data, hlt_bytes, ctx);
            __dtor_state(s, ctx);

            GC_CLEAR(s->resume, hlt_exception, ctx);
        }

        // Clear any left-over exceptions.
        __hlt_context_clear_exception(ctx);

        if ( sink_excpt && sink_excpt->type == &hlt_exception_yield ) {
            // Suspended.
            DBG_LOG("binpac-sinks", "- delivering to sink %p suspended for parser %p", sink, s->pobj);
            GC_CCTOR(sink_excpt, hlt_exception, ctx);
            s->resume = sink_excpt;
            s = s->next;
            sink_excpt = 0;
        }

        else if ( sink_excpt && sink_excpt->type == &binpac_exception_parserdisabled ) {
            // Disabled
            DBG_LOG("binpac-sinks", "- writing to sink %p disabled for parser %p", sink, s->pobj);
            GC_DTOR(sink_excpt, hlt_exception, ctx);
            sink_excpt = 0;
            __parser_state* next = s->next;
            // This guy is finished, remove.
            __unlink_state(sink, s, ctx);
            s = next;
        }

        else {
            DBG_LOG("binpac-sinks", "- delivering to sink %p finished for parser %p", sink, s->pobj);
            __parser_state* next = s->next;
            // This guy is finished, remove.
            __unlink_state(sink, s, ctx);
            s = next;
        }

        if ( sink_excpt ) {
            // Error, abort.
            *excpt = sink_excpt;
            goto exit;
        }
    }

    // Savely delete disconnected parsers.

    int done = 0;

    while ( ! done ) {
        done = 1;
        for ( __parser_state* s = sink->head; s; s = s->next ) {
            if ( s->disconnected ) {
                // We ignore parse error triggered by the disconnect.
                hlt_exception* ignore_excpt = 0;
                __finish_parser(sink, s, &ignore_excpt, ctx);

                if ( ignore_excpt )
                    GC_DTOR(ignore_excpt, hlt_exception, ctx);

                done = 0;
                break;
            }
        }
    }

exit:
    ctx->fiber = saved_fiber;
    ctx->blockable = saved_blockable;

    sink->cur_rseq = rupper;
    sink->last_reassem_rseq = rupper;

    if ( sink->auto_trim )
        __trim(sink, rupper, user, excpt, ctx);

    DBG_LOG("binpac-sinks", "done delivering to sink %p", sink);

    return 1;
}
Exemple #12
0
static void __delete_chunk(__chunk* c, hlt_exception** excpt, hlt_execution_context* ctx)
{
    GC_DTOR(c->data, hlt_bytes, ctx);
    hlt_free(c);
}
Exemple #13
0
void __binpac_globals_done()
{
    assert(_globals);
    GC_DTOR(_globals->parsers, hlt_list, hlt_global_execution_context());
    GC_DTOR(_globals->mime_types, hlt_map, hlt_global_execution_context());
}