Github User Fetcher 1.0.0
C Application with Server and GUI
Loading...
Searching...
No Matches
duktape-1.5.2/src-separate/duk_bi_regexp.c
Go to the documentation of this file.
1/*
2 * RegExp built-ins
3 */
4
5#include "duk_internal.h"
6
7#ifdef DUK_USE_REGEXP_SUPPORT
8
10 duk_hobject *h;
11
12 duk_push_this(ctx);
14 DUK_ASSERT(h != NULL);
15 DUK_UNREF(h);
16 duk_insert(ctx, 0); /* prepend regexp to valstack 0 index */
17}
18
19/* XXX: much to improve (code size) */
21 duk_hthread *thr = (duk_hthread *) ctx;
22 duk_hobject *h_pattern;
23
24 DUK_ASSERT_TOP(ctx, 2);
25 h_pattern = duk_get_hobject(ctx, 0);
26
27 if (!duk_is_constructor_call(ctx) &&
28 h_pattern != NULL &&
30 duk_is_undefined(ctx, 1)) {
31 /* Called as a function, pattern has [[Class]] "RegExp" and
32 * flags is undefined -> return object as is.
33 */
34 duk_dup(ctx, 0);
35 return 1;
36 }
37
38 /* Else functionality is identical for function call and constructor
39 * call.
40 */
41
42 if (h_pattern != NULL &&
44 if (duk_is_undefined(ctx, 1)) {
45 duk_bool_t flag_g, flag_i, flag_m;
50
51 duk_push_sprintf(ctx, "%s%s%s",
52 (const char *) (flag_g ? "g" : ""),
53 (const char *) (flag_i ? "i" : ""),
54 (const char *) (flag_m ? "m" : ""));
55
56 /* [ ... pattern flags ] */
57 } else {
58 return DUK_RET_TYPE_ERROR;
59 }
60 } else {
61 if (duk_is_undefined(ctx, 0)) {
62 duk_push_string(ctx, "");
63 } else {
64 duk_dup(ctx, 0);
65 duk_to_string(ctx, -1);
66 }
67 if (duk_is_undefined(ctx, 1)) {
68 duk_push_string(ctx, "");
69 } else {
70 duk_dup(ctx, 1);
71 duk_to_string(ctx, -1);
72 }
73
74 /* [ ... pattern flags ] */
75 }
76
77 DUK_DDD(DUK_DDDPRINT("RegExp constructor/function call, pattern=%!T, flags=%!T",
78 (duk_tval *) duk_get_tval(ctx, -2), (duk_tval *) duk_get_tval(ctx, -1)));
79
80 /* [ ... pattern flags ] */
81
83
84 /* [ ... bytecode escaped_source ] */
85
87
88 /* [ ... RegExp ] */
89
90 return 1;
91}
92
95
96 /* [ regexp input ] */
97
99
100 /* [ result ] */
101
102 return 1;
103}
104
107
108 /* [ regexp input ] */
109
110 /* result object is created and discarded; wasteful but saves code space */
112
113 /* [ result ] */
114
115 duk_push_boolean(ctx, (duk_is_null(ctx, -1) ? 0 : 1));
116
117 return 1;
118}
119
121 duk_hstring *h_bc;
122 duk_small_int_t re_flags;
123
124#if 0
125 /* A little tricky string approach to provide the flags string.
126 * This depends on the specific flag values in duk_regexp.h,
127 * which needs to be asserted for. In practice this doesn't
128 * produce more compact code than the easier approach in use.
129 */
130
131 const char *flag_strings = "gim\0gi\0gm\0g\0";
132 duk_uint8_t flag_offsets[8] = {
133 (duk_uint8_t) 3, /* flags: "" */
134 (duk_uint8_t) 10, /* flags: "g" */
135 (duk_uint8_t) 5, /* flags: "i" */
136 (duk_uint8_t) 4, /* flags: "gi" */
137 (duk_uint8_t) 2, /* flags: "m" */
138 (duk_uint8_t) 7, /* flags: "gm" */
139 (duk_uint8_t) 1, /* flags: "im" */
140 (duk_uint8_t) 0, /* flags: "gim" */
141 };
145#endif
146
148
149 /* [ regexp ] */
150
153 h_bc = duk_get_hstring(ctx, -1);
154 DUK_ASSERT(h_bc != NULL);
157 DUK_ASSERT(DUK_HSTRING_GET_DATA(h_bc)[0] < 0x80);
158 re_flags = (duk_small_int_t) DUK_HSTRING_GET_DATA(h_bc)[0];
159
160 /* [ regexp source bytecode ] */
161
162#if 1
163 /* This is a cleaner approach and also produces smaller code than
164 * the other alternative. Use duk_require_string() for format
165 * safety (although the source property should always exist).
166 */
167 duk_push_sprintf(ctx, "/%s/%s%s%s",
168 (const char *) duk_require_string(ctx, -2), /* require to be safe */
169 (re_flags & DUK_RE_FLAG_GLOBAL) ? "g" : "",
170 (re_flags & DUK_RE_FLAG_IGNORE_CASE) ? "i" : "",
171 (re_flags & DUK_RE_FLAG_MULTILINE) ? "m" : "");
172#else
173 /* This should not be necessary because no-one should tamper with the
174 * regexp bytecode, but is prudent to avoid potential segfaults if that
175 * were to happen for some reason.
176 */
177 re_flags &= 0x07;
178 DUK_ASSERT(re_flags >= 0 && re_flags <= 7); /* three flags */
179 duk_push_sprintf(ctx, "/%s/%s",
180 (const char *) duk_require_string(ctx, -2),
181 (const char *) (flag_strings + flag_offsets[re_flags]));
182#endif
183
184 return 1;
185}
186
187#else /* DUK_USE_REGEXP_SUPPORT */
188
190 DUK_UNREF(ctx);
192}
193
195 DUK_UNREF(ctx);
197}
198
200 DUK_UNREF(ctx);
202}
203
205 DUK_UNREF(ctx);
207}
208
209#endif /* DUK_USE_REGEXP_SUPPORT */
duk_small_int_t duk_ret_t
duk_small_int_t duk_bool_t
DUK_EXTERNAL const char * duk_push_string(duk_context *ctx, const char *str)
#define DUK_HSTRING_GET_DATA(x)
#define DUK_HOBJECT_CLASS_REGEXP
DUK_EXTERNAL duk_bool_t duk_is_undefined(duk_context *ctx, duk_idx_t index)
DUK_EXTERNAL void duk_push_this(duk_context *ctx)
DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx)
DUK_INTERNAL_DECL void duk_regexp_match(duk_hthread *thr)
DUK_EXTERNAL void duk_push_boolean(duk_context *ctx, duk_bool_t val)
#define DUK_RE_FLAG_MULTILINE
DUK_INTERNAL_DECL duk_hobject * duk_require_hobject_with_class(duk_context *ctx, duk_idx_t index, duk_small_uint_t classnum)
#define DUK_HSTRING_GET_CHARLEN(x)
#define DUK_HSTRING_GET_BYTELEN(x)
DUK_EXTERNAL void duk_dup(duk_context *ctx, duk_idx_t from_index)
DUK_EXTERNAL void duk_insert(duk_context *ctx, duk_idx_t to_index)
DUK_EXTERNAL duk_bool_t duk_is_null(duk_context *ctx, duk_idx_t index)
DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx_boolean(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx, duk_bool_t *out_has_prop)
DUK_EXTERNAL duk_bool_t duk_is_constructor_call(duk_context *ctx)
DUK_EXTERNAL const char * duk_push_sprintf(duk_context *ctx, const char *fmt,...)
#define DUK_ASSERT_TOP(ctx, n)
#define DUK_STRIDX_IGNORE_CASE
DUK_EXTERNAL const char * duk_to_string(duk_context *ctx, duk_idx_t index)
#define DUK_RE_FLAG_IGNORE_CASE
#define DUK_STRIDX_INT_BYTECODE
DUK_INTERNAL_DECL duk_hobject * duk_get_hobject(duk_context *ctx, duk_idx_t index)
#define DUK_HOBJECT_GET_CLASS_NUMBER(h)
DUK_INTERNAL_DECL duk_hstring * duk_get_hstring(duk_context *ctx, duk_idx_t index)
DUK_EXTERNAL const char * duk_require_string(duk_context *ctx, duk_idx_t index)
DUK_INTERNAL_DECL void duk_regexp_create_instance(duk_hthread *thr)
DUK_INTERNAL_DECL duk_tval * duk_get_tval(duk_context *ctx, duk_idx_t index)
DUK_INTERNAL_DECL void duk_regexp_compile(duk_hthread *thr)
#define DUK_RET_UNSUPPORTED_ERROR
DUK_INTERNAL duk_ret_t duk_bi_regexp_constructor(duk_context *ctx)
DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_test(duk_context *ctx)
DUK_LOCAL void duk__get_this_regexp(duk_context *ctx)
DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_to_string(duk_context *ctx)
DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_exec(duk_context *ctx)
#define NULL
Definition gmacros.h:924