Skip to content

Commit e779e5a

Browse files
committed
Add append optimisation for string '+', and don't append to flat/native/etc strings (fix #1746)
1 parent b3aeb08 commit e779e5a

File tree

3 files changed

+9
-4
lines changed

3 files changed

+9
-4
lines changed

ChangeLog

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
Bangle.js: Remove deprecated Bangle.menu
7575
Ensure it's possible to get a solid background when using 4x6 font
7676
Bangle.js: Add Bangle.showLauncher
77+
Add append optimisation for string '+', and don't append to flat/native/etc strings (fix #1746)
7778

7879
2v04 : Allow \1..\9 escape codes in RegExp
7980
ESP8266: reading storage is not working for boot from user2 (fix #1507)

src/jsparse.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1998,7 +1998,7 @@ NO_INLINE JsVar *__jspeAssignmentExpression(JsVar *lhs) {
19981998
else if (op==LEX_RSHIFTUNSIGNEDEQUAL) op=LEX_RSHIFTUNSIGNED;
19991999
if (op=='+' && jsvIsName(lhs)) {
20002000
JsVar *currentValue = jsvSkipName(lhs);
2001-
if (jsvIsString(currentValue) && !jsvIsFlatString(currentValue) && jsvGetRefs(currentValue)==1 && rhs!=currentValue) {
2001+
if (jsvIsBasicString(currentValue) && jsvGetRefs(currentValue)==1 && rhs!=currentValue) {
20022002
/* A special case for string += where this is the only use of the string
20032003
* and we're not appending to ourselves. In this case we can do a
20042004
* simple append (rather than clone + append)*/

src/jsvar.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ bool jsvIsInt(const JsVar *v) { return v && ((v->flags&JSV_VARTYPEMASK)==JSV_INT
7171
bool jsvIsFloat(const JsVar *v) { return v && (v->flags&JSV_VARTYPEMASK)==JSV_FLOAT; }
7272
bool jsvIsBoolean(const JsVar *v) { return v && ((v->flags&JSV_VARTYPEMASK)==JSV_BOOLEAN || (v->flags&JSV_VARTYPEMASK)==JSV_NAME_INT_BOOL); }
7373
bool jsvIsString(const JsVar *v) { return v && (v->flags&JSV_VARTYPEMASK)>=_JSV_STRING_START && (v->flags&JSV_VARTYPEMASK)<=_JSV_STRING_END; } ///< String, or a NAME too
74-
bool jsvIsBasicString(const JsVar *v) { return v && (v->flags&JSV_VARTYPEMASK)>=JSV_STRING_0 && (v->flags&JSV_VARTYPEMASK)<=JSV_STRING_MAX; } ///< Just a string (NOT a name)
74+
bool jsvIsBasicString(const JsVar *v) { return v && (v->flags&JSV_VARTYPEMASK)>=JSV_STRING_0 && (v->flags&JSV_VARTYPEMASK)<=JSV_STRING_MAX; } ///< Just a string (NOT a name/flatstr/nativestr or flashstr)
7575
bool jsvIsStringExt(const JsVar *v) { return v && (v->flags&JSV_VARTYPEMASK)>=JSV_STRING_EXT_0 && (v->flags&JSV_VARTYPEMASK)<=JSV_STRING_EXT_MAX; } ///< The extra bits dumped onto the end of a string to store more data
7676
bool jsvIsFlatString(const JsVar *v) { return v && (v->flags&JSV_VARTYPEMASK)==JSV_FLAT_STRING; }
7777
bool jsvIsNativeString(const JsVar *v) { return v && (v->flags&JSV_VARTYPEMASK)==JSV_NATIVE_STRING; }
@@ -3485,8 +3485,12 @@ JsVar *jsvMathsOp(JsVar *a, JsVar *b, int op) {
34853485
return 0;
34863486
}
34873487
if (op=='+') {
3488-
JsVar *v = jsvCopy(da, false);
3489-
// TODO: can we be fancy and not copy da if we know it isn't reffed? what about locks?
3488+
JsVar *v;
3489+
// Don't copy 'da' if it's not used elsewhere (eg we made it in 'jsvAsString' above)
3490+
if (jsvIsBasicString(da) && jsvGetLocks(da)==1 && jsvGetRefs(da)==0)
3491+
v = jsvLockAgain(da);
3492+
else
3493+
v = jsvCopy(da, false);
34903494
if (v) // could be out of memory
34913495
jsvAppendStringVarComplete(v, db);
34923496
jsvUnLock2(da, db);

0 commit comments

Comments
 (0)