@@ -1088,10 +1088,12 @@ regexp_match (re_matcher_ctx *re_ctx_p, /**< RegExp matcher context */
1088
1088
* RegExp helper function
1089
1089
*/
1090
1090
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 */
1092
1093
const ecma_char_t *str_p) /* *< start of the input string */
1093
1094
{
1094
1095
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
1096
+ int32_t input_length = ecma_zt_string_length (str_p);
1095
1097
re_matcher_ctx re_ctx;
1096
1098
re_ctx.input_start_p = str_p;
1097
1099
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
1100
1102
1101
1103
/* 1. Read bytecode header and init regexp matcher context. */
1102
1104
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
+
1103
1110
re_ctx.num_of_captures = get_value (&bc_p);
1104
1111
JERRY_ASSERT (re_ctx.num_of_captures % 2 == 0 );
1105
1112
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
1120
1127
1121
1128
bool match = false ;
1122
1129
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
+ }
1123
1142
1124
1143
/* 2. Try to match */
1144
+ const ecma_char_t *sub_str_p;
1125
1145
while (str_p && str_p <= re_ctx.input_end_p && ecma_is_completion_value_empty (ret_value))
1126
1146
{
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)
1130
1148
{
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 ;
1132
1157
break ;
1133
1158
}
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);
1136
1182
}
1137
1183
1138
1184
/* 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
1143
1189
ecma_completion_value_t new_array = ecma_op_create_array_object (0 , 0 , false );
1144
1190
ecma_object_t *new_array_p = ecma_get_object_from_completion_value (new_array);
1145
1191
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
+
1146
1272
for (uint32_t i = 0 ; i < re_ctx.num_of_captures ; i += 2 )
1147
1273
{
1148
1274
ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (i / 2 );
0 commit comments