mirror of https://github.com/axmolengine/axmol.git
Merge pull request #1852 from dumganhar/iss1660-js-debugger
issue #1660: Adding debug support for js
This commit is contained in:
commit
cc2865e294
|
@ -9,6 +9,10 @@
|
|||
#include "js_bindings_ccbreader.h"
|
||||
#include "js_bindings_system_registration.h"
|
||||
|
||||
#if JSB_ENABLE_DEBUGGER
|
||||
#include "js_bindings_dbg.h"
|
||||
#endif
|
||||
|
||||
USING_NS_CC;
|
||||
using namespace CocosDenshion;
|
||||
|
||||
|
@ -47,7 +51,12 @@ bool AppDelegate::applicationDidFinishLaunching()
|
|||
|
||||
CCScriptEngineProtocol *pEngine = ScriptingCore::getInstance();
|
||||
CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);
|
||||
#if JSB_ENABLE_DEBUGGER
|
||||
ScriptingCore::getInstance()->enableDebugger();
|
||||
ScriptingCore::getInstance()->runScript("main.debug.js");
|
||||
#else
|
||||
ScriptingCore::getInstance()->runScript("MoonWarriors-jsb.js");
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
2e242c0171e848d248e90070640ddf579e07ec13
|
||||
c29148da456b0a1eb38816bf26c68ba21fa50ab7
|
|
@ -40,12 +40,28 @@
|
|||
#define LOGD(...) js_log(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#include "js_bindings_config.h"
|
||||
#if JSB_ENABLE_DEBUGGER
|
||||
#include "js_bindings_dbg.h"
|
||||
#endif
|
||||
|
||||
pthread_t debugThread;
|
||||
string inData;
|
||||
string outData;
|
||||
vector<string> queue;
|
||||
pthread_mutex_t g_qMutex;
|
||||
pthread_mutex_t g_rwMutex;
|
||||
bool vmLock = false;
|
||||
jsval frame = JSVAL_NULL, script = JSVAL_NULL;
|
||||
int clientSocket;
|
||||
|
||||
// server entry point for the bg thread
|
||||
void* serverEntryPoint(void*);
|
||||
|
||||
js_proxy_t *_native_js_global_ht = NULL;
|
||||
js_proxy_t *_js_native_global_ht = NULL;
|
||||
js_type_class_t *_js_global_type_ht = NULL;
|
||||
char *_js_log_buf = NULL;
|
||||
static const char * JSB_version = "JSB v0.5";
|
||||
|
||||
|
||||
std::vector<sc_register_sth> registrationList;
|
||||
|
||||
|
@ -291,12 +307,6 @@ void registerDefaultClasses(JSContext* cx, JSObject* global) {
|
|||
JS_DefineFunction(cx, global, "executeScript", ScriptingCore::executeScript, 1, JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(cx, global, "forceGC", ScriptingCore::forceGC, 0, JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
|
||||
// these are used in the debug socket
|
||||
JS_DefineFunction(cx, global, "_socketOpen", jsSocketOpen, 1, JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(cx, global, "_socketWrite", jsSocketWrite, 1, JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(cx, global, "_socketRead", jsSocketRead, 1, JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(cx, global, "_socketClose", jsSocketClose, 1, JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
|
||||
JS_DefineFunction(cx, global, "__getPlatform", JSBCore_platform, 0, JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(cx, global, "__getOS", JSBCore_os, 0, JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(cx, global, "__getVersion", JSBCore_version, 0, JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
|
@ -415,6 +425,9 @@ void ScriptingCore::createGlobalContext() {
|
|||
//JS_SetGCZeal(this->cx_, 2, JS_DEFAULT_ZEAL_FREQ);
|
||||
#endif
|
||||
this->global_ = NewGlobalObject(cx_);
|
||||
#if JSB_ENABLE_DEBUGGER
|
||||
JS_SetDebugMode(cx_, JS_TRUE);
|
||||
#endif
|
||||
for (std::vector<sc_register_sth>::iterator it = registrationList.begin(); it != registrationList.end(); it++) {
|
||||
sc_register_sth callback = *it;
|
||||
callback(this->cx_, this->global_);
|
||||
|
@ -460,6 +473,7 @@ JSBool ScriptingCore::runScript(const char *path, JSObject* global, JSContext* c
|
|||
evaluatedOK = JS_ExecuteScript(cx, global, script, &rval);
|
||||
if (JS_FALSE == evaluatedOK) {
|
||||
CCLog("(evaluatedOK == JS_FALSE)");
|
||||
JS_ReportPendingException(cx);
|
||||
}
|
||||
}
|
||||
return evaluatedOK;
|
||||
|
@ -1399,41 +1413,55 @@ jsval cccolor3b_to_jsval(JSContext* cx, const ccColor3B& v) {
|
|||
|
||||
#pragma mark - Debug
|
||||
|
||||
void ScriptingCore::enableDebugger() {
|
||||
void ScriptingCore::debugProcessInput(string str) {
|
||||
JSString* jsstr = JS_NewStringCopyZ(cx_, str.c_str());
|
||||
jsval argv[3] = {
|
||||
STRING_TO_JSVAL(jsstr),
|
||||
frame,
|
||||
script
|
||||
};
|
||||
jsval outval;
|
||||
JSAutoCompartment ac(cx_, debugGlobal_);
|
||||
JS_CallFunctionName(cx_, debugGlobal_, "processInput", 3, argv, &outval);
|
||||
}
|
||||
|
||||
void ScriptingCore::enableDebugger() {
|
||||
if (debugGlobal_ == NULL) {
|
||||
debugGlobal_ = NewGlobalObject(cx_, true);
|
||||
// these are used in the debug socket
|
||||
JS_WrapObject(cx_, &debugGlobal_);
|
||||
JSAutoCompartment ac(cx_, debugGlobal_);
|
||||
// these are used in the debug program
|
||||
JS_DefineFunction(cx_, debugGlobal_, "log", ScriptingCore::log, 0, JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(cx_, debugGlobal_, "_getScript", jsGetScript, 1, JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(cx_, debugGlobal_, "_socketOpen", jsSocketOpen, 1, JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(cx_, debugGlobal_, "_socketWrite", jsSocketWrite, 1, JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(cx_, debugGlobal_, "_socketRead", jsSocketRead, 1, JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(cx_, debugGlobal_, "_socketClose", jsSocketClose, 1, JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(cx_, debugGlobal_, "_bufferWrite", JSBDebug_BufferWrite, 1, JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(cx_, debugGlobal_, "_bufferRead", JSBDebug_BufferRead, 0, JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(cx_, debugGlobal_, "_lockVM", JSBDebug_LockExecution, 2, JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(cx_, debugGlobal_, "_unlockVM", JSBDebug_UnlockExecution, 0, JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
|
||||
runScript("jsb_debugger.js", debugGlobal_);
|
||||
|
||||
runScript("debugger.js", debugGlobal_);
|
||||
// prepare the debugger
|
||||
do {
|
||||
jsval argv = OBJECT_TO_JSVAL(global_);
|
||||
jsval out;
|
||||
JS_WrapObject(cx_, &debugGlobal_);
|
||||
JSAutoCompartment ac(cx_, debugGlobal_);
|
||||
JS_CallFunctionName(cx_, debugGlobal_, "_prepareDebugger", 1, &argv, &out);
|
||||
} while (0);
|
||||
jsval argv = OBJECT_TO_JSVAL(global_);
|
||||
jsval outval;
|
||||
JSBool ok = JS_CallFunctionName(cx_, debugGlobal_, "_prepareDebugger", 1, &argv, &outval);
|
||||
if (!ok) {
|
||||
JS_ReportPendingException(cx_);
|
||||
}
|
||||
// define the start debugger function
|
||||
JS_DefineFunction(cx_, global_, "startDebugger", jsStartDebugger, 3, JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineFunction(cx_, global_, "startDebugger", JSBDebug_StartDebugger, 3, JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
// start bg thread
|
||||
pthread_create(&debugThread, NULL, serverEntryPoint, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
JSBool jsStartDebugger(JSContext* cx, unsigned argc, jsval* vp)
|
||||
{
|
||||
JSObject* debugGlobal = ScriptingCore::getInstance()->getDebugGlobal();
|
||||
if (argc == 3) {
|
||||
if (argc >= 2) {
|
||||
jsval* argv = JS_ARGV(cx, vp);
|
||||
jsval out;
|
||||
JS_WrapObject(cx, &debugGlobal);
|
||||
JSAutoCompartment ac(cx, debugGlobal);
|
||||
JS_CallFunctionName(cx, debugGlobal, "_startDebugger", 3, argv, &out);
|
||||
JS_CallFunctionName(cx, debugGlobal, "_startDebugger", argc, argv, &out);
|
||||
return JS_TRUE;
|
||||
}
|
||||
return JS_FALSE;
|
||||
|
@ -1474,110 +1502,6 @@ JSObject* NewGlobalObject(JSContext* cx, bool debug)
|
|||
return glob;
|
||||
}
|
||||
|
||||
// open a socket, bind it to a port and start listening, all at once :)
|
||||
JSBool jsSocketOpen(JSContext* cx, unsigned argc, jsval* vp)
|
||||
{
|
||||
if (argc == 2) {
|
||||
jsval* argv = JS_ARGV(cx, vp);
|
||||
int port = JSVAL_TO_INT(argv[0]);
|
||||
JSObject* callback = JSVAL_TO_OBJECT(argv[1]);
|
||||
|
||||
int s;
|
||||
s = ports_sockets[port];
|
||||
if (!s) {
|
||||
char myname[256];
|
||||
struct sockaddr_in sa;
|
||||
struct hostent *hp;
|
||||
memset(&sa, 0, sizeof(struct sockaddr_in));
|
||||
gethostname(myname, 256);
|
||||
hp = gethostbyname(myname);
|
||||
sa.sin_family = hp->h_addrtype;
|
||||
sa.sin_port = htons(port);
|
||||
if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
JS_ReportError(cx, "error opening socket");
|
||||
return JS_FALSE;
|
||||
}
|
||||
int optval = 1;
|
||||
if ((setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof(optval))) < 0) {
|
||||
close(s);
|
||||
JS_ReportError(cx, "error setting socket options");
|
||||
return JS_FALSE;
|
||||
}
|
||||
if ((bind(s, (const struct sockaddr *)&sa, sizeof(struct sockaddr_in))) < 0) {
|
||||
close(s);
|
||||
JS_ReportError(cx, "error binding socket");
|
||||
return JS_FALSE;
|
||||
}
|
||||
listen(s, 1);
|
||||
int clientSocket;
|
||||
if ((clientSocket = accept(s, NULL, NULL)) > 0) {
|
||||
ports_sockets[port] = clientSocket;
|
||||
jsval fval = OBJECT_TO_JSVAL(callback);
|
||||
jsval jsSocket = INT_TO_JSVAL(clientSocket);
|
||||
jsval outVal;
|
||||
JS_CallFunctionValue(cx, NULL, fval, 1, &jsSocket, &outVal);
|
||||
}
|
||||
} else {
|
||||
// just call the callback with the client socket
|
||||
jsval fval = OBJECT_TO_JSVAL(callback);
|
||||
jsval jsSocket = INT_TO_JSVAL(s);
|
||||
jsval outVal;
|
||||
JS_CallFunctionValue(cx, NULL, fval, 1, &jsSocket, &outVal);
|
||||
}
|
||||
JS_SET_RVAL(cx, vp, INT_TO_JSVAL(s));
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool jsSocketRead(JSContext* cx, unsigned argc, jsval* vp)
|
||||
{
|
||||
if (argc == 1) {
|
||||
jsval* argv = JS_ARGV(cx, vp);
|
||||
int s = JSVAL_TO_INT(argv[0]);
|
||||
char buff[1024];
|
||||
JSString* outStr = JS_NewStringCopyZ(cx, "");
|
||||
|
||||
int bytesRead;
|
||||
while ((bytesRead = read(s, buff, 1024)) > 0) {
|
||||
JSString* newStr = JS_NewStringCopyN(cx, buff, bytesRead);
|
||||
outStr = JS_ConcatStrings(cx, outStr, newStr);
|
||||
// break on new line
|
||||
if (buff[bytesRead-1] == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(outStr));
|
||||
} else {
|
||||
JS_SET_RVAL(cx, vp, JSVAL_NULL);
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool jsSocketWrite(JSContext* cx, unsigned argc, jsval* vp)
|
||||
{
|
||||
if (argc == 2) {
|
||||
jsval* argv = JS_ARGV(cx, vp);
|
||||
int s;
|
||||
|
||||
s = JSVAL_TO_INT(argv[0]);
|
||||
JSString* jsstr = JS_ValueToString(cx, argv[1]);
|
||||
JSStringWrapper str(jsstr);
|
||||
|
||||
write(s, str, strlen(str));
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool jsSocketClose(JSContext* cx, unsigned argc, jsval* vp)
|
||||
{
|
||||
if (argc == 1) {
|
||||
jsval* argv = JS_ARGV(cx, vp);
|
||||
int s = JSVAL_TO_INT(argv[0]);
|
||||
close(s);
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool jsb_set_reserved_slot(JSObject *obj, uint32_t idx, jsval value)
|
||||
{
|
||||
JSClass *klass = JS_GetClass(obj);
|
||||
|
@ -1601,3 +1525,181 @@ JSBool jsb_get_reserved_slot(JSObject *obj, uint32_t idx, jsval& ret)
|
|||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
#pragma mark - Debugger
|
||||
|
||||
JSBool JSBDebug_StartDebugger(JSContext* cx, unsigned argc, jsval* vp)
|
||||
{
|
||||
JSObject* debugGlobal = ScriptingCore::getInstance()->getDebugGlobal();
|
||||
if (argc >= 2) {
|
||||
jsval* argv = JS_ARGV(cx, vp);
|
||||
jsval out;
|
||||
JS_WrapObject(cx, &debugGlobal);
|
||||
JSAutoCompartment ac(cx, debugGlobal);
|
||||
JS_CallFunctionName(cx, debugGlobal, "_startDebugger", argc, argv, &out);
|
||||
return JS_TRUE;
|
||||
}
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JSBool JSBDebug_BufferRead(JSContext* cx, unsigned argc, jsval* vp)
|
||||
{
|
||||
if (argc == 0) {
|
||||
JSString* str;
|
||||
// this is safe because we're already inside a lock (from clearBuffers)
|
||||
if (vmLock) {
|
||||
pthread_mutex_lock(&g_rwMutex);
|
||||
}
|
||||
str = JS_NewStringCopyZ(cx, inData.c_str());
|
||||
inData.clear();
|
||||
if (vmLock) {
|
||||
pthread_mutex_unlock(&g_rwMutex);
|
||||
}
|
||||
JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(str));
|
||||
} else {
|
||||
JS_SET_RVAL(cx, vp, JSVAL_NULL);
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool JSBDebug_BufferWrite(JSContext* cx, unsigned argc, jsval* vp)
|
||||
{
|
||||
if (argc == 1) {
|
||||
jsval* argv = JS_ARGV(cx, vp);
|
||||
const char* str;
|
||||
|
||||
JSString* jsstr = JS_ValueToString(cx, argv[0]);
|
||||
str = JS_EncodeString(cx, jsstr);
|
||||
|
||||
// this is safe because we're already inside a lock (from clearBuffers)
|
||||
outData.append(str);
|
||||
|
||||
JS_free(cx, (void*)str);
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
// this should lock the execution of the running thread, waiting for a signal
|
||||
JSBool JSBDebug_LockExecution(JSContext* cx, unsigned argc, jsval* vp)
|
||||
{
|
||||
if (argc == 2) {
|
||||
printf("locking vm\n");
|
||||
jsval* argv = JS_ARGV(cx, vp);
|
||||
frame = argv[0];
|
||||
script = argv[1];
|
||||
vmLock = true;
|
||||
while (vmLock) {
|
||||
// try to read the input, if there's anything
|
||||
pthread_mutex_lock(&g_qMutex);
|
||||
while (queue.size() > 0) {
|
||||
vector<string>::iterator first = queue.begin();
|
||||
string str = *first;
|
||||
ScriptingCore::getInstance()->debugProcessInput(str);
|
||||
queue.erase(first);
|
||||
}
|
||||
pthread_mutex_unlock(&g_qMutex);
|
||||
sched_yield();
|
||||
}
|
||||
printf("vm unlocked\n");
|
||||
frame = JSVAL_NULL;
|
||||
script = JSVAL_NULL;
|
||||
return JS_TRUE;
|
||||
}
|
||||
JS_ReportError(cx, "invalid call to _lockVM");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JSBool JSBDebug_UnlockExecution(JSContext* cx, unsigned argc, jsval* vp)
|
||||
{
|
||||
vmLock = false;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
bool serverAlive = true;
|
||||
|
||||
void processInput(string data) {
|
||||
pthread_mutex_lock(&g_qMutex);
|
||||
queue.push_back(string(data));
|
||||
pthread_mutex_unlock(&g_qMutex);
|
||||
}
|
||||
|
||||
void clearBuffers() {
|
||||
pthread_mutex_lock(&g_rwMutex);
|
||||
{
|
||||
// only process input if there's something and we're not locked
|
||||
if (inData.length() > 0) {
|
||||
processInput(inData);
|
||||
inData.clear();
|
||||
}
|
||||
if (outData.length() > 0) {
|
||||
write(clientSocket, outData.c_str(), outData.length());
|
||||
outData.clear();
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&g_rwMutex);
|
||||
}
|
||||
|
||||
void* serverEntryPoint(void*)
|
||||
{
|
||||
// init the mutex
|
||||
assert(pthread_mutex_init(&g_rwMutex, NULL) == 0);
|
||||
assert(pthread_mutex_init(&g_qMutex, NULL) == 0);
|
||||
// start a server, accept the connection and keep reading data from it
|
||||
struct addrinfo hints, *result, *rp;
|
||||
int s;
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM; // TCP
|
||||
|
||||
int err;
|
||||
stringstream portstr;
|
||||
portstr << JSB_DEBUGGER_PORT;
|
||||
const char* tmp = portstr.str().c_str();
|
||||
if ((err = getaddrinfo(NULL, tmp, &hints, &result)) != 0) {
|
||||
printf("error: %s\n", gai_strerror(err));
|
||||
}
|
||||
|
||||
for (rp = result; rp != NULL; rp = rp->ai_next) {
|
||||
if ((s = socket(rp->ai_family, rp->ai_socktype, 0)) < 0) {
|
||||
continue;
|
||||
}
|
||||
int optval = 1;
|
||||
if ((setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof(optval))) < 0) {
|
||||
close(s);
|
||||
LOGD("error setting socket options");
|
||||
return NULL;
|
||||
}
|
||||
if ((bind(s, rp->ai_addr, rp->ai_addrlen)) == 0) {
|
||||
break;
|
||||
}
|
||||
close(s);
|
||||
s = -1;
|
||||
}
|
||||
if (s < 0 || rp == NULL) {
|
||||
LOGD("error creating/binding socket");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
freeaddrinfo(result);
|
||||
|
||||
listen(s, 1);
|
||||
while (serverAlive && (clientSocket = accept(s, NULL, NULL)) > 0) {
|
||||
// read/write data
|
||||
LOGD("debug client connected");
|
||||
while (serverAlive) {
|
||||
char buf[256];
|
||||
int readBytes;
|
||||
while ((readBytes = read(clientSocket, buf, 256)) > 0) {
|
||||
buf[readBytes] = '\0';
|
||||
// no other thread is using this
|
||||
inData.append(buf);
|
||||
// process any input, send any output
|
||||
clearBuffers();
|
||||
} // while(read)
|
||||
} // while(serverAlive)
|
||||
}
|
||||
// we're done, destroy the mutex
|
||||
pthread_mutex_destroy(&g_rwMutex);
|
||||
pthread_mutex_destroy(&g_qMutex);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include "cocos2d.h"
|
||||
#include "js_bindings_config.h"
|
||||
#include "js_bindings_core.h"
|
||||
#include "uthash.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
|
@ -19,6 +21,7 @@
|
|||
void js_log(const char *format, ...);
|
||||
|
||||
using namespace cocos2d;
|
||||
using namespace std;
|
||||
|
||||
typedef void (*sc_register_sth)(JSContext* cx, JSObject* global);
|
||||
|
||||
|
@ -175,6 +178,7 @@ public:
|
|||
/**
|
||||
* enable the debug environment
|
||||
*/
|
||||
void debugProcessInput(string str);
|
||||
void enableDebugger();
|
||||
JSObject* getDebugGlobal() { return debugGlobal_; }
|
||||
|
||||
|
@ -205,7 +209,7 @@ JSBool jsvals_variadic_to_ccarray( JSContext *cx, jsval *vp, int argc, CCArray**
|
|||
jsval int32_to_jsval( JSContext *cx, int32_t l);
|
||||
jsval uint32_to_jsval( JSContext *cx, uint32_t number );
|
||||
jsval long_long_to_jsval(JSContext* cx, long long v);
|
||||
jsval std_string_to_jsval(JSContext* cx, std::string& v);
|
||||
jsval std_string_to_jsval(JSContext* cx, string& v);
|
||||
jsval c_string_to_jsval(JSContext* cx, const char* v);
|
||||
jsval ccpoint_to_jsval(JSContext* cx, CCPoint& v);
|
||||
jsval ccrect_to_jsval(JSContext* cx, CCRect& v);
|
||||
|
@ -221,10 +225,11 @@ JSObject* NewGlobalObject(JSContext* cx, bool debug = false);
|
|||
JSBool jsStartDebugger(JSContext* cx, unsigned argc, jsval* vp);
|
||||
JSBool jsGetScript(JSContext* cx, unsigned argc, jsval* vp);
|
||||
|
||||
JSBool jsSocketOpen(JSContext* cx, unsigned argc, jsval* vp);
|
||||
JSBool jsSocketRead(JSContext* cx, unsigned argc, jsval* vp);
|
||||
JSBool jsSocketWrite(JSContext* cx, unsigned argc, jsval* vp);
|
||||
JSBool jsSocketClose(JSContext* cx, unsigned argc, jsval* vp);
|
||||
JSBool JSBDebug_StartDebugger(JSContext* cx, unsigned argc, jsval* vp);
|
||||
JSBool JSBDebug_BufferRead(JSContext* cx, unsigned argc, jsval* vp);
|
||||
JSBool JSBDebug_BufferWrite(JSContext* cx, unsigned argc, jsval* vp);
|
||||
JSBool JSBDebug_LockExecution(JSContext* cx, unsigned argc, jsval* vp);
|
||||
JSBool JSBDebug_UnlockExecution(JSContext* cx, unsigned argc, jsval* vp);
|
||||
|
||||
// just a simple utility to avoid mem leaking when using JSString
|
||||
class JSStringWrapper
|
||||
|
@ -264,7 +269,7 @@ public:
|
|||
}
|
||||
buffer = JS_EncodeString(cx, string);
|
||||
}
|
||||
std::string get() {
|
||||
std::string get() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
dbg = {};
|
||||
|
||||
// fallback for no cc
|
||||
cc = {};
|
||||
cc.log = log;
|
||||
|
||||
var breakpointHandler = {
|
||||
hit: function (frame) {
|
||||
var script = frame.script;
|
||||
|
@ -28,7 +24,7 @@ var stepFunction = function (frame, script) {
|
|||
|
||||
dbg.breakLine = 0;
|
||||
|
||||
var processInput = function (str, frame, script) {
|
||||
this.processInput = function (str, frame, script) {
|
||||
str = str.replace(/\n$/, "");
|
||||
if (str.length === 0) {
|
||||
return;
|
||||
|
@ -171,20 +167,26 @@ dbg.onError = function (frame, report) {
|
|||
cc.log("!! exception");
|
||||
};
|
||||
|
||||
function _prepareDebugger(global) {
|
||||
this._prepareDebugger = function (global) {
|
||||
var tmp = new Debugger(global);
|
||||
tmp.onNewScript = dbg.onNewScript;
|
||||
tmp.onDebuggerStatement = dbg.onDebuggerStatement;
|
||||
tmp.onError = dbg.onError;
|
||||
dbg.dbg = tmp;
|
||||
}
|
||||
};
|
||||
|
||||
function _startDebugger(global, files, startFunc) {
|
||||
cc.log("starting with debugger enabled");
|
||||
this._startDebugger = function (global, files, startFunc) {
|
||||
cc.log("[DBG] starting debug session");
|
||||
for (var i in files) {
|
||||
global['eval']("require('" + files[i] + "');");
|
||||
try {
|
||||
global['eval']("require('" + files[i] + "');");
|
||||
} catch (e) {
|
||||
cc.log("[DBG] error evaluating file: " + files[i]);
|
||||
}
|
||||
}
|
||||
cc.log("[DBG] all files required");
|
||||
if (startFunc) {
|
||||
cc.log("executing start func: " + startFunc);
|
||||
global['eval'](startFunc);
|
||||
}
|
||||
// beginDebug();
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* bootstrap for the debugger. You can test to see if the debugger is loaded by checking the type of
|
||||
* `startDebugger`. If that function is defined, then you should call it with the global object,
|
||||
* which at this point is `this`, the array of files that you need to load (usually is just your
|
||||
* main javascript), and the function that needs to be called to start your game, as a string.
|
||||
* If the `startDebugger` function is not defined, then you just require your files and start your
|
||||
* game :)
|
||||
*/
|
||||
var files = ['MoonWarriors-jsb.js'];
|
||||
if (typeof startDebugger !== "undefined") {
|
||||
cc.log("**** will start debugger ****");
|
||||
startDebugger(this, files);
|
||||
} else {
|
||||
cc.log("**** no debugger loaded ****");
|
||||
for (var i in files) {
|
||||
require(files[i]);
|
||||
}
|
||||
// run();
|
||||
}
|
|
@ -148,6 +148,12 @@ JSAutoCompartment ac(cx, obj)
|
|||
#define JSB_ENSURE_AUTOCOMPARTMENT(cx, obj)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def JSB_DEBUGGER_PORT
|
||||
* The port number, where the client will be listening on
|
||||
*/
|
||||
#define JSB_DEBUGGER_PORT 1337
|
||||
|
||||
/** @def JSB_INCLUDE_SYSTEM
|
||||
Whether or not it should include bindings for system components like LocalStorage
|
||||
*/
|
||||
|
|
|
@ -44,9 +44,9 @@ static tHashJSObject *hash = NULL;
|
|||
static tHashJSObject *reverse_hash = NULL;
|
||||
|
||||
// Globals
|
||||
char * JSB_association_proxy_key = NULL;
|
||||
char* JSB_association_proxy_key = NULL;
|
||||
|
||||
const char * JSB_version = "0.3-beta";
|
||||
const char* JSB_version = "0.3-beta";
|
||||
|
||||
|
||||
static void its_finalize(JSFreeOp *fop, JSObject *obj)
|
||||
|
|
Loading…
Reference in New Issue