Skip to content

Commit 83590db

Browse files
committed
Define properties of RegExp result array.
JerryScript-DCO-1.0-Signed-off-by: László Langó [email protected]
1 parent 26cb2f3 commit 83590db

File tree

5 files changed

+144
-21
lines changed

5 files changed

+144
-21
lines changed

jerry-core/ecma/base/ecma-magic-strings.inc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ ECMA_MAGIC_STRING_DEF (ECMA_MAGIC_STRING_SOURCE, "source")
3636
ECMA_MAGIC_STRING_DEF (ECMA_MAGIC_STRING_GLOBAL, "global")
3737
ECMA_MAGIC_STRING_DEF (ECMA_MAGIC_STRING_IGNORECASE, "ignoreCase")
3838
ECMA_MAGIC_STRING_DEF (ECMA_MAGIC_STRING_MULTILINE, "multiline")
39+
ECMA_MAGIC_STRING_DEF (ECMA_MAGIC_STRING_INDEX, "index")
40+
ECMA_MAGIC_STRING_DEF (ECMA_MAGIC_STRING_INPUT, "input")
3941
ECMA_MAGIC_STRING_DEF (ECMA_MAGIC_STRING_LASTINDEX, "lastIndex")
4042
ECMA_MAGIC_STRING_DEF (ECMA_MAGIC_STRING_NAN, "NaN")
4143
ECMA_MAGIC_STRING_DEF (ECMA_MAGIC_STRING_INFINITY_UL, "Infinity")

jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.cpp

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ ecma_builtin_regexp_prototype_exec (ecma_value_t this_arg, /**< this argument */
7777
ssize_t zt_str_size = (ssize_t) sizeof (ecma_char_t) * (chars + 1);
7878
ecma_string_to_zt_string (input_str_p, input_zt_str_p, zt_str_size);
7979

80-
ret_value = ecma_regexp_exec_helper (bytecode_p, input_zt_str_p);
80+
ret_value = ecma_regexp_exec_helper (obj_p, bytecode_p, input_zt_str_p);
8181

8282
MEM_FINALIZE_LOCAL_ARRAY (input_zt_str_p);
8383

@@ -87,12 +87,6 @@ ecma_builtin_regexp_prototype_exec (ecma_value_t this_arg, /**< this argument */
8787
return ret_value;
8888
} /* ecma_builtin_regexp_prototype_exec */
8989

90-
/**
91-
* @}
92-
* @}
93-
* @}
94-
*/
95-
9690
/**
9791
* The RegExp.prototype object's 'test' routine
9892
*
@@ -124,12 +118,6 @@ ecma_builtin_regexp_prototype_test (ecma_value_t this_arg, /**< this argument */
124118
return ret_value;
125119
} /* ecma_builtin_regexp_prototype_test */
126120

127-
/**
128-
* @}
129-
* @}
130-
* @}
131-
*/
132-
133121
/**
134122
* The RegExp.prototype object's 'toString' routine
135123
*

jerry-core/ecma/builtin-objects/ecma-builtin-regexp.inc.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,20 @@ SIMPLE_VALUE (ECMA_MAGIC_STRING_MULTILINE,
7474
ECMA_PROPERTY_NOT_WRITABLE,
7575
ECMA_PROPERTY_NOT_ENUMERABLE,
7676
ECMA_PROPERTY_NOT_CONFIGURABLE)
77+
7778
// ECMA-262 v5, 15.10.7.5
7879
NUMBER_VALUE (ECMA_MAGIC_STRING_LASTINDEX,
7980
0,
8081
ECMA_PROPERTY_NOT_WRITABLE,
8182
ECMA_PROPERTY_NOT_ENUMERABLE,
8283
ECMA_PROPERTY_NOT_CONFIGURABLE)
8384

85+
NUMBER_VALUE (ECMA_MAGIC_STRING_LENGTH,
86+
2,
87+
ECMA_PROPERTY_NOT_WRITABLE,
88+
ECMA_PROPERTY_NOT_ENUMERABLE,
89+
ECMA_PROPERTY_NOT_CONFIGURABLE)
90+
8491
#undef OBJECT_ID
8592
#undef SIMPLE_VALUE
8693
#undef NUMBER_VALUE

jerry-core/ecma/operations/ecma-regexp-object.cpp

Lines changed: 133 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,10 +1088,12 @@ regexp_match (re_matcher_ctx *re_ctx_p, /**< RegExp matcher context */
10881088
* RegExp helper function
10891089
*/
10901090
ecma_completion_value_t
1091-
ecma_regexp_exec_helper (re_bytecode_t *bc_p, /**< start of the RegExp bytecode */
1091+
ecma_regexp_exec_helper (ecma_object_t *obj_p, /**< RegExp object */
1092+
re_bytecode_t *bc_p, /**< start of the RegExp bytecode */
10921093
const ecma_char_t *str_p) /**< start of the input string */
10931094
{
10941095
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
1096+
int32_t input_length = ecma_zt_string_length (str_p);
10951097
re_matcher_ctx re_ctx;
10961098
re_ctx.input_start_p = str_p;
10971099
re_ctx.input_end_p = str_p + strlen ((char *) str_p);
@@ -1100,6 +1102,11 @@ ecma_regexp_exec_helper (re_bytecode_t *bc_p, /**< start of the RegExp bytecode
11001102

11011103
/* 1. Read bytecode header and init regexp matcher context. */
11021104
re_ctx.flags = (uint8_t) get_value (&bc_p);
1105+
JERRY_DDLOG ("Exec with flags [global: %d, ignoreCase: %d, multiline: %d]\n",
1106+
re_ctx.flags & RE_FLAG_GLOBAL,
1107+
re_ctx.flags & RE_FLAG_IGNORE_CASE,
1108+
re_ctx.flags & RE_FLAG_MULTILINE);
1109+
11031110
re_ctx.num_of_captures = get_value (&bc_p);
11041111
JERRY_ASSERT (re_ctx.num_of_captures % 2 == 0);
11051112
re_ctx.num_of_non_captures = get_value (&bc_p);
@@ -1120,19 +1127,58 @@ ecma_regexp_exec_helper (re_bytecode_t *bc_p, /**< start of the RegExp bytecode
11201127

11211128
bool match = false;
11221129
re_ctx.num_of_iterations = num_of_iter_p;
1130+
int32_t index = 0;
1131+
1132+
if (re_ctx.flags & RE_FLAG_GLOBAL)
1133+
{
1134+
ecma_string_t *magic_str_p = ecma_get_magic_string (ECMA_MAGIC_STRING_LASTINDEX);
1135+
ecma_property_t *lastindex_prop_p = ecma_op_object_get_property (obj_p, magic_str_p);
1136+
ecma_number_t *lastindex_num_p = ecma_get_number_from_value (lastindex_prop_p->u.named_data_property.value);
1137+
index = ecma_number_to_int32 (*lastindex_num_p);
1138+
JERRY_ASSERT (str_p != NULL);
1139+
str_p += ecma_number_to_int32 (*lastindex_num_p);
1140+
ecma_deref_ecma_string (magic_str_p);
1141+
}
11231142

11241143
/* 2. Try to match */
1144+
const ecma_char_t *sub_str_p;
11251145
while (str_p && str_p <= re_ctx.input_end_p && ecma_is_completion_value_empty (ret_value))
11261146
{
1127-
const ecma_char_t *sub_str_p;
1128-
ECMA_TRY_CATCH (match_value, regexp_match (&re_ctx, bc_p, str_p, &sub_str_p), ret_value);
1129-
if (ecma_is_value_true (match_value))
1147+
if (index < 0 || index > input_length)
11301148
{
1131-
match = true;
1149+
ecma_string_t *magic_str_p = ecma_get_magic_string (ECMA_MAGIC_STRING_LASTINDEX);
1150+
ecma_number_t *lastindex_num_p = ecma_alloc_number ();
1151+
*lastindex_num_p = ECMA_NUMBER_ZERO;
1152+
ecma_op_object_put (obj_p, magic_str_p, ecma_make_number_value (lastindex_num_p), true);
1153+
ecma_dealloc_number (lastindex_num_p);
1154+
ecma_deref_ecma_string (magic_str_p);
1155+
1156+
match = false;
11321157
break;
11331158
}
1134-
str_p++;
1135-
ECMA_FINALIZE (match_value);
1159+
else
1160+
{
1161+
sub_str_p = NULL;
1162+
ECMA_TRY_CATCH (match_value, regexp_match (&re_ctx, bc_p, str_p, &sub_str_p), ret_value);
1163+
if (ecma_is_value_true (match_value))
1164+
{
1165+
match = true;
1166+
break;
1167+
}
1168+
str_p++;
1169+
index++;
1170+
ECMA_FINALIZE (match_value);
1171+
}
1172+
}
1173+
1174+
if (re_ctx.flags & RE_FLAG_GLOBAL)
1175+
{
1176+
ecma_string_t *magic_str_p = ecma_get_magic_string (ECMA_MAGIC_STRING_LASTINDEX);
1177+
ecma_number_t *lastindex_num_p = ecma_alloc_number ();
1178+
*lastindex_num_p = ((ecma_number_t) (sub_str_p - re_ctx.input_start_p));
1179+
ecma_op_object_put (obj_p, magic_str_p, ecma_make_number_value (lastindex_num_p), true);
1180+
ecma_dealloc_number (lastindex_num_p);
1181+
ecma_deref_ecma_string (magic_str_p);
11361182
}
11371183

11381184
/* 3. Fill the result array or return with 'undefiend' */
@@ -1143,6 +1189,86 @@ ecma_regexp_exec_helper (re_bytecode_t *bc_p, /**< start of the RegExp bytecode
11431189
ecma_completion_value_t new_array = ecma_op_create_array_object (0, 0, false);
11441190
ecma_object_t *new_array_p = ecma_get_object_from_completion_value (new_array);
11451191

1192+
/* Set index property of the result array */
1193+
ecma_string_t* result_prop_str_p = ecma_get_magic_string (ECMA_MAGIC_STRING_INDEX);
1194+
{
1195+
ecma_property_descriptor_t array_item_prop_desc = ecma_make_empty_property_descriptor ();
1196+
1197+
array_item_prop_desc.is_value_defined = true;
1198+
1199+
ecma_number_t *num_p = ecma_alloc_number ();
1200+
*num_p = (ecma_number_t) index;
1201+
array_item_prop_desc.value = ecma_make_number_value (num_p);
1202+
1203+
array_item_prop_desc.is_writable_defined = true;
1204+
array_item_prop_desc.is_writable = true;
1205+
1206+
array_item_prop_desc.is_enumerable_defined = true;
1207+
array_item_prop_desc.is_enumerable = true;
1208+
1209+
array_item_prop_desc.is_configurable_defined = true;
1210+
array_item_prop_desc.is_configurable = true;
1211+
1212+
ecma_op_object_define_own_property (new_array_p,
1213+
result_prop_str_p,
1214+
&array_item_prop_desc,
1215+
true);
1216+
1217+
ecma_dealloc_number (num_p);
1218+
}
1219+
ecma_deref_ecma_string (result_prop_str_p);
1220+
1221+
/* Set input property of the result array */
1222+
result_prop_str_p = ecma_get_magic_string (ECMA_MAGIC_STRING_INPUT);
1223+
{
1224+
ecma_property_descriptor_t array_item_prop_desc = ecma_make_empty_property_descriptor ();
1225+
1226+
array_item_prop_desc.is_value_defined = true;
1227+
ecma_string_t *input_str_p = ecma_new_ecma_string (re_ctx.input_start_p);
1228+
array_item_prop_desc.value = ecma_make_string_value (input_str_p);
1229+
1230+
array_item_prop_desc.is_writable_defined = true;
1231+
array_item_prop_desc.is_writable = true;
1232+
1233+
array_item_prop_desc.is_enumerable_defined = true;
1234+
array_item_prop_desc.is_enumerable = true;
1235+
1236+
array_item_prop_desc.is_configurable_defined = true;
1237+
array_item_prop_desc.is_configurable = true;
1238+
1239+
ecma_op_object_define_own_property (new_array_p,
1240+
result_prop_str_p,
1241+
&array_item_prop_desc,
1242+
true);
1243+
1244+
ecma_deref_ecma_string (input_str_p);
1245+
}
1246+
ecma_deref_ecma_string (result_prop_str_p);
1247+
1248+
/* Set length property of the result array */
1249+
result_prop_str_p = ecma_get_magic_string (ECMA_MAGIC_STRING_LENGTH);
1250+
{
1251+
1252+
ecma_property_descriptor_t array_item_prop_desc = ecma_make_empty_property_descriptor ();
1253+
array_item_prop_desc.is_value_defined = true;
1254+
1255+
ecma_number_t *num_p = ecma_alloc_number ();
1256+
*num_p = (ecma_number_t) (re_ctx.num_of_captures / 2);
1257+
array_item_prop_desc.value = ecma_make_number_value (num_p);
1258+
1259+
array_item_prop_desc.is_writable_defined = false;
1260+
array_item_prop_desc.is_enumerable_defined = false;
1261+
array_item_prop_desc.is_configurable_defined = false;
1262+
1263+
ecma_op_object_define_own_property (new_array_p,
1264+
result_prop_str_p,
1265+
&array_item_prop_desc,
1266+
true);
1267+
1268+
ecma_dealloc_number (num_p);
1269+
}
1270+
ecma_deref_ecma_string (result_prop_str_p);
1271+
11461272
for (uint32_t i = 0; i < re_ctx.num_of_captures; i += 2)
11471273
{
11481274
ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (i / 2);

jerry-core/ecma/operations/ecma-regexp-object.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ extern ecma_completion_value_t
5050
ecma_op_create_regexp_object (ecma_string_t *pattern_p, ecma_string_t *flags_str_p);
5151

5252
extern ecma_completion_value_t
53-
ecma_regexp_exec_helper (re_bytecode_t *bc_p, const ecma_char_t *str_p);
53+
ecma_regexp_exec_helper (ecma_object_t *obj_p, re_bytecode_t *bc_p, const ecma_char_t *str_p);
5454

5555
/**
5656
* @}

0 commit comments

Comments
 (0)