@@ -1176,8 +1176,8 @@ static int JS_ToUint8ClampFree(JSContext *ctx, int32_t *pres, JSValue val);
11761176static JSValue js_new_string8_len(JSContext *ctx, const char *buf, int len);
11771177static JSValue js_compile_regexp(JSContext *ctx, JSValueConst pattern,
11781178 JSValueConst flags);
1179- static JSValue js_regexp_constructor_internal (JSContext *ctx, JSValueConst ctor ,
1180- JSValue pattern, JSValue bc);
1179+ static JSValue js_regexp_set_internal (JSContext *ctx, JSValue obj ,
1180+ JSValue pattern, JSValue bc);
11811181static void gc_decref(JSRuntime *rt);
11821182static int JS_NewClass1(JSRuntime *rt, JSClassID class_id,
11831183 const JSClassDef *class_def, JSAtom name);
@@ -1261,6 +1261,8 @@ static JSValue js_promise_resolve(JSContext *ctx, JSValueConst this_val,
12611261 int argc, JSValueConst *argv, int magic);
12621262static JSValue js_promise_then(JSContext *ctx, JSValueConst this_val,
12631263 int argc, JSValueConst *argv);
1264+ static BOOL js_string_eq(JSContext *ctx,
1265+ const JSString *p1, const JSString *p2);
12641266static int js_string_compare(JSContext *ctx,
12651267 const JSString *p1, const JSString *p2);
12661268static JSValue JS_ToNumber(JSContext *ctx, JSValueConst val);
@@ -3226,9 +3228,9 @@ static JSValue JS_AtomIsNumericIndex1(JSContext *ctx, JSAtom atom)
32263228 JS_FreeValue(ctx, num);
32273229 return str;
32283230 }
3229- ret = js_string_compare (ctx, p, JS_VALUE_GET_STRING(str));
3231+ ret = js_string_eq (ctx, p, JS_VALUE_GET_STRING(str));
32303232 JS_FreeValue(ctx, str);
3231- if (ret == 0 ) {
3233+ if (ret) {
32323234 return num;
32333235 } else {
32343236 JS_FreeValue(ctx, num);
@@ -4130,6 +4132,16 @@ static int js_string_memcmp(const JSString *p1, int pos1, const JSString *p2,
41304132 return res;
41314133}
41324134
4135+ static BOOL js_string_eq(JSContext *ctx,
4136+ const JSString *p1, const JSString *p2)
4137+ {
4138+ if (p1->len != p2->len)
4139+ return FALSE;
4140+ if (p1 == p2)
4141+ return TRUE;
4142+ return js_string_memcmp(p1, 0, p2, 0, p1->len) == 0;
4143+ }
4144+
41334145/* return < 0, 0 or > 0 */
41344146static int js_string_compare(JSContext *ctx,
41354147 const JSString *p1, const JSString *p2)
@@ -5226,7 +5238,7 @@ static JSValue JS_NewObjectFromShape(JSContext *ctx, JSShape *sh, JSClassID clas
52265238 case JS_CLASS_REGEXP:
52275239 p->u.regexp.pattern = NULL;
52285240 p->u.regexp.bytecode = NULL;
5229- goto set_exotic ;
5241+ break ;
52305242 default:
52315243 set_exotic:
52325244 if (ctx->rt->class_array[class_id].exotic) {
@@ -13414,6 +13426,11 @@ static void js_print_regexp(JSPrintValueState *s, JSObject *p1)
1341413426 int i, n, c, c2, bra, flags;
1341513427 static const char regexp_flags[] = { 'g', 'i', 'm', 's', 'u', 'y', 'd', 'v' };
1341613428
13429+ if (!re->pattern || !re->bytecode) {
13430+ /* the regexp fields are zeroed at init */
13431+ js_puts(s, "[uninitialized_regexp]");
13432+ return;
13433+ }
1341713434 p = re->pattern;
1341813435 js_putc(s, '/');
1341913436 if (p->len == 0) {
@@ -15265,8 +15282,8 @@ static BOOL js_strict_eq2(JSContext *ctx, JSValue op1, JSValue op2,
1526515282 if (!tag_is_string(tag2)) {
1526615283 res = FALSE;
1526715284 } else if (tag1 == JS_TAG_STRING && tag2 == JS_TAG_STRING) {
15268- res = (js_string_compare (ctx, JS_VALUE_GET_STRING(op1),
15269- JS_VALUE_GET_STRING(op2)) == 0 );
15285+ res = js_string_eq (ctx, JS_VALUE_GET_STRING(op1),
15286+ JS_VALUE_GET_STRING(op2));
1527015287 } else {
1527115288 res = (js_string_rope_compare(ctx, op1, op2, TRUE) == 0);
1527215289 }
@@ -17120,18 +17137,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
1712017137 CASE(OP_push_empty_string):
1712117138 *sp++ = JS_AtomToString(ctx, JS_ATOM_empty_string);
1712217139 BREAK;
17123- CASE(OP_get_length):
17124- {
17125- JSValue val;
17126-
17127- sf->cur_pc = pc;
17128- val = JS_GetProperty(ctx, sp[-1], JS_ATOM_length);
17129- if (unlikely(JS_IsException(val)))
17130- goto exception;
17131- JS_FreeValue(ctx, sp[-1]);
17132- sp[-1] = val;
17133- }
17134- BREAK;
1713517140#endif
1713617141 CASE(OP_push_atom_value):
1713717142 *sp++ = JS_AtomToValue(ctx, get_u32(pc));
@@ -17638,8 +17643,13 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
1763817643
1763917644 CASE(OP_regexp):
1764017645 {
17641- sp[-2] = js_regexp_constructor_internal(ctx, JS_UNDEFINED,
17642- sp[-2], sp[-1]);
17646+ JSValue obj;
17647+ obj = JS_NewObjectClass(ctx, JS_CLASS_REGEXP);
17648+ if (JS_IsException(obj))
17649+ goto exception;
17650+ sp[-2] = js_regexp_set_internal(ctx, obj, sp[-2], sp[-1]);
17651+ if (JS_IsException(sp[-2]))
17652+ goto exception;
1764317653 sp--;
1764417654 }
1764517655 BREAK;
@@ -18305,16 +18315,20 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
1830518315 }
1830618316 BREAK;
1830718317
18308- #define GET_FIELD_INLINE(name, keep) \
18318+ #define GET_FIELD_INLINE(name, keep, is_length) \
1830918319 { \
1831018320 JSValue val, obj; \
1831118321 JSAtom atom; \
1831218322 JSObject *p; \
1831318323 JSProperty *pr; \
1831418324 JSShapeProperty *prs; \
1831518325 \
18316- atom = get_u32(pc); \
18317- pc += 4; \
18326+ if (is_length) { \
18327+ atom = JS_ATOM_length; \
18328+ } else { \
18329+ atom = get_u32(pc); \
18330+ pc += 4; \
18331+ } \
1831818332 \
1831918333 obj = sp[-1]; \
1832018334 if (likely(JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT)) { \
@@ -18358,13 +18372,19 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
1835818372
1835918373
1836018374 CASE(OP_get_field):
18361- GET_FIELD_INLINE(get_field, 0);
18375+ GET_FIELD_INLINE(get_field, 0, 0 );
1836218376 BREAK;
1836318377
1836418378 CASE(OP_get_field2):
18365- GET_FIELD_INLINE(get_field2, 1);
18379+ GET_FIELD_INLINE(get_field2, 1, 0 );
1836618380 BREAK;
1836718381
18382+ #if SHORT_OPCODES
18383+ CASE(OP_get_length):
18384+ GET_FIELD_INLINE(get_length, 0, 1);
18385+ BREAK;
18386+ #endif
18387+
1836818388 CASE(OP_put_field):
1836918389 {
1837018390 int ret;
@@ -30239,21 +30259,21 @@ static JSValue js_async_module_execution_rejected(JSContext *ctx, JSValueConst t
3023930259 module->status = JS_MODULE_STATUS_EVALUATED;
3024030260 module->async_evaluation = FALSE;
3024130261
30242- for(i = 0; i < module->async_parent_modules_count; i++) {
30243- JSModuleDef *m = module->async_parent_modules[i];
30244- JSValue m_obj = JS_NewModuleValue(ctx, m);
30245- js_async_module_execution_rejected(ctx, JS_UNDEFINED, 1, &error, 0,
30246- &m_obj);
30247- JS_FreeValue(ctx, m_obj);
30248- }
30249-
3025030262 if (!JS_IsUndefined(module->promise)) {
3025130263 JSValue ret_val;
3025230264 assert(module->cycle_root == module);
3025330265 ret_val = JS_Call(ctx, module->resolving_funcs[1], JS_UNDEFINED,
3025430266 1, &error);
3025530267 JS_FreeValue(ctx, ret_val);
3025630268 }
30269+
30270+ for(i = 0; i < module->async_parent_modules_count; i++) {
30271+ JSModuleDef *m = module->async_parent_modules[i];
30272+ JSValue m_obj = JS_NewModuleValue(ctx, m);
30273+ js_async_module_execution_rejected(ctx, JS_UNDEFINED, 1, &error, 0,
30274+ &m_obj);
30275+ JS_FreeValue(ctx, m_obj);
30276+ }
3025730277 return JS_UNDEFINED;
3025830278}
3025930279
@@ -41537,6 +41557,31 @@ static JSValue js_array_push(JSContext *ctx, JSValueConst this_val,
4153741557 int i;
4153841558 int64_t len, from, newLen;
4153941559
41560+ if (likely(JS_VALUE_GET_TAG(this_val) == JS_TAG_OBJECT && !unshift)) {
41561+ JSObject *p = JS_VALUE_GET_OBJ(this_val);
41562+ if (likely(p->class_id == JS_CLASS_ARRAY && p->fast_array &&
41563+ p->extensible &&
41564+ p->shape->proto == JS_VALUE_GET_OBJ(ctx->class_proto[JS_CLASS_ARRAY]) &&
41565+ ctx->std_array_prototype &&
41566+ JS_VALUE_GET_TAG(p->prop[0].u.value) == JS_TAG_INT &&
41567+ JS_VALUE_GET_INT(p->prop[0].u.value) == p->u.array.count &&
41568+ (get_shape_prop(p->shape)->flags & JS_PROP_WRITABLE) != 0)) {
41569+ /* fast case */
41570+ uint32_t new_len;
41571+ new_len = p->u.array.count + argc;
41572+ if (likely(new_len <= INT32_MAX)) {
41573+ if (unlikely(new_len > p->u.array.u1.size)) {
41574+ if (expand_fast_array(ctx, p, new_len))
41575+ return JS_EXCEPTION;
41576+ }
41577+ for(i = 0; i < argc; i++)
41578+ p->u.array.u.values[p->u.array.count + i] = JS_DupValue(ctx, argv[i]);
41579+ p->prop[0].u.value = JS_NewInt32(ctx, new_len);
41580+ p->u.array.count = new_len;
41581+ return JS_NewInt32(ctx, new_len);
41582+ }
41583+ }
41584+ }
4154041585 obj = JS_ToObject(ctx, this_val);
4154141586 if (js_get_length64(ctx, &len, obj))
4154241587 goto exception;
@@ -46084,8 +46129,10 @@ static void js_regexp_finalizer(JSRuntime *rt, JSValue val)
4608446129{
4608546130 JSObject *p = JS_VALUE_GET_OBJ(val);
4608646131 JSRegExp *re = &p->u.regexp;
46087- JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_STRING, re->bytecode));
46088- JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_STRING, re->pattern));
46132+ if (re->bytecode != NULL)
46133+ JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_STRING, re->bytecode));
46134+ if (re->pattern != NULL)
46135+ JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_STRING, re->pattern));
4608946136}
4609046137
4609146138/* create a string containing the RegExp bytecode */
@@ -46167,32 +46214,29 @@ static JSValue js_compile_regexp(JSContext *ctx, JSValueConst pattern,
4616746214 return ret;
4616846215}
4616946216
46170- /* create a RegExp object from a string containing the RegExp bytecode
46171- and the source pattern */
46172- static JSValue js_regexp_constructor_internal(JSContext *ctx, JSValueConst ctor ,
46173- JSValue pattern, JSValue bc)
46217+ /* set the RegExp fields */
46218+ static JSValue js_regexp_set_internal(JSContext *ctx,
46219+ JSValue obj ,
46220+ JSValue pattern, JSValue bc)
4617446221{
46175- JSValue obj;
4617646222 JSObject *p;
4617746223 JSRegExp *re;
4617846224
4617946225 /* sanity check */
46180- if (JS_VALUE_GET_TAG(bc) != JS_TAG_STRING ||
46181- JS_VALUE_GET_TAG(pattern) != JS_TAG_STRING) {
46226+ if (unlikely( JS_VALUE_GET_TAG(bc) != JS_TAG_STRING ||
46227+ JS_VALUE_GET_TAG(pattern) != JS_TAG_STRING) ) {
4618246228 JS_ThrowTypeError(ctx, "string expected");
46183- fail:
46229+ JS_FreeValue(ctx, obj);
4618446230 JS_FreeValue(ctx, bc);
4618546231 JS_FreeValue(ctx, pattern);
4618646232 return JS_EXCEPTION;
4618746233 }
4618846234
46189- obj = js_create_from_ctor(ctx, ctor, JS_CLASS_REGEXP);
46190- if (JS_IsException(obj))
46191- goto fail;
4619246235 p = JS_VALUE_GET_OBJ(obj);
4619346236 re = &p->u.regexp;
4619446237 re->pattern = JS_VALUE_GET_STRING(pattern);
4619546238 re->bytecode = JS_VALUE_GET_STRING(bc);
46239+ /* Note: cannot fail because the field is preallocated */
4619646240 JS_DefinePropertyValue(ctx, obj, JS_ATOM_lastIndex, JS_NewInt32(ctx, 0),
4619746241 JS_PROP_WRITABLE);
4619846242 return obj;
@@ -46229,7 +46273,7 @@ static int js_is_regexp(JSContext *ctx, JSValueConst obj)
4622946273static JSValue js_regexp_constructor(JSContext *ctx, JSValueConst new_target,
4623046274 int argc, JSValueConst *argv)
4623146275{
46232- JSValue pattern, flags, bc, val;
46276+ JSValue pattern, flags, bc, val, obj = JS_UNDEFINED ;
4623346277 JSValueConst pat, flags1;
4623446278 JSRegExp *re;
4623546279 int pat_is_regexp;
@@ -46255,18 +46299,19 @@ static JSValue js_regexp_constructor(JSContext *ctx, JSValueConst new_target,
4625546299 }
4625646300 }
4625746301 re = js_get_regexp(ctx, pat, FALSE);
46302+ flags = JS_UNDEFINED;
4625846303 if (re) {
4625946304 pattern = JS_DupValue(ctx, JS_MKPTR(JS_TAG_STRING, re->pattern));
4626046305 if (JS_IsUndefined(flags1)) {
4626146306 bc = JS_DupValue(ctx, JS_MKPTR(JS_TAG_STRING, re->bytecode));
46307+ obj = js_create_from_ctor(ctx, new_target, JS_CLASS_REGEXP);
46308+ if (JS_IsException(obj))
46309+ goto fail;
4626246310 goto no_compilation;
4626346311 } else {
46264- flags = JS_ToString(ctx, flags1);
46265- if (JS_IsException(flags))
46266- goto fail;
46312+ flags = JS_DupValue(ctx, flags1);
4626746313 }
4626846314 } else {
46269- flags = JS_UNDEFINED;
4627046315 if (pat_is_regexp) {
4627146316 pattern = JS_GetProperty(ctx, pat, JS_ATOM_source);
4627246317 if (JS_IsException(pattern))
@@ -46292,15 +46337,19 @@ static JSValue js_regexp_constructor(JSContext *ctx, JSValueConst new_target,
4629246337 goto fail;
4629346338 }
4629446339 }
46340+ obj = js_create_from_ctor(ctx, new_target, JS_CLASS_REGEXP);
46341+ if (JS_IsException(obj))
46342+ goto fail;
4629546343 bc = js_compile_regexp(ctx, pattern, flags);
4629646344 if (JS_IsException(bc))
4629746345 goto fail;
4629846346 JS_FreeValue(ctx, flags);
4629946347 no_compilation:
46300- return js_regexp_constructor_internal (ctx, new_target , pattern, bc);
46348+ return js_regexp_set_internal (ctx, obj , pattern, bc);
4630146349 fail:
4630246350 JS_FreeValue(ctx, pattern);
4630346351 JS_FreeValue(ctx, flags);
46352+ JS_FreeValue(ctx, obj);
4630446353 return JS_EXCEPTION;
4630546354}
4630646355
0 commit comments