Fix exception when performing record access on object from getter (fix #1454)

This commit is contained in:
Gordon Williams 2018-05-31 12:29:46 +01:00
parent d484396779
commit 4b10fad88f
5 changed files with 26 additions and 16 deletions

View File

@ -9,6 +9,7 @@
Added getter and setter support
Stop parsing blocks if not executing (fix #572)
Fix stack overflow if interpreting a file full of '{' (fix #1448)
Fix exception when performing record access on object from getter (fix #1454)
1v99 : Increase jslMatch error buffer size to handle "UNFINISHED TEMPLATE LITERAL" string (#1426)
nRF5x: Make FlashWrite cope with flash writes > 4k

View File

@ -1044,7 +1044,7 @@ NO_INLINE JsVar *jspeFactorMember(JsVar *a, JsVar **parentResult) {
// Note: name will go away when we parse something else!
const char *name = jslGetTokenValueAsString(lex);
JsVar *aVar = jsvSkipName(a);
JsVar *aVar = jsvSkipNameWithParent(a,true,parent);
JsVar *child = 0;
if (aVar)
child = jspGetNamedField(aVar, name, true);
@ -1079,7 +1079,7 @@ NO_INLINE JsVar *jspeFactorMember(JsVar *a, JsVar **parentResult) {
JSP_MATCH_WITH_CLEANUP_AND_RETURN(']', jsvUnLock2(parent, index);, a);
if (JSP_SHOULD_EXECUTE) {
index = jsvAsArrayIndexAndUnLock(index);
JsVar *aVar = jsvSkipName(a);
JsVar *aVar = jsvSkipNameWithParent(a,true,parent);
JsVar *child = 0;
if (aVar)
child = jspGetVarNamedField(aVar, index, true);

View File

@ -2096,8 +2096,10 @@ void jsvCheckReferenceError(JsVar *a) {
/** If a is a name skip it and go to what it points to - and so on (if repeat=true).
* ALWAYS locks - so must unlock what it returns. It MAY
* return 0. Throws a ReferenceError if variable is not defined,
* but you can check if it will with jsvIsReferenceError */
static JsVar *jsvSkipNameInternal(JsVar *a, bool repeat) {
* but you can check if it will with jsvIsReferenceError.
* If a 'getter' needs to be executed, 'parent' is the object that
* gets used unless a NewChild overwrites it */
JsVar *jsvSkipNameWithParent(JsVar *a, bool repeat, JsVar *parent) {
if (!a) return 0;
if (jsvIsArrayBufferName(a)) return jsvArrayBufferGetFromName(a);
if (jsvIsNameInt(a)) return jsvNewFromInteger((JsVarInt)jsvGetFirstChildSigned(a));
@ -2113,16 +2115,16 @@ static JsVar *jsvSkipNameInternal(JsVar *a, bool repeat) {
}
pa = jsvLock(n);
assert(pa!=a);
#ifndef SAVE_ON_FLASH
if (jsvIsGetterOrSetter(pa)) {
JsVar *parent = jsvIsNewChild(a)?jsvLock(jsvGetNextSibling(a)):0;
JsVar *v = jsvExecuteGetter(parent, pa);
jsvUnLock2(parent,pa);
pa = v;
}
#endif
if (!repeat) return pa;
if (!repeat) break;
}
#ifndef SAVE_ON_FLASH
if (jsvIsGetterOrSetter(pa)) {
JsVar *getterParent = jsvIsNewChild(a)?jsvLock(jsvGetNextSibling(a)):0;
JsVar *v = jsvExecuteGetter(getterParent?getterParent:parent, pa);
jsvUnLock2(getterParent,pa);
pa = v;
}
#endif
return pa;
}
@ -2131,7 +2133,7 @@ static JsVar *jsvSkipNameInternal(JsVar *a, bool repeat) {
* return 0. Throws a ReferenceError if variable is not defined,
* but you can check if it will with jsvIsReferenceError */
JsVar *jsvSkipName(JsVar *a) {
return jsvSkipNameInternal(a, true);
return jsvSkipNameWithParent(a, true, 0);
}
/** If a is a name skip it and go to what it points to.
@ -2139,7 +2141,7 @@ JsVar *jsvSkipName(JsVar *a) {
* return 0. Throws a ReferenceError if variable is not defined,
* but you can check if it will with jsvIsReferenceError */
JsVar *jsvSkipOneName(JsVar *a) {
return jsvSkipNameInternal(a, false);
return jsvSkipNameWithParent(a, false, 0);
}
/** If a is a's child is a name skip it and go to what it points to.

View File

@ -580,6 +580,12 @@ JsVar *jsvGetValueOfName(JsVar *name);
/* Check for and trigger a ReferenceError on a variable if it's a name that doesn't exist */
void jsvCheckReferenceError(JsVar *a);
/** If a is a name skip it and go to what it points to - and so on (if repeat=true).
* ALWAYS locks - so must unlock what it returns. It MAY
* return 0. Throws a ReferenceError if variable is not defined,
* but you can check if it will with jsvIsReferenceError */
JsVar *jsvSkipNameWithParent(JsVar *a, bool repeat, JsVar *parent);
/** If a is a name skip it and go to what it points to - and so on.
* ALWAYS locks - so must unlock what it returns. It MAY
* return 0. Throws a ReferenceError if variable is not defined,

View File

@ -49,6 +49,7 @@ var jsobj = {
};
// accessing jsobj.prop works, jsobj.prop.a doesn't!
results.push(jsobj.prop.a);
results.push(jsobj["prop"]["b"]);
result = results=="c,test,,1,world,astring";
result = results=="c,test,,1,world,astring,1234";