I love Eclipse global regex replace :)

Use jsvUnLock2/etc to really drop memory usage
This commit is contained in:
Gordon Williams 2015-09-18 12:10:59 +01:00
parent 7e02bc438a
commit 80ce11135a
39 changed files with 267 additions and 364 deletions

View File

@ -334,8 +334,8 @@ JsVar *jswrap_fs_stat(JsVar *path) {
if (res==0 /*ok*/) {
JsVar *obj = jsvNewWithFlags(JSV_OBJECT);
if (!obj) return 0;
jsvUnLock(jsvObjectSetChild(obj, "size", jsvNewFromInteger((JsVarInt)info.fsize)));
jsvUnLock(jsvObjectSetChild(obj, "dir", jsvNewFromBool(info.fattrib & AM_DIR)));
jsvObjectSetChildAndUnLock(obj, "size", jsvNewFromInteger((JsVarInt)info.fsize));
jsvObjectSetChildAndUnLock(obj, "dir", jsvNewFromBool(info.fattrib & AM_DIR));
CalendarDate date;
date.year = 1980+(int)((info.fdate>>9)&127);
@ -348,7 +348,7 @@ JsVar *jswrap_fs_stat(JsVar *path) {
td.sec = (int)((info.ftime)&63);
td.ms = 0;
td.zone = 0;
jsvUnLock(jsvObjectSetChild(obj, "mtime", jswrap_date_from_milliseconds(fromTimeInDay(&td))));
jsvObjectSetChildAndUnLock(obj, "mtime", jswrap_date_from_milliseconds(fromTimeInDay(&td)));
return obj;
}
}
@ -357,9 +357,9 @@ JsVar *jswrap_fs_stat(JsVar *path) {
if (stat(pathStr, &info)==0 /*ok*/) {
JsVar *obj = jsvNewWithFlags(JSV_OBJECT);
if (!obj) return 0;
jsvUnLock(jsvObjectSetChild(obj, "size", jsvNewFromInteger((JsVarInt)info.st_size)));
jsvUnLock(jsvObjectSetChild(obj, "dir", jsvNewFromBool(S_ISDIR(info.st_mode))));
jsvUnLock(jsvObjectSetChild(obj, "mtime", jswrap_date_from_milliseconds((JsVarFloat)info.st_mtime*1000.0)));
jsvObjectSetChildAndUnLock(obj, "size", jsvNewFromInteger((JsVarInt)info.st_size));
jsvObjectSetChildAndUnLock(obj, "dir", jsvNewFromBool(S_ISDIR(info.st_mode)));
jsvObjectSetChildAndUnLock(obj, "mtime", jswrap_date_from_milliseconds((JsVarFloat)info.st_mtime*1000.0));
return obj;
}
#endif

View File

@ -67,8 +67,7 @@ void jswrap_graphics_init() {
lcdSetCallbacks_FSMC(&gfx);
graphicsSplash(&gfx);
graphicsSetVar(&gfx);
jsvUnLock(parentObj);
jsvUnLock(parent);
jsvUnLock2(parentObj, parent);
}
#endif
}
@ -192,12 +191,12 @@ JsVar *jswrap_graphics_createCallback(int width, int height, int bpp, JsVar *cal
callbackSetPixel = jsvLockAgain(callback);
if (!jsvIsFunction(callbackSetPixel)) {
jsExceptionHere(JSET_ERROR, "Expecting Callback Function or an Object but got %t", callbackSetPixel);
jsvUnLock(callbackSetPixel);jsvUnLock(callbackFillRect);
jsvUnLock2(callbackSetPixel, callbackFillRect);
return 0;
}
if (!jsvIsUndefined(callbackFillRect) && !jsvIsFunction(callbackFillRect)) {
jsExceptionHere(JSET_ERROR, "Expecting Callback Function or an Object but got %t", callbackFillRect);
jsvUnLock(callbackSetPixel);jsvUnLock(callbackFillRect);
jsvUnLock2(callbackSetPixel, callbackFillRect);
return 0;
}
@ -213,7 +212,7 @@ JsVar *jswrap_graphics_createCallback(int width, int height, int bpp, JsVar *cal
gfx.data.bpp = (unsigned char)bpp;
lcdInit_JS(&gfx, callbackSetPixel, callbackFillRect);
graphicsSetVar(&gfx);
jsvUnLock(callbackSetPixel);jsvUnLock(callbackFillRect);
jsvUnLock2(callbackSetPixel, callbackFillRect);
return parent;
}
@ -564,8 +563,8 @@ void jswrap_graphics_setFontCustom(JsVar *parent, JsVar *bitmap, int firstChar,
}
jsvObjectSetChild(parent, JSGRAPHICS_CUSTOMFONT_BMP, bitmap);
jsvObjectSetChild(parent, JSGRAPHICS_CUSTOMFONT_WIDTH, width);
jsvUnLock(jsvObjectSetChild(parent, JSGRAPHICS_CUSTOMFONT_HEIGHT, jsvNewFromInteger(height)));
jsvUnLock(jsvObjectSetChild(parent, JSGRAPHICS_CUSTOMFONT_FIRSTCHAR, jsvNewFromInteger(firstChar)));
jsvObjectSetChildAndUnLock(parent, JSGRAPHICS_CUSTOMFONT_HEIGHT, jsvNewFromInteger(height));
jsvObjectSetChildAndUnLock(parent, JSGRAPHICS_CUSTOMFONT_FIRSTCHAR, jsvNewFromInteger(firstChar));
gfx.data.fontSize = JSGRAPHICS_FONTSIZE_CUSTOM;
graphicsSetVar(&gfx);
}
@ -653,10 +652,7 @@ void jswrap_graphics_drawString(JsVar *parent, JsVar *var, int x, int y) {
jsvStringIteratorNext(&it);
}
jsvStringIteratorFree(&it);
jsvUnLock(str);
jsvUnLock(customBitmap);
jsvUnLock(customWidth);
jsvUnLock3(str, customBitmap, customWidth);
graphicsSetVar(&gfx); // gfx data changed because modified area
}
@ -704,9 +700,7 @@ JsVarInt jswrap_graphics_stringWidth(JsVar *parent, JsVar *var) {
jsvStringIteratorNext(&it);
}
jsvStringIteratorFree(&it);
jsvUnLock(str);
jsvUnLock(customWidth);
jsvUnLock2(str, customWidth);
return width;
}
@ -935,10 +929,10 @@ JsVar *jswrap_graphics_getModified(JsVar *parent, bool reset) {
if (gfx.data.modMinX <= gfx.data.modMaxX) { // do we have a rect?
obj = jsvNewWithFlags(JSV_OBJECT);
if (obj) {
jsvUnLock(jsvObjectSetChild(obj, "x1", jsvNewFromInteger(gfx.data.modMinX)));
jsvUnLock(jsvObjectSetChild(obj, "y1", jsvNewFromInteger(gfx.data.modMinY)));
jsvUnLock(jsvObjectSetChild(obj, "x2", jsvNewFromInteger(gfx.data.modMaxX)));
jsvUnLock(jsvObjectSetChild(obj, "y2", jsvNewFromInteger(gfx.data.modMaxY)));
jsvObjectSetChildAndUnLock(obj, "x1", jsvNewFromInteger(gfx.data.modMinX));
jsvObjectSetChildAndUnLock(obj, "y1", jsvNewFromInteger(gfx.data.modMinY));
jsvObjectSetChildAndUnLock(obj, "x2", jsvNewFromInteger(gfx.data.modMaxX));
jsvObjectSetChildAndUnLock(obj, "y2", jsvNewFromInteger(gfx.data.modMaxY));
}
}
if (reset) {

View File

@ -118,8 +118,7 @@ void lcdFillRect_ArrayBuffer(struct JsGraphics *gfx, short x1, short y1, short
void lcdInit_ArrayBuffer(JsGraphics *gfx) {
// create buffer
JsVar *buf = jswrap_arraybuffer_constructor((gfx->data.width * gfx->data.height * gfx->data.bpp + 7) >> 3);
jsvUnLock(jsvAddNamedChild(gfx->graphicsVar, buf, "buffer"));
jsvUnLock(buf);
jsvUnLock2(jsvAddNamedChild(gfx->graphicsVar, buf, "buffer"), buf);
}
void lcdSetCallbacks_ArrayBuffer(JsGraphics *gfx) {

View File

@ -112,11 +112,11 @@ JsVar *jswrap_hashlib_sha2(JsHashType hash_type) {
jsvSetString(jsCtx, hashFunctions[hash_type].data, hashFunctions[hash_type].ctx_size);
jsvUnLock(jsvObjectSetChild(hashobj, "block_size", jsvNewFromInteger((JsVarInt)hashFunctions[hash_type].block_size)));
jsvUnLock(jsvObjectSetChild(hashobj, "context", jsCtx));
jsvUnLock(jsvObjectSetChild(hashobj, "digest_size", jsvNewFromInteger((JsVarInt)hashFunctions[hash_type].digest_size)));
jsvUnLock(jsvObjectSetChild(hashobj, "hash_type", jsvNewFromInteger(hash_type)));
jsvUnLock(jsvObjectSetChild(hashobj, "name", jsvNewFromString(hashFunctions[hash_type].name)));
jsvObjectSetChildAndUnLock(hashobj, "block_size", jsvNewFromInteger((JsVarInt)hashFunctions[hash_type].block_size));
jsvObjectSetChildAndUnLock(hashobj, "context", jsCtx);
jsvObjectSetChildAndUnLock(hashobj, "digest_size", jsvNewFromInteger((JsVarInt)hashFunctions[hash_type].digest_size));
jsvObjectSetChildAndUnLock(hashobj, "hash_type", jsvNewFromInteger(hash_type));
jsvObjectSetChildAndUnLock(hashobj, "name", jsvNewFromString(hashFunctions[hash_type].name));
return hashobj;
}

View File

@ -381,8 +381,7 @@ static void cc3000_state_change(const char *data) {
JsVar *dataVar = jsvNewFromString(data);
if (wlanObj)
jsiQueueObjectCallbacks(wlanObj, CC3000_ON_STATE_CHANGE, &dataVar, 1);
jsvUnLock(dataVar);
jsvUnLock(wlanObj);
jsvUnLock2(dataVar, wlanObj);
}
void cc3000_usynch_callback(long lEventType, char *pcData, unsigned char ucLength) {

View File

@ -134,7 +134,7 @@ bool jswrap_wlan_connect(JsVar *wlanObj, JsVar *vAP, JsVar *vKey, JsVar *callbac
// if previously completely disconnected, try and reconnect
if (jsvGetBoolAndUnLock(jsvObjectGetChild(wlanObj,JS_HIDDEN_CHAR_STR"DIS",0))) {
cc3000_initialise(wlanObj);
jsvUnLock(jsvObjectSetChild(wlanObj,JS_HIDDEN_CHAR_STR"DIS", jsvNewFromBool(false)));
jsvObjectSetChildAndUnLock(wlanObj,JS_HIDDEN_CHAR_STR"DIS", jsvNewFromBool(false));
}
if (jsvIsFunction(callback)) {
@ -172,7 +172,7 @@ void jswrap_wlan_disconnect(JsVar *wlanObj) {
JsNetwork net;
if (!networkGetFromVar(&net)) return;
jsvUnLock(jsvObjectSetChild(wlanObj,JS_HIDDEN_CHAR_STR"DIS", jsvNewFromBool(true)));
jsvObjectSetChildAndUnLock(wlanObj,JS_HIDDEN_CHAR_STR"DIS", jsvNewFromBool(true));
networkState = NETWORKSTATE_OFFLINE; // force offline
//wlan_disconnect();
wlan_stop();
@ -197,9 +197,7 @@ void jswrap_wlan_reconnect(JsVar *wlanObj) {
JsVar *cb = jsvObjectGetChild(wlanObj,CC3000_ON_STATE_CHANGE, 0);
jswrap_wlan_disconnect(wlanObj);
jswrap_wlan_connect(wlanObj, ap, key, cb);
jsvUnLock(ap);
jsvUnLock(key);
jsvUnLock(cb);
jsvUnLock3(ap, key, cb);
networkFree(&net);
}

View File

@ -386,7 +386,7 @@ bool net_esp8266_connect(JsVar *vAP, JsVar *vKey, JsVar *callback) {
void net_esp8266_gethostbyname(JsNetwork *net, char * hostName, uint32_t* out_ip_addr) {
// hacky - save the last checked name so we can put it straight into the request
*out_ip_addr = 0xFFFFFFFF;
jsvUnLock(jsvObjectSetChild(execInfo.hiddenRoot, ESP8266_DNS_NAME, jsvNewFromString(hostName)));
jsvObjectSetChildAndUnLock(execInfo.hiddenRoot, ESP8266_DNS_NAME, jsvNewFromString(hostName));
}
/// Called on idle. Do any checks required for this device
@ -507,7 +507,7 @@ int net_esp8266_recv(JsNetwork *net, int sckt, void *buf, size_t len) {
JsVar *newIpd = (chars>len) ? jsvNewFromStringVar(ipd, len, JSVAPPENDSTRINGVAR_MAXLENGTH) : 0;
jsvUnLock(ipd);
jsvUnLock(jsvObjectSetChild(execInfo.hiddenRoot, ipdName, newIpd));
jsvObjectSetChildAndUnLock(execInfo.hiddenRoot, ipdName, newIpd);
}
return (int)((chars>len) ? len : chars);
}

View File

@ -263,8 +263,7 @@ JsVar *jswrap_http_get(JsVar *options, JsVar *callback) {
if (jsvIsObject(options)) {
// if options is a string - it will be parsed, and GET will be set automatically
JsVar *method = jsvNewFromString("GET");
jsvUnLock(jsvAddNamedChild(options, method, "method"));
jsvUnLock(method);
jsvUnLock2(jsvAddNamedChild(options, method, "method"), method);
}
JsVar *skippedCallback = jsvSkipName(callback);
if (!jsvIsUndefined(skippedCallback) && !jsvIsFunction(skippedCallback)) {

View File

@ -36,8 +36,7 @@ JsVar *callFn(char* name, int argCount, JsVar **argPtr) {
r = jspeFunctionCall(child, 0, netObj, false, argCount, argPtr);
execInfo = oldExecInfo;
}
jsvUnLock(child);
jsvUnLock(netObj);
jsvUnLock2(child, netObj);
return r;
}
@ -48,7 +47,7 @@ void net_js_gethostbyname(JsNetwork *net, char * hostName, uint32_t* out_ip_addr
NOT_USED(net);
// hacky - save the last checked name so we can put it straight into the request
*out_ip_addr = 0xFFFFFFFF;
jsvUnLock(jsvObjectSetChild(execInfo.hiddenRoot, JSNET_DNS_NAME, jsvNewFromString(hostName)));
jsvObjectSetChildAndUnLock(execInfo.hiddenRoot, JSNET_DNS_NAME, jsvNewFromString(hostName));
}
/// Called on idle. Do any checks required for this device
@ -90,8 +89,7 @@ void net_js_closesocket(JsNetwork *net, int sckt) {
JsVar *args[1] = {
jsvNewFromInteger(sckt)
};
jsvUnLock(callFn("close", 1, args));
jsvUnLock(args[0]);
jsvUnLock2(callFn("close", 1, args), args[0]);
}
/// If the given server socket can accept a connection, return it (or return < 0)
@ -103,8 +101,7 @@ int net_js_accept(JsNetwork *net, int serverSckt) {
};
int sckt = jsvGetIntegerAndUnLock(callFn("accept", 1, args));
jsvUnLock(args[0]);
jsvUnLock(netObj);
jsvUnLock2(args[0], netObj);
return sckt;
}

View File

@ -133,23 +133,23 @@ JsVar *jswrap_url_parse(JsVar *url, bool parseQuery) {
if (pathStart<0) pathStart = charIdx;
int addrEnd = (portStart>=0) ? portStart : pathStart;
// pull out details
jsvUnLock(jsvObjectSetChild(obj, "method", jsvNewFromString("GET")));
jsvUnLock(jsvObjectSetChild(obj, "host", jsvNewFromStringVar(url, (size_t)(addrStart+1), (size_t)(addrEnd-(addrStart+1)))));
jsvObjectSetChildAndUnLock(obj, "method", jsvNewFromString("GET"));
jsvObjectSetChildAndUnLock(obj, "host", jsvNewFromStringVar(url, (size_t)(addrStart+1), (size_t)(addrEnd-(addrStart+1))));
JsVar *v;
v = jsvNewFromStringVar(url, (size_t)pathStart, JSVAPPENDSTRINGVAR_MAXLENGTH);
if (jsvGetStringLength(v)==0) jsvAppendString(v, "/");
jsvUnLock(jsvObjectSetChild(obj, "path", v));
jsvObjectSetChildAndUnLock(obj, "path", v);
v = jsvNewFromStringVar(url, (size_t)pathStart, (size_t)((searchStart>=0)?(searchStart-pathStart):JSVAPPENDSTRINGVAR_MAXLENGTH));
if (jsvGetStringLength(v)==0) jsvAppendString(v, "/");
jsvUnLock(jsvObjectSetChild(obj, "pathname", v));
jsvObjectSetChildAndUnLock(obj, "pathname", v);
jsvUnLock(jsvObjectSetChild(obj, "search", (searchStart>=0)?jsvNewFromStringVar(url, (size_t)searchStart, JSVAPPENDSTRINGVAR_MAXLENGTH):jsvNewNull()));
jsvObjectSetChildAndUnLock(obj, "search", (searchStart>=0)?jsvNewFromStringVar(url, (size_t)searchStart, JSVAPPENDSTRINGVAR_MAXLENGTH):jsvNewNull());
if (portNumber<=0 || portNumber>65535) portNumber=80;
jsvUnLock(jsvObjectSetChild(obj, "port", jsvNewFromInteger(portNumber)));
jsvObjectSetChildAndUnLock(obj, "port", jsvNewFromInteger(portNumber));
JsVar *query = (searchStart>=0)?jsvNewFromStringVar(url, (size_t)(searchStart+1), JSVAPPENDSTRINGVAR_MAXLENGTH):jsvNewNull();
if (parseQuery && !jsvIsNull(query)) {
@ -168,8 +168,7 @@ JsVar *jswrap_url_parse(JsVar *url, bool parseQuery) {
key = jsvAsArrayIndexAndUnLock(key); // make sure "0" gets made into 0
jsvMakeIntoVariableName(key, val);
jsvAddName(query, key);
jsvUnLock(key);
jsvUnLock(val);
jsvUnLock2(key, val);
key = jsvNewFromEmptyString();
val = jsvNewFromEmptyString();
hadEquals = false;
@ -199,10 +198,9 @@ JsVar *jswrap_url_parse(JsVar *url, bool parseQuery) {
jsvMakeIntoVariableName(key, val);
jsvAddName(query, key);
}
jsvUnLock(key);
jsvUnLock(val);
jsvUnLock2(key, val);
}
jsvUnLock(jsvObjectSetChild(obj, "query", query));
jsvObjectSetChildAndUnLock(obj, "query", query);
return obj;
}

View File

@ -104,7 +104,7 @@ JsVar *networkGetAddressAsString(unsigned char *ip, int nBytes, unsigned int bas
}
void networkPutAddressAsString(JsVar *object, const char *name, unsigned char *ip, int nBytes, unsigned int base, char separator) {
jsvUnLock(jsvObjectSetChild(object, name, networkGetAddressAsString(ip, nBytes, base, separator)));
jsvObjectSetChildAndUnLock(object, name, networkGetAddressAsString(ip, nBytes, base, separator));
}
/** Some devices (CC3000) store the IP address with the first element last, so we must flip it */
@ -136,7 +136,7 @@ void networkCreate(JsNetwork *net, JsNetworkType type) {
net->data.pinCS = PIN_UNDEFINED;
net->data.pinIRQ = PIN_UNDEFINED;
net->data.pinEN = PIN_UNDEFINED;
jsvUnLock(jsvObjectSetChild(execInfo.hiddenRoot, NETWORK_VAR_NAME, net->networkVar));
jsvObjectSetChildAndUnLock(execInfo.hiddenRoot, NETWORK_VAR_NAME, net->networkVar);
networkSet(net);
networkGetFromVar(net);
}

View File

@ -51,8 +51,7 @@ static void httpAppendHeaders(JsVar *string, JsVar *headerObject) {
jsvAppendString(string, ": ");
jsvAppendStringVarComplete(string, v);
jsvAppendString(string, "\r\n");
jsvUnLock(k);
jsvUnLock(v);
jsvUnLock2(k, v);
jsvObjectIteratorNext(&it);
}
jsvObjectIteratorFree(&it);
@ -135,12 +134,12 @@ bool httpParseHeaders(JsVar **receiveData, JsVar *objectForData, bool isServer)
jsvUnLock(vHeaders);
// try and pull out methods/etc
if (isServer) {
jsvUnLock(jsvObjectSetChild(objectForData, "method", jsvNewFromStringVar(*receiveData, 0, (size_t)firstSpace)));
jsvUnLock(jsvObjectSetChild(objectForData, "url", jsvNewFromStringVar(*receiveData, (size_t)(firstSpace+1), (size_t)(secondSpace-(firstSpace+1)))));
jsvObjectSetChildAndUnLock(objectForData, "method", jsvNewFromStringVar(*receiveData, 0, (size_t)firstSpace));
jsvObjectSetChildAndUnLock(objectForData, "url", jsvNewFromStringVar(*receiveData, (size_t)(firstSpace+1), (size_t)(secondSpace-(firstSpace+1))));
} else {
jsvUnLock(jsvObjectSetChild(objectForData, "httpVersion", jsvNewFromStringVar(*receiveData, 5, (size_t)firstSpace-5)));
jsvUnLock(jsvObjectSetChild(objectForData, "statusCode", jsvNewFromStringVar(*receiveData, (size_t)(firstSpace+1), (size_t)(secondSpace-(firstSpace+1)))));
jsvUnLock(jsvObjectSetChild(objectForData, "statusMessage", jsvNewFromStringVar(*receiveData, (size_t)(secondSpace+1), (size_t)(firstEOL-(secondSpace+1)))));
jsvObjectSetChildAndUnLock(objectForData, "httpVersion", jsvNewFromStringVar(*receiveData, 5, (size_t)firstSpace-5));
jsvObjectSetChildAndUnLock(objectForData, "statusCode", jsvNewFromStringVar(*receiveData, (size_t)(firstSpace+1), (size_t)(secondSpace-(firstSpace+1))));
jsvObjectSetChildAndUnLock(objectForData, "statusMessage", jsvNewFromStringVar(*receiveData, (size_t)(secondSpace+1), (size_t)(firstEOL-(secondSpace+1))));
}
// strip out the header
JsVar *afterHeaders = jsvNewFromStringVar(*receiveData, (size_t)headerEnd, JSVAPPENDSTRINGVAR_MAXLENGTH);
@ -176,7 +175,7 @@ static NO_INLINE SocketType socketGetType(JsVar *var) {
}
static NO_INLINE void socketSetType(JsVar *var, SocketType socketType) {
jsvUnLock(jsvObjectSetChild(var, HTTP_NAME_SOCKETTYPE, jsvNewFromInteger((JsVarInt)socketType)));
jsvObjectSetChildAndUnLock(var, HTTP_NAME_SOCKETTYPE, jsvNewFromInteger((JsVarInt)socketType));
}
void _socketConnectionKill(JsNetwork *net, JsVar *connection) {
@ -299,7 +298,7 @@ bool socketServerConnectionsIdle(JsNetwork *net) {
bool hadHeaders = jsvGetBoolAndUnLock(jsvObjectGetChild(connection,HTTP_NAME_HAD_HEADERS,0));
if (!hadHeaders && httpParseHeaders(&receiveData, connection, true)) {
hadHeaders = true;
jsvUnLock(jsvObjectSetChild(connection, HTTP_NAME_HAD_HEADERS, jsvNewFromBool(hadHeaders)));
jsvObjectSetChildAndUnLock(connection, HTTP_NAME_HAD_HEADERS, jsvNewFromBool(hadHeaders));
JsVar *server = jsvObjectGetChild(connection,HTTP_NAME_SERVER_VAR,0);
JsVar *args[2] = { connection, socket };
jsiQueueObjectCallbacks(server, HTTP_NAME_ON_CONNECT, args, (socketType==ST_HTTP) ? 2 : 1);
@ -353,8 +352,7 @@ bool socketServerConnectionsIdle(JsNetwork *net) {
jsvUnLock(connectionName);
} else
jsvObjectIteratorNext(&it);
jsvUnLock(connection);
jsvUnLock(socket);
jsvUnLock2(connection, socket);
}
jsvObjectIteratorFree(&it);
jsvUnLock(arr);
@ -436,7 +434,7 @@ bool socketClientConnectionsIdle(JsNetwork *net) {
JsVar *resVar = jsvObjectGetChild(connection,HTTP_NAME_RESPONSE_VAR,0);
if (httpParseHeaders(&receiveData, resVar, false)) {
hadHeaders = true;
jsvUnLock(jsvObjectSetChild(connection, HTTP_NAME_HAD_HEADERS, jsvNewFromBool(hadHeaders)));
jsvObjectSetChildAndUnLock(connection, HTTP_NAME_HAD_HEADERS, jsvNewFromBool(hadHeaders));
jsiQueueObjectCallbacks(connection, HTTP_NAME_ON_CONNECT, &resVar, 1);
}
jsvUnLock(resVar);
@ -470,9 +468,7 @@ bool socketClientConnectionsIdle(JsNetwork *net) {
jsvObjectIteratorNext(&it);
}
jsvUnLock(receiveData);
jsvUnLock(connection);
jsvUnLock(socket);
jsvUnLock3(receiveData, connection, socket);
}
jsvUnLock(arr);
@ -512,13 +508,12 @@ bool socketIdle(JsNetwork *net) {
}
jsvObjectSetChild(req, HTTP_NAME_RESPONSE_VAR, res);
jsvObjectSetChild(req, HTTP_NAME_SERVER_VAR, server);
jsvUnLock(jsvObjectSetChild(req, HTTP_NAME_SOCKET, jsvNewFromInteger(theClient+1)));
jsvObjectSetChildAndUnLock(req, HTTP_NAME_SOCKET, jsvNewFromInteger(theClient+1));
// on response
jsvUnLock(jsvObjectSetChild(res, HTTP_NAME_CODE, jsvNewFromInteger(200)));
jsvUnLock(jsvObjectSetChild(res, HTTP_NAME_HEADERS, jsvNewWithFlags(JSV_OBJECT)));
jsvObjectSetChildAndUnLock(res, HTTP_NAME_CODE, jsvNewFromInteger(200));
jsvObjectSetChildAndUnLock(res, HTTP_NAME_HEADERS, jsvNewWithFlags(JSV_OBJECT));
}
jsvUnLock(req);
jsvUnLock(res);
jsvUnLock2(req, res);
} else {
// Normal sockets
JsVar *sock = jspNewObject(0, "Socket");
@ -529,7 +524,7 @@ bool socketIdle(JsNetwork *net) {
jsvArrayPush(arr, sock);
jsvUnLock(arr);
}
jsvUnLock(jsvObjectSetChild(sock, HTTP_NAME_SOCKET, jsvNewFromInteger(theClient+1)));
jsvObjectSetChildAndUnLock(sock, HTTP_NAME_SOCKET, jsvNewFromInteger(theClient+1));
jsiQueueObjectCallbacks(server, HTTP_NAME_ON_CONNECT, &sock, 1);
jsvUnLock(sock);
}
@ -563,14 +558,14 @@ void serverListen(JsNetwork *net, JsVar *server, int port) {
JsVar *arr = socketGetArray(HTTP_ARRAY_HTTP_SERVERS, true);
if (!arr) return; // out of memory
jsvUnLock(jsvObjectSetChild(server, HTTP_NAME_PORT, jsvNewFromInteger(port)));
jsvObjectSetChildAndUnLock(server, HTTP_NAME_PORT, jsvNewFromInteger(port));
int sckt = net->createsocket(net, 0/*server*/, (unsigned short)port);
if (sckt<0) {
jsError("Unable to create socket\n");
jsvUnLock(jsvObjectSetChild(server, HTTP_NAME_CLOSENOW, jsvNewFromBool(true)));
jsvObjectSetChildAndUnLock(server, HTTP_NAME_CLOSENOW, jsvNewFromBool(true));
} else {
jsvUnLock(jsvObjectSetChild(server, HTTP_NAME_SOCKET, jsvNewFromInteger(sckt+1)));
jsvObjectSetChildAndUnLock(server, HTTP_NAME_SOCKET, jsvNewFromInteger(sckt+1));
// add to list of servers
jsvArrayPush(arr, server);
}
@ -614,8 +609,7 @@ JsVar *clientRequestNew(SocketType socketType, JsVar *options, JsVar *callback)
jsvObjectSetChild(req, HTTP_NAME_RESPONSE_VAR, res);
jsvObjectSetChild(req, HTTP_NAME_OPTIONS_VAR, options);
}
jsvUnLock(res);
jsvUnLock(arr);
jsvUnLock2(res, arr);
return req;
}
@ -632,8 +626,7 @@ void clientRequestWrite(JsVar *httpClientReqVar, JsVar *data) {
JsVar *method = jsvObjectGetChild(options, "method", 0);
JsVar *path = jsvObjectGetChild(options, "path", 0);
sendData = jsvVarPrintf("%v %v HTTP/1.0\r\nUser-Agent: Espruino "JS_VERSION"\r\nConnection: close\r\n", method, path);
jsvUnLock(method);
jsvUnLock(path);
jsvUnLock2(method, path);
JsVar *headers = jsvObjectGetChild(options, "headers", 0);
bool hasHostHeader = false;
if (jsvIsObject(headers)) {
@ -690,7 +683,7 @@ void clientRequestConnect(JsNetwork *net, JsVar *httpClientReqVar) {
if(!host_addr) {
jsError("Unable to locate host");
jsvUnLock(jsvObjectSetChild(httpClientReqVar, HTTP_NAME_CLOSENOW, jsvNewFromBool(true)));
jsvObjectSetChildAndUnLock(httpClientReqVar, HTTP_NAME_CLOSENOW, jsvNewFromBool(true));
jsvUnLock(options);
net->checkError(net);
return;
@ -699,9 +692,9 @@ void clientRequestConnect(JsNetwork *net, JsVar *httpClientReqVar) {
int sckt = net->createsocket(net, host_addr, port);
if (sckt<0) {
jsError("Unable to create socket\n");
jsvUnLock(jsvObjectSetChild(httpClientReqVar, HTTP_NAME_CLOSENOW, jsvNewFromBool(true)));
jsvObjectSetChildAndUnLock(httpClientReqVar, HTTP_NAME_CLOSENOW, jsvNewFromBool(true));
} else {
jsvUnLock(jsvObjectSetChild(httpClientReqVar, HTTP_NAME_SOCKET, jsvNewFromInteger(sckt+1)));
jsvObjectSetChildAndUnLock(httpClientReqVar, HTTP_NAME_SOCKET, jsvNewFromInteger(sckt+1));
// For HTTP we get the connection callback when we've got a header back
// Otherwise we just call back on success
@ -723,7 +716,7 @@ void clientRequestEnd(JsNetwork *net, JsVar *httpClientReqVar) {
clientRequestConnect(net, httpClientReqVar);
} else {
// on normal sockets, we actually request close after all data sent
jsvUnLock(jsvObjectSetChild(httpClientReqVar, HTTP_NAME_CLOSE, jsvNewFromBool(true)));
jsvObjectSetChildAndUnLock(httpClientReqVar, HTTP_NAME_CLOSE, jsvNewFromBool(true));
}
}
@ -734,7 +727,7 @@ void serverResponseWriteHead(JsVar *httpServerResponseVar, int statusCode, JsVar
return;
}
jsvUnLock(jsvObjectSetChild(httpServerResponseVar, HTTP_NAME_CODE, jsvNewFromInteger(statusCode)));
jsvObjectSetChildAndUnLock(httpServerResponseVar, HTTP_NAME_CODE, jsvNewFromInteger(statusCode));
JsVar *sendHeaders = jsvObjectGetChild(httpServerResponseVar, HTTP_NAME_HEADERS, 0);
if (sendHeaders) {
if (!jsvIsUndefined(headers)) {
@ -777,6 +770,6 @@ void serverResponseWrite(JsVar *httpServerResponseVar, JsVar *data) {
void serverResponseEnd(JsVar *httpServerResponseVar) {
serverResponseWrite(httpServerResponseVar, 0); // force connection->sendData to be created even if data not called
jsvUnLock(jsvObjectSetChild(httpServerResponseVar, HTTP_NAME_CLOSE, jsvNewFromBool(true)));
jsvObjectSetChildAndUnLock(httpServerResponseVar, HTTP_NAME_CLOSE, jsvNewFromBool(true));
}

View File

@ -208,11 +208,9 @@ JsVar *jswrap_trig_getTrigger(JsVarInt num) {
if (!obj) return 0;
JsVar *v;
v = jsvNewFromFloat(position);
jsvUnLock(jsvAddNamedChild(obj, v, "pos"));
jsvUnLock(v);
jsvUnLock2(jsvAddNamedChild(obj, v, "pos"), v);
v = jsvNewFromFloat(jshGetMillisecondsFromTime(tp->pulseLength));
jsvUnLock(jsvAddNamedChild(obj, v, "pulseLength"));
jsvUnLock(v);
jsvUnLock2(jsvAddNamedChild(obj, v, "pulseLength"), v);
v = jsvNewWithFlags(JSV_ARRAY);
int i;
if (v) {
@ -221,8 +219,7 @@ JsVar *jswrap_trig_getTrigger(JsVarInt num) {
jsvArrayPushAndUnLock(v, jsvNewFromPin(tp->pins[i]));
}
}
jsvUnLock(jsvAddNamedChild(obj, v, "pins"));
jsvUnLock(v);
jsvUnLock2(jsvAddNamedChild(obj, v, "pins"), v);
return obj;
}

View File

@ -384,8 +384,7 @@ void jsiSoftInit() {
// Now run initialisation code
JsVar *initCode = jsvObjectGetChild(execInfo.hiddenRoot, JSI_INIT_CODE_NAME, 0);
if (initCode) {
jsvUnLock(jspEvaluateVar(initCode, 0, false));
jsvUnLock(initCode);
jsvUnLock2(jspEvaluateVar(initCode, 0, false), initCode);
jsvRemoveNamedChild(execInfo.hiddenRoot, JSI_INIT_CODE_NAME);
}
@ -398,8 +397,7 @@ void jsiSoftInit() {
JsVar *watch = jsvObjectIteratorGetValue(&it);
JsVar *watchPin = jsvObjectGetChild(watch, "pin", 0);
jshPinWatch(jshGetPinFromVar(watchPin), true);
jsvUnLock(watchPin);
jsvUnLock(watch);
jsvUnLock2(watchPin, watch);
jsvObjectIteratorNext(&it);
}
jsvObjectIteratorFree(&it);
@ -467,9 +465,7 @@ void jsiDumpSerialInitialisation(vcbprintf_callback user_callback, void *user_da
}
user_callback(");\n", user_data);
}
jsvUnLock(baud);
jsvUnLock(options);
jsvUnLock(serialVar);
jsvUnLock3(baud, options, serialVar);
}
}
@ -484,8 +480,7 @@ void jsiDumpDeviceInitialisation(vcbprintf_callback user_callback, void *user_da
jsfGetJSONWithCallback(options, JSON_SHOW_DEVICES, user_callback, user_data);
user_callback(");\n", user_data);
}
jsvUnLock(options);
jsvUnLock(deviceVar);
jsvUnLock2(options, deviceVar);
}
}
@ -568,8 +563,7 @@ void jsiSoftKill() {
JsVar *watchPtr = jsvObjectIteratorGetValue(&it);
JsVar *watchPin = jsvObjectGetChild(watchPtr, "pin", 0);
jshPinWatch(jshGetPinFromVar(watchPin), false);
jsvUnLock(watchPin);
jsvUnLock(watchPtr);
jsvUnLock2(watchPin, watchPtr);
jsvObjectIteratorNext(&it);
}
jsvObjectIteratorFree(&it);
@ -701,8 +695,7 @@ bool jsiFreeMoreMemory() {
if (!history) return 0;
JsVar *item = jsvArrayPopFirst(history);
bool freed = item!=0;
jsvUnLock(item);
jsvUnLock(history);
jsvUnLock2(item, history);
// TODO: could also free the array structure?
// TODO: could look at all streams (Serial1/HTTP/etc) and see if their buffers contain data that could be removed
@ -752,8 +745,7 @@ bool jsiIsInHistory(JsVar *line) {
if (!history) return false;
JsVar *historyFound = jsvGetArrayIndexOf(history, line, true/*exact*/);
bool inHistory = historyFound!=0;
jsvUnLock(historyFound);
jsvUnLock(history);
jsvUnLock2(historyFound, history);
return inHistory;
}
@ -1149,8 +1141,7 @@ void jsiQueueEvents(JsVar *object, JsVar *callback, JsVar **args, int argCount)
if (argCount) {
JsVar *arr = jsvNewArray(args, argCount);
if (arr) {
jsvUnLock(jsvAddNamedChild(event, arr, "args"));
jsvUnLock(arr);
jsvUnLock2(jsvAddNamedChild(event, arr, "args"), arr);
}
}
if (object) jsvUnLock(jsvAddNamedChild(event, object, "this"));
@ -1188,8 +1179,7 @@ void jsiExecuteEvents() {
jsiExecuteEventCallbackArgsArray(thisVar, func, argsArray);
jsvUnLock(argsArray);
//jsPrint("Event Done\n");
jsvUnLock(func);
jsvUnLock(thisVar);
jsvUnLock2(func, thisVar);
}
if (hasEvents) {
jsiSetBusy(BUSY_INTERACTIVE, false);
@ -1267,8 +1257,7 @@ bool jsiIsWatchingPin(Pin pin) {
JsVar *pinVar = jsvObjectGetChild(watchPtr, "pin", 0);
if (jshGetPinFromVar(pinVar) == pin)
isWatched = true;
jsvUnLock(pinVar);
jsvUnLock(watchPtr);
jsvUnLock2(pinVar, watchPtr);
jsvObjectIteratorNext(&it);
}
jsvObjectIteratorFree(&it);
@ -1384,12 +1373,12 @@ void jsiIdle() {
} else { // Debouncing - use timeouts to ensure we only fire at the right time
// store the current state of the pin
bool oldWatchState = jsvGetBoolAndUnLock(jsvObjectGetChild(watchPtr, "state",0));
jsvUnLock(jsvObjectSetChild(watchPtr, "state", jsvNewFromBool(pinIsHigh)));
jsvObjectSetChildAndUnLock(watchPtr, "state", jsvNewFromBool(pinIsHigh));
JsVar *timeout = jsvObjectGetChild(watchPtr, "timeout", 0);
if (timeout) { // if we had a timeout, update the callback time
JsSysTime timeoutTime = jsiLastIdleTime + (JsSysTime)jsvGetIntegerAndUnLock(jsvObjectGetChild(timeout, "time", 0));
jsvUnLock(jsvObjectSetChild(timeout, "time", jsvNewFromInteger((JsVarInt)(eventTime - jsiLastIdleTime) + debounce)));
jsvObjectSetChildAndUnLock(timeout, "time", jsvNewFromInteger((JsVarInt)(eventTime - jsiLastIdleTime) + debounce));
if (eventTime > timeoutTime) {
// timeout should have fired, but we didn't get around to executing it!
// Do it now (with the old timeout time)
@ -1401,10 +1390,10 @@ void jsiIdle() {
timeout = jsvNewWithFlags(JSV_OBJECT);
if (timeout) {
jsvObjectSetChild(timeout, "watch", watchPtr); // no unlock
jsvUnLock(jsvObjectSetChild(timeout, "time", jsvNewFromInteger((JsVarInt)(eventTime - jsiLastIdleTime) + debounce)));
jsvUnLock(jsvObjectSetChild(timeout, "callback", jsvObjectGetChild(watchPtr, "callback", 0)));
jsvUnLock(jsvObjectSetChild(timeout, "lastTime", jsvObjectGetChild(watchPtr, "lastTime", 0)));
jsvUnLock(jsvObjectSetChild(timeout, "pin", jsvNewFromPin(pin)));
jsvObjectSetChildAndUnLock(timeout, "time", jsvNewFromInteger((JsVarInt)(eventTime - jsiLastIdleTime) + debounce));
jsvObjectSetChildAndUnLock(timeout, "callback", jsvObjectGetChild(watchPtr, "callback", 0));
jsvObjectSetChildAndUnLock(timeout, "lastTime", jsvObjectGetChild(watchPtr, "lastTime", 0));
jsvObjectSetChildAndUnLock(timeout, "pin", jsvNewFromPin(pin));
// Add to timer array
jsiTimerAdd(timeout);
// Add to our watch
@ -1422,11 +1411,11 @@ void jsiIdle() {
bool watchRecurring = jsvGetBoolAndUnLock(jsvObjectGetChild(watchPtr, "recur", 0));
JsVar *data = jsvNewWithFlags(JSV_OBJECT);
if (data) {
jsvUnLock(jsvObjectSetChild(data, "lastTime", jsvObjectGetChild(watchPtr, "lastTime", 0)));
jsvObjectSetChildAndUnLock(data, "lastTime", jsvObjectGetChild(watchPtr, "lastTime", 0));
// set both data.time, and watch.lastTime in one go
jsvObjectSetChild(data, "time", timePtr); // no unlock
jsvUnLock(jsvObjectSetChild(data, "pin", jsvNewFromPin(pin)));
jsvUnLock(jsvObjectSetChild(data, "state", jsvNewFromBool(pinIsHigh)));
jsvObjectSetChildAndUnLock(data, "pin", jsvNewFromPin(pin));
jsvObjectSetChildAndUnLock(data, "state", jsvNewFromBool(pinIsHigh));
}
if (!jsiExecuteEventCallback(0, watchCallback, 1, &data) && watchRecurring) {
jsError("Ctrl-C while processing watch - removing it.");
@ -1443,7 +1432,7 @@ void jsiIdle() {
}
jsvUnLock(watchCallback);
}
jsvUnLock(jsvObjectSetChild(watchPtr, "lastTime", timePtr));
jsvObjectSetChildAndUnLock(watchPtr, "lastTime", timePtr);
}
}
@ -1504,10 +1493,10 @@ void jsiIdle() {
bool state = jsvGetBoolAndUnLock(jsvObjectSetChild(data, "state", jsvObjectGetChild(watchPtr, "state", 0)));
exec = jsiShouldExecuteWatch(watchPtr, state);
// set up the lastTime variable of data to what was in the watch
jsvUnLock(jsvObjectSetChild(data, "lastTime", jsvObjectGetChild(watchPtr, "lastTime", 0)));
jsvObjectSetChildAndUnLock(data, "lastTime", jsvObjectGetChild(watchPtr, "lastTime", 0));
// set up the watches lastTime to this one
jsvObjectSetChild(watchPtr, "lastTime", timePtr); // don't unlock
jsvUnLock(jsvObjectSetChild(data, "time", timePtr));
jsvObjectSetChildAndUnLock(data, "time", timePtr);
}
}
JsVar *interval = jsvObjectGetChild(timerPtr, "interval", 0);
@ -1568,7 +1557,7 @@ void jsiIdle() {
minTimeUntilNext = timeUntilNext;
// update the timer's time
if (!hasDeletedTimer) {
jsvUnLock(jsvObjectSetChild(timerPtr, "time", jsvNewFromLongInteger(timeUntilNext)));
jsvObjectSetChildAndUnLock(timerPtr, "time", jsvNewFromLongInteger(timeUntilNext));
jsvObjectIteratorNext(&it);
}
jsvUnLock(timerPtr);
@ -1735,8 +1724,7 @@ NO_INLINE void jsiDumpObjectState(vcbprintf_callback user_callback, void *user_d
}
}
}
jsvUnLock(data);
jsvUnLock(child);
jsvUnLock2(data, child);
jsvObjectIteratorNext(&it);
}
jsvObjectIteratorFree(&it);
@ -1791,8 +1779,7 @@ void jsiDumpState(vcbprintf_callback user_callback, void *user_data) {
}
}
}
jsvUnLock(data);
jsvUnLock(child);
jsvUnLock2(data, child);
jsvObjectIteratorNext(&it);
}
jsvObjectIteratorFree(&it);
@ -1807,8 +1794,7 @@ void jsiDumpState(vcbprintf_callback user_callback, void *user_data) {
user_callback(timerInterval ? "setInterval(" : "setTimeout(", user_data);
jsiDumpJSON(user_callback, user_data, timerCallback, 0);
cbprintf(user_callback, user_data, ", %f);\n", jshGetMillisecondsFromTime(timerInterval ? jsvGetLongInteger(timerInterval) : jsvGetLongIntegerAndUnLock(jsvObjectGetChild(timer, "time", 0))));
jsvUnLock(timerInterval);
jsvUnLock(timerCallback);
jsvUnLock2(timerInterval, timerCallback);
// next
jsvUnLock(timer);
jsvObjectIteratorNext(&it);
@ -1834,8 +1820,7 @@ void jsiDumpState(vcbprintf_callback user_callback, void *user_data) {
if (watchDebounce>0)
cbprintf(user_callback, user_data, ", debounce : %f", jshGetMillisecondsFromTime(watchDebounce));
user_callback(" });\n", user_data);
jsvUnLock(watchPin);
jsvUnLock(watchCallback);
jsvUnLock2(watchPin, watchCallback);
// next
jsvUnLock(watch);
jsvObjectIteratorNext(&it);
@ -1928,9 +1913,7 @@ void jsiDebuggerPrintScope(JsVar *scope) {
jsiConsolePrint("\n");
}
jsvUnLock(k);
jsvUnLock(ks);
jsvUnLock(v);
jsvUnLock3(k, ks, v);
jsvObjectIteratorNext(&it);
}
jsvObjectIteratorFree(&it);

View File

@ -370,8 +370,7 @@ NO_INLINE JsVar *jspeFunctionDefinition(bool parseNamedFunction) {
// Get arguments save them to the structure
if (!jspeFunctionArguments(funcVar)) {
jsvUnLock(functionInternalName);
jsvUnLock(funcVar);
jsvUnLock2(functionInternalName, funcVar);
// parse failed
return 0;
}
@ -385,17 +384,15 @@ NO_INLINE JsVar *jspeFunctionDefinition(bool parseNamedFunction) {
if (actuallyCreateFunction) {
// code var
JsVar *funcCodeVar = jslNewFromLexer(&funcBegin, (size_t)(execInfo.lex->tokenLastStart+1));
jsvUnLock(jsvAddNamedChild(funcVar, funcCodeVar, JSPARSE_FUNCTION_CODE_NAME));
jsvUnLock(funcCodeVar);
jsvUnLock2(jsvAddNamedChild(funcVar, funcCodeVar, JSPARSE_FUNCTION_CODE_NAME), funcCodeVar);
// scope var
JsVar *funcScopeVar = jspeiGetScopesAsVar();
if (funcScopeVar) {
jsvUnLock(jsvAddNamedChild(funcVar, funcScopeVar, JSPARSE_FUNCTION_SCOPE_NAME));
jsvUnLock(funcScopeVar);
jsvUnLock2(jsvAddNamedChild(funcVar, funcScopeVar, JSPARSE_FUNCTION_SCOPE_NAME), funcScopeVar);
}
// if we had a function name, add it to the end
if (functionInternalName)
jsvUnLock(jsvObjectSetChild(funcVar, JSPARSE_FUNCTION_NAME_NAME, functionInternalName));
jsvObjectSetChildAndUnLock(funcVar, JSPARSE_FUNCTION_NAME_NAME, functionInternalName);
}
jslCharPosFree(&funcBegin);
@ -587,14 +584,12 @@ NO_INLINE JsVar *jspeFunctionCall(JsVar *function, JsVar *functionName, JsVar *t
jsvUnLock(paramName);
} else
jspSetError(false);
jsvUnLock(value);
jsvUnLock(param);
jsvUnLock2(value, param);
jsvObjectIteratorNext(&it);
param = jsvObjectIteratorGetKey(&it);
value = jsvObjectIteratorGetValue(&it);
}
jsvUnLock(value);
jsvUnLock(param);
jsvUnLock2(value, param);
if (isParsing) {
int hadParams = 0;
// grab in all parameters. We go around this loop until we've run out
@ -669,8 +664,7 @@ NO_INLINE JsVar *jspeFunctionCall(JsVar *function, JsVar *functionName, JsVar *t
if (functionInternalName) {
JsVar *name = jsvMakeIntoVariableName(jsvNewFromStringVar(functionInternalName,0,JSVAPPENDSTRINGVAR_MAXLENGTH), function);
jsvAddName(functionRoot, name);
jsvUnLock(name);
jsvUnLock(functionInternalName);
jsvUnLock2(name, functionInternalName);
}
// setup a return variable
returnVarName = jsvAddNamedChild(functionRoot, 0, JSPARSE_RETURN_VAR);
@ -864,8 +858,7 @@ static NO_INLINE JsVar *jspGetNamedFieldInParents(JsVar *object, const char* nam
// create a new name
JsVar *nameVar = jsvNewFromString(name);
JsVar *newChild = jsvCreateNewChild(object, nameVar, child);
jsvUnLock(nameVar);
jsvUnLock(child);
jsvUnLock2(nameVar, child);
child = newChild;
}
@ -1011,7 +1004,7 @@ NO_INLINE JsVar *jspeFactorMember(JsVar *a, JsVar **parentResult) {
JsVar *index;
JSP_ASSERT_MATCH('[');
index = jsvSkipNameAndUnLock(jspeAssignmentExpression());
JSP_MATCH_WITH_CLEANUP_AND_RETURN(']', jsvUnLock(parent);jsvUnLock(index);, a);
JSP_MATCH_WITH_CLEANUP_AND_RETURN(']', jsvUnLock2(parent, index);, a);
if (JSP_SHOULD_EXECUTE) {
index = jsvAsArrayIndexAndUnLock(index);
JsVar *aVar = jsvSkipName(a);
@ -1058,9 +1051,7 @@ NO_INLINE JsVar *jspeConstruct(JsVar *func, JsVar *funcName, bool hasArgs) {
JsVar *prototypeName = jsvFindChildFromString(func, JSPARSE_PROTOTYPE_VAR, true);
jspEnsureIsPrototype(func, prototypeName); // make sure it's an object
JsVar *prototypeVar = jsvSkipName(prototypeName);
jsvUnLock(jsvAddNamedChild(thisObj, prototypeVar, JSPARSE_INHERITS_VAR));
jsvUnLock(prototypeVar);
jsvUnLock(prototypeName);
jsvUnLock3(jsvAddNamedChild(thisObj, prototypeVar, JSPARSE_INHERITS_VAR), prototypeVar, prototypeName);
JsVar *a = jspeFunctionCall(func, funcName, thisObj, hasArgs, 0, 0);
@ -1104,10 +1095,8 @@ NO_INLINE JsVar *jspeFactorFunctionCall() {
} else
a = jspeFunctionCall(func, funcName, parent, true, 0, 0);
jsvUnLock(funcName);
jsvUnLock(func);
jsvUnLock(parent); parent=0;
jsvUnLock3(funcName, func, parent);
parent=0;
a = jspeFactorMember(a, &parent);
}
@ -1150,8 +1139,7 @@ NO_INLINE JsVar *jspeFactorObject() {
JsVar *contentsName = jsvFindChildFromVar(contents, varName, true);
if (contentsName) {
JsVar *value = jsvSkipNameAndUnLock(jspeAssignmentExpression()); // value can be 0 (could be undefined!)
jsvUnLock(jsvSetValueOfName(contentsName, value));
jsvUnLock(value);
jsvUnLock2(jsvSetValueOfName(contentsName, value), value);
}
}
jsvUnLock(varName);
@ -1217,9 +1205,7 @@ NO_INLINE void jspEnsureIsPrototype(JsVar *instanceOf, JsVar *prototypeName) {
}
JsVar *constructor = jsvFindChildFromString(prototypeVar, JSPARSE_CONSTRUCTOR_VAR, true);
if (constructor) jsvSetValueOfName(constructor, instanceOf);
jsvUnLock(constructor);
jsvUnLock(prototypeVar);
jsvUnLock2(constructor, prototypeVar);
}
NO_INLINE JsVar *jspeFactorTypeOf() {
@ -1261,8 +1247,7 @@ NO_INLINE JsVar *jspeFactorDelete() {
result = jsvNewFromBool(ok);
}
jsvUnLock(a);
jsvUnLock(parent);
jsvUnLock2(a, parent);
return result;
}
@ -1481,8 +1466,7 @@ NO_INLINE JsVar *__jspeBinaryExpression(JsVar *a, unsigned int lastPrecedence) {
jsvUnLock(a);
a = 0;
}
jsvUnLock(av);
jsvUnLock(bv);
jsvUnLock2(av, bv);
} else if (op==LEX_R_INSTANCEOF) {
bool inst = false;
JsVar *av = jsvSkipName(a);
@ -1509,9 +1493,7 @@ NO_INLINE JsVar *__jspeBinaryExpression(JsVar *a, unsigned int lastPrecedence) {
}
}
}
jsvUnLock(av);
jsvUnLock(bv);
jsvUnLock(a);
jsvUnLock3(av, bv, a);
a = jsvNewFromBool(inst);
} else { // --------------------------------------------- NORMAL
JsVar *res = jsvMathsOpSkipNames(a, b, op);
@ -1779,7 +1761,7 @@ NO_INLINE JsVar *jspeStatementSwitch() {
if (execute) execInfo.execute=EXEC_YES|EXEC_IN_SWITCH;
JsVar *test = jspeAssignmentExpression();
execInfo.execute = oldFlags|EXEC_IN_SWITCH;;
JSP_MATCH_WITH_CLEANUP_AND_RETURN(':', jsvUnLock(switchOn);jsvUnLock(test), 0);
JSP_MATCH_WITH_CLEANUP_AND_RETURN(':', jsvUnLock2(switchOn, test), 0);
bool cond = false;
if (execute)
cond = jsvGetBoolAndUnLock(jsvMathsOpSkipNames(switchOn, test, LEX_TYPEEQUAL));
@ -1925,7 +1907,7 @@ NO_INLINE JsVar *jspeStatementFor() {
}
JSP_MATCH_WITH_CLEANUP_AND_RETURN(LEX_R_IN, jsvUnLock(forStatement), 0);
JsVar *array = jsvSkipNameAndUnLock(jspeExpression());
JSP_MATCH_WITH_CLEANUP_AND_RETURN(')', jsvUnLock(forStatement);jsvUnLock(array), 0);
JSP_MATCH_WITH_CLEANUP_AND_RETURN(')', jsvUnLock2(forStatement, array), 0);
JslCharPos forBodyStart = jslCharPosClone(&execInfo.lex->tokenStart);
JSP_SAVE_EXECUTE();
jspSetNoExecute();
@ -2000,8 +1982,7 @@ NO_INLINE JsVar *jspeStatementFor() {
if (addedIteratorToScope) {
jsvRemoveChild(execInfo.root, forStatement);
}
jsvUnLock(forStatement);
jsvUnLock(array);
jsvUnLock2(forStatement, array);
} else { // ----------------------------------------------- NORMAL FOR LOOP
#ifdef JSPARSE_MAX_LOOP_ITERATIONS
int loopCount = JSPARSE_MAX_LOOP_ITERATIONS;
@ -2331,8 +2312,7 @@ NO_INLINE JsVar *jspNewPrototype(const char *instanceOf) {
JsVar *prototypeName = jsvFindChildFromString(objFunc, JSPARSE_PROTOTYPE_VAR, true);
jspEnsureIsPrototype(objFunc, prototypeName); // make sure it's an object
jsvUnLock(objFunc);
jsvUnLock(objFuncName);
jsvUnLock2(objFunc, objFuncName);
return prototypeName;
}
@ -2362,9 +2342,7 @@ NO_INLINE JsVar *jspNewObject(const char *name, const char *instanceOf) {
}
// add __proto__
JsVar *prototypeVar = jsvSkipName(prototypeName);
jsvUnLock(jsvAddNamedChild(obj, prototypeVar, JSPARSE_INHERITS_VAR));
jsvUnLock(prototypeVar);
jsvUnLock(prototypeName);prototypeName=0;
jsvUnLock3(jsvAddNamedChild(obj, prototypeVar, JSPARSE_INHERITS_VAR), prototypeVar, prototypeName);prototypeName=0;
if (name) {
JsVar *objName = jsvFindChildFromString(execInfo.root, name, true);
@ -2496,8 +2474,7 @@ JsVar *jspEvaluateModule(JsVar *moduleContents) {
JsVar *scopeExports = jsvNewWithFlags(JSV_OBJECT);
if (!scopeExports) { jsvUnLock(scope); return 0; } // out of mem
JsVar *exportsName = jsvAddNamedChild(scope, scopeExports, "exports");
jsvUnLock(scopeExports);
jsvUnLock(jsvAddNamedChild(scope, scope, "module"));
jsvUnLock2(scopeExports, jsvAddNamedChild(scope, scope, "module"));
// TODO: maybe we do want to parse twice here, to get functions defined after their use?
JsVar *oldThisVar = execInfo.thisVar;

View File

@ -483,6 +483,18 @@ ALWAYS_INLINE void jsvUnLock(JsVar *var) {
if ((var->flags & JSV_LOCK_MASK) == 0) jsvUnLockFreeIfNeeded(var);
}
/// Unlock 2 variables in one go
void jsvUnLock2(JsVar *var1, JsVar *var2) {
jsvUnLock(var1);
jsvUnLock(var2);
}
/// Unlock 3 variables in one go
void jsvUnLock3(JsVar *var1, JsVar *var2, JsVar *var3) {
jsvUnLock(var1);
jsvUnLock(var2);
jsvUnLock(var3);
}
/// Unlock an array of variables
NO_INLINE void jsvUnLockMany(unsigned int count, JsVar **vars) {
while (count) jsvUnLock(vars[--count]);
@ -2134,6 +2146,10 @@ JsVar *jsvObjectSetChild(JsVar *obj, const char *name, JsVar *child) {
return child;
}
void jsvObjectSetChildAndUnLock(JsVar *obj, const char *name, JsVar *child) {
jsvUnLock(jsvObjectSetChild(obj, name, child));
}
int jsvGetChildren(JsVar *v) {
//OPT: could length be stored as the value of the array?
int children = 0;
@ -2428,8 +2444,11 @@ JsVar *jsvArrayPopFirst(JsVar *arr) {
void jsvArrayAddString(JsVar *arr, const char *text) {
JsVar *v = jsvNewFromString(text);
JsVar *idx = jsvGetArrayIndexOf(arr, v, false); // did it already exist?
if (!idx) jsvArrayPush(arr, v);
else jsvUnLock(idx);
if (!idx) {
jsvArrayPush(arr, v);
} else {
jsvUnLock(idx);
}
jsvUnLock(v);
}
@ -2515,11 +2534,9 @@ JsVar *jsvMathsOpSkipNames(JsVar *a, JsVar *b, int op) {
JsVar *pb = jsvSkipName(b);
JsVar *oa = jsvGetValueOf(pa);
JsVar *ob = jsvGetValueOf(pb);
jsvUnLock(pa);
jsvUnLock(pb);
jsvUnLock2(pa, pb);
JsVar *res = jsvMathsOp(oa,ob,op);
jsvUnLock(oa);
jsvUnLock(ob);
jsvUnLock2(oa, ob);
return res;
}
@ -2653,8 +2670,7 @@ JsVar *jsvMathsOp(JsVar *a, JsVar *b, int op) {
JsVar *da = jsvAsString(a, false);
JsVar *db = jsvAsString(b, false);
if (!da || !db) { // out of memory
jsvUnLock(da);
jsvUnLock(db);
jsvUnLock2(da, db);
return 0;
}
if (op=='+') {
@ -2662,14 +2678,12 @@ JsVar *jsvMathsOp(JsVar *a, JsVar *b, int op) {
// TODO: can we be fancy and not copy da if we know it isn't reffed? what about locks?
if (v) // could be out of memory
jsvAppendStringVarComplete(v, db);
jsvUnLock(da);
jsvUnLock(db);
jsvUnLock2(da, db);
return v;
}
int cmp = jsvCompareString(da,db,0,0,false);
jsvUnLock(da);
jsvUnLock(db);
jsvUnLock2(da, db);
// use strings
switch (op) {
case LEX_EQUAL: return jsvNewFromBool(cmp==0);
@ -2686,8 +2700,7 @@ JsVar *jsvMathsOp(JsVar *a, JsVar *b, int op) {
JsVar *jsvNegateAndUnLock(JsVar *v) {
JsVar *zero = jsvNewFromInteger(0);
JsVar *res = jsvMathsOpSkipNames(zero, v, '-');
jsvUnLock(zero);
jsvUnLock(v);
jsvUnLock2(zero, v);
return res;
}
@ -2712,8 +2725,7 @@ JsVar *jsvGetPathTo(JsVar *root, JsVar *element, int maxDepth, JsVar *ignorePare
// we found it! Append our name onto it as well
JsVar *keyName = jsvIteratorGetKey(&it);
JsVar *name = jsvVarPrintf(jsvIsObject(el) ? "%v.%v" : "%v[%q]",keyName,n);
jsvUnLock(keyName);
jsvUnLock(n);
jsvUnLock2(keyName, n);
jsvIteratorFree(&it);
return name;
}

View File

@ -320,6 +320,11 @@ ALWAYS_INLINE JsVar *jsvLockAgainSafe(JsVar *var);
/// Unlock this variable - this is SAFE for null variables
ALWAYS_INLINE void jsvUnLock(JsVar *var);
/// Unlock 2 variables in one go
void jsvUnLock2(JsVar *var1, JsVar *var2);
/// Unlock 3 variables in one go
void jsvUnLock3(JsVar *var1, JsVar *var2, JsVar *var3);
/// Unlock an array of variables
NO_INLINE void jsvUnLockMany(unsigned int count, JsVar **vars);
@ -601,6 +606,8 @@ void jsvRemoveNamedChild(JsVar *parent, const char *name);
JsVar *jsvObjectGetChild(JsVar *obj, const char *name, JsVarFlags createChild);
/// Set the named child of an object, and return the child (so you can choose to unlock it if you want)
JsVar *jsvObjectSetChild(JsVar *obj, const char *name, JsVar *child);
/// Set the named child of an object, and unlock the child
void jsvObjectSetChildAndUnLock(JsVar *obj, const char *name, JsVar *child);
int jsvGetChildren(JsVar *v); ///< number of children of a variable. also see jsvGetArrayLength and jsvGetLength
JsVar *jsvGetFirstName(JsVar *v); ///< Get the first child's name from an object,array or function

View File

@ -34,8 +34,7 @@ bool jsvIterateCallback(JsVar *data, void (*callback)(int item, void *callbackDa
} else {
jsWarn("If specifying an object, it must be of the form {data : ..., count : N}");
}
jsvUnLock(countVar);
jsvUnLock(dataVar);
jsvUnLock2(countVar, dataVar);
} else if (jsvIsString(data)) {
JsvStringIterator it;
jsvStringIteratorNew(&it, data, 0);

View File

@ -497,8 +497,7 @@ JsVar *jswrap_array_shift(JsVar *parent) {
JsVar *nRemove = jsvNewFromInteger(1);
JsVar *elements = jsvNewWithFlags(JSV_ARRAY);
JsVar *arr = jswrap_array_splice(parent, 0, nRemove, elements);
jsvUnLock(elements);
jsvUnLock(nRemove);
jsvUnLock2(elements, nRemove);
// unpack element from the array
JsVar *el = 0;
if (jsvIsArray(arr))
@ -523,8 +522,7 @@ Remove the first element of the array, and return it
JsVarInt jswrap_array_unshift(JsVar *parent, JsVar *elements) {
// just use splice, as this does all the hard work for us
JsVar *nRemove = jsvNewFromInteger(0);
jsvUnLock(jswrap_array_splice(parent, 0, nRemove, elements));
jsvUnLock(nRemove);
jsvUnLock2(jswrap_array_splice(parent, 0, nRemove, elements), nRemove);
// return new length
return jsvGetLength(parent);
}
@ -611,8 +609,7 @@ NO_INLINE static JsVarInt _jswrap_array_sort_compare(JsVar *a, JsVar *b, JsVar *
JsVar *sa = jsvAsString(a, false);
JsVar *sb = jsvAsString(b, false);
JsVarInt r = jsvCompareString(sa,sb, 0, 0, false);
jsvUnLock(sa);
jsvUnLock(sb);
jsvUnLock2(sa, sb);
return r;
}
}
@ -863,8 +860,7 @@ void _jswrap_array_reverse_block(JsVar *parent, JsvIterator *it, int items) {
JsVar *vb = jsvIteratorGetValue(&itb);
jsvIteratorSetValue(&ita, vb);
jsvIteratorSetValue(&itb, va);
jsvUnLock(va);
jsvUnLock(vb);
jsvUnLock2(va, vb);
// if it's an array, we need to swap the key values too
if (jsvIsArray(parent)) {
JsVar *ka = jsvIteratorGetKey(&ita);
@ -873,8 +869,7 @@ void _jswrap_array_reverse_block(JsVar *parent, JsvIterator *it, int items) {
JsVarInt kvb = jsvGetInteger(kb);
jsvSetInteger(ka, kvb);
jsvSetInteger(kb, kva);
jsvUnLock(ka);
jsvUnLock(kb);
jsvUnLock2(ka, kb);
}
jsvIteratorNext(&ita);

View File

@ -160,7 +160,7 @@ JsVarFloat jswrap_date_now() {
JsVar *jswrap_date_from_milliseconds(JsVarFloat time) {
JsVar *d = jspNewObject(0,"Date");
if (!d) return 0;
jsvUnLock(jsvObjectSetChild(d, "ms", jsvNewFromFloat(time)));
jsvObjectSetChildAndUnLock(d, "ms", jsvNewFromFloat(time));
return d;
}

View File

@ -54,9 +54,9 @@ JsVar *_jswrap_error_constructor(JsVar *msg, char *type) {
if (msg) {
msg = jsvAsString(msg, false);
jsvUnLock(jsvObjectSetChild(d, "msg", msg));
jsvObjectSetChildAndUnLock(d, "msg", msg);
}
jsvUnLock(jsvObjectSetChild(d, "type", jsvNewFromString(type)));
jsvObjectSetChildAndUnLock(d, "type", jsvNewFromString(type));
return d;
}
@ -181,8 +181,7 @@ JsVar *jswrap_error_toString(JsVar *parent) {
JsVar *msg = jsvObjectGetChild(parent, "msg", 0);
if (msg) {
JsVar *newStr = jsvVarPrintf("%v: %v", str, msg);
jsvUnLock(msg);
jsvUnLock(str);
jsvUnLock2(msg, str);
str = newStr;
}

View File

@ -139,8 +139,7 @@ JsVar *jswrap_espruino_nativeCall(JsVarInt addr, JsVar *signature, JsVar *data)
JsVar *fn = jsvNewNativeFunction((void *)(size_t)addr, (unsigned short)argTypes);
if (data) {
JsVar *flat = jsvAsFlatString(data);
jsvUnLock(jsvAddNamedChild(fn, flat, JSPARSE_FUNCTION_CODE_NAME));
jsvUnLock(flat);
jsvUnLock2(jsvAddNamedChild(fn, flat, JSPARSE_FUNCTION_CODE_NAME), flat);
}
return fn;
}
@ -942,7 +941,7 @@ void jswrap_espruino_setUSBHID(JsVar *arr) {
JsVar *s = jswrap_espruino_toString(report);
jsvUnLock(report);
// Enable HID
jsvUnLock(jsvObjectSetChild(execInfo.hiddenRoot, JS_USB_HID_VAR_NAME, s));
jsvObjectSetChildAndUnLock(execInfo.hiddenRoot, JS_USB_HID_VAR_NAME, s);
}
/*JSON{

View File

@ -62,8 +62,8 @@ JsVar *jswrap_flash_getPage(int addr) {
return 0;
JsVar *obj = jsvNewWithFlags(JSV_OBJECT);
if (!obj) return 0;
jsvUnLock(jsvObjectSetChild(obj, "addr", jsvNewFromInteger((JsVarInt)pageStart)));
jsvUnLock(jsvObjectSetChild(obj, "length", jsvNewFromInteger((JsVarInt)pageLength)));
jsvObjectSetChildAndUnLock(obj, "addr", jsvNewFromInteger((JsVarInt)pageStart));
jsvObjectSetChildAndUnLock(obj, "length", jsvNewFromInteger((JsVarInt)pageLength));
return obj;
}

View File

@ -87,7 +87,7 @@ JsVar *jswrap_function_constructor(JsVar *args) {
JsVar *codeStr = jsvVarPrintf("{\n%v\n}", v);
jsvUnLock(v);
jsvUnLock(jsvObjectSetChild(fn, JSPARSE_FUNCTION_CODE_NAME, codeStr));
jsvObjectSetChildAndUnLock(fn, JSPARSE_FUNCTION_CODE_NAME, codeStr);
return fn;
}

View File

@ -235,8 +235,7 @@ void jswrap_interface_edit(JsVar *funcName) {
JsVar *scopeVar = jsvFindChildFromString(func, JSPARSE_FUNCTION_SCOPE_NAME, false);
JsVar *inRoot = jsvGetArrayIndexOf(execInfo.root, func, true);
bool normalDecl = scopeVar==0 && inRoot!=0;
jsvUnLock(inRoot);
jsvUnLock(scopeVar);
jsvUnLock2(inRoot, scopeVar);
JsVar *newLine = jsvNewFromEmptyString();
if (newLine) { // could be out of memory
/* normalDecl:
@ -271,8 +270,7 @@ void jswrap_interface_edit(JsVar *funcName) {
} else {
jsExceptionHere(JSET_ERROR, "Edit should be called with edit(funcName) or edit('funcName')");
}
jsvUnLock(func);
jsvUnLock(funcName);
jsvUnLock2(func, funcName);
}
@ -429,9 +427,9 @@ JsVar *_jswrap_interface_setTimeoutOrInterval(JsVar *func, JsVarFloat interval,
JsVar *timerPtr = jsvNewWithFlags(JSV_OBJECT);
if (interval<TIMER_MIN_INTERVAL) interval=TIMER_MIN_INTERVAL;
JsSysTime intervalInt = jshGetTimeFromMilliseconds(interval);
jsvUnLock(jsvObjectSetChild(timerPtr, "time", jsvNewFromLongInteger((jshGetSystemTime() - jsiLastIdleTime) + intervalInt)));
jsvObjectSetChildAndUnLock(timerPtr, "time", jsvNewFromLongInteger((jshGetSystemTime() - jsiLastIdleTime) + intervalInt));
if (!isTimeout) {
jsvUnLock(jsvObjectSetChild(timerPtr, "interval", jsvNewFromLongInteger(intervalInt)));
jsvObjectSetChildAndUnLock(timerPtr, "interval", jsvNewFromLongInteger(intervalInt));
}
jsvObjectSetChild(timerPtr, "callback", func); // intentionally no unlock
if (jsvGetArrayLength(args))
@ -492,8 +490,7 @@ void _jswrap_interface_clearTimeoutOrInterval(JsVar *idVar, bool isTimeout) {
if (child) {
JsVar *timerArrayPtr = jsvLock(timerArray);
jsvRemoveChild(timerArrayPtr, child);
jsvUnLock(child);
jsvUnLock(timerArrayPtr);
jsvUnLock2(child, timerArrayPtr);
} else {
jsExceptionHere(JSET_ERROR, isTimeout ? "Unknown Timeout" : "Unknown Interval");
}
@ -534,12 +531,9 @@ void jswrap_interface_changeInterval(JsVar *idVar, JsVarFloat interval) {
JsVar *v;
JsVarInt intervalInt = (JsVarInt)jshGetTimeFromMilliseconds(interval);
v = jsvNewFromInteger(intervalInt);
jsvUnLock(jsvSetNamedChild(timer, v, "interval"));
jsvUnLock(v);
jsvUnLock2(jsvSetNamedChild(timer, v, "interval"), v);
v = jsvNewFromInteger((JsVarInt)(jshGetSystemTime()-jsiLastIdleTime) + intervalInt);
jsvUnLock(jsvSetNamedChild(timer, v, "time"));
jsvUnLock(v);
jsvUnLock(timer);
jsvUnLock3(jsvSetNamedChild(timer, v, "time"), v, timer);
// timerName already unlocked
jsiTimersChanged(); // mark timers as changed
} else {

View File

@ -451,10 +451,10 @@ JsVar *jswrap_interface_setWatch(JsVar *func, Pin pin, JsVar *repeatOrObject) {
// Create a new watch
JsVar *watchPtr = jsvNewWithFlags(JSV_OBJECT);
if (watchPtr) {
jsvUnLock(jsvObjectSetChild(watchPtr, "pin", jsvNewFromPin(pin)));
if (repeat) jsvUnLock(jsvObjectSetChild(watchPtr, "recur", jsvNewFromBool(repeat)));
if (debounce>0) jsvUnLock(jsvObjectSetChild(watchPtr, "debounce", jsvNewFromInteger((JsVarInt)jshGetTimeFromMilliseconds(debounce))));
if (edge) jsvUnLock(jsvObjectSetChild(watchPtr, "edge", jsvNewFromInteger(edge)));
jsvObjectSetChildAndUnLock(watchPtr, "pin", jsvNewFromPin(pin));
if (repeat) jsvObjectSetChildAndUnLock(watchPtr, "recur", jsvNewFromBool(repeat));
if (debounce>0) jsvObjectSetChildAndUnLock(watchPtr, "debounce", jsvNewFromInteger((JsVarInt)jshGetTimeFromMilliseconds(debounce)));
if (edge) jsvObjectSetChildAndUnLock(watchPtr, "edge", jsvNewFromInteger(edge));
jsvObjectSetChild(watchPtr, "callback", func); // no unlock intentionally
}
@ -480,8 +480,7 @@ JsVar *jswrap_interface_setWatch(JsVar *func, Pin pin, JsVar *repeatOrObject) {
JsVar *watchArrayPtr = jsvLock(watchArray);
itemIndex = jsvArrayAddToEnd(watchArrayPtr, watchPtr, 1) - 1;
jsvUnLock(watchArrayPtr);
jsvUnLock(watchPtr);
jsvUnLock2(watchArrayPtr, watchPtr);
}
@ -508,8 +507,7 @@ void jswrap_interface_clearWatch(JsVar *idVar) {
JsVar *watchPtr = jsvObjectIteratorGetValue(&it);
JsVar *watchPin = jsvObjectGetChild(watchPtr, "pin", 0);
jshPinWatch(jshGetPinFromVar(watchPin), false);
jsvUnLock(watchPin);
jsvUnLock(watchPtr);
jsvUnLock2(watchPin, watchPtr);
jsvObjectIteratorNext(&it);
}
jsvObjectIteratorFree(&it);
@ -527,8 +525,7 @@ void jswrap_interface_clearWatch(JsVar *idVar) {
JsVar *watchArrayPtr = jsvLock(watchArray);
jsvRemoveChild(watchArrayPtr, watchNamePtr);
jsvUnLock(watchNamePtr);
jsvUnLock(watchArrayPtr);
jsvUnLock2(watchNamePtr, watchArrayPtr);
// Now check if this pin is still being watched
if (!jsiIsWatchingPin(pin))

View File

@ -64,8 +64,7 @@ JsVar *jswrap_json_parse_internal(JsLex *lex) {
JsVar *v = jswrap_json_parse_internal(lex);
JsVar *zero = jsvNewFromInteger(0);
JsVar *r = jsvMathsOp(zero, v, '-');
jsvUnLock(v);
jsvUnLock(zero);
jsvUnLock2(v, zero);
return r;
}
case LEX_INT: {
@ -90,8 +89,7 @@ JsVar *jswrap_json_parse_internal(JsLex *lex) {
JsVar *value = jswrap_json_parse_internal(lex);
if (!value ||
(lex->tk!=']' && !jslMatch(lex, ','))) {
jsvUnLock(value);
jsvUnLock(arr);
jsvUnLock2(value, arr);
return 0;
}
jsvArrayPush(arr, value);
@ -113,14 +111,11 @@ JsVar *jswrap_json_parse_internal(JsLex *lex) {
if (!jslMatch(lex, ':') ||
!(value=jswrap_json_parse_internal(lex)) ||
(lex->tk!='}' && !jslMatch(lex, ','))) {
jsvUnLock(key);
jsvUnLock(value);
jsvUnLock(obj);
jsvUnLock3(key, value, obj);
return 0;
}
jsvAddName(obj, jsvMakeIntoVariableName(key, value));
jsvUnLock(value);
jsvUnLock(key);
jsvUnLock2(value, key);
}
if (!jslMatch(lex, '}')) {
jsvUnLock(obj);
@ -331,8 +326,7 @@ void jsfGetJSONWithCallback(JsVar *var, JSONFlags flags, vcbprintf_callback user
jsfGetJSONWithCallback(item, nflags, user_callback, user_data);
needNewLine = newNeedsNewLine;
}
jsvUnLock(index);
jsvUnLock(item);
jsvUnLock2(index, item);
jsvObjectIteratorNext(&it);
}
jsvObjectIteratorFree(&it);
@ -352,8 +346,7 @@ void jsfGetJSONWithCallback(JsVar *var, JSONFlags flags, vcbprintf_callback user
JsVar *var1 = jsvNewFromStringVar(var, 0, JSON_LIMITED_STRING_AMOUNT);
JsVar *var2 = jsvNewFromStringVar(var, jsvGetStringLength(var)-JSON_LIMITED_STRING_AMOUNT, JSON_LIMITED_STRING_AMOUNT);
cbprintf(user_callback, user_data, "%q%s%q", var1, JSON_LIMIT_TEXT, var2);
jsvUnLock(var1);
jsvUnLock(var2);
jsvUnLock2(var1, var2);
} else {
cbprintf(user_callback, user_data, "%q", var);
}

View File

@ -87,8 +87,7 @@ JsVar *jswrap_require(JsVar *moduleName) {
jsvUnLock(modulePath);
#endif
if (!fileContents || jsvIsStringEqual(fileContents,"")) {
jsvUnLock(moduleExportName);
jsvUnLock(fileContents);
jsvUnLock2(moduleExportName, fileContents);
jsWarn("Module %q not found", moduleName);
return 0;
}

View File

@ -65,8 +65,7 @@ JsVar *jswrap_object_constructor(JsVar *value) {
if (!funcName) return jsvNewWithFlags(JSV_OBJECT);
JsVar *func = jsvSkipName(funcName);
JsVar *result = jspeFunctionCall(func, funcName, 0, false, 1, &value);
jsvUnLock(funcName);
jsvUnLock(func);
jsvUnLock2(funcName, func);
return result;
}
@ -304,12 +303,11 @@ JsVar *jswrap_object_getOwnPropertyDescriptor(JsVar *parent, JsVar *name) {
JsvIsInternalChecker checkerFunction = jsvGetInternalFunctionCheckerFor(parent);
jsvObjectSetChild(obj, "value", var);
jsvUnLock(jsvObjectSetChild(obj, "writable", jsvNewFromBool(true)));
jsvUnLock(jsvObjectSetChild(obj, "enumerable", jsvNewFromBool(!checkerFunction || !checkerFunction(varName))));
jsvUnLock(jsvObjectSetChild(obj, "configurable", jsvNewFromBool(!isBuiltIn)));
jsvObjectSetChildAndUnLock(obj, "writable", jsvNewFromBool(true));
jsvObjectSetChildAndUnLock(obj, "enumerable", jsvNewFromBool(!checkerFunction || !checkerFunction(varName)));
jsvObjectSetChildAndUnLock(obj, "configurable", jsvNewFromBool(!isBuiltIn));
jsvUnLock(var);
jsvUnLock(varName);
jsvUnLock2(var, varName);
return obj;
}
@ -397,8 +395,7 @@ JsVar *jswrap_object_defineProperty(JsVar *parent, JsVar *propName, JsVar *desc)
jsvUnLock(name);
if (property && value)
jsvSetValueOfName(property, value);
jsvUnLock(property);
jsvUnLock(value);
jsvUnLock2(property, value);
return jsvLockAgain(parent);
}
@ -431,9 +428,7 @@ JsVar *jswrap_object_defineProperties(JsVar *parent, JsVar *props) {
while (jsvObjectIteratorHasValue(&it)) {
JsVar *name = jsvObjectIteratorGetKey(&it);
JsVar *desc = jsvObjectIteratorGetValue(&it);
jsvUnLock(jswrap_object_defineProperty(parent, name, desc));
jsvUnLock(name);
jsvUnLock(desc);
jsvUnLock3(jswrap_object_defineProperty(parent, name, desc), name, desc);
jsvObjectIteratorNext(&it);
}
jsvObjectIteratorFree(&it);
@ -468,8 +463,7 @@ void jswrap_object_addEventListener(JsVar *parent, const char *eventName, void (
JsVar *n = jsvNewFromString(eventName);
JsVar *cb = jsvNewNativeFunction(callback, argTypes);
jswrap_object_on(parent, n, cb);
jsvUnLock(cb);
jsvUnLock(n);
jsvUnLock2(cb, n);
}
#define EVENTNAME_SIZE 16
@ -528,8 +522,7 @@ void jswrap_object_on(JsVar *parent, JsVar *event, JsVar *listener) {
jsvUnLock(arr);
}
}
jsvUnLock(eventListeners);
jsvUnLock(eventList);
jsvUnLock2(eventListeners, eventList);
/* Special case if we're a data listener and data has already arrived then
* we queue an event immediately. */
if (jsvIsStringEqual(event, "data")) {
@ -793,8 +786,7 @@ JsVar *jswrap_function_bind(JsVar *parent, JsVar *thisArg, JsVar *argsArray) {
jsvUnLock(newParam);
}
}
jsvUnLock(param);
jsvUnLock(defaultValue);
jsvUnLock2(param, defaultValue);
if (!wasBound) break;
jsvObjectIteratorNext(&fnIt);
}
@ -815,8 +807,7 @@ JsVar *jswrap_function_bind(JsVar *parent, JsVar *thisArg, JsVar *argsArray) {
jsvSetValueOfName(newParam, defaultValue);
jsvAddName(fn, newParam);
addedParam = true;
jsvUnLock(param);
jsvUnLock(newParam);
jsvUnLock2(param, newParam);
jsvObjectIteratorNext(&fnIt);
}

View File

@ -103,7 +103,7 @@ Create a software OneWire implementation on the given pin
JsVar *jswrap_onewire_constructor(Pin pin) {
JsVar *ow = jspNewObject(0, "OneWire");
if (!ow) return 0;
jsvUnLock(jsvObjectSetChild(ow, "pin", jsvNewFromPin(pin)));
jsvObjectSetChildAndUnLock(ow, "pin", jsvNewFromPin(pin));
return ow;
}

View File

@ -56,8 +56,9 @@ static void handlePipeClose(JsVar *arr, JsvObjectIterator *it, JsVar* pipe) {
/* call write fn - we ignore drain/etc here because the source has
just closed and we want to get this sorted quickly */
JsVar *writeFunc = jspGetNamedField(destination, "write", false);
if (jsvIsFunction(writeFunc)) // do the objects have the necessary methods on them?
if (jsvIsFunction(writeFunc)) { // do the objects have the necessary methods on them?
jsvUnLock(jspExecuteFunction(writeFunc, destination, 1, &buffer));
}
jsvUnLock(writeFunc);
// update position
JsVar *position = jsvObjectGetChild(pipe,"position",0);
@ -77,14 +78,12 @@ static void handlePipeClose(JsVar *arr, JsvObjectIterator *it, JsVar* pipe) {
// execute the 'end' function
JsVar *endFunc = jspGetNamedField(destination, "end", false);
if (endFunc) {
jsvUnLock(jspExecuteFunction(endFunc, destination, 0, 0));
jsvUnLock(endFunc);
jsvUnLock2(jspExecuteFunction(endFunc, destination, 0, 0), endFunc);
}
// execute the 'close' function
JsVar *closeFunc = jspGetNamedField(destination, "close", false);
if (closeFunc) {
jsvUnLock(jspExecuteFunction(closeFunc, destination, 0, 0));
jsvUnLock(closeFunc);
jsvUnLock2(jspExecuteFunction(closeFunc, destination, 0, 0), closeFunc);
}
}
/* call source.close if available - probably not what node does
@ -96,13 +95,11 @@ static void handlePipeClose(JsVar *arr, JsvObjectIterator *it, JsVar* pipe) {
// execute the 'close' function
JsVar *closeFunc = jspGetNamedField(source, "close", false);
if (closeFunc) {
jsvUnLock(jspExecuteFunction(closeFunc, source, 0, 0));
jsvUnLock(closeFunc);
jsvUnLock2(jspExecuteFunction(closeFunc, source, 0, 0), closeFunc);
}
}
}
jsvUnLock(source);
jsvUnLock(destination);
jsvUnLock2(source, destination);
JsVar *idx = jsvObjectIteratorGetKey(it);
jsvRemoveChild(arr,idx);
jsvUnLock(idx);
@ -129,7 +126,7 @@ static bool handlePipe(JsVar *arr, JsvObjectIterator *it, JsVar* pipe) {
JsVar *response = jspExecuteFunction(writeFunc, destination, 1, &buffer);
if (jsvIsBoolean(response) && jsvGetBool(response)==false) {
// If boolean false was returned, wait for drain event (http://nodejs.org/api/stream.html#stream_writable_write_chunk_encoding_callback)
jsvUnLock(jsvObjectSetChild(pipe,"drainWait",jsvNewFromBool(true)));
jsvObjectSetChildAndUnLock(pipe,"drainWait",jsvNewFromBool(true));
}
jsvUnLock(response);
jsvSetInteger(position, jsvGetInteger(position) + bufferSize);
@ -143,16 +140,13 @@ static bool handlePipe(JsVar *arr, JsvObjectIterator *it, JsVar* pipe) {
if(!jsvIsFunction(writeFunc))
jsExceptionHere(JSET_ERROR, "Destination Stream does not implement the required write(buffer) method.");
}
jsvUnLock(readFunc);
jsvUnLock(writeFunc);
jsvUnLock2(readFunc, writeFunc);
}
if(!dataTransferred) { // when no more chunks are possible, execute the callback
handlePipeClose(arr, it, pipe);
}
jsvUnLock(source);
jsvUnLock(destination);
jsvUnLock(chunkSize);
jsvUnLock3(source, destination, chunkSize);
jsvUnLock(position);
return dataTransferred;
}
@ -207,10 +201,9 @@ static void jswrap_pipe_drain_listener(JsVar *destination) {
JsVar *dst = jsvObjectGetChild(pipe,"destination",0);
if (dst == destination) {
// found it! said wait to false
jsvUnLock(jsvObjectSetChild(pipe,"drainWait",jsvNewFromBool(false)));
jsvObjectSetChildAndUnLock(pipe,"drainWait",jsvNewFromBool(false));
}
jsvUnLock(dst);
jsvUnLock(pipe);
jsvUnLock2(dst, pipe);
jsvObjectIteratorNext(&it);
}
jsvObjectIteratorFree(&it);
@ -233,8 +226,7 @@ static void jswrap_pipe_close_listener(JsVar *destination, const char *name) {
// found it! said wait to false
handlePipeClose(arr, &it, pipe);
}
jsvUnLock(dst);
jsvUnLock(pipe);
jsvUnLock2(dst, pipe);
jsvObjectIteratorNext(&it);
}
jsvObjectIteratorFree(&it);
@ -299,11 +291,11 @@ void jswrap_pipe(JsVar* source, JsVar* dest, JsVar* options) {
jswrap_object_addEventListener(dest, "drain", jswrap_pipe_drain_listener, JSWAT_VOID | (JSWAT_JSVAR << (JSWAT_BITS*1)));
jswrap_object_addEventListener(dest, "close", jswrap_pipe_dst_close_listener, JSWAT_VOID | (JSWAT_JSVAR << (JSWAT_BITS*1)));
// set up the rest of the pipe
jsvUnLock(jsvObjectSetChild(pipe, "chunkSize", jsvNewFromInteger(chunkSize)));
jsvUnLock(jsvObjectSetChild(pipe, "end", jsvNewFromBool(callEnd)));
jsvUnLock(jsvAddNamedChild(pipe, position, "position"));
jsvUnLock(jsvAddNamedChild(pipe, source, "source"));
jsvUnLock(jsvAddNamedChild(pipe, dest, "destination"));
jsvObjectSetChildAndUnLock(pipe, "chunkSize", jsvNewFromInteger(chunkSize));
jsvObjectSetChildAndUnLock(pipe, "end", jsvNewFromBool(callEnd));
jsvUnLock3(jsvAddNamedChild(pipe, position, "position"),
jsvAddNamedChild(pipe, source, "source"),
jsvAddNamedChild(pipe, dest, "destination"));
// add the pipe to our list
jsvArrayPush(arr, pipe);
} else {
@ -312,11 +304,8 @@ void jswrap_pipe(JsVar* source, JsVar* dest, JsVar* options) {
} else {
jsExceptionHere(JSET_ERROR, "Source object does not implement the required read(buffer, length, position) method.");
}
jsvUnLock(readFunc);
jsvUnLock(writeFunc);
jsvUnLock2(readFunc, writeFunc);
}
jsvUnLock(arr);
jsvUnLock(pipe);
jsvUnLock(position);
jsvUnLock3(arr, pipe, position);
}

View File

@ -64,30 +64,30 @@ Returns an Object containing various pre-defined variables. standard ones are BO
*/
JsVar *jswrap_process_env() {
JsVar *obj = jsvNewWithFlags(JSV_OBJECT);
jsvUnLock(jsvObjectSetChild(obj, "VERSION", jsvNewFromString(JS_VERSION)));
jsvUnLock(jsvObjectSetChild(obj, "BUILD_DATE", jsvNewFromString(__DATE__)));
jsvUnLock(jsvObjectSetChild(obj, "BUILD_TIME", jsvNewFromString(__TIME__)));
jsvObjectSetChildAndUnLock(obj, "VERSION", jsvNewFromString(JS_VERSION));
jsvObjectSetChildAndUnLock(obj, "BUILD_DATE", jsvNewFromString(__DATE__));
jsvObjectSetChildAndUnLock(obj, "BUILD_TIME", jsvNewFromString(__TIME__));
#ifdef GIT_COMMIT
jsvUnLock(jsvObjectSetChild(obj, "GIT_COMMIT", jsvNewFromString(STRINGIFY(GIT_COMMIT))));
jsvObjectSetChildAndUnLock(obj, "GIT_COMMIT", jsvNewFromString(STRINGIFY(GIT_COMMIT)));
#endif
jsvUnLock(jsvObjectSetChild(obj, "BOARD", jsvNewFromString(PC_BOARD_ID)));
jsvUnLock(jsvObjectSetChild(obj, "CHIP", jsvNewFromString(PC_BOARD_CHIP)));
jsvUnLock(jsvObjectSetChild(obj, "CHIP_FAMILY", jsvNewFromString(PC_BOARD_CHIP_FAMILY)));
jsvUnLock(jsvObjectSetChild(obj, "FLASH", jsvNewFromInteger(FLASH_TOTAL)));
jsvUnLock(jsvObjectSetChild(obj, "RAM", jsvNewFromInteger(RAM_TOTAL)));
jsvUnLock(jsvObjectSetChild(obj, "SERIAL", jswrap_interface_getSerial()));
jsvUnLock(jsvObjectSetChild(obj, "CONSOLE", jsvNewFromString(jshGetDeviceString(jsiGetConsoleDevice()))));
jsvObjectSetChildAndUnLock(obj, "BOARD", jsvNewFromString(PC_BOARD_ID));
jsvObjectSetChildAndUnLock(obj, "CHIP", jsvNewFromString(PC_BOARD_CHIP));
jsvObjectSetChildAndUnLock(obj, "CHIP_FAMILY", jsvNewFromString(PC_BOARD_CHIP_FAMILY));
jsvObjectSetChildAndUnLock(obj, "FLASH", jsvNewFromInteger(FLASH_TOTAL));
jsvObjectSetChildAndUnLock(obj, "RAM", jsvNewFromInteger(RAM_TOTAL));
jsvObjectSetChildAndUnLock(obj, "SERIAL", jswrap_interface_getSerial());
jsvObjectSetChildAndUnLock(obj, "CONSOLE", jsvNewFromString(jshGetDeviceString(jsiGetConsoleDevice())));
JsVar *arr = jsvNewWithFlags(JSV_OBJECT);
if (arr) {
const char *s = exportNames;
void **p = (void**)exportPtrs;
while (*s) {
jsvUnLock(jsvObjectSetChild(arr, s, jsvNewFromInteger((JsVarInt)(size_t)*p)));
jsvObjectSetChildAndUnLock(arr, s, jsvNewFromInteger((JsVarInt)(size_t)*p));
p++;
while (*s) s++; // skip until 0
s++; // skip over 0
}
jsvUnLock(jsvObjectSetChild(obj, "EXPORTS", arr));
jsvObjectSetChildAndUnLock(obj, "EXPORTS", arr);
}
return obj;
@ -131,17 +131,17 @@ JsVar *jswrap_process_memory() {
}
unsigned int usage = jsvGetMemoryUsage() - history;
unsigned int total = jsvGetMemoryTotal();
jsvUnLock(jsvObjectSetChild(obj, "free", jsvNewFromInteger((JsVarInt)(total-usage))));
jsvUnLock(jsvObjectSetChild(obj, "usage", jsvNewFromInteger((JsVarInt)usage)));
jsvUnLock(jsvObjectSetChild(obj, "total", jsvNewFromInteger((JsVarInt)total)));
jsvUnLock(jsvObjectSetChild(obj, "history", jsvNewFromInteger((JsVarInt)history)));
jsvObjectSetChildAndUnLock(obj, "free", jsvNewFromInteger((JsVarInt)(total-usage)));
jsvObjectSetChildAndUnLock(obj, "usage", jsvNewFromInteger((JsVarInt)usage));
jsvObjectSetChildAndUnLock(obj, "total", jsvNewFromInteger((JsVarInt)total));
jsvObjectSetChildAndUnLock(obj, "history", jsvNewFromInteger((JsVarInt)history));
#ifdef ARM
jsvUnLock(jsvObjectSetChild(obj, "stackEndAddress", jsvNewFromInteger((JsVarInt)(unsigned int)&_end)));
jsvUnLock(jsvObjectSetChild(obj, "flash_start", jsvNewFromInteger((JsVarInt)FLASH_START)));
jsvUnLock(jsvObjectSetChild(obj, "flash_binary_end", jsvNewFromInteger((JsVarInt)(unsigned int)&_etext)));
jsvUnLock(jsvObjectSetChild(obj, "flash_code_start", jsvNewFromInteger((JsVarInt)FLASH_SAVED_CODE_START)));
jsvUnLock(jsvObjectSetChild(obj, "flash_length", jsvNewFromInteger((JsVarInt)FLASH_TOTAL)));
jsvObjectSetChildAndUnLock(obj, "stackEndAddress", jsvNewFromInteger((JsVarInt)(unsigned int)&_end));
jsvObjectSetChildAndUnLock(obj, "flash_start", jsvNewFromInteger((JsVarInt)FLASH_START));
jsvObjectSetChildAndUnLock(obj, "flash_binary_end", jsvNewFromInteger((JsVarInt)(unsigned int)&_etext));
jsvObjectSetChildAndUnLock(obj, "flash_code_start", jsvNewFromInteger((JsVarInt)FLASH_SAVED_CODE_START));
jsvObjectSetChildAndUnLock(obj, "flash_length", jsvNewFromInteger((JsVarInt)FLASH_TOTAL));
#endif
}
return obj;

View File

@ -195,16 +195,16 @@ void jswrap_serial_setup(JsVar *parent, JsVar *baud, JsVar *options) {
jsvUnLock(v);
#ifdef LINUX
jsvUnLock(jsvObjectSetChild(parent, "path", jsvObjectGetChild(options, "path", 0)));
jsvObjectSetChildAndUnLock(parent, "path", jsvObjectGetChild(options, "path", 0));
#endif
}
jshUSARTSetup(device, &inf);
// Set baud rate in object, so we can initialise it on startup
jsvUnLock(jsvObjectSetChild(parent, USART_BAUDRATE_NAME, jsvNewFromInteger(inf.baudRate)));
jsvObjectSetChildAndUnLock(parent, USART_BAUDRATE_NAME, jsvNewFromInteger(inf.baudRate));
// Do the same for options
if (options)
jsvUnLock(jsvObjectSetChild(parent, DEVICE_OPTIONS_NAME, options));
jsvObjectSetChildAndUnLock(parent, DEVICE_OPTIONS_NAME, options);
else
jsvRemoveNamedChild(parent, DEVICE_OPTIONS_NAME);
}

View File

@ -85,7 +85,7 @@ void jswrap_spi_setup(JsVar *parent, JsVar *options) {
jshSPISetup(device, &inf);
#ifdef LINUX
if (jsvIsObject(options)) {
jsvUnLock(jsvObjectSetChild(parent, "path", jsvObjectGetChild(options, "path", 0)));
jsvObjectSetChildAndUnLock(parent, "path", jsvObjectGetChild(options, "path", 0));
}
#endif
} else if (device == EV_NONE) {

View File

@ -53,7 +53,7 @@ JsVar *jswrap_stream_read(JsVar *parent, JsVarInt chars) {
// return just part of the buffer, and shorten it accordingly
data = jsvNewFromStringVar(buf, 0, (size_t)chars);
JsVar *newBuf = jsvNewFromStringVar(buf, (size_t)chars, JSVAPPENDSTRINGVAR_MAXLENGTH);
jsvUnLock(jsvObjectSetChild(parent, STREAM_BUFFER_NAME, newBuf));
jsvObjectSetChildAndUnLock(parent, STREAM_BUFFER_NAME, newBuf);
}
} else
data = jsvNewFromEmptyString();

View File

@ -226,8 +226,7 @@ JsVar *jswrap_string_replace(JsVar *parent, JsVar *subStr, JsVar *newSubStr) {
str = newStr;
}
jsvUnLock(subStr);
jsvUnLock(newSubStr);
jsvUnLock2(subStr, newSubStr);
return str;
}

View File

@ -71,7 +71,7 @@ bool jswrap_waveform_idle() {
jsiQueueObjectCallbacks(waveform, "#onfinish", &arrayBuffer, 1);
jsvUnLock(arrayBuffer);
running = false;
jsvUnLock(jsvObjectSetChild(waveform, "running", jsvNewFromBool(running)));
jsvObjectSetChildAndUnLock(waveform, "running", jsvNewFromBool(running));
} else {
// If the timer task is still there...
if (task.data.buffer.nextBuffer &&
@ -81,7 +81,7 @@ bool jswrap_waveform_idle() {
int oldBuffer = jsvGetIntegerAndUnLock(jsvObjectGetChild(waveform, "currentBuffer", JSV_INTEGER));
if (oldBuffer != currentBuffer) {
// buffers have changed - fire off a 'buffer' event with the buffer that needs to be filled
jsvUnLock(jsvObjectSetChild(waveform, "currentBuffer", jsvNewFromInteger(currentBuffer)));
jsvObjectSetChildAndUnLock(waveform, "currentBuffer", jsvNewFromInteger(currentBuffer));
JsVar *arrayBuffer = jsvObjectGetChild(waveform, (currentBuffer==0) ? "buffer" : "buffer2", 0);
jsiQueueObjectCallbacks(waveform, "#onbuffer", &arrayBuffer, 1);
jsvUnLock(arrayBuffer);
@ -178,13 +178,11 @@ JsVar *jswrap_waveform_constructor(int samples, JsVar *options) {
if (!waveform || !arrayBuffer || (doubleBuffer && !arrayBuffer2)) {
jsvUnLock(waveform);
jsvUnLock(arrayBuffer); // out of memory
jsvUnLock(arrayBuffer2);
jsvUnLock3(waveform,arrayBuffer,arrayBuffer2); // out of memory
return 0;
}
jsvUnLock(jsvObjectSetChild(waveform, "buffer", arrayBuffer));
if (arrayBuffer2) jsvUnLock(jsvObjectSetChild(waveform, "buffer2", arrayBuffer2));
jsvObjectSetChildAndUnLock(waveform, "buffer", arrayBuffer);
if (arrayBuffer2) jsvObjectSetChildAndUnLock(waveform, "buffer2", arrayBuffer2);
return waveform;
}
@ -231,11 +229,10 @@ static void jswrap_waveform_start(JsVar *waveform, Pin pin, JsVarFloat freq, JsV
// And finally set it up
if (!jstStartSignal(startTime, jshGetTimeFromMilliseconds(1000.0 / freq), pin, buffer, repeat?(buffer2?buffer2:buffer):0, eventType))
jsWarn("Unable to schedule a timer");
jsvUnLock(buffer);
jsvUnLock(buffer2);
jsvUnLock2(buffer,buffer2);
jsvUnLock(jsvObjectSetChild(waveform, "running", jsvNewFromBool(true)));
jsvUnLock(jsvObjectSetChild(waveform, "freq", jsvNewFromFloat(freq)));
jsvObjectSetChildAndUnLock(waveform, "running", jsvNewFromBool(true));
jsvObjectSetChildAndUnLock(waveform, "freq", jsvNewFromFloat(freq));
// Add to our list of active waveforms
JsVar *waveforms = jsvObjectGetChild(execInfo.hiddenRoot, JSI_WAVEFORM_NAME, JSV_ARRAY);
if (waveforms) {

View File

@ -165,8 +165,7 @@ bool jshGetDevicePath(IOEventFlags device, char *buf, size_t bufSize) {
jsvGetString(str, buf, bufSize);
success = true;
}
jsvUnLock(str);
jsvUnLock(obj);
jsvUnLock2(str, obj);
return success;
}

View File

@ -20,7 +20,7 @@
bool isRunning = true;
void addNativeFunction(const char *name, void (*callbackPtr)(void)) {
jsvUnLock(jsvObjectSetChild(execInfo.root, name, jsvNewNativeFunction(callbackPtr, JSWAT_VOID)));
jsvObjectSetChildAndUnLock(execInfo.root, name, jsvNewNativeFunction(callbackPtr, JSWAT_VOID));
}