mirror of
https://github.com/espruino/Espruino.git
synced 2025-12-08 19:06:15 +00:00
I love Eclipse global regex replace :)
Use jsvUnLock2/etc to really drop memory usage
This commit is contained in:
parent
7e02bc438a
commit
80ce11135a
@ -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
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
44
src/jsvar.c
44
src/jsvar.c
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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{
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user