Exemplo n.º 1
0
DUK_EXTERNAL void duk_dump_function(duk_context *ctx) {
	duk_hthread *thr;
	duk_hcompiledfunction *func;
	duk_bufwriter_ctx bw_ctx_alloc;
	duk_bufwriter_ctx *bw_ctx = &bw_ctx_alloc;
	duk_uint8_t *p;

	DUK_ASSERT(ctx != NULL);
	thr = (duk_hthread *) ctx;

	/* Bound functions don't have all properties so we'd either need to
	 * lookup the non-bound target function or reject bound functions.
	 * For now, bound functions are rejected.
	 */
	func = duk_require_hcompiledfunction(ctx, -1);
	DUK_ASSERT(func != NULL);
	DUK_ASSERT(!DUK_HOBJECT_HAS_BOUND(&func->obj));

	/* Estimating the result size beforehand would be costly, so
	 * start with a reasonable size and extend as needed.
	 */
	DUK_BW_INIT_PUSHBUF(thr, bw_ctx, DUK__BYTECODE_INITIAL_ALLOC);
	p = DUK_BW_GET_PTR(thr, bw_ctx);
	*p++ = DUK__SER_MARKER;
	*p++ = DUK__SER_VERSION;
	p = duk__dump_func(ctx, func, bw_ctx, p);
	DUK_BW_SET_PTR(thr, bw_ctx, p);
	DUK_BW_COMPACT(thr, bw_ctx);

	DUK_DD(DUK_DDPRINT("serialized result: %!T", duk_get_tval(ctx, -1)));

	duk_remove(ctx, -2);  /* [ ... func buf ] -> [ ... buf ] */
}
DUK_LOCAL void duk__create_escaped_source(duk_hthread *thr, int idx_pattern) {
    duk_context *ctx = (duk_context *) thr;
    duk_hstring *h;
    const duk_uint8_t *p;
    duk_bufwriter_ctx bw_alloc;
    duk_bufwriter_ctx *bw;
    duk_uint8_t *q;
    duk_size_t i, n;
    duk_uint_fast8_t c_prev, c;

    h = duk_get_hstring(ctx, idx_pattern);
    DUK_ASSERT(h != NULL);
    p = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);
    n = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h);

    if (n == 0) {
        /* return '(?:)' */
        duk_push_hstring_stridx(ctx, DUK_STRIDX_ESCAPED_EMPTY_REGEXP);
        return;
    }

    bw = &bw_alloc;
    DUK_BW_INIT_PUSHBUF(thr, bw, n);
    q = DUK_BW_GET_PTR(thr, bw);

    c_prev = (duk_uint_fast8_t) 0;

    for (i = 0; i < n; i++) {
        c = p[i];

        q = DUK_BW_ENSURE_RAW(thr, bw, 2, q);

        if (c == (duk_uint_fast8_t) '/' && c_prev != (duk_uint_fast8_t) '\\') {
            /* Unescaped '/' ANYWHERE in the regexp (in disjunction,
             * inside a character class, ...) => same escape works.
             */
            *q++ = DUK_ASC_BACKSLASH;
        }
        *q++ = (duk_uint8_t) c;

        c_prev = c;
    }

    DUK_BW_SETPTR_AND_COMPACT(thr, bw, q);
    duk_to_string(ctx, -1);  /* -> [ ... escaped_source ] */
}