mirror of
https://github.com/espruino/Espruino.git
synced 2025-12-08 19:06:15 +00:00
Fix exception when performing record access on object from getter (fix #1454)
This commit is contained in:
parent
d484396779
commit
4b10fad88f
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
28
src/jsvar.c
28
src/jsvar.c
@ -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.
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user