@@ -1151,6 +1151,11 @@ static const JSClassExoticMethods js_proxy_exotic_methods;
1151
1151
static const JSClassExoticMethods js_module_ns_exotic_methods;
1152
1152
static JSClassID js_class_id_alloc = JS_CLASS_INIT_COUNT;
1153
1153
1154
+ static JSValue js_int32(int32_t v)
1155
+ {
1156
+ return JS_MKVAL(JS_TAG_INT, v);
1157
+ }
1158
+
1154
1159
static void js_trigger_gc(JSRuntime *rt, size_t size)
1155
1160
{
1156
1161
BOOL force_gc;
@@ -39831,6 +39836,9 @@ static JSValue js_compile_regexp(JSContext *ctx, JSValueConst pattern,
39831
39836
/* XXX: re_flags = LRE_FLAG_OCTAL unless strict mode? */
39832
39837
for (i = 0; i < len; i++) {
39833
39838
switch(str[i]) {
39839
+ case 'd':
39840
+ mask = LRE_FLAG_INDICES;
39841
+ break;
39834
39842
case 'g':
39835
39843
mask = LRE_FLAG_GLOBAL;
39836
39844
break;
@@ -40153,6 +40161,11 @@ static JSValue js_regexp_get_flags(JSContext *ctx, JSValueConst this_val)
40153
40161
if (JS_VALUE_GET_TAG(this_val) != JS_TAG_OBJECT)
40154
40162
return JS_ThrowTypeErrorNotAnObject(ctx);
40155
40163
40164
+ res = JS_ToBoolFree(ctx, JS_GetPropertyStr(ctx, this_val, "hasIndices"));
40165
+ if (res < 0)
40166
+ goto exception;
40167
+ if (res)
40168
+ *p++ = 'd';
40156
40169
res = JS_ToBoolFree(ctx, JS_GetProperty(ctx, this_val, JS_ATOM_global));
40157
40170
if (res < 0)
40158
40171
goto exception;
@@ -40232,53 +40245,56 @@ static JSValue js_regexp_exec(JSContext *ctx, JSValueConst this_val,
40232
40245
{
40233
40246
JSRegExp *re = js_get_regexp(ctx, this_val, TRUE);
40234
40247
JSString *str;
40235
- JSValue str_val, obj, val, groups = JS_UNDEFINED;
40248
+ JSValue t, ret, str_val, obj, val, groups;
40249
+ JSValue indices, indices_groups;
40236
40250
uint8_t *re_bytecode;
40237
- int ret;
40238
40251
uint8_t **capture, *str_buf;
40239
- int capture_count, shift, i, re_flags;
40252
+ int rc, capture_count, shift, i, re_flags;
40240
40253
int64_t last_index;
40241
40254
const char *group_name_ptr;
40242
40255
40243
40256
if (!re)
40244
40257
return JS_EXCEPTION;
40258
+
40245
40259
str_val = JS_ToString(ctx, argv[0]);
40246
40260
if (JS_IsException(str_val))
40247
- return str_val;
40248
- val = JS_GetProperty(ctx, this_val, JS_ATOM_lastIndex);
40249
- if (JS_IsException(val) ||
40250
- JS_ToLengthFree(ctx, &last_index, val)) {
40251
- JS_FreeValue(ctx, str_val);
40252
40261
return JS_EXCEPTION;
40253
- }
40262
+
40263
+ ret = JS_EXCEPTION;
40264
+ obj = JS_NULL;
40265
+ groups = JS_UNDEFINED;
40266
+ indices = JS_UNDEFINED;
40267
+ indices_groups = JS_UNDEFINED;
40268
+ capture = NULL;
40269
+
40270
+ val = JS_GetProperty(ctx, this_val, JS_ATOM_lastIndex);
40271
+ if (JS_IsException(val) || JS_ToLengthFree(ctx, &last_index, val))
40272
+ goto fail;
40273
+
40254
40274
re_bytecode = re->bytecode->u.str8;
40255
40275
re_flags = lre_get_flags(re_bytecode);
40256
40276
if ((re_flags & (LRE_FLAG_GLOBAL | LRE_FLAG_STICKY)) == 0) {
40257
40277
last_index = 0;
40258
40278
}
40259
40279
str = JS_VALUE_GET_STRING(str_val);
40260
40280
capture_count = lre_get_capture_count(re_bytecode);
40261
- capture = NULL;
40262
40281
if (capture_count > 0) {
40263
40282
capture = js_malloc(ctx, sizeof(capture[0]) * capture_count * 2);
40264
- if (!capture) {
40265
- JS_FreeValue(ctx, str_val);
40266
- return JS_EXCEPTION;
40267
- }
40283
+ if (!capture)
40284
+ goto fail;
40268
40285
}
40269
40286
shift = str->is_wide_char;
40270
40287
str_buf = str->u.str8;
40271
40288
if (last_index > str->len) {
40272
- ret = 2;
40289
+ rc = 2;
40273
40290
} else {
40274
- ret = lre_exec(capture, re_bytecode,
40275
- str_buf, last_index, str->len,
40276
- shift, ctx);
40291
+ rc = lre_exec(capture, re_bytecode,
40292
+ str_buf, last_index, str->len,
40293
+ shift, ctx);
40277
40294
}
40278
- obj = JS_NULL;
40279
- if (ret != 1) {
40280
- if (ret >= 0) {
40281
- if (ret == 2 || (re_flags & (LRE_FLAG_GLOBAL | LRE_FLAG_STICKY))) {
40295
+ if (rc != 1) {
40296
+ if (rc >= 0) {
40297
+ if (rc == 2 || (re_flags & (LRE_FLAG_GLOBAL | LRE_FLAG_STICKY))) {
40282
40298
if (JS_SetProperty(ctx, this_val, JS_ATOM_lastIndex,
40283
40299
JS_NewInt32(ctx, 0)) < 0)
40284
40300
goto fail;
@@ -40287,7 +40303,6 @@ static JSValue js_regexp_exec(JSContext *ctx, JSValueConst this_val,
40287
40303
JS_ThrowInternalError(ctx, "out of memory in regexp execution");
40288
40304
goto fail;
40289
40305
}
40290
- JS_FreeValue(ctx, str_val);
40291
40306
} else {
40292
40307
int prop_flags;
40293
40308
if (re_flags & (LRE_FLAG_GLOBAL | LRE_FLAG_STICKY)) {
@@ -40305,52 +40320,123 @@ static JSValue js_regexp_exec(JSContext *ctx, JSValueConst this_val,
40305
40320
if (JS_IsException(groups))
40306
40321
goto fail;
40307
40322
}
40308
-
40309
- for(i = 0; i < capture_count; i++) {
40310
- int start, end;
40311
- JSValue val;
40312
- if (capture[2 * i] == NULL ||
40313
- capture[2 * i + 1] == NULL) {
40314
- val = JS_UNDEFINED;
40315
- } else {
40316
- start = (capture[2 * i] - str_buf) >> shift;
40317
- end = (capture[2 * i + 1] - str_buf) >> shift;
40318
- val = js_sub_string(ctx, str, start, end);
40319
- if (JS_IsException(val))
40323
+ if (re_flags & LRE_FLAG_INDICES) {
40324
+ indices = JS_NewArray(ctx);
40325
+ if (JS_IsException(indices))
40326
+ goto fail;
40327
+ if (group_name_ptr) {
40328
+ indices_groups = JS_NewObjectProto(ctx, JS_NULL);
40329
+ if (JS_IsException(indices_groups))
40320
40330
goto fail;
40321
40331
}
40332
+ }
40333
+
40334
+ for(i = 0; i < capture_count; i++) {
40335
+ const char *name = NULL;
40336
+ uint8_t **match = &capture[2 * i];
40337
+ int start = -1;
40338
+ int end = -1;
40339
+
40322
40340
if (group_name_ptr && i > 0) {
40323
- if (*group_name_ptr) {
40324
- if (JS_DefinePropertyValueStr(ctx, groups, group_name_ptr,
40325
- JS_DupValue(ctx, val),
40326
- prop_flags) < 0) {
40341
+ if (*group_name_ptr) name = group_name_ptr;
40342
+ group_name_ptr += strlen(group_name_ptr) + 1;
40343
+ }
40344
+
40345
+ if (match[0] && match[1]) {
40346
+ start = (match[0] - str_buf) >> shift;
40347
+ end = (match[1] - str_buf) >> shift;
40348
+ }
40349
+
40350
+ if (!JS_IsUndefined(indices)) {
40351
+ JSValue val = JS_UNDEFINED;
40352
+ if (start != -1) {
40353
+ val = JS_NewArray(ctx);
40354
+ if (JS_IsException(val))
40355
+ goto fail;
40356
+ if (JS_DefinePropertyValueUint32(ctx, val, 0,
40357
+ js_int32(start),
40358
+ prop_flags) < 0) {
40359
+ JS_FreeValue(ctx, val);
40360
+ goto fail;
40361
+ }
40362
+ if (JS_DefinePropertyValueUint32(ctx, val, 1,
40363
+ js_int32(end),
40364
+ prop_flags) < 0) {
40327
40365
JS_FreeValue(ctx, val);
40328
40366
goto fail;
40329
40367
}
40330
40368
}
40331
- group_name_ptr += strlen(group_name_ptr) + 1;
40369
+ if (name && !JS_IsUndefined(indices_groups)) {
40370
+ val = JS_DupValue(ctx, val);
40371
+ if (JS_DefinePropertyValueStr(ctx, indices_groups,
40372
+ name, val, prop_flags) < 0) {
40373
+ JS_FreeValue(ctx, val);
40374
+ goto fail;
40375
+ }
40376
+ }
40377
+ if (JS_DefinePropertyValueUint32(ctx, indices, i, val,
40378
+ prop_flags) < 0) {
40379
+ goto fail;
40380
+ }
40381
+ }
40382
+
40383
+ JSValue val = JS_UNDEFINED;
40384
+ if (start != -1) {
40385
+ val = js_sub_string(ctx, str, start, end);
40386
+ if (JS_IsException(val))
40387
+ goto fail;
40388
+ }
40389
+
40390
+ if (name) {
40391
+ if (JS_DefinePropertyValueStr(ctx, groups, name,
40392
+ JS_DupValue(ctx, val),
40393
+ prop_flags) < 0) {
40394
+ JS_FreeValue(ctx, val);
40395
+ goto fail;
40396
+ }
40332
40397
}
40398
+
40333
40399
if (JS_DefinePropertyValueUint32(ctx, obj, i, val, prop_flags) < 0)
40334
40400
goto fail;
40335
40401
}
40402
+
40403
+ t = groups, groups = JS_UNDEFINED;
40336
40404
if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_groups,
40337
- groups , prop_flags) < 0)
40405
+ t , prop_flags) < 0) {
40338
40406
goto fail;
40339
- if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_index,
40340
- JS_NewInt32(ctx, (capture[0] - str_buf) >> shift), prop_flags) < 0)
40407
+ }
40408
+
40409
+ t = js_int32((capture[0] - str_buf) >> shift);
40410
+ if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_index, t, prop_flags) < 0)
40341
40411
goto fail;
40342
- if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_input, str_val, prop_flags) < 0)
40343
- goto fail1;
40412
+
40413
+ t = str_val, str_val = JS_UNDEFINED;
40414
+ if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_input, t, prop_flags) < 0)
40415
+ goto fail;
40416
+
40417
+ if (!JS_IsUndefined(indices)) {
40418
+ t = indices_groups, indices_groups = JS_UNDEFINED;
40419
+ if (JS_DefinePropertyValue(ctx, indices, JS_ATOM_groups,
40420
+ t, prop_flags) < 0) {
40421
+ goto fail;
40422
+ }
40423
+ t = indices, indices = JS_UNDEFINED;
40424
+ if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_indices,
40425
+ t, prop_flags) < 0) {
40426
+ goto fail;
40427
+ }
40428
+ }
40344
40429
}
40345
- js_free(ctx, capture) ;
40346
- return obj;
40430
+ ret = obj ;
40431
+ obj = JS_UNDEFINED ;
40347
40432
fail:
40348
- JS_FreeValue(ctx, groups);
40433
+ JS_FreeValue(ctx, indices_groups);
40434
+ JS_FreeValue(ctx, indices);
40349
40435
JS_FreeValue(ctx, str_val);
40350
- fail1:
40436
+ JS_FreeValue(ctx, groups);
40351
40437
JS_FreeValue(ctx, obj);
40352
40438
js_free(ctx, capture);
40353
- return JS_EXCEPTION ;
40439
+ return ret ;
40354
40440
}
40355
40441
40356
40442
/* delete portions of a string that match a given regex */
@@ -41185,12 +41271,13 @@ static const JSCFunctionListEntry js_regexp_funcs[] = {
41185
41271
static const JSCFunctionListEntry js_regexp_proto_funcs[] = {
41186
41272
JS_CGETSET_DEF("flags", js_regexp_get_flags, NULL ),
41187
41273
JS_CGETSET_DEF("source", js_regexp_get_source, NULL ),
41188
- JS_CGETSET_MAGIC_DEF("global", js_regexp_get_flag, NULL, 1 ),
41189
- JS_CGETSET_MAGIC_DEF("ignoreCase", js_regexp_get_flag, NULL, 2 ),
41190
- JS_CGETSET_MAGIC_DEF("multiline", js_regexp_get_flag, NULL, 4 ),
41191
- JS_CGETSET_MAGIC_DEF("dotAll", js_regexp_get_flag, NULL, 8 ),
41192
- JS_CGETSET_MAGIC_DEF("unicode", js_regexp_get_flag, NULL, 16 ),
41193
- JS_CGETSET_MAGIC_DEF("sticky", js_regexp_get_flag, NULL, 32 ),
41274
+ JS_CGETSET_MAGIC_DEF("global", js_regexp_get_flag, NULL, LRE_FLAG_GLOBAL ),
41275
+ JS_CGETSET_MAGIC_DEF("ignoreCase", js_regexp_get_flag, NULL, LRE_FLAG_IGNORECASE ),
41276
+ JS_CGETSET_MAGIC_DEF("multiline", js_regexp_get_flag, NULL, LRE_FLAG_MULTILINE ),
41277
+ JS_CGETSET_MAGIC_DEF("dotAll", js_regexp_get_flag, NULL, LRE_FLAG_DOTALL ),
41278
+ JS_CGETSET_MAGIC_DEF("unicode", js_regexp_get_flag, NULL, LRE_FLAG_UTF16 ),
41279
+ JS_CGETSET_MAGIC_DEF("sticky", js_regexp_get_flag, NULL, LRE_FLAG_STICKY ),
41280
+ JS_CGETSET_MAGIC_DEF("hasIndices", js_regexp_get_flag, NULL, LRE_FLAG_INDICES ),
41194
41281
JS_CFUNC_DEF("exec", 1, js_regexp_exec ),
41195
41282
JS_CFUNC_DEF("compile", 2, js_regexp_compile ),
41196
41283
JS_CFUNC_DEF("test", 1, js_regexp_test ),
0 commit comments