示例#1
0
/* XXX: much to improve (code size) */
DUK_INTERNAL duk_ret_t duk_bi_regexp_constructor(duk_hthread *thr) {
	duk_hobject *h_pattern;

	DUK_ASSERT_TOP(thr, 2);
	h_pattern = duk_get_hobject(thr, 0);

	if (!duk_is_constructor_call(thr) &&
	    h_pattern != NULL &&
	    DUK_HOBJECT_GET_CLASS_NUMBER(h_pattern) == DUK_HOBJECT_CLASS_REGEXP &&
	    duk_is_undefined(thr, 1)) {
		/* Called as a function, pattern has [[Class]] "RegExp" and
		 * flags is undefined -> return object as is.
		 */
		/* XXX: ES2015 has a NewTarget SameValue() check which is not
		 * yet implemented.
		 */
		duk_dup_0(thr);
		return 1;
	}

	/* Else functionality is identical for function call and constructor
	 * call.
	 */

	if (h_pattern != NULL &&
	    DUK_HOBJECT_GET_CLASS_NUMBER(h_pattern) == DUK_HOBJECT_CLASS_REGEXP) {
		duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_SOURCE);
		if (duk_is_undefined(thr, 1)) {
			/* In ES5 one would need to read the flags individually;
			 * in ES2015 just read .flags.
			 */
			duk_get_prop_stridx(thr, 0, DUK_STRIDX_FLAGS);
		} else {
			/* In ES2015 allowed; overrides argument RegExp flags. */
			duk_dup_1(thr);
		}
	} else {
		if (duk_is_undefined(thr, 0)) {
			duk_push_hstring_empty(thr);
		} else {
			duk_dup_0(thr);
			duk_to_string(thr, -1);  /* Rejects Symbols. */
		}
		if (duk_is_undefined(thr, 1)) {
			duk_push_hstring_empty(thr);
		} else {
			duk_dup_1(thr);
			duk_to_string(thr, -1);  /* Rejects Symbols. */
		}

		/* [ ... pattern flags ] */
	}

	DUK_DDD(DUK_DDDPRINT("RegExp constructor/function call, pattern=%!T, flags=%!T",
	                     (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));

	/* [ ... pattern flags ] (both uncoerced) */

	duk_to_string(thr, -2);
	duk_to_string(thr, -1);
	duk_regexp_compile(thr);

	/* [ ... bytecode escaped_source ] */

	duk_regexp_create_instance(thr);

	/* [ ... RegExp ] */

	return 1;
}
示例#2
0
/* XXX: much to improve (code size) */
DUK_INTERNAL duk_ret_t duk_bi_regexp_constructor(duk_context *ctx) {
	duk_hthread *thr = (duk_hthread *) ctx;
	duk_hobject *h_pattern;

	DUK_ASSERT_TOP(ctx, 2);
	h_pattern = duk_get_hobject(ctx, 0);

	if (!duk_is_constructor_call(ctx) &&
	    h_pattern != NULL &&
	    DUK_HOBJECT_GET_CLASS_NUMBER(h_pattern) == DUK_HOBJECT_CLASS_REGEXP &&
	    duk_is_undefined(ctx, 1)) {
		/* Called as a function, pattern has [[Class]] "RegExp" and
		 * flags is undefined -> return object as is.
		 */
		duk_dup(ctx, 0);
		return 1;
	}

	/* Else functionality is identical for function call and constructor
	 * call.
	 */

	if (h_pattern != NULL &&
	    DUK_HOBJECT_GET_CLASS_NUMBER(h_pattern) == DUK_HOBJECT_CLASS_REGEXP) {
		if (duk_is_undefined(ctx, 1)) {
			duk_bool_t flag_g, flag_i, flag_m;
			duk_get_prop_stridx(ctx, 0, DUK_STRIDX_SOURCE);
			flag_g = duk_get_prop_stridx_boolean(ctx, 0, DUK_STRIDX_GLOBAL, NULL);
			flag_i = duk_get_prop_stridx_boolean(ctx, 0, DUK_STRIDX_IGNORE_CASE, NULL);
			flag_m = duk_get_prop_stridx_boolean(ctx, 0, DUK_STRIDX_MULTILINE, NULL);

			duk_push_sprintf(ctx, "%s%s%s",
			                 (const char *) (flag_g ? "g" : ""),
			                 (const char *) (flag_i ? "i" : ""),
			                 (const char *) (flag_m ? "m" : ""));

			/* [ ... pattern flags ] */
		} else {
			return DUK_RET_TYPE_ERROR;
		}
	} else {
		if (duk_is_undefined(ctx, 0)) {
			duk_push_string(ctx, "");
		} else {
			duk_dup(ctx, 0);
			duk_to_string(ctx, -1);
		}
		if (duk_is_undefined(ctx, 1)) {
			duk_push_string(ctx, "");
		} else {
			duk_dup(ctx, 1);
			duk_to_string(ctx, -1);
		}

		/* [ ... pattern flags ] */
	}

	DUK_DDD(DUK_DDDPRINT("RegExp constructor/function call, pattern=%!T, flags=%!T",
	                     (duk_tval *) duk_get_tval(ctx, -2), (duk_tval *) duk_get_tval(ctx, -1)));

	/* [ ... pattern flags ] */

	duk_regexp_compile(thr);

	/* [ ... bytecode escaped_source ] */

	duk_regexp_create_instance(thr);

	/* [ ... RegExp ] */

	return 1;
}