Example #1
0
size_t fixed_memory_sweep(Memory *mem) {
    Array *stack = mem->stack;
    Array *from = mem->heap;
    Array *to = from==&mem->h1 ? &mem->h2 : &mem->h1;
    Object scanned;
    size_t from_size, to_size;

    from_size = from->current - from->head;
    to->current = to->head;

    /* copy objects referenced by root set(stack-space). */
    copy_space(stack, to);

    /* to-space has gray color objects.
     * copy objects referenced by gray color objects. */
    copy_space(to, to);

    to_size = to->current - to->head;

    scanned = from->head;
    while(scanned!=from->current) {
        /* obj is garbage if TYPE(obj)!=T_FORWARD */
        if(TYPE(scanned)==T_STR) {
            free(STR_BUF(scanned));
        }
        ++scanned;
    }

    mem->heap = to;

    return from_size - to_size;
}
Example #2
0
/*
 * Copy space if exists
 */
static int
copy_space_optional(const rchar **source_, rchar **target_,
                    rcssmin_ctx_t *ctx)
{
    const rchar *source = *source_;

    if (!(source < ctx->sentinel))
        return -1;

    if (*source == U('/')) {
        *source_ = source + 1;
        return copy_space_comment(source_, target_, ctx, NEED_SPACE_NEVER);
    }
    else if (RCSSMIN_IS_SPACE(*source)) {
        *source_ = source + 1;
        copy_space(source_, target_, ctx, NEED_SPACE_NEVER);
        return 0;
    }

    return -1;
}
Example #3
0
/*
 * Copy space if comment
 */
static int
copy_space_comment(const rchar **source_, rchar **target_,
                   rcssmin_ctx_t *ctx, need_space_flag need_space)
{
    const rchar *source = *source_;
    rchar *target = *target_;

    if (source < ctx->sentinel && *source == U('*')) {
        copy_space(source_, target_, ctx, need_space);
        if (*source_ > source)
            return 0;
    }
    if (!(target < ctx->tsentinel))
        RABORT(-1);

    *target++ = source[-1];

    /* *source_ = source; <-- unchanged */
    *target_ = target;

    return -1;
}
Example #4
0
/*
 * Main function
 *
 * The return value determines the result length (kept in the target buffer).
 * However, if the target buffer is too small, the return value is greater
 * than tlength. The difference to tlength is the number of unconsumed source
 * characters at the time the buffer was full. In this case you should resize
 * the target buffer to the return value and call rcssmin again. Repeat as
 * often as needed.
 */
static Py_ssize_t
rcssmin(const rchar *source, rchar *target, Py_ssize_t slength,
        Py_ssize_t tlength, int keep_bang_comments)
{
    rcssmin_ctx_t ctx_, *ctx = &ctx_;
    const rchar *tstart = target;
    rchar c;

    ctx->start = source;
    ctx->sentinel = source + slength;
    ctx->tsentinel = target + tlength;
    ctx->at_group = 0;
    ctx->in_macie5 = 0;
    ctx->in_rule = 0;
    ctx->keep_bang_comments = keep_bang_comments;

    while (source < ctx->sentinel && target < ctx->tsentinel) {
        c = *source++;
        if (RCSSMIN_IS_DULL(c)) {
            *target++ = c;
            continue;
        }
        else if (RCSSMIN_IS_SPACE(c)) {
            copy_space(&source, &target, ctx, NEED_SPACE_MAYBE);
            continue;
        }

        switch (c) {

        /* Escape */
        case U('\\'):
            copy_escape(&source, &target, ctx);
            continue;

        /* String */
        case U('"'): case U('\''):
            copy_string(&source, &target, ctx);
            continue;

        /* URL */
        case U('u'):
            copy_url(&source, &target, ctx);
            continue;

        /* IE7hack */
        case U('>'):
            copy_ie7hack(&source, &target, ctx);
            continue;

        /* @-group */
        case U('@'):
            copy_at_group(&source, &target, ctx);
            continue;

        /* ; */
        case U(';'):
            copy_semicolon(&source, &target, ctx);
            continue;

        /* :first-line|letter followed by [{,] */
        /* (apparently needed for IE6) */
        case U(':'):
            copy_first(&source, &target, ctx);
            continue;

        /* { */
        case U('{'):
            if (ctx->at_group)
                --ctx->at_group;
            else
                ++ctx->in_rule;
            *target++ = c;
            continue;

        /* } */
        case U('}'):
            if (ctx->in_rule)
                --ctx->in_rule;
            *target++ = c;
            continue;

        /* space starting with comment */
        case U('/'):
            (void)copy_space_comment(&source, &target, ctx, NEED_SPACE_MAYBE);
            continue;

        /* Fallback: copy character. Better safe than sorry. Should not be
         * reached, though */
        default:
            *target++ = c;
            continue;
        }
    }

    return
        (Py_ssize_t)(target - tstart) + (Py_ssize_t)(ctx->sentinel - source);
}