Пример #1
0
DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_exec(duk_hthread *thr) {
	duk__get_this_regexp(thr);

	/* [ regexp input ] */

	duk_regexp_match(thr);

	/* [ result ] */

	return 1;
}
Пример #2
0
DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_exec(duk_context *ctx) {
	duk__get_this_regexp(ctx);

	/* [ regexp input ] */

	duk_regexp_match((duk_hthread *) ctx);

	/* [ result ] */

	return 1;
}
Пример #3
0
DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_test(duk_hthread *thr) {
	duk__get_this_regexp(thr);

	/* [ regexp input ] */

	/* result object is created and discarded; wasteful but saves code space */
	duk_regexp_match(thr);

	/* [ result ] */

	duk_push_boolean(thr, (duk_is_null(thr, -1) ? 0 : 1));

	return 1;
}
Пример #4
0
DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_to_string(duk_context *ctx) {
	duk_hstring *h_bc;
	duk_small_int_t re_flags;

#if 0
	/* A little tricky string approach to provide the flags string.
	 * This depends on the specific flag values in duk_regexp.h,
	 * which needs to be asserted for.  In practice this doesn't
	 * produce more compact code than the easier approach in use.
	 */

	const char *flag_strings = "gim\0gi\0gm\0g\0";
	duk_uint8_t flag_offsets[8] = {
		(duk_uint8_t) 3,   /* flags: ""    */
		(duk_uint8_t) 10,  /* flags: "g"   */
		(duk_uint8_t) 5,   /* flags: "i"   */
		(duk_uint8_t) 4,   /* flags: "gi"  */
		(duk_uint8_t) 2,   /* flags: "m"   */
		(duk_uint8_t) 7,   /* flags: "gm"  */
		(duk_uint8_t) 1,   /* flags: "im"  */
		(duk_uint8_t) 0,   /* flags: "gim" */
	};
	DUK_ASSERT(DUK_RE_FLAG_GLOBAL == 1);
	DUK_ASSERT(DUK_RE_FLAG_IGNORE_CASE == 2);
	DUK_ASSERT(DUK_RE_FLAG_MULTILINE == 4);
#endif

	duk__get_this_regexp(ctx);

	/* [ regexp ] */

	duk_get_prop_stridx(ctx, 0, DUK_STRIDX_SOURCE);
	duk_get_prop_stridx(ctx, 0, DUK_STRIDX_INT_BYTECODE);
	h_bc = duk_get_hstring(ctx, -1);
	DUK_ASSERT(h_bc != NULL);
	DUK_ASSERT(DUK_HSTRING_GET_BYTELEN(h_bc) >= 1);
	DUK_ASSERT(DUK_HSTRING_GET_CHARLEN(h_bc) >= 1);
	DUK_ASSERT(DUK_HSTRING_GET_DATA(h_bc)[0] < 0x80);
	re_flags = (duk_small_int_t) DUK_HSTRING_GET_DATA(h_bc)[0];

	/* [ regexp source bytecode ] */

#if 1
	/* This is a cleaner approach and also produces smaller code than
	 * the other alternative.  Use duk_require_string() for format
	 * safety (although the source property should always exist).
	 */
	duk_push_sprintf(ctx, "/%s/%s%s%s",
	                 (const char *) duk_require_string(ctx, -2),  /* require to be safe */
	                 (re_flags & DUK_RE_FLAG_GLOBAL) ? "g" : "",
	                 (re_flags & DUK_RE_FLAG_IGNORE_CASE) ? "i" : "",
	                 (re_flags & DUK_RE_FLAG_MULTILINE) ? "m" : "");
#else
	/* This should not be necessary because no-one should tamper with the
	 * regexp bytecode, but is prudent to avoid potential segfaults if that
	 * were to happen for some reason.
	 */
	re_flags &= 0x07;
	DUK_ASSERT(re_flags >= 0 && re_flags <= 7);  /* three flags */
	duk_push_sprintf(ctx, "/%s/%s",
	                 (const char *) duk_require_string(ctx, -2),
	                 (const char *) (flag_strings + flag_offsets[re_flags]));
#endif

	return 1;
}