1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2026-02-25 00:53:02 +00:00

Major agent update.

This commit is contained in:
Ylian Saint-Hilaire
2018-09-05 11:01:17 -07:00
parent 4b5c77b4fd
commit 3c80473a94
174 changed files with 19033 additions and 3307 deletions

View File

@@ -30,7 +30,92 @@ limitations under the License.
#endif
#define ILibDuktape_ModSearch_ModuleFile (void*)0xFF
#define ILibDuktape_ModSearch_ModuleObject (void*)0xFE
#define ILibDuktape_ModSearch_JSInclude "\xFF_ModSearch_JSINCLUDE"
#define ILibDuktape_ModSearch_ModulePath "\xFF_ModSearch_Path"
duk_ret_t ILibDuktape_ModSearch_GetJSModule(duk_context *ctx, char *id)
{
ILibHashtable table = NULL;
int idLen = (int)strnlen_s(id, 1024);
char *retVal = NULL;
duk_push_heap_stash(ctx); // [stash]
if (duk_has_prop_string(ctx, -1, "ModSearchTable"))
{
duk_get_prop_string(ctx, -1, "ModSearchTable"); // [stash][ptr]
table = (ILibHashtable)duk_to_pointer(ctx, -1);
duk_pop(ctx); // [stash]
}
else
{
table = ILibHashtable_Create();
duk_push_pointer(ctx, table); // [stash][ptr]
duk_put_prop_string(ctx, -2, "ModSearchTable"); // [stash]
}
duk_pop(ctx); // ...
retVal = ILibHashtable_Get(table, ILibDuktape_ModSearch_ModuleFile, id, idLen);
if (retVal == NULL)
{
duk_push_heap_stash(ctx);
char *mpath;
duk_size_t mpathLen;
mpath = Duktape_GetStringPropertyValueEx(ctx, -1, ILibDuktape_ModSearch_ModulePath, NULL, &mpathLen);
duk_pop(ctx);
char *fileName = ILibMemory_AllocateA(idLen + 4 + mpathLen + 1);
if (mpath == NULL)
{
sprintf_s(fileName, idLen + 4, "%s.js", id);
}
else
{
sprintf_s(fileName, idLen + 5 + mpathLen, "%s/%s.js", mpath, id);
}
int dataLen = ILibReadFileFromDiskEx(&retVal, fileName);
if (dataLen > 0) { duk_push_lstring(ctx, retVal, dataLen); free(retVal); }
else
{
return(0);
}
}
else
{
duk_push_string(ctx, retVal);
}
return(1);
}
void ILibDuktape_ModSearch_AddModuleObject(duk_context *ctx, char *id, void *heapptr)
{
int idLen = (int)strnlen_s(id, 1024);
ILibHashtable table = NULL;
duk_push_heap_stash(ctx); // [stash]
if (duk_has_prop_string(ctx, -1, "ModSearchTable"))
{
duk_get_prop_string(ctx, -1, "ModSearchTable"); // [stash][ptr]
table = (ILibHashtable)duk_to_pointer(ctx, -1);
duk_pop(ctx); // [stash]
}
else
{
table = ILibHashtable_Create();
duk_push_pointer(ctx, table); // [stash][ptr]
duk_put_prop_string(ctx, -2, "ModSearchTable"); // [stash]
}
duk_push_heapptr(ctx, heapptr);
duk_put_prop_string(ctx, -2, Duktape_GetStashKey(heapptr));
heapptr = ILibHashtable_Put(table, ILibDuktape_ModSearch_ModuleObject, id, idLen, heapptr);
if (heapptr != NULL)
{
// Remove the old object that was in the table
duk_del_prop_string(ctx, -1, Duktape_GetStashKey(heapptr));
}
duk_pop(ctx); // ...
}
int ILibDuktape_ModSearch_AddModule(duk_context *ctx, char *id, char *module, int moduleLen)
{
ILibHashtable table = NULL;
@@ -89,8 +174,20 @@ duk_ret_t mod_Search_Files(duk_context *ctx, char* id)
char fileName[255];
char *data;
int dataLen;
char *mpath = NULL;
sprintf_s(fileName, sizeof(fileName), "%s.js", id);
duk_push_heap_stash(ctx);
mpath = Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_ModSearch_ModulePath, NULL);
duk_pop(ctx);
if (mpath == NULL)
{
sprintf_s(fileName, sizeof(fileName), "%s.js", id);
}
else
{
sprintf_s(fileName, sizeof(fileName), "%s/%s.js", mpath, id);
}
dataLen = ILibReadFileFromDiskEx(&data, fileName);
if (dataLen > 0)
{
@@ -118,6 +215,13 @@ duk_ret_t mod_Search_Files(duk_context *ctx, char* id)
return DUK_RET_ERROR;
}
}
void ILibDuktape_ModSearch_AddHandler_AlsoIncludeJS(duk_context *ctx, char *js, size_t jsLen)
{
duk_push_heap_stash(ctx); // [stash]
duk_push_lstring(ctx, js, jsLen); // [stash][str]
duk_put_prop_string(ctx, -2, ILibDuktape_ModSearch_JSInclude); // [stash]
duk_pop(ctx); // ...
}
duk_ret_t mod_Search(duk_context *ctx)
{
@@ -128,6 +232,7 @@ duk_ret_t mod_Search(duk_context *ctx)
void *chain;
ILibSimpleDataStore mDS = NULL;
char *module;
void *j;
if (!duk_is_string(ctx, 0)) { return ILibDuktape_Error(ctx, "mod_search(): Invalid 'ID' parameter"); }
id = (char*)duk_get_lstring(ctx, 0, &idLen);
@@ -142,8 +247,17 @@ duk_ret_t mod_Search(duk_context *ctx)
duk_push_heap_stash(ctx);
duk_get_prop_string(ctx, -1, "ModSearchTable");
table = (ILibHashtable)duk_to_pointer(ctx, -1);
func = (ILibDuktape_ModSearch_PUSH_Object)ILibHashtable_Get(table, NULL, id, (int)idLen);
// First check if there is a JS override
j = ILibHashtable_Get(table, ILibDuktape_ModSearch_ModuleObject, id, (int)idLen);
if (j != NULL)
{
duk_push_heapptr(ctx, j);
duk_put_prop_string(ctx, 3, "exports");
return(0);
}
func = (ILibDuktape_ModSearch_PUSH_Object)ILibHashtable_Get(table, NULL, id, (int)idLen);
if (func == NULL)
{
if ((module = (char*)ILibHashtable_Get(table, ILibDuktape_ModSearch_ModuleFile, id, (int)idLen)) != NULL)
@@ -173,18 +287,30 @@ duk_ret_t mod_Search(duk_context *ctx)
}
else
{
sprintf_s(key, sizeof(key), "Module: %s (NOT FOUND in DB)", id);
duk_push_string(ctx, key);
duk_throw(ctx);
return DUK_RET_ERROR;
return mod_Search_Files(ctx, id);
}
}
}
else
{
// Init this temp value, to detect if the module wants to add JS code
duk_push_heap_stash(ctx);
duk_del_prop_string(ctx, -1, ILibDuktape_ModSearch_JSInclude);
duk_pop(ctx);
func(ctx, chain);
duk_put_prop_string(ctx, 3, "exports");
return 0;
duk_push_heap_stash(ctx);
if (duk_has_prop_string(ctx, -1, ILibDuktape_ModSearch_JSInclude))
{
duk_get_prop_string(ctx, -1, ILibDuktape_ModSearch_JSInclude);
return(1);
}
else
{
return 0;
}
}
}
void ILibDuktape_ModSearch_Destroy(duk_context *ctx, void *user)
@@ -202,6 +328,23 @@ void ILibDuktape_ModSearch_Destroy(duk_context *ctx, void *user)
duk_pop(ctx);
}
}
duk_ret_t ILibDuktape_ModSearch_setModulePath(duk_context *ctx)
{
if (duk_is_string(ctx, 0))
{
duk_push_heap_stash(ctx);
duk_dup(ctx, 0);
duk_put_prop_string(ctx, -2, ILibDuktape_ModSearch_ModulePath);
}
else
{
return(ILibDuktape_Error(ctx, "Invalid Path"));
}
return(0);
}
void ILibDuktape_ModSearch_Init(duk_context * ctx, void * chain, ILibSimpleDataStore mDB)
{
duk_module_duktape_init(ctx);
@@ -225,5 +368,10 @@ void ILibDuktape_ModSearch_Init(duk_context * ctx, void * chain, ILibSimpleDataS
duk_put_prop_string(ctx, -2, "modSearch"); // [globalString]
duk_pop(ctx); // ...
duk_push_global_object(ctx); // [g]
ILibDuktape_CreateInstanceMethod(ctx, "setModulePath", ILibDuktape_ModSearch_setModulePath, 1);
duk_pop(ctx); // ...
ILibDuktape_Helper_AddHeapFinalizer(ctx, ILibDuktape_ModSearch_Destroy, NULL);
}

View File

@@ -23,7 +23,10 @@ limitations under the License.
typedef void (*ILibDuktape_ModSearch_PUSH_Object)(duk_context *ctx, void *chain);
int ILibDuktape_ModSearch_AddHandler(duk_context *ctx, char *id, ILibDuktape_ModSearch_PUSH_Object handler);
void ILibDuktape_ModSearch_AddHandler_AlsoIncludeJS(duk_context *ctx, char *js, size_t jsLen);
int ILibDuktape_ModSearch_AddModule(duk_context *ctx, char *id, char *module, int moduleLen);
void ILibDuktape_ModSearch_AddModuleObject(duk_context *ctx, char *id, void *heapptr);
duk_ret_t ILibDuktape_ModSearch_GetJSModule(duk_context *ctx, char *id);
void ILibDuktape_ModSearch_Init(duk_context *ctx, void *chain, ILibSimpleDataStore mDB);
#endif

View File

@@ -137,34 +137,40 @@ ILibDuktape_ChildProcess_SubProcess* ILibDuktape_ChildProcess_SpawnedProcess_PUS
ILibDuktape_CreateInstanceMethod(ctx, "kill", ILibDuktape_ChildProcess_Kill, 0);
duk_push_object(ctx);
ILibDuktape_WriteID(ctx, "childProcess.subProcess.stdout");
duk_dup(ctx, -2);
ILibDuktape_CreateReadonlyProperty(ctx, "parent");
retVal->stdOut = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_ChildProcess_SubProcess_StdOut_OnPause, ILibDuktape_ChildProcess_SubProcess_StdOut_OnResume, retVal);
ILibDuktape_CreateReadonlyProperty(ctx, "stdout");
if (ILibProcessPipe_Process_IsDetached(mProcess) == 0)
{
duk_push_object(ctx);
ILibDuktape_WriteID(ctx, "childProcess.subProcess.stdout");
duk_dup(ctx, -2);
ILibDuktape_CreateReadonlyProperty(ctx, "parent");
retVal->stdOut = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_ChildProcess_SubProcess_StdOut_OnPause, ILibDuktape_ChildProcess_SubProcess_StdOut_OnResume, retVal);
ILibDuktape_CreateReadonlyProperty(ctx, "stdout");
duk_push_object(ctx);
ILibDuktape_WriteID(ctx, "childProcess.subProcess.stderr");
duk_dup(ctx, -2);
ILibDuktape_CreateReadonlyProperty(ctx, "parent");
retVal->stdErr = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_ChildProcess_SubProcess_StdErr_OnPause, ILibDuktape_ChildProcess_SubProcess_StdErr_OnResume, retVal);
ILibDuktape_CreateReadonlyProperty(ctx, "stderr");
duk_push_object(ctx);
ILibDuktape_WriteID(ctx, "childProcess.subProcess.stderr");
duk_dup(ctx, -2);
ILibDuktape_CreateReadonlyProperty(ctx, "parent");
retVal->stdErr = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_ChildProcess_SubProcess_StdErr_OnPause, ILibDuktape_ChildProcess_SubProcess_StdErr_OnResume, retVal);
ILibDuktape_CreateReadonlyProperty(ctx, "stderr");
duk_push_object(ctx);
ILibDuktape_WriteID(ctx, "childProcess.subProcess.stdin");
duk_dup(ctx, -2);
ILibDuktape_CreateReadonlyProperty(ctx, "parent");
retVal->stdIn = ILibDuktape_WritableStream_Init(ctx, ILibDuktape_ChildProcess_SubProcess_StdIn_WriteHandler, ILibDuktape_ChildProcess_SubProcess_StdIn_EndHandler, retVal);
ILibDuktape_CreateReadonlyProperty(ctx, "stdin");
duk_push_object(ctx);
ILibDuktape_WriteID(ctx, "childProcess.subProcess.stdin");
duk_dup(ctx, -2);
ILibDuktape_CreateReadonlyProperty(ctx, "parent");
retVal->stdIn = ILibDuktape_WritableStream_Init(ctx, ILibDuktape_ChildProcess_SubProcess_StdIn_WriteHandler, ILibDuktape_ChildProcess_SubProcess_StdIn_EndHandler, retVal);
ILibDuktape_CreateReadonlyProperty(ctx, "stdin");
if (callback != NULL) { ILibDuktape_EventEmitter_AddOnce(emitter, "exit", callback); }
ILibProcessPipe_Process_AddHandlers(mProcess, 4096, ILibDuktape_ChildProcess_SubProcess_ExitHandler,
ILibDuktape_ChildProcess_SubProcess_StdOutHandler,
ILibDuktape_ChildProcess_SubProcess_StdErrHandler,
ILibDuktape_ChildProcess_SubProcess_SendOK, retVal);
if (callback != NULL) { ILibDuktape_EventEmitter_AddOnce(emitter, "exit", callback); }
ILibProcessPipe_Process_AddHandlers(mProcess, 4096, ILibDuktape_ChildProcess_SubProcess_ExitHandler,
ILibDuktape_ChildProcess_SubProcess_StdOutHandler,
ILibDuktape_ChildProcess_SubProcess_StdErrHandler,
ILibDuktape_ChildProcess_SubProcess_SendOK, retVal);
}
else
{
if (callback != NULL) { ILibDuktape_EventEmitter_AddOnce(emitter, "exit", callback); }
}
return(retVal);
}
@@ -189,6 +195,10 @@ duk_ret_t ILibDuktape_ChildProcess_execFile(duk_context *ctx)
void *callback = NULL;
ILibProcessPipe_Process p = NULL;
ILibProcessPipe_SpawnTypes spawnType = ILibProcessPipe_SpawnTypes_DEFAULT;
#ifndef WIN32
int uid = -1;
#endif
for (i = 0; i < nargs; ++i)
{
@@ -215,6 +225,9 @@ duk_ret_t ILibDuktape_ChildProcess_execFile(duk_context *ctx)
{
// Options
spawnType = (ILibProcessPipe_SpawnTypes)Duktape_GetIntPropertyValue(ctx, i, "type", (int)ILibProcessPipe_SpawnTypes_DEFAULT);
#ifndef WIN32
uid = Duktape_GetIntPropertyValue(ctx, i, "uid", -1);
#endif
}
}
@@ -237,7 +250,11 @@ duk_ret_t ILibDuktape_ChildProcess_execFile(duk_context *ctx)
}
#endif
#ifdef WIN32
p = ILibProcessPipe_Manager_SpawnProcessEx2(manager, target, args, spawnType, 0);
#else
p = ILibProcessPipe_Manager_SpawnProcessEx3(manager, target, args, spawnType, (void*)(uint64_t)uid, 0);
#endif
if (p == NULL)
{
return(ILibDuktape_Error(ctx, "child_process.execFile(): Could not exec [%s]", target));
@@ -263,6 +280,8 @@ void ILibDuktape_ChildProcess_PUSH(duk_context *ctx, void *chain)
duk_put_prop_string(ctx, -2, "WINLOGON");
duk_push_int(ctx, 3);
duk_put_prop_string(ctx, -2, "TERM");
duk_push_int(ctx, 4);
duk_put_prop_string(ctx, -2, "DETACHED");
duk_put_prop_string(ctx, -2, "SpawnTypes");
}
void ILibDuktape_ChildProcess_Init(duk_context *ctx)
@@ -324,4 +343,4 @@ public:
WritableStream stdin;
};
#endif
#endif

View File

@@ -21,14 +21,34 @@ limitations under the License.
#include "microstack/ILibParsers.h"
#include "microstack/ILibAsyncServerSocket.h"
#include "microstack/ILibSimpleDataStore.h"
#include "ILibDuktape_Helpers.h"
#include "duktape.h"
#include "ILibDuktape_ScriptContainer.h"
#include "ILibDuktape_Debugger.h"
#include "ILibDuktapeModSearch.h"
#define ILibDuktape_Debugger_SCRIPT_SOURCE "_scriptSourceForDebugger"
#define ILibDuktape_Debugger_SCRIPT_PATH "_scriptPathForDebugger"
#define ILibDuktape_Debugger_AttachOptions "\xFF_debugger_attachOptions"
#define ILibDuktape_Debugger_Options_Rejector "\xFF_rejector"
#define ILibDuktape_Debugger_Options_Resolver "\xFF_resolver"
#define ILibDuktape_Debugger_DebugObject "_DbgObj"
#define ILibDuktape_Debugger_HostChain "_HostChain"
#define ILibDuktape_Debugger_MemoryReportInterval "_Debugger_MemoryReporting"
extern size_t ILibDuktape_ScriptContainer_TotalAllocations;
typedef struct ILibDuktape_Debugger
{
ILibChain_Link *chainedObject;
duk_context *ctx;
duk_thread_state hoststate;
sem_t hostlock;
int waitConnection;
void *debugThread;
int webport;
void *interval;
char data[sizeof(char*)];
#ifdef WIN32
SOCKET listener;
SOCKET client;
@@ -38,7 +58,130 @@ typedef struct ILibDuktape_Debugger
#endif
}ILibDuktape_Debugger;
void *DebugWebEngine_Context;
void *DebugWebEngine_Chain;
void *DebugWebEngine_Thread;
void ILibDuktape_Debugger_AsyncWaitConn(ILibDuktape_Debugger *dbg);
duk_ret_t ILibDuktape_Debugger_MemoryReportingSink(duk_context *ctx)
{
duk_push_string(ctx, "MemoryAllocations");
duk_push_int(ctx, (duk_int_t)ILibDuktape_ScriptContainer_TotalAllocations);
duk_debugger_notify(ctx, 2);
return(0);
}
void ILibDuktape_Debugger_StartMemoryReporting(duk_context *ctx)
{
duk_push_global_object(ctx); // [g]
duk_get_prop_string(ctx, -1, "setInterval"); // [g][setInterval]
duk_swap_top(ctx, -2); // [setInterVal][this]
duk_push_c_function(ctx, ILibDuktape_Debugger_MemoryReportingSink, 0); // [setInterVal][this][func]
duk_push_int(ctx, 5000); // [setInterVal][this][func][delay]
if (duk_pcall_method(ctx, 2) != 0) { duk_pop(ctx); return; } // [interval]
duk_push_heap_stash(ctx); // [interval][stash]
duk_swap_top(ctx, -2); // [stash][interval]
duk_put_prop_string(ctx, -2, ILibDuktape_Debugger_MemoryReportInterval);// [stash]
duk_pop(ctx); // ...
}
void ILibDuktape_Debugger_StopMemoryReporting(duk_context *ctx)
{
duk_push_heap_stash(ctx);
duk_del_prop_string(ctx, -1, ILibDuktape_Debugger_MemoryReportInterval);
duk_pop(ctx);
}
void ILibDuktape_Debugger_Socket_finish(void *udata)
{
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)udata;
if (dbg->client != ~0)
{
#ifdef WIN32
closesocket(dbg->client);
#else
shutdown(dbg->client, SHUT_RDWR);
close(dbg->client);
#endif
dbg->client = ~0;
}
ILibDuktape_Debugger_StopMemoryReporting(dbg->ctx);
}
void ILibDuktape_Debugger_Socket_waitconn(void *udata)
{
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)udata;
if (!ILibMemory_CanaryOK(dbg))
{
printf("INVALID CANARY\n");
}
dbg->client = accept(dbg->listener, NULL, NULL);
((void**)dbg->data)[0] = dbg;
if (dbg->client == ~0)
{
#ifdef WIN32
printf("Ooops, invalid socket: %d\n", WSAGetLastError());
#else
printf("Ooops, invalid socket: %d\n", errno);
#endif
}
}
duk_size_t ILibDuktape_Debugger_PeekCB(void *udata)
{
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)udata;
int bytes = 0;
#ifndef WIN32
char tmp[8];
#endif
// Set the socket to non-blocking mode, because we need to play nice and share the MicroStack thread
#if defined(WIN32)
if (dbg->client == ~0)
{
return(0);
}
//// On Windows must set NON_BLOCK to check this
//int flags = 1;
//ioctlsocket(dbg->client, FIONBIO, (u_long *)(&flags));
//bytes = recv(dbg->client, tmp, sizeof(tmp), MSG_PEEK);
//flags = 0;
//ioctlsocket(dbg->client, FIONBIO, (u_long *)(&flags));
u_long avail = 0;
int rc = ioctlsocket(dbg->client, FIONREAD, &avail);
if (rc != 0)
{
fprintf(stderr, "%s: ioctlsocket() returned %d, closing connection\n",
__FILE__, rc);
fflush(stderr);
return(0);
}
else
{
if (avail == 0)
{
return 0; /* nothing to read */
}
else
{
return 1; /* something to read */
}
}
#else
// Everything else, use MSG_DONTWAIT
bytes = recv(dbg->client, tmp, sizeof(tmp), MSG_PEEK | MSG_DONTWAIT);
#endif
return(bytes > 0 ? 1 : 0);
}
duk_size_t ILibDuktape_Debugger_ReadCB(void *udata, char *buffer, duk_size_t length)
{
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)udata;
@@ -50,41 +193,554 @@ duk_size_t ILibDuktape_Debugger_WriteCB(void *udata, const char *buffer, duk_siz
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)udata;
return (duk_size_t)send(dbg->client, buffer, (int)length, 0);
}
void ILibDuktape_Debugger_DetachCB(void *udata)
void ILibDuktape_Debugger_DetachCB(duk_context *ctx, void *udata)
{
ILibDuktape_Debugger_Socket_finish(udata);
ILibDuktape_Debugger_AsyncWaitConn((ILibDuktape_Debugger*)udata);
UNREFERENCED_PARAMETER(ctx);
}
void ILibDuktape_Debugger_AsyncWaitConn_PreSelect(void* object, fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime)
{
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)((void**)((ILibChain_Link*)object)->ExtraMemoryPtr)[0];
if (dbg == NULL || !ILibMemory_CanaryOK(dbg))
{
((void**)((ILibChain_Link*)object)->ExtraMemoryPtr)[0] = NULL;
ILibChain_SafeRemove(((ILibChain_Link*)object)->ParentChain, object);
return;
}
if (dbg->waitConnection != 0 && dbg->listener != (SOCKET)~0)
{
FD_SET(dbg->listener, readset);
}
}
void ILibDuktape_Debugger_AsyncWaitConn_PostSelect(void* object, int slct, fd_set *readset, fd_set *writeset, fd_set *errorset)
{
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)((void**)((ILibChain_Link*)object)->ExtraMemoryPtr)[0];
if (dbg == NULL || !ILibMemory_CanaryOK(dbg)) { return; }
if (dbg->waitConnection != 0 && dbg->listener != (SOCKET)~0 && FD_ISSET(dbg->listener, readset))
{
dbg->waitConnection = 0;
dbg->client = accept(dbg->listener, NULL, NULL);
((void**)dbg->data)[0] = dbg;
if (dbg->client != ~0)
{
ILibDuktape_Debugger_StartMemoryReporting(dbg->ctx);
duk_debugger_attach(dbg->ctx, ILibDuktape_Debugger_ReadCB, ILibDuktape_Debugger_WriteCB, ILibDuktape_Debugger_PeekCB, NULL, NULL, NULL, ILibDuktape_Debugger_DetachCB, (void*)dbg);
}
}
}
void ILibDuktape_Debugger_AsyncWaitConn(ILibDuktape_Debugger *dbg)
{
if (dbg->chainedObject == NULL)
{
dbg->chainedObject = ILibChain_Link_Allocate(sizeof(ILibChain_Link), sizeof(void*));
((void**)dbg->chainedObject->ExtraMemoryPtr)[0] = dbg;
dbg->chainedObject->PreSelectHandler = ILibDuktape_Debugger_AsyncWaitConn_PreSelect;
dbg->chainedObject->PostSelectHandler = ILibDuktape_Debugger_AsyncWaitConn_PostSelect;
ILibChain_SafeAdd(Duktape_GetChain(dbg->ctx), dbg->chainedObject);
}
else
{
ILibForceUnBlockChain(Duktape_GetChain(dbg->ctx));
}
dbg->waitConnection = 1;
}
void ILibDuktape_Debugger_DestroyEx(void *chain, void *user)
{
duk_destroy_heap(DebugWebEngine_Context);
}
void DebugWebEngine_RunEx(void *chain, void *user)
{
ILibChain_OnDestroyEvent_AddHandler(chain, ILibDuktape_Debugger_DestroyEx, NULL);
if (duk_peval_string(DebugWebEngine_Context, "process.on('uncaughtException', function(e){console.log('Uncaught:', e);}); var duktape_debugger = require('duktape-debugger'); var dbg = new duktape_debugger(); dbg.run();") == 0)
{
printf("Debugger Initialized...\n");
}
else
{
printf("Unable to launch debugger client: %s\n", duk_safe_to_string(DebugWebEngine_Context, -1));
}
duk_pop(DebugWebEngine_Context);
}
void DebugWebEngine_Run(void *obj)
{
ILibChain_RunOnMicrostackThreadEx(DebugWebEngine_Chain, DebugWebEngine_RunEx, NULL);
ILibStartChain(DebugWebEngine_Chain);
}
void ILibDuktape_Debugger_Destroy(void *chain, void *user)
{
ILibStopChain(DebugWebEngine_Chain);
#ifdef WIN32
WaitForSingleObject(DebugWebEngine_Thread, INFINITE);
#endif
}
duk_ret_t ILibDuktape_Debugger_StartEngine_UpdatePort(duk_context *ctx)
{
duk_push_current_function(ctx);
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Debugger_DebugObject);
int port = duk_require_int(ctx, 0);
if (dbg != NULL && ILibMemory_CanaryOK(dbg))
{
dbg->webport = port;
sem_post(&(dbg->hostlock));
}
return(0);
}
void ILibDuktape_Debugger_hostCooperate_Sink(void *chain, void *user)
{
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)user;
if (ILibMemory_CanaryOK(dbg))
{
duk_debugger_cooperate(dbg->ctx);
}
}
duk_ret_t ILibDuktape_Debugger_hostCooperate(duk_context *ctx)
{
duk_push_current_function(ctx);
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Debugger_DebugObject);
void *chain = Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Debugger_HostChain);
if (chain != NULL && dbg != NULL && ILibMemory_CanaryOK(dbg))
{
ILibChain_RunOnMicrostackThreadEx(chain, ILibDuktape_Debugger_hostCooperate_Sink, dbg);
}
return(0);
}
void ILibDuktape_Debugger_detachCleanup_Sink(void *chain, void *user)
{
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)user;
if (ILibMemory_CanaryOK(dbg))
{
if (dbg->client != (SOCKET)~0 && dbg->waitConnection==0)
{
ILibDuktape_Debugger_Socket_finish((void*)dbg);
ILibDuktape_Debugger_AsyncWaitConn(dbg);
}
}
}
duk_ret_t ILibDuktape_Debugger_detachCleanup(duk_context *ctx)
{
duk_push_current_function(ctx);
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Debugger_DebugObject);
void *chain = Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Debugger_HostChain);
if (chain != NULL && dbg != NULL && ILibMemory_CanaryOK(dbg))
{
ILibChain_RunOnMicrostackThreadEx(chain, ILibDuktape_Debugger_detachCleanup_Sink, dbg);
}
return(0);
}
void ILibDuktape_Debugger_hostGC_sink(void *chain, void *user)
{
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)user;
if (ILibMemory_CanaryOK(dbg))
{
duk_peval_string(dbg->ctx, "_debugGC();"); duk_pop(dbg->ctx);
duk_push_string(dbg->ctx, "MemoryAllocations");
duk_push_int(dbg->ctx, (duk_int_t)ILibDuktape_ScriptContainer_TotalAllocations);
duk_debugger_notify(dbg->ctx, 2);
}
}
duk_ret_t ILibDuktape_Debugger_hostGC(duk_context *ctx)
{
duk_push_current_function(ctx);
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Debugger_DebugObject);
void *chain = Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Debugger_HostChain);
if (chain != NULL && dbg != NULL && ILibMemory_CanaryOK(dbg))
{
ILibChain_RunOnMicrostackThreadEx(chain, ILibDuktape_Debugger_hostGC_sink, dbg);
}
return(0);
}
void ILibDuktape_Debugger_Start(duk_context *ctx, unsigned short debugPort)
void* ILibDuktape_Debugger_StartEngine(duk_context *ctx, int transport, int webport)
{
ILibDuktape_Debugger *dbg;
struct sockaddr_in6 local_int;
struct sockaddr_in6 remote_int;
int remote_int_size = sizeof(struct sockaddr_in6);
char *promise = NULL, *duktapeDebugger = NULL;
duk_size_t promiseLen, duktapeDebuggerLen;
ILibDuktape_Debugger *retVal = NULL;
memset(&local_int, 0, sizeof(struct sockaddr_in6));
local_int.sin6_family = AF_INET;
((struct sockaddr_in*)&local_int)->sin_addr.s_addr = INADDR_ANY;
local_int.sin6_port = htons(debugPort);
if (ILibDuktape_ScriptContainer_DebuggingOK(ctx) != 0)
{
// Check to made sure we have the debugger dependencies
int argTop = duk_get_top(ctx);
if (duk_peval_string(ctx, "getJSModule('promise');") == 0 && duk_peval_string(ctx, "getJSModule('duktape-debugger');") == 0)
{
promise = (char*)duk_to_lstring(ctx, -2, &promiseLen);
duktapeDebugger = (char*)duk_to_lstring(ctx, -1, &duktapeDebuggerLen);
}
else
{
// Missing Dependencies, so cannot continue with setup
duk_peval_string(ctx, "process.emit('uncaughtException', 'Cannot setup debugger, missing promise and/or duktape-debugger');");
duk_set_top(ctx, argTop);
return(NULL);
}
duk_push_global_object(ctx); // [obj]
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_Debugger)); // [obj][buf]
dbg = (ILibDuktape_Debugger*)Duktape_GetBuffer(ctx, -1, NULL);
duk_put_prop_string(ctx, -2, "_DbgObj"); // [obj]
duk_pop(ctx); // ...
// Setup WebEngine
DebugWebEngine_Chain = ILibCreateChain();
DebugWebEngine_Context = ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx(SCRIPT_ENGINE_NO_DEBUGGER | SCRIPT_ENGINE_NO_MESH_AGENT_ACCESS | SCRIPT_ENGINE_NO_GENERIC_MARSHAL_ACCESS | SCRIPT_ENGINE_NO_PROCESS_SPAWNING, 0, DebugWebEngine_Chain, NULL, NULL, NULL, NULL, NULL, NULL);
ILibChain_OnDestroyEvent_AddHandler(Duktape_GetChain(ctx), ILibDuktape_Debugger_Destroy, NULL);
ILibDuktape_ModSearch_AddModule(DebugWebEngine_Context, "promise", promise, (int)promiseLen);
ILibDuktape_ModSearch_AddModule(DebugWebEngine_Context, "duktape-debugger", duktapeDebugger, (int)duktapeDebuggerLen);
duk_push_heap_stash(ctx);
char *src = Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_Debugger_SCRIPT_SOURCE, NULL);
char *srcPath = Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_Debugger_SCRIPT_PATH, NULL);
duk_pop(ctx);
if (src != NULL)
{
if (srcPath == NULL)
{
duk_push_global_object(ctx); // [g]
duk_get_prop_string(ctx, -1, "process"); // [g][process]
duk_get_prop_string(ctx, -1, "argv0"); // [g][process][argv0]
srcPath = (char*)duk_get_string(ctx, -1);
duk_pop_n(ctx, 3); // ...
}
duk_push_global_object(DebugWebEngine_Context); // [g]
duk_push_string(DebugWebEngine_Context, src); // [g][str]
duk_get_prop_string(DebugWebEngine_Context, -1, "split"); // [g][str][split]
duk_swap_top(DebugWebEngine_Context, -2); // [g][split][this]
duk_push_string(DebugWebEngine_Context, "\n"); // [g][split][this][\n]
duk_pcall_method(DebugWebEngine_Context, 1); // [g][tokens]
duk_put_prop_string(DebugWebEngine_Context, -2, "_scriptTokens"); // [g]
duk_push_string(DebugWebEngine_Context, srcPath); // [g][path]
duk_put_prop_string(DebugWebEngine_Context, -2, "_scriptPath"); // [g]
duk_pop(DebugWebEngine_Context); // ...
}
duk_push_heap_stash(ctx); // [stash]
retVal = (ILibDuktape_Debugger*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_Debugger)); // [stash][dbgobj]
duk_put_prop_string(ctx, -2, ILibDuktape_Debugger_DebugObject); // [stash]
duk_pop(ctx); // ...
duk_push_global_object(DebugWebEngine_Context); // [g]
duk_push_c_function(DebugWebEngine_Context, ILibDuktape_Debugger_StartEngine_UpdatePort, 1); // [g][func]
duk_push_pointer(DebugWebEngine_Context, retVal); // [g][func][ptr]
duk_put_prop_string(DebugWebEngine_Context, -2, ILibDuktape_Debugger_DebugObject); // [g][func]
duk_put_prop_string(DebugWebEngine_Context, -2, "updateWebPort"); // [g]
duk_push_c_function(DebugWebEngine_Context, ILibDuktape_Debugger_hostCooperate, 0); // [g][func]
duk_push_pointer(DebugWebEngine_Context, retVal); // [g][func][ptr]
duk_put_prop_string(DebugWebEngine_Context, -2, ILibDuktape_Debugger_DebugObject); // [g][func]
duk_push_pointer(DebugWebEngine_Context, Duktape_GetChain(ctx)); // [g][func][ptr]
duk_put_prop_string(DebugWebEngine_Context, -2, ILibDuktape_Debugger_HostChain); // [g][func]
duk_put_prop_string(DebugWebEngine_Context, -2, "hostCooperate"); // [g]
duk_push_c_function(DebugWebEngine_Context, ILibDuktape_Debugger_hostGC, 0); // [g][func]
duk_push_pointer(DebugWebEngine_Context, retVal); // [g][func][ptr]
duk_put_prop_string(DebugWebEngine_Context, -2, ILibDuktape_Debugger_DebugObject); // [g][func]
duk_push_pointer(DebugWebEngine_Context, Duktape_GetChain(ctx)); // [g][func][ptr]
duk_put_prop_string(DebugWebEngine_Context, -2, ILibDuktape_Debugger_HostChain); // [g][func]
duk_put_prop_string(DebugWebEngine_Context, -2, "hostGC"); // [g]
duk_push_c_function(DebugWebEngine_Context, ILibDuktape_Debugger_detachCleanup, 0); // [g][func]
duk_push_pointer(DebugWebEngine_Context, retVal); // [g][func][ptr]
duk_put_prop_string(DebugWebEngine_Context, -2, ILibDuktape_Debugger_DebugObject); // [g][func]
duk_push_pointer(DebugWebEngine_Context, Duktape_GetChain(ctx)); // [g][func][ptr]
duk_put_prop_string(DebugWebEngine_Context, -2, ILibDuktape_Debugger_HostChain); // [g][func]
duk_put_prop_string(DebugWebEngine_Context, -2, "detachCleanup"); // [g]
duk_push_int(DebugWebEngine_Context, transport);
duk_put_prop_string(DebugWebEngine_Context, -2, "transport");
duk_push_int(DebugWebEngine_Context, webport);
duk_put_prop_string(DebugWebEngine_Context, -2, "webport");
duk_pop(DebugWebEngine_Context); // ...
retVal->ctx = ctx;
sem_init(&(retVal->hostlock), 0, 0);
retVal->webport = webport;
DebugWebEngine_Thread = ILibSpawnNormalThread(DebugWebEngine_Run, NULL);
}
return(retVal);
}
duk_ret_t ILibDuktape_Debugger_JSAttach_promise_wait(duk_context *ctx)
{
char *eventName = (char*)duk_require_string(ctx, 0);
if (strcmp(eventName, "resolved") != 0) { return(0); }
duk_push_heap_stash(ctx);
duk_get_prop_string(ctx, -1, ILibDuktape_Debugger_DebugObject);
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)Duktape_GetBuffer(ctx, -1, NULL);
memset(dbg, 0, sizeof(ILibDuktape_Debugger));
dbg->ctx = ctx;
if((dbg->listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { dbg->listener = (SOCKET)~0; return; }
bind(dbg->listener, (struct sockaddr*)&local_int, sizeof(struct sockaddr_in6));
listen(dbg->listener, 1);
dbg->client = accept(dbg->listener, (struct sockaddr*)&remote_int, &remote_int_size);
ILibDuktape_Debugger_Socket_waitconn(dbg);
ILibDuktape_Debugger_StartMemoryReporting(dbg->ctx);
duk_debugger_attach(dbg->ctx, ILibDuktape_Debugger_ReadCB, ILibDuktape_Debugger_WriteCB, ILibDuktape_Debugger_PeekCB, NULL, NULL, NULL, ILibDuktape_Debugger_DetachCB, (void*)dbg);
duk_debugger_attach(ctx, ILibDuktape_Debugger_ReadCB, ILibDuktape_Debugger_WriteCB, NULL, NULL, NULL, ILibDuktape_Debugger_DetachCB, (void*)dbg);
return(0);
}
void ILibDuktape_Debugger_Stop(duk_context *ctx)
void ILibDuktape_Debugger_JSAttach_PopulateSource(duk_context *ctx, char *source)
{
if (source != NULL)
{
duk_push_heap_stash(ctx); // [stash]
duk_push_string(ctx, source); // [stash][src]
duk_put_prop_string(ctx, -2, ILibDuktape_Debugger_SCRIPT_SOURCE); // [stash]
duk_pop(ctx); // ...
}
else
{
char *script, *scriptPath;
int scriptLen;
duk_push_global_object(ctx); // [g]
duk_get_prop_string(ctx, -1, "process"); // [g][process]
duk_get_prop_string(ctx, -1, "argv0"); // [g][process][argv0]
scriptPath = (char*)duk_to_string(ctx, -1);
ILibDuktape_ScriptContainer_CheckEmbeddedEx(scriptPath, &script, &scriptLen);
duk_pop_3(ctx); // ...
if (script != NULL)
{
duk_push_heap_stash(ctx); // [stash]
duk_push_lstring(ctx, script, (duk_size_t)scriptLen); // [stash][src]
duk_put_prop_string(ctx, -2, ILibDuktape_Debugger_SCRIPT_SOURCE); // [stash]
duk_push_string(ctx, "[embedded].js");
duk_put_prop_string(ctx, -2, ILibDuktape_Debugger_SCRIPT_PATH); // [stash]
duk_pop(ctx); // ...
free(script);
}
else
{
duk_push_global_object(ctx); // [g]
duk_get_prop_string(ctx, -1, "process"); // [g][process]
duk_get_prop_string(ctx, -1, "argv0"); // [g][process][argv0]
if (duk_get_length(ctx, -1) == 0)
{
// JS was not specified on command line
if (duk_peval_string(ctx, "require('MeshAgent');") == 0)
{
int CoreModuleLen = 0;
ILibSimpleDataStore *db = (ILibSimpleDataStore*)Duktape_GetPointerProperty(ctx, -1, "\xFF_MasterDB");
if (db == NULL || (CoreModuleLen = ILibSimpleDataStore_Get(db, "CoreModule", NULL, 0)) <= 0)
{
ILibDuktape_Error(ctx, "Could Not retrive CoreModule from MeshAgent"); return;
}
// [g][process][argv0][MeshAgent]
char* CoreModule = ILibMemory_Allocate(CoreModuleLen, 0, NULL, NULL);
ILibSimpleDataStore_Get(db, "CoreModule", CoreModule, CoreModuleLen);
duk_push_lstring(ctx, CoreModule + 4, CoreModuleLen - 4); // [g][process][argv0][MeshAgent][CoreModule]
duk_push_heap_stash(ctx);
duk_swap_top(ctx, -2);
duk_put_prop_string(ctx, -2, ILibDuktape_Debugger_SCRIPT_SOURCE);
duk_push_string(ctx, "CoreModule.js");
duk_put_prop_string(ctx, -2, ILibDuktape_Debugger_SCRIPT_PATH);
free(CoreModule);
return;
}
else
{
ILibDuktape_Error(ctx, "Unable to retrive running java script"); return;
}
}
else
{
duk_eval_string(ctx, "require('fs');"); // [g][process][argv0][fs]
duk_get_prop_string(ctx, -1, "readFileSync"); // [g][process][argv0][fs][rfs]
duk_swap_top(ctx, -2); // [g][process][argv0][rfs][this]
duk_dup(ctx, -3); // [g][process][argv0][rfs][this][path]
duk_call_method(ctx, 1); // [g][process][argv0][sourceBuffer]
}
duk_get_prop_string(ctx, -1, "toString"); // [g][process][argv0][sourceBuffer][toString]
duk_swap_top(ctx, -2); // [g][process][argv0][toString][this]
duk_call_method(ctx, 0); // [g][process][argv0][sourceBuffer]
duk_push_heap_stash(ctx); // [g][process][argv0][source][stash]
duk_dup(ctx, -2); // [g][process][argv0][source][stash][source]
duk_put_prop_string(ctx, -2, ILibDuktape_Debugger_SCRIPT_SOURCE); // [g][process][argv0][source][stash]
}
}
}
duk_ret_t ILibDuktape_Debugger_JSAttach_promise(duk_context *ctx)
{
int needWait = 0;
#ifndef DUK_USE_DEBUGGER_SUPPORT
duk_dup(ctx, 1); // [rejector]
duk_push_this(ctx); // [rejector][this]
duk_push_string(ctx, "No debugger support"); // [rejector][this][err]
duk_call_method(ctx, 1); // [ret]
return(0);
#endif
#ifdef WIN32
SOCKET listenerSocket;
#else
int listenerSocket;
#endif
struct sockaddr_in6 *local_int;
struct sockaddr_in6 localBounded;
int localBoundedSize = sizeof(struct sockaddr_in6);
duk_push_heap_stash(ctx); // [stash]
if (duk_has_prop_string(ctx, -1, ILibDuktape_Debugger_AttachOptions))
{
duk_dup(ctx, 1); // [stash][rejector]
duk_push_this(ctx); // [stash][rejector][this]
duk_push_string(ctx, "attachDebugger() already called"); // [stash][rejector][this][err]
duk_call_method(ctx, 1); // [stash][ret]
return(0);
}
else
{
duk_push_current_function(ctx); // [stash][func]
duk_get_prop_string(ctx, -1, "options"); // [stash][func][options]
duk_remove(ctx, -2); // [stash][options]
duk_dup(ctx, -1); // [stash][options][options]
duk_put_prop_string(ctx, -3, ILibDuktape_Debugger_AttachOptions); // [stash][options]
duk_dup(ctx, 0); duk_put_prop_string(ctx, -2, ILibDuktape_Debugger_Options_Resolver);
duk_dup(ctx, 1); duk_put_prop_string(ctx, -2, ILibDuktape_Debugger_Options_Rejector);
}
int transport = Duktape_GetIntPropertyValue(ctx, -1, "transport", 0);
int webport = Duktape_GetIntPropertyValue(ctx, -1, "webport", 0);
char *source = Duktape_GetStringPropertyValue(ctx, -1, "source", NULL);
local_int = Duktape_IPAddress4_FromString("127.0.0.1", transport);
#ifdef WIN32
if ((listenerSocket = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_NO_HANDLE_INHERIT)) == -1) { listenerSocket = (SOCKET)~0; }
#else
if ((listenerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { listenerSocket = (SOCKET)~0; }
#endif
if (listenerSocket == (SOCKET)~0)
{
// Error creating socket
duk_dup(ctx, 1); // [rejector]
duk_push_this(ctx); // [rejector][this]
duk_push_string(ctx, "Error Creating Debug Transport Socket"); // [rejector][this][err]
duk_call_method(ctx, 1);
return(0);
}
bind(listenerSocket, (struct sockaddr*)local_int, sizeof(struct sockaddr_in6));
#if defined(WINSOCK2)
getsockname(listenerSocket, (struct sockaddr*)&localBounded, (int*)&localBoundedSize);
#else
getsockname(listenerSocket, (struct sockaddr*)&localBounded, (socklen_t*)&localBoundedSize);
#endif
transport = (int)ntohs(localBounded.sin6_port);
if (Duktape_GetIntPropertyValue(ctx, -1, "wait", 0) == 1)
{
needWait = 1;
// WaitForDebugger... We'll hookup an event hook, so we can be notified when somebody calls 'then'
duk_push_this(ctx); // [promise]
duk_get_prop_string(ctx, -1, "_internal"); // [promise][internal]
duk_get_prop_string(ctx, -1, "once"); // [promise][internal][once]
duk_swap_top(ctx, -2); // [promise][on][this]
duk_push_string(ctx, "_eventHook"); // [promise][on][this][eventHook]
duk_push_c_function(ctx, ILibDuktape_Debugger_JSAttach_promise_wait, 2);// [promise][on][this][eventHook][func]
duk_call_method(ctx, 2);
}
// Before we do anything, we need to setup the source
ILibDuktape_Debugger_JSAttach_PopulateSource(ctx, source);
ILibDuktape_Debugger *dbg;
if ((dbg = ILibDuktape_Debugger_StartEngine(ctx, transport, webport)) == NULL)
{
// error
duk_dup(ctx, 1); // [rejector]
duk_push_this(ctx); // [rejector][this]
duk_push_string(ctx, "Error Starting Debug Engine");// [rejector][this][err]
duk_call_method(ctx, 1);
}
else
{
// success
duk_suspend(ctx, &(dbg->hoststate));
dbg->listener = listenerSocket;
sem_wait(&(dbg->hostlock));
sem_destroy(&(dbg->hostlock));
duk_resume(ctx, &(dbg->hoststate));
if (needWait == 0)
{
listen(dbg->listener, 1);
ILibDuktape_Debugger_AsyncWaitConn(dbg);
}
// Resolve the promise with the bounded WebPort
duk_dup(ctx, 0); // [resolver]
duk_push_this(ctx); // [resolver][this]
duk_push_int(ctx, dbg->webport); // [resolver][this][webport]
duk_call_method(ctx, 1);
}
return(0);
}
duk_ret_t ILibDuktape_Debugger_JSAttach(duk_context *ctx)
{
int nargs = duk_get_top(ctx);
duk_eval_string(ctx, "require('promise');"); // [promisectr]
duk_push_c_function(ctx, ILibDuktape_Debugger_JSAttach_promise, 2); // [promisectr][func]
if (nargs > 0 && duk_is_object(ctx, 0))
{
duk_dup(ctx, 0); duk_put_prop_string(ctx, -2, "options");
}
else
{
duk_push_object(ctx); duk_put_prop_string(ctx, -2, "options");
}
duk_new(ctx, 1); // [promise]
return(1);
}
void ILibDuktape_Debugger_Init(duk_context *ctx, unsigned short debugPort)
{
duk_push_global_object(ctx);
ILibDuktape_CreateInstanceMethod(ctx, "attachDebugger", ILibDuktape_Debugger_JSAttach, DUK_VARARGS);
duk_pop(ctx);
}
void ILibDuktape_Debugger_SetScriptEx(void *chain, void *user)
{
if (ILibMemory_CanaryOK(user))
{
duk_push_global_object(DebugWebEngine_Context);
duk_push_lstring(DebugWebEngine_Context, ILibMemory_Extra(user), ILibMemory_ExtraSize(user));
duk_put_prop_string(DebugWebEngine_Context, -2, "_scriptPath");
duk_pop(DebugWebEngine_Context);
duk_push_lstring(DebugWebEngine_Context, (char*)user, (duk_size_t)ILibMemory_Size(user)); // [str]
duk_get_prop_string(DebugWebEngine_Context, -1, "split"); // [str][split]
duk_swap_top(DebugWebEngine_Context, -2); // [split][this]
duk_push_string(DebugWebEngine_Context, "\n"); // [split][this][\n]
if (duk_pcall_method(DebugWebEngine_Context, 1) == 0)
{ // [tokens]
duk_push_global_object(DebugWebEngine_Context); // [tokens][g]
duk_swap_top(DebugWebEngine_Context, -2); // [g][tokens]
duk_put_prop_string(DebugWebEngine_Context, -2, "_scriptTokens"); // [g]
}
duk_pop(DebugWebEngine_Context);
ILibMemory_Free(user);
}
}
void ILibDuktape_Debugger_SetScript(char *js, int jsLen, char *fileName, int fileNameLen)
{
if (DebugWebEngine_Chain != NULL)
{
if (fileNameLen <= 0 && fileName != NULL)
{
fileNameLen = (int)strnlen_s(fileName, _MAX_PATH);
}
char *jsRef = (char*)ILibMemory_SmartAllocateEx(jsLen, fileNameLen);
memcpy_s(jsRef, jsLen, js, jsLen);
if (fileNameLen > 0)
{
memcpy_s(ILibMemory_Extra(jsRef), ILibMemory_ExtraSize(jsRef), fileName, fileNameLen);
}
ILibChain_RunOnMicrostackThreadEx(DebugWebEngine_Chain, ILibDuktape_Debugger_SetScriptEx, jsRef);
}
}

View File

@@ -19,8 +19,7 @@ limitations under the License.
#include "duktape.h"
void ILibDuktape_Debugger_Start(duk_context *ctx, unsigned short debugPort);
void ILibDuktape_Debugger_Init(duk_context *ctx, unsigned short debugPort);
void ILibDuktape_Debugger_SetScript(char *js, int jsLen, char *fileName, int fileNameLen);
#endif

View File

@@ -610,4 +610,4 @@ public:
};
#endif
#endif

View File

@@ -70,11 +70,9 @@ ILibDuktape_DuplexStream * ILibDuktape_DuplexStream_InitEx(duk_context * ctx, IL
{
ILibDuktape_DuplexStream *retVal;
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_DuplexStream)); // [obj][buffer]
retVal = (ILibDuktape_DuplexStream*)Duktape_GetBuffer(ctx, -1, NULL); // [obj][buffer]
duk_put_prop_string(ctx, -2, ILibDuktape_DuplexStream_bufferPtr); // [obj]
retVal = (ILibDuktape_DuplexStream*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_DuplexStream)); // [obj][buffer]
duk_put_prop_string(ctx, -2, ILibDuktape_DuplexStream_bufferPtr); // [obj]
memset(retVal, 0, sizeof(ILibDuktape_DuplexStream));
retVal->user = user;
retVal->readableStream = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_DuplexStream_OnPause, ILibDuktape_DuplexStream_OnResume, UnshiftHandler != NULL ? ILibDuktape_DuplexStream_OnUnshift : NULL, retVal);
retVal->writableStream = ILibDuktape_WritableStream_Init(ctx, ILibDuktape_DuplexStream_OnWrite, ILibDuktape_DuplexStream_OnEnd, retVal);
@@ -166,4 +164,4 @@ ILibDuktape_WritableStream *ILibDuktape_DuplexStream_GetNativeWritable(duk_conte
}
duk_pop(ctx); // ...
return(retVal);
}
}

View File

@@ -66,11 +66,11 @@ typedef void(*ILibDuktape_DuplexStream_EndHandler)(ILibDuktape_DuplexStream *str
typedef void(*ILibDuktape_DuplexStream_PauseResumeHandler)(ILibDuktape_DuplexStream *sender, void *user);
typedef int(*ILibDuktape_DuplexStream_UnshiftHandler)(ILibDuktape_DuplexStream *sender, int unshiftBytes, void *user);
#define ILibDuktape_DuplexStream_Ready(duplexStream) ILibDuktape_WritableStream_Ready((duplexStream)->writableStream)
#define ILibDuktape_DuplexStream_WriteData(duplexStream, buffer, bufferLen) ILibDuktape_readableStream_WriteData((duplexStream)->readableStream, buffer, bufferLen)
#define ILibDuktape_DuplexStream_WriteDataEx(duplexStream, streamReserved, buffer, bufferLen) ILibDuktape_readableStream_WriteDataEx((duplexStream)->readableStream, streamReserved, buffer, bufferLen)
#define ILibDuktape_DuplexStream_WriteEnd(duplexStream) ILibDuktape_readableStream_WriteEnd((duplexStream)->readableStream)
#define ILibDuktape_DuplexStream_Closed(duplexStream) ILibDuktape_readableStream_Closed((duplexStream)->readableStream)
#define ILibDuktape_DuplexStream_Ready(duplexStream) if(ILibMemory_CanaryOK(duplexStream)){ILibDuktape_WritableStream_Ready((duplexStream)->writableStream);}
#define ILibDuktape_DuplexStream_WriteData(duplexStream, buffer, bufferLen) (ILibMemory_CanaryOK(duplexStream)?(ILibDuktape_readableStream_WriteData((duplexStream)!=NULL?((duplexStream)->readableStream):NULL, buffer, bufferLen)):1)
#define ILibDuktape_DuplexStream_WriteDataEx(duplexStream, streamReserved, buffer, bufferLen) (ILibMemory_CanaryOK(duplexStream)?(ILibDuktape_readableStream_WriteDataEx((duplexStream)!=NULL?((duplexStream)->readableStream):NULL, streamReserved, buffer, bufferLen)):1)
#define ILibDuktape_DuplexStream_WriteEnd(duplexStream) (ILibMemory_CanaryOK(duplexStream)?ILibDuktape_readableStream_WriteEnd((duplexStream)->readableStream):1)
#define ILibDuktape_DuplexStream_Closed(duplexStream) if(ILibMemory_CanaryOK(duplexStream)){ILibDuktape_readableStream_Closed((duplexStream)->readableStream);}
ILibDuktape_DuplexStream* ILibDuktape_DuplexStream_InitEx(duk_context *ctx, ILibDuktape_DuplexStream_WriteHandler WriteHandler, ILibDuktape_DuplexStream_EndHandler EndHandler, ILibDuktape_DuplexStream_PauseResumeHandler PauseHandler, ILibDuktape_DuplexStream_PauseResumeHandler ResumeHandler, ILibDuktape_DuplexStream_UnshiftHandler UnshiftHandler, void *user);
#define ILibDuktape_DuplexStream_Init(ctx, WriteHandler, EndHandler, PauseHandler, ResumeHandler, user) ILibDuktape_DuplexStream_InitEx(ctx, WriteHandler, EndHandler, PauseHandler, ResumeHandler, NULL, user)

View File

@@ -266,4 +266,4 @@ public:
*/
DuplexStream decryptedStream;
};
#endif
#endif

View File

@@ -20,13 +20,22 @@ limitations under the License.
#include "duktape.h"
#include "microstack/ILibParsers.h"
typedef enum ILibDuktape_EventEmitter_Types
{
ILibDuktape_EventEmitter_Type_EXPLICIT = 0,
ILibDuktape_EventEmitter_Type_IMPLICIT = 1
}ILibDuktape_EventEmitter_Types;
typedef void(*ILibDuktape_EventEmitter_Handler)(duk_context *ctx, void *object, char *eventName, void *duk_eventArgs);
typedef struct ILibDuktape_EventEmitter
{
duk_context *ctx;
void *object;
void *tmpObject;
void *lastReturnValue;
void *retValTable;
unsigned int *totalListeners;
ILibDuktape_EventEmitter_Types eventType;
ILibHashtable eventTable;
}ILibDuktape_EventEmitter;
typedef void(*ILibDuktape_EventEmitter_HookHandler)(ILibDuktape_EventEmitter *sender, char *eventName, void *hookedCallback);
@@ -50,11 +59,16 @@ int ILibDuktape_EventEmitter_HasListeners(ILibDuktape_EventEmitter *emitter, cha
#define ILibDuktape_EventEmitter_AddOnceEx2(ctx, idx, eventName, func, argCount) ILibDuktape_EventEmitter_AddOnceEx3(ctx, idx, eventName, func)
#define ILibDuktape_EventEmitter_SetupEmit(ctx, heapptr, eventName) duk_push_heapptr((ctx), heapptr);duk_get_prop_string((ctx), -1, "emit");duk_swap_top((ctx), -2);duk_push_string((ctx), eventName)
#define ILibDuktape_EventEmitter_SetupOn(ctx, heapptr, eventName) duk_push_heapptr((ctx), heapptr);duk_get_prop_string((ctx), -1, "on");duk_swap_top((ctx), -2);duk_push_string((ctx), eventName)
#define ILibDuktape_EventEmitter_SetupPrependOnce(ctx, heapptr, eventName) duk_push_heapptr((ctx), heapptr);duk_get_prop_string((ctx), -1, "prependOnceListener");duk_swap_top((ctx), -2);duk_push_string((ctx), eventName)
int ILibDuktape_EventEmitter_AddOn(ILibDuktape_EventEmitter *emitter, char *eventName, void *heapptr); // Add native event handler
int ILibDuktape_EventEmitter_AddOnEx(duk_context *ctx, duk_idx_t idx, char *eventName, duk_c_function func);
void ILibDuktape_EventEmitter_AddHook(ILibDuktape_EventEmitter *emitter, char *eventName, ILibDuktape_EventEmitter_HookHandler handler);
void ILibDuktape_EventEmitter_ClearHook(ILibDuktape_EventEmitter *emitter, char *eventName);
void ILibDuktape_EventEmitter_ForwardEvent(duk_context *ctx, duk_idx_t eventSourceIndex, char *sourceEventName, duk_idx_t eventTargetIndex, char *targetEventName);
void ILibDuktape_EventEmitter_DeleteForwardEvent(duk_context *ctx, duk_idx_t eventSourceIndex, char *sourceEventName);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -23,4 +23,4 @@ limitations under the License.
void ILibDuktape_GenericMarshal_init(duk_context *ctx);
#endif
#endif

View File

@@ -120,6 +120,7 @@ typedef struct ILibDuktape_HECI_Session
OVERLAPPED wv;
ILibProcessPipe_Manager mgr;
HANDLE descriptor;
DWORD bytesRead;
#else
int descriptor;
#endif
@@ -230,6 +231,13 @@ int ILibDuktape_HECI_linuxInit()
duk_ret_t ILibDuktape_HECI_SessionFinalizer(duk_context *ctx)
{
if (duk_has_prop_string(ctx, 0, ILibDuktape_HECI_SessionMemPtr))
{
duk_get_prop_string(ctx, 0, ILibDuktape_HECI_SessionMemPtr);
ILibDuktape_HECI_Session *s = (ILibDuktape_HECI_Session*)Duktape_GetBuffer(ctx, -1, NULL);
if (s != NULL && s->PendingWrites != NULL) { ILibQueue_Destroy(s->PendingWrites); } // ToDo: If there is anything pending, we need to clear that too
if (s != NULL) { s->stream = NULL; }
}
return(0);
}
@@ -297,7 +305,7 @@ ILibTransport_DoneState ILibDuktape_HECI_Session_WriteHandler_Process(ILibDuktap
ssize_t bytesWritten;
#endif
while (ILibQueue_GetCount(session->PendingWrites) > 0)
while (session->noPipelining || ILibQueue_GetCount(session->PendingWrites) > 0)
{
ILibDuktape_HECI_WriteState *state = (ILibDuktape_HECI_WriteState*)ILibQueue_PeekQueue(session->PendingWrites);
returnIgnored = state->returnIgnored;
@@ -469,15 +477,19 @@ ILibTransport_DoneState ILibDuktape_HECI_Session_WriteSink(ILibDuktape_DuplexStr
}
void ILibDuktape_HECI_Session_EndSink(ILibDuktape_DuplexStream *stream, void *user)
{
duk_context *ctx = stream->readableStream->ctx;
duk_push_this(ctx);
duk_get_prop_string(ctx, -1, "disconnect");
duk_swap_top(ctx, -2);
if (duk_pcall_method(ctx, 0) != 0) { ILibDuktape_Process_UncaughtException(ctx); }
duk_pop(ctx);
}
void ILibDuktape_HECI_Session_PauseSink(ILibDuktape_DuplexStream *sender, void *user)
{
#ifdef WIN32
ILibDuktape_HECI_Session *session = (ILibDuktape_HECI_Session*)user;
// To Pause, all we need to do is remove our handle
ILibProcessPipe_WaitHandle_Remove(session->mgr, session->v.hEvent);
// NO-OP Because we are already PAUSED, since we context switched
UNREFERENCED_PARAMETER(sender);
UNREFERENCED_PARAMETER(user);
#else
UNREFERENCED_PARAMETER(sender);
UNREFERENCED_PARAMETER(user);
@@ -485,6 +497,15 @@ void ILibDuktape_HECI_Session_PauseSink(ILibDuktape_DuplexStream *sender, void *
}
#ifdef WIN32
BOOL ILibDuktape_HECI_Session_ReceiveSink(HANDLE event, void* user);
void __stdcall ILibDuktape_HECI_Session_ResumeSink2(ULONG_PTR obj)
{
ILibDuktape_HECI_Session *session = (ILibDuktape_HECI_Session*)obj;
BOOL result = ReadFile(session->descriptor, session->buffer, (DWORD)session->bufferSize, &(session->bytesRead), &(session->v));
if (result == TRUE || GetLastError() == ERROR_IO_PENDING)
{
ILibProcessPipe_WaitHandle_Add(session->mgr, session->v.hEvent, session, ILibDuktape_HECI_Session_ReceiveSink);
}
}
#endif
void ILibDuktape_HECI_Session_ResumeSink_NoPipeline(void *chain, void *user)
{
@@ -508,37 +529,34 @@ void ILibDuktape_HECI_Session_ResumeSink(ILibDuktape_DuplexStream *sender, void
if (session->noPipelining != 0)
{
ILibChain_RunOnMicrostackThread(sender->readableStream->chain, ILibDuktape_HECI_Session_ResumeSink_NoPipeline, session);
// Note: DO NOT 'return' here, because we still need to QueueUserAPC, to resume the stream on Windows
}
#ifdef WIN32
DWORD bytesRead;
// To Resume, we need to ReadFile, then re-add our waithandle
BOOL result = ReadFile(session->descriptor, session->buffer, (DWORD)session->bufferSize, &bytesRead, &(session->v));
if (result == TRUE || GetLastError() == ERROR_IO_PENDING)
{
ILibProcessPipe_WaitHandle_Add(session->mgr, session->v.hEvent, session, ILibDuktape_HECI_Session_ReceiveSink);
}
// To Resume, we need to first context switch to the Windows Thread
QueueUserAPC((PAPCFUNC)ILibDuktape_HECI_Session_ResumeSink2, ILibProcessPipe_Manager_GetWorkerThread(session->mgr), (ULONG_PTR)session);
#endif
}
#ifdef WIN32
void ILibDuktape_HECI_Session_ReceiveSink2(void *chain, void *user)
{
ILibDuktape_HECI_Session *session = (ILibDuktape_HECI_Session*)user;
if (!ILibMemory_CanaryOK(session)) { return; }
ILibDuktape_DuplexStream_WriteData(session->stream, session->buffer, session->bytesRead);
if (session->stream != NULL && !session->stream->readableStream->paused)
{
ILibDuktape_HECI_Session_ResumeSink(session->stream, session->stream->user);
}
}
BOOL ILibDuktape_HECI_Session_ReceiveSink(HANDLE event, void* user)
{
ILibDuktape_HECI_Session *session = (ILibDuktape_HECI_Session*)user;
DWORD bytesRead;
do
if (ILibMemory_CanaryOK(session))
{
if (GetOverlappedResult(session->descriptor, &(session->v), &bytesRead, FALSE) == FALSE) { break; }
ILibDuktape_DuplexStream_WriteData(session->stream, session->buffer, bytesRead);
} while (session->stream->readableStream->paused == 0 && ReadFile(session->descriptor, session->buffer, (DWORD)session->bufferSize, &bytesRead, &(session->v)) == TRUE);
if (session->stream->readableStream->paused == 0 && GetLastError() != ERROR_IO_PENDING)
{
// Broken Connection
ILibProcessPipe_WaitHandle_Remove(session->mgr, session->v.hEvent); // Remove ourselves from processing loop
ILibDuktape_DuplexStream_WriteEnd(session->stream);
if (GetOverlappedResult(session->descriptor, &(session->v), &(session->bytesRead), FALSE) == TRUE) { ILibChain_RunOnMicrostackThreadEx(session->chain, ILibDuktape_HECI_Session_ReceiveSink2, session); }
}
return(TRUE);
return(FALSE);
}
void __stdcall ILibDuktape_HECI_Session_Start(ULONG_PTR obj)
{
@@ -560,6 +578,7 @@ duk_ret_t ILibDuktape_HECI_create_OnClientConnect(duk_context *ctx)
duk_swap_top(ctx, -2); // [emit][this]
duk_push_string(ctx, "error"); // [emit][this][error]
duk_push_error_object(ctx, DUK_ERR_ERROR, "HECI Connection Error [%d]", statusCode); // [emit][this][error][err]
duk_push_int(ctx, statusCode); duk_put_prop_string(ctx, -2, "errno");
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "HECI.session.onError(): "); }
duk_pop(ctx); // ...
}
@@ -570,12 +589,10 @@ duk_ret_t ILibDuktape_HECI_create_OnClientConnect(duk_context *ctx)
if (bufferLen > 4)
{
duk_push_int(ctx, ((int*)buffer)[0]);
duk_put_prop_string(ctx, -2, ILibDuktape_HECI_MaxBufferSize); // [session]
duk_put_prop_string(ctx, -2, ILibDuktape_HECI_MaxBufferSize); // [session]
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_HECI_Session) + ((int*)buffer)[0]); // [session][buffer]
session = (ILibDuktape_HECI_Session*)Duktape_GetBuffer(ctx, -1, NULL);
memset(session, 0, sizeof(ILibDuktape_HECI_Session) + ((int*)buffer)[0]);
duk_put_prop_string(ctx, -2, ILibDuktape_HECI_SessionMemPtr); // [session]
session = (ILibDuktape_HECI_Session*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_HECI_Session) + ((int*)buffer)[0]); // [session][buffer]
duk_put_prop_string(ctx, -2, ILibDuktape_HECI_SessionMemPtr); // [session]
#ifdef WIN32
session->v.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
session->wv.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
@@ -590,7 +607,6 @@ duk_ret_t ILibDuktape_HECI_create_OnClientConnect(duk_context *ctx)
duk_push_current_function(ctx);
session->noPipelining = Duktape_GetIntPropertyValue(ctx, -1, ILibDuktape_HECI_Session_NoPipeline, 0);
duk_pop(ctx);
#ifdef _POSIX
//printf("Session: %p\n", session);
duk_get_prop_string(ctx, -1, ILibDuktape_HECI_Child); // [session][heci]
@@ -675,6 +691,51 @@ duk_ret_t ILibDuktape_HECI_Session_connect(duk_context *ctx)
duk_pop(ctx); // ...
return(0);
}
#ifdef WIN32
void __stdcall ILibDuktape_HECI_Session_CloseSink2(ULONG_PTR obj)
{
HANDLE h = (HANDLE)obj;
CloseHandle(h);
}
#endif
duk_ret_t ILibDuktape_HECI_Session_close(duk_context *ctx)
{
duk_push_this(ctx); // [session]
if (duk_has_prop_string(ctx, -1, ILibDuktape_HECI_Child))
{
duk_get_prop_string(ctx, -1, ILibDuktape_HECI_Child); // [session][heci]
duk_get_prop_string(ctx, -1, "disconnect"); // [session][heci][close]
duk_swap_top(ctx, -2); // [session][close][this]
duk_call_method(ctx, 0);
}
duk_push_this(ctx);
#ifdef WIN32
ILibDuktape_HECI_Session *session = NULL;
if (duk_has_prop_string(ctx, -1, ILibDuktape_HECI_SessionMemPtr))
{
duk_get_prop_string(ctx, -1, ILibDuktape_HECI_SessionMemPtr); // [HECI][SESSION]
session = (ILibDuktape_HECI_Session*)Duktape_GetBuffer(ctx, -1, NULL);
ILibProcessPipe_WaitHandle_Remove(session->mgr, session->v.hEvent);
ILibProcessPipe_WaitHandle_Remove(session->mgr, session->wv.hEvent);
session->stream = NULL;
QueueUserAPC((PAPCFUNC)ILibDuktape_HECI_Session_CloseSink2, ILibProcessPipe_Manager_GetWorkerThread(session->mgr), (ULONG_PTR)session->descriptor);
}
#else
int d = Duktape_GetIntPropertyValue(ctx, -1, ILibDuktape_HECI_Descriptor, -1);
HECI_chainLink *hcl = (HECI_chainLink*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_HECI_ChainLink);
if (hcl != NULL)
{
hcl->descriptor = -1;
if (d != -1) { close(d); };
duk_del_prop_string(ctx, -1, ILibDuktape_HECI_Descriptor);
}
#endif
return(0);
}
duk_ret_t ILibDuktape_HECI_create(duk_context *ctx)
{
duk_push_object(ctx); // [Session]
@@ -689,6 +750,7 @@ duk_ret_t ILibDuktape_HECI_create(duk_context *ctx)
ILibDuktape_EventEmitter_CreateEventEx(emitter, "error");
ILibDuktape_CreateProperty_InstanceMethod(ctx, "connect", ILibDuktape_HECI_Session_connect, DUK_VARARGS);
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_HECI_SessionFinalizer);
ILibDuktape_CreateInstanceMethod(ctx, "disconnect", ILibDuktape_HECI_Session_close, 0);
return(1);
}
@@ -743,6 +805,8 @@ void ILibDuktape_HECI_NextIoctl(ILibQueue q)
{
ILibDuktape_HECI_ioctl_data *data = (ILibDuktape_HECI_ioctl_data*)ILibQueue_PeekQueue(q);
int res;
if (data == NULL) { return; } // This line is unnecessary, because this method is only called on a non-empty Queue, but to satisfy Klockwork...
data->bytesReceived = 0;
ResetEvent(data->v.hEvent);
@@ -817,9 +881,7 @@ duk_ret_t ILibDuktape_HECI_doIoctl(duk_context *ctx)
ILibDuktape_Push_ObjectStash(ctx); // [heci][stash]
duk_push_array(ctx); // [heci][stash][array]
ILibDuktape_HECI_ioctl_data *data;
duk_push_fixed_buffer(ctx, bufferLen + sizeof(ILibDuktape_HECI_ioctl_data)); // [heci][stash][array][state]
data = (ILibDuktape_HECI_ioctl_data*)Duktape_GetBuffer(ctx, -1, NULL);
memset(data, 0, sizeof(ILibDuktape_HECI_ioctl_data));
data = (ILibDuktape_HECI_ioctl_data*)Duktape_PushBuffer(ctx, bufferLen + sizeof(ILibDuktape_HECI_ioctl_data));
duk_put_prop_index(ctx, -2, 0); // [heci][stash][array]
if (outBufferLen > 0)
{ // [heci][stash][array][buffer]
@@ -954,6 +1016,7 @@ void ILibDuktape_HECI_PostSelect(void* object, int slct, fd_set *readset, fd_set
ILibDuktape_DuplexStream_WriteEnd(h->session->stream);
}
}
if (h->descriptor <= 0) { return; }
if (FD_ISSET(h->descriptor, writeset))
{
ILibDuktape_HECI_Session_WriteHandler_Process(h->session);
@@ -971,6 +1034,7 @@ void ILibDuktape_HECI_Destroy(void *object)
close(h->descriptor);
}
#endif
void ILibDuktape_HECI_Push(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [HECI]
@@ -1011,6 +1075,7 @@ void ILibDuktape_HECI_Push(duk_context *ctx, void *chain)
#endif
if (chain != NULL) { ILibDuktape_CreateInstanceMethod(ctx, "create", ILibDuktape_HECI_create, 0); }
ILibDuktape_CreateInstanceMethod(ctx, "doIoctl", ILibDuktape_HECI_doIoctl, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "disconnect", ILibDuktape_HECI_Session_close, 0);
#ifdef _POSIX
duk_push_pointer(ctx, hlink->Q); // [HECI][Q]
#else
@@ -1038,4 +1103,4 @@ void ILibDuktape_HECI_Push(duk_context *ctx, void *chain)
void ILibDuktape_HECI_Init(duk_context *ctx)
{
ILibDuktape_ModSearch_AddHandler(ctx, "heci", ILibDuktape_HECI_Push);
}
}

View File

@@ -22,4 +22,4 @@ limitations under the License.
void ILibDuktape_HECI_Init(duk_context *ctx);
#endif
#endif

View File

@@ -112,7 +112,7 @@ void *Duktape_GetPointerProperty(duk_context *ctx, duk_idx_t i, char* propertyNa
char* Duktape_GetStringPropertyValueEx(duk_context *ctx, duk_idx_t i, char* propertyName, char* defaultValue, duk_size_t *len)
{
char *retVal = defaultValue;
if (duk_has_prop_string(ctx, i, propertyName))
if (ctx != NULL && duk_has_prop_string(ctx, i, propertyName))
{
duk_get_prop_string(ctx, i, propertyName);
retVal = (char*)duk_get_lstring(ctx, -1, len);
@@ -127,7 +127,7 @@ char* Duktape_GetStringPropertyValueEx(duk_context *ctx, duk_idx_t i, char* prop
int Duktape_GetIntPropertyValue(duk_context *ctx, duk_idx_t i, char* propertyName, int defaultValue)
{
int retVal = defaultValue;
if (duk_has_prop_string(ctx, i, propertyName))
if (ctx!=NULL && duk_has_prop_string(ctx, i, propertyName))
{
duk_get_prop_string(ctx, i, propertyName);
retVal = duk_to_int(ctx, -1);
@@ -159,6 +159,7 @@ char *Duktape_GetStashKey(void* value)
char* Duktape_GetBuffer(duk_context *ctx, duk_idx_t i, duk_size_t *bufLen)
{
char *retVal = NULL;
duk_size_t len = 0;
if (bufLen != NULL) { *bufLen = 0; }
if (duk_is_string(ctx, i))
@@ -167,11 +168,29 @@ char* Duktape_GetBuffer(duk_context *ctx, duk_idx_t i, duk_size_t *bufLen)
}
else if (duk_is_buffer(ctx, i))
{
retVal = (char*)duk_require_buffer(ctx, i,bufLen);
retVal = (char*)duk_require_buffer(ctx, i, &len);
if (ILibMemory_CanaryOK(ILibMemory_FromRaw(retVal)) && ILibMemory_RawSize(ILibMemory_FromRaw(retVal)) == len)
{
retVal = ILibMemory_FromRaw(retVal);
if (bufLen != NULL) { *bufLen = ILibMemory_Size(retVal); }
}
else if (bufLen != NULL)
{
*bufLen = len;
}
}
else if(duk_is_buffer_data(ctx, i))
{
retVal = (char*)duk_require_buffer_data(ctx, i, bufLen);
retVal = (char*)duk_require_buffer_data(ctx, i, &len);
if (ILibMemory_CanaryOK(ILibMemory_FromRaw(retVal)) && ILibMemory_RawSize(ILibMemory_FromRaw(retVal)) == len)
{
retVal = ILibMemory_FromRaw(retVal);
if (bufLen != NULL) { *bufLen = ILibMemory_Size(retVal); }
}
else if (bufLen != NULL)
{
*bufLen = len;
}
}
else if (duk_is_object(ctx, i))
{
@@ -607,37 +626,7 @@ void *ILibDuktape_Memory_AllocEx(duk_context *ctx, duk_idx_t index, duk_size_t s
duk_pop_2(ctx); // ...
return(retVal);
}
void ILibDuktape_ValidatePointer(void *chain, void *ptr)
{
ILibHashtable_Put(ILibChain_GetBaseHashtable(chain), ptr, NULL, 0, (void*)0xFFFF);
}
void ILibDuktape_InValidatePointer(void *chain, void *ptr)
{
ILibHashtable_Remove(ILibChain_GetBaseHashtable(chain), ptr, NULL, 0);
}
int ILibDuktape_IsPointerValid(void *chain, void *ptr)
{
return(ILibHashtable_Get(ILibChain_GetBaseHashtable(chain), ptr, NULL, 0) == NULL ? 0 : 1);
}
duk_ret_t ILibDuktape_PointerValidation_Finalizer(duk_context *ctx)
{
duk_push_this(ctx);
void *chain = Duktape_GetChain(ctx);
void *obj = duk_get_heapptr(ctx, -1);
ILibDuktape_InValidatePointer(chain, obj);
duk_pop(ctx);
return(0);
}
void ILibDuktape_PointerValidation_Init(duk_context *ctx)
{
void *chain = Duktape_GetChain(ctx);
if (!ILibDuktape_IsPointerValid(chain, duk_get_heapptr(ctx, -1)))
{
// Not set up yet, so set it up
ILibDuktape_ValidatePointer(chain, duk_get_heapptr(ctx, -1));
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_PointerValidation_Finalizer);
}
}
duk_ret_t ILibDuktape_Immediate_Sink(duk_context *ctx)
{
ILibDuktape_ImmediateHandler userCallback = (ILibDuktape_ImmediateHandler)duk_get_pointer(ctx, 0);
@@ -689,6 +678,61 @@ void* ILibDuktape_Immediate(duk_context *ctx, void ** args, int argsLen, ILibDuk
if (duk_pcall_method(ctx, 3) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "ILibDuktape_Immediate => immediate(): "); duk_pop(ctx); return(NULL); }
retval = duk_get_heapptr(ctx, -1); // [immediate]
duk_push_heap_stash(ctx); // [immediate][stash]
duk_swap_top(ctx, -2); // [stash][immediate]
duk_put_prop_string(ctx, -2, Duktape_GetStashKey(retval)); // [stash]
duk_pop(ctx); // ...
return(retval);
}
duk_ret_t ILibDuktape_Interval_Sink(duk_context *ctx)
{
ILibDuktape_ImmediateHandler userCallback = (ILibDuktape_ImmediateHandler)duk_get_pointer(ctx, 0);
void **args = NULL;
int argsLen, i;
duk_push_this(ctx); // [immediate]
duk_dup(ctx, 1); // [immediate][array]
if ((argsLen = (int)duk_get_length(ctx, -1)) > 0)
{
args = ILibMemory_AllocateA(sizeof(void*)*argsLen);
for (i = 0; i < argsLen; ++i)
{
duk_get_prop_index(ctx, -1, i); // [immediate][array][arg]
args[i] = duk_get_pointer(ctx, -1);
duk_pop(ctx); // [immediate][array]
}
}
if (userCallback != NULL) { userCallback(ctx, args, argsLen); }
return(0);
}
void* ILibDuktape_Interval(duk_context *ctx, void **args, int argsLen, int delay, ILibDuktape_IntervalHandler callback)
{
void *retval = NULL;
int i = 0;
duk_push_global_object(ctx); // [g]
duk_get_prop_string(ctx, -1, "setInterval"); // [g][setInterval]
duk_swap_top(ctx, -2); // [setInterval][this]
duk_push_c_function(ctx, ILibDuktape_Interval_Sink, DUK_VARARGS); // [setInterval][this][func]
duk_push_int(ctx, delay); // [setInterval][this][func][delay]
duk_push_pointer(ctx, callback); // [setInterval][this][func][delay][userFunc]
duk_push_array(ctx); // [setInterval][this][func][delay][userFunc][array]
while (args[i] != NULL && i < argsLen)
{
duk_get_prop_string(ctx, -1, "push"); // [setInterval][this][func][delay][userFunc][array][push]
duk_dup(ctx, -2); // [setInterval][this][func][delay][userFunc][array][push][this]
duk_push_pointer(ctx, args[i]); // [setInterval][this][func][delay][userFunc][array][push][this][val]
if (duk_pcall_method(ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "ILibDuktape_Immediate => Array.push(): "); }
duk_pop(ctx); // [setInterval][this][func][delay][userFunc][array]
++i;
}
if (duk_pcall_method(ctx, 4) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "ILibDuktape_Interval => interval(): "); duk_pop(ctx); return(NULL); }
retval = duk_get_heapptr(ctx, -1); // [immediate]
duk_push_heap_stash(ctx); // [immediate][stash]
duk_swap_top(ctx, -2); // [stash][immediate]
@@ -725,6 +769,142 @@ duk_idx_t duk_push_int_ex(duk_context *ctx, duk_int_t val)
return(duk_push_int(ctx, val), duk_get_top_index(ctx));
}
void Duktape_Console_Log_ChainEx(duk_context *ctx, ILibDuktape_LogTypes logType, char *msg, duk_size_t msgLen)
{
duk_push_global_object(ctx); // [g]
duk_get_prop_string(ctx, -1, "console"); // [g][console]
switch (logType)
{
case ILibDuktape_LogType_Error:
duk_get_prop_string(ctx, -1, "error"); // [g][console][error]
break;
case ILibDuktape_LogType_Warn:
duk_get_prop_string(ctx, -1, "warn"); // [g][console][warn]
break;
default:
duk_get_prop_string(ctx, -1, "log"); // [g][console][log]
break;
}
duk_swap_top(ctx, -2); // [g][log][this]
duk_push_lstring(ctx, msg, msgLen); // [g][log][this][str]
duk_pcall_method(ctx, 1); duk_pop(ctx); // [g]
duk_pop(ctx); // ...
}
typedef struct Duktape_Console_Log_data
{
duk_context *ctx;
ILibDuktape_LogTypes logType;
}Duktape_Console_Log_data;
void Duktape_Console_Log_Chain(void *chain, void *user)
{
Duktape_Console_Log_data *data = (Duktape_Console_Log_data*)user;
char *msg = (char*)ILibMemory_Extra(data);
Duktape_Console_Log_ChainEx(data->ctx, data->logType, msg, ILibMemory_Size(msg));
ILibMemory_Free(user);
}
void Duktape_Console_Log(duk_context *ctx, void *chain, ILibDuktape_LogTypes logType, char *msg, duk_size_t msgLen)
{
if (ILibIsRunningOnChainThread(chain))
{
Duktape_Console_Log_ChainEx(ctx, logType, msg, msgLen);
}
else
{
Duktape_Console_Log_data *data = (Duktape_Console_Log_data*)ILibMemory_SmartAllocateEx(sizeof(Duktape_Console_Log_data), msgLen);
data->ctx = ctx;
data->logType = logType;
memcpy_s(ILibMemory_Extra(data), ILibMemory_ExtraSize(data), msg, msgLen);
ILibChain_RunOnMicrostackThreadEx(chain, Duktape_Console_Log_Chain, data);
}
}
char* ILibDuktape_String_AsWide(duk_context *ctx, duk_idx_t idx, duk_size_t *len)
{
char *src;
src = (char*)duk_require_string(ctx, idx);
#ifdef WIN32
size_t inBufferLen = 2 + (2 * MultiByteToWideChar(CP_UTF8, 0, (LPCCH)src, -1, NULL, 0));
LPWSTR inBuffer = (LPWSTR)ILibMemory_AllocateTemp(Duktape_GetChain(ctx), inBufferLen);
int r = MultiByteToWideChar(CP_UTF8, 0, (LPCCH)src, -1, inBuffer, (int)inBufferLen);
if (len != NULL)
{
*len = (duk_size_t)r;
}
return(r == 0 ? NULL : (char*)inBuffer);
#else
return(src);
#endif
}
void ILibDuktape_String_PushWideString(duk_context *ctx, char *wstr, size_t wstrlen)
{
#ifdef WIN32
char *tmp;
size_t tmpLen;
tmpLen = 2 + (size_t)WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)wstr, (int)(wstrlen > 0 ? wstrlen : -1), NULL, 0, NULL, NULL);
tmp = (char*)ILibMemory_AllocateTemp(Duktape_GetChain(ctx), tmpLen);
if (WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)wstr, (int)(wstrlen > 0 ? wstrlen : -1), (LPSTR)tmp, (int)tmpLen, NULL, NULL) != 0)
{
duk_push_string(ctx, tmp);
}
else
{
ILibDuktape_Error(ctx, "String_PushWideString() Error: %u", GetLastError());
}
#else
if (wstrlen == 0)
{
duk_push_string(ctx, wstr);
}
else
{
duk_push_lstring(ctx, wstr, wstrlen);
}
#endif
}
char *ILibDuktape_String_WideToUTF8(duk_context *ctx, char *wstr)
{
#ifdef WIN32
char *tmp;
size_t tmpLen;
tmpLen = 2 + (size_t)WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)wstr, -1, NULL, 0, NULL, NULL);
tmp = (char*)ILibMemory_AllocateTemp(Duktape_GetChain(ctx), tmpLen);
WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)wstr, -1, tmp, (int)tmpLen, NULL, NULL);
return(tmp);
#else
// NOP for non-Windows, because should already be UTF8
return(wstr);
#endif
}
char *ILibDuktape_String_UTF8ToWide(duk_context *ctx, char *str)
{
#ifdef WIN32
size_t tmpLen = 2 + (2 * MultiByteToWideChar(CP_UTF8, 0, (LPCCH)str, -1, NULL, 0));
LPWSTR retVal = (LPWSTR)ILibMemory_AllocateTemp(Duktape_GetChain(ctx), tmpLen);
MultiByteToWideChar(CP_UTF8, 0, (LPCCH)str, -1, retVal, (int)tmpLen);
return((char*)retVal);
#else
// NOP on non-Windows, as strings should always be UTF-8 by default
return(str);
#endif
}
void ILibDuktape_Log_Object(duk_context *ctx, duk_idx_t i, char *meta)
{
void *h = duk_get_heapptr(ctx, i);
duk_enum(ctx, i, DUK_ENUM_INCLUDE_HIDDEN | DUK_ENUM_INCLUDE_SYMBOLS);
while (duk_next(ctx, -1, 1))
{
printf(" [%s: %p] => %s (%p)\n", (meta==NULL?"OBJ":meta), h, (char*)duk_get_string(ctx, -2), duk_get_heapptr(ctx, -1));
duk_pop_2(ctx);
}
duk_pop(ctx);
}

View File

@@ -37,6 +37,17 @@ typedef void(*ILibDuktape_HelperEvent)(duk_context *ctx, void *user);
#define ILibDuktape_CR2HTTP "\xFF_CR2HTTP"
#define ILibDuktape_CR2Options "\xFF_CR2Options"
typedef enum ILibDuktape_LogTypes
{
ILibDuktape_LogType_Normal = 0,
ILibDuktape_LogType_Warn,
ILibDuktape_LogType_Error,
ILibDuktape_LogType_Info1,
ILibDuktape_LogType_Info2,
ILibDuktape_LogType_Info3
}ILibDuktape_LogTypes;
void ILibDuktape_Log_Object(duk_context *ctx, duk_idx_t i, char *meta);
char* Duktape_GetContextGuidHex(duk_context *ctx);
void *Duktape_GetChain(duk_context *ctx);
char *Duktape_GetStashKey(void* value);
@@ -53,6 +64,14 @@ struct sockaddr_in6* Duktape_IPAddress6_FromString(char* address, unsigned short
void ILibDuktape_SockAddrToOptions(duk_context *ctx, struct sockaddr_in6 *addr);
void *ILibDuktape_GetProcessObject(duk_context *ctx);
char* ILibDuktape_String_AsWide(duk_context *ctx, duk_idx_t idx, duk_size_t *len);
void ILibDuktape_String_PushWideString(duk_context *ctx, char *wstr, size_t wstrlen);
char *ILibDuktape_String_WideToUTF8(duk_context *ctx, char *wstr);
char *ILibDuktape_String_UTF8ToWide(duk_context *ctx, char *str);
#define Duktape_PushBuffer(ctx, bufSize) ILibMemory_Init(duk_push_fixed_buffer(ctx, (duk_size_t)(bufSize) + sizeof(ILibMemory_Header)), (bufSize), 0, ILibMemory_Types_OTHER)
void Duktape_Console_Log(duk_context *ctx, void *chain, ILibDuktape_LogTypes logType, char *msg, duk_size_t msgLen);
typedef void(*ILibDuktape_NativeUncaughtExceptionHandler)(duk_context *ctx, char *msg, void *user);
void ILibDuktape_SetNativeUncaughtExceptionHandler(duk_context *ctx, ILibDuktape_NativeUncaughtExceptionHandler handler, void *user);
@@ -93,17 +112,13 @@ void ILibDuktape_Helper_AddHeapFinalizer(duk_context *ctx, ILibDuktape_HelperEve
void ILibDuktape_Push_ObjectStash(duk_context *ctx);
void ILibDuktape_PointerValidation_Init(duk_context *ctx);
void ILibDuktape_ValidatePointer(void *chain, void *ptr);
void ILibDuktape_InValidatePointer(void *chain, void *ptr);
int ILibDuktape_IsPointerValid(void *chain, void *ptr);
#define ILibDuktape_ValidateHeapPointer(ctx, objIdx) ILibDuktape_ValidatePointer(Duktape_GetChain(ctx), duk_get_heapptr(ctx, objIdx))
#define ILibDuktape_InValidateHeapPointer(ctx, objIdx) ILibDuktape_InValidatePointer(Duktape_GetChain(ctx), duk_get_heapptr(ctx, objIdx))
typedef void(*ILibDuktape_ImmediateHandler)(duk_context *ctx, void ** args, int argsLen);
typedef ILibDuktape_ImmediateHandler ILibDuktape_IntervalHandler;
void* ILibDuktape_Immediate(duk_context *ctx, void ** args, int argsLen, ILibDuktape_ImmediateHandler callback);
void* ILibDuktape_Interval(duk_context *ctx, void **args, int argsLen, int delay, ILibDuktape_IntervalHandler callback);
int ILibDuktape_GetReferenceCount(duk_context *ctx, duk_idx_t i);
#define ILibDuktape_WriteID(ctx, id) duk_push_string(ctx, id);duk_put_prop_string(ctx, -2, ILibDuktape_OBJID)
#endif
#endif

View File

@@ -57,6 +57,7 @@ extern void ILibWebClient_ResetWCDO(struct ILibWebClientDataObject *wcdo);
#define ILibDuktape_HTTP2PipedWritable "\xFF_HTTP2PipedWritable"
#define ILibDuktape_HTTPStream2Data "\xFF_HTTPStream2Data"
#define ILibDuktape_HTTPStream2HTTP "\xFF_HTTPStream2HTTP"
#define ILibDuktape_HTTPStream2IMSG "\xFF_HTTPStream2IMSG"
#define ILibDuktape_HTTPStream2Socket "\xFF_HTTPStream2Socket"
#define ILibDuktape_IMSG2HttpStream "\xFF_IMSG2HttpStream"
#define ILibDuktape_IMSG2Ptr "\xFF_IMSG2Ptr"
@@ -130,6 +131,7 @@ typedef struct ILibDuktape_HttpStream_ServerResponse_BufferedImplicit_State
void *ctx;
void *writeStream;
void *serverResponseObj;
void *serverResponseStream;
int endBytes;
int chunk;
size_t bufferLen;
@@ -514,6 +516,9 @@ duk_ret_t ILibDuktape_HttpStream_http_onUpgrade(duk_context *ctx)
duk_ret_t ILibDuktape_HttpStream_http_endResponseSink(duk_context *ctx)
{
duk_push_this(ctx); // [imsg]
//ILibDuktape_Log_Object(ctx, -1, "IMSG");
duk_del_prop_string(ctx, -1, ILibDuktape_IMSG2Ptr);
duk_get_prop_string(ctx, -1, ILibDuktape_IMSG2HttpStream); // [imsg][httpstream]
duk_get_prop_string(ctx, -1, ILibDuktape_HTTP2CR); // [imsg][httpstream][CR]
@@ -543,6 +548,24 @@ duk_ret_t ILibDuktape_HttpStream_http_endResponseSink(duk_context *ctx)
duk_get_prop_string(ctx, -1, "keepSocketAlive"); // [socket][imsg][httpstream][CR][Agent][keepSocketAlive]
duk_swap_top(ctx, -2); // [socket][imsg][httpstream][CR][keepSocketAlive][this]
duk_dup(ctx, -6); // [socket][imsg][httpstream][CR][keepSocketAlive][this][socket]
//printf("End Response -->\n");
//if (duk_has_prop_string(ctx, -1, ILibDuktape_Socket2HttpStream))
//{
// duk_get_prop_string(ctx, -1, ILibDuktape_Socket2HttpStream);
// printf(" [Socket: %p] => [HTTPStream: %p]\n", duk_get_heapptr(ctx, -2), duk_get_heapptr(ctx, -1));
// ILibDuktape_Log_Object(ctx, -1, "HTTPStream");
// duk_pop(ctx);
//}
//if (duk_has_prop_string(ctx, -1, ILibDuktape_SOCKET2OPTIONS))
//{
// duk_get_prop_string(ctx, -1, ILibDuktape_SOCKET2OPTIONS);
// ILibDuktape_Log_Object(ctx, -1, "OPTIONS");
// duk_pop(ctx);
//}
//ILibDuktape_Log_Object(ctx, -1, "SOCKET");
//printf("\n");
duk_call_method(ctx, 1); duk_pop(ctx); // [socket][imsg][httpstream][CR]
return(0);
}
@@ -671,6 +694,9 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
if (data->bodyStream != NULL) { ILibDuktape_readableStream_WriteEnd(data->bodyStream); data->bodyStream = NULL; }
duk_pop(ctx); // [socket][clientRequest][HTTPStream]
ILibDuktape_EventEmitter_DeleteForwardEvent(ctx, -1, "response");
ILibDuktape_EventEmitter_DeleteForwardEvent(ctx, -1, "continue");
// We need to change the events to propagate to the new clientRequest instead of the old one
duk_get_prop_string(ctx, -1, "removeAllListeners"); // [socket][clientRequest][HTTPStream][remove]
duk_dup(ctx, -2); // [socket][clientRequest][HTTPStream][remove][this]
@@ -684,6 +710,8 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
duk_dup(ctx, -2); // [socket][clientRequest][HTTPStream][remove][this]
duk_push_string(ctx, "upgrade"); // [socket][clientRequest][HTTPStream][remove][this][upgrade]
duk_call_method(ctx, 1); duk_pop(ctx); // [socket][clientRequest][HTTPStream]
duk_push_this(ctx); // [socket][clientRequest][HTTPStream][clientRequest]
duk_put_prop_string(ctx, -2, ILibDuktape_HTTP2CR); // [socket][clientRequest][HTTPStream]
@@ -996,7 +1024,20 @@ void ILibDuktape_HttpStream_http_request_transform(struct ILibDuktape_Transform
}
}
duk_ret_t ILibDuktape_ClientRequest_Finalizer(duk_context *ctx)
{
if (duk_has_prop_string(ctx, 0, ILibDuktape_CR_RequestBuffer))
{
duk_get_prop_string(ctx, 0, ILibDuktape_CR_RequestBuffer);
ILibDuktape_Http_ClientRequest_WriteData *data = (ILibDuktape_Http_ClientRequest_WriteData*)Duktape_GetBuffer(ctx, -1, NULL);
if (data->buffer != NULL)
{
free(data->buffer);
data->buffer = NULL;
}
}
return(0);
}
duk_ret_t ILibDuktape_HttpStream_http_request(duk_context *ctx)
{
char *proto;
@@ -1086,7 +1127,7 @@ duk_ret_t ILibDuktape_HttpStream_http_request(duk_context *ctx)
ILibDuktape_EventEmitter_CreateEventEx(emitter, "upgrade");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "error");
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "socket", ILibDuktape_HttpStream_http_OnSocketReady);
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "~", ILibDuktape_ClientRequest_Finalizer);
if (nargs > 1 && duk_is_function(ctx, 1))
@@ -1465,7 +1506,7 @@ duk_ret_t ILibDuktape_HttpStream_http_server_onConnection(duk_context *ctx)
duk_get_prop_string(ctx, -1, "pipe"); // [NS][socket][pipe]
duk_dup(ctx, -2); // [NS][socket][pipe][this]
duk_eval_string(ctx, "require('http').createStream();"); // [NS][socket][pipe][this][httpStream]
duk_eval_string(ctx, "require('http').createStream();"); // [NS][socket][pipe][this][httpStream]
duk_get_prop_string(ctx, -5, ILibDuktape_NS2HttpServer); // [NS][socket][pipe][this][httpStream][httpServer]
duk_dup(ctx, -1); // [NS][socket][pipe][this][httpStream][httpServer][dup]
duk_put_prop_string(ctx, -3, ILibduktape_HttpStream2HttpServer); // [NS][socket][pipe][this][httpStream][httpServer]
@@ -1813,7 +1854,7 @@ void ILibDuktape_HttpStream_ServerResponse_WriteImplicitHeaders(void *chain, voi
{
int retVal;
ILibDuktape_HttpStream_ServerResponse_BufferedImplicit_State *state = (ILibDuktape_HttpStream_ServerResponse_BufferedImplicit_State*)user;
if (chain != NULL && !ILibDuktape_IsPointerValid(chain, state->serverResponseObj)) { free(user); }
if (!ILibMemory_CanaryOK(state->serverResponseStream)) { free(user); return; }
// We are on Microstack Thread, so we can access the JS object, and write the implicit headers
duk_push_heapptr(state->ctx, state->serverResponseObj); // [SR]
@@ -1956,6 +1997,7 @@ ILibTransport_DoneState ILibDuktape_HttpStream_ServerResponse_WriteSink(struct I
memset(tmp, 0, sizeof(ILibDuktape_HttpStream_ServerResponse_BufferedImplicit_State));
tmp->ctx = stream->ctx;
tmp->serverResponseObj = stream->obj;
tmp->serverResponseStream = stream;
tmp->writeStream = state->writeStream;
tmp->endBytes = stream->endBytes;
tmp->chunk = state->chunkSupported;
@@ -1970,6 +2012,7 @@ ILibTransport_DoneState ILibDuktape_HttpStream_ServerResponse_WriteSink(struct I
memset(buffered, 0, sizeof(ILibDuktape_HttpStream_ServerResponse_BufferedImplicit_State));
buffered->ctx = stream->ctx;
buffered->serverResponseObj = stream->obj;
buffered->serverResponseStream = stream;
buffered->writeStream = state->writeStream;
buffered->bufferLen = bufferLen;
buffered->endBytes = stream->endBytes;
@@ -2059,6 +2102,7 @@ ILibTransport_DoneState ILibDuktape_HttpStream_ServerResponse_WriteSink(struct I
data->ctx = stream->ctx;
data->endBytes = stream->endBytes;
data->serverResponseObj = stream->obj;
data->serverResponseStream = stream;
data->writeStream = state->writeStream;
data->bufferLen = bufferLen;
memcpy_s(data->buffer, bufferLen, buffer, bufferLen);
@@ -2403,8 +2447,6 @@ void ILibDuktape_HttpStream_ServerResponse_PUSH(duk_context *ctx, void* writeStr
duk_remove(ctx, -2); // [resp][http/s.serverResponse]
duk_put_prop_string(ctx, -2, ILibDuktape_OBJID); // [resp]
ILibDuktape_PointerValidation_Init(ctx);
ILibDuktape_WriteID(ctx, "http.serverResponse");
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_HttpStream_ServerResponse_State)); // [resp][state]
state = (ILibDuktape_HttpStream_ServerResponse_State*)Duktape_GetBuffer(ctx, -1, NULL);
@@ -2666,10 +2708,11 @@ int ILibDuktape_HttpStream_IncomingMessage_UnshiftBytes(ILibDuktape_readableStre
}
void ILibDuktape_HttpStream_DispatchEnd(void *chain, void *user)
{
if (ILibDuktape_IsPointerValid(chain, ((void**)user)[1]) != 0)
if(ILibMemory_CanaryOK(((void**)user)[1]))
{
duk_context *ctx = (duk_context*)((void**)user)[0];
void *heapPtr = ((void**)user)[1];
void *heapPtr = ((ILibDuktape_DuplexStream*)((void**)user)[1])->ParentObject;
((ILibDuktape_HttpStream_Data*)((void**)user)[2])->bodyStream = NULL;
duk_push_heapptr(ctx, heapPtr); // [httpStream]
duk_get_prop_string(ctx, -1, "emit"); // [httpStream][emit]
@@ -2694,7 +2737,7 @@ duk_ret_t ILibDuktape_HttpStream_OnReceive_bodyStreamFinalized(duk_context *ctx)
ILibDuktape_HttpStream_Data *data = (ILibDuktape_HttpStream_Data*)Duktape_GetPointerProperty(ctx, 0, ILibDuktape_IMSG2Ptr);
if (data != NULL)
{
if (data->endPropagated == 0) { ILibDuktape_readableStream_WriteEnd(data->bodyStream); }
if ((data->endPropagated == 0) && (data->bodyStream != NULL)) { ILibDuktape_readableStream_WriteEnd(data->bodyStream); }
data->endPropagated = 1;
data->bodyStream = NULL;
}
@@ -2773,28 +2816,38 @@ void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject,
{
if (valLen == 12 && strncasecmp(val, "100-Continue", 12) == 0)
{
duk_push_string(ctx, "checkContinue"); // [emit][this][checkContinue]
ILibDuktape_HttpStream_IncomingMessage_PUSH(ctx, header, data->DS->ParentObject); // [emit][this][checkContinue][imsg]
data->bodyStream = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_HttpStream_IncomingMessage_PauseSink, ILibDuktape_HttpStream_IncomingMessage_ResumeSink, ILibDuktape_HttpStream_IncomingMessage_UnshiftBytes, data);
ILibDuktape_HttpStream_ServerResponse_PUSH(ctx, data->DS->writableStream->pipedReadable, header, data->DS->ParentObject); // [emit][this][checkContinue][imsg][rsp]
duk_dup(ctx, -1); // [emit][this][checkContinue][imsg][rsp][rsp]
duk_insert(ctx, -6); // [rsp][emit][this][checkContinue][imsg][rsp]
if (duk_pcall_method(ctx, 3) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.httpStream.onReceive->checkContinue(): "); } // [rsp][hadListener]
// Is there a listener for 'checkContinue'?
if (ILibDuktape_EventEmitter_HasListenersEx(ctx, -1, "checkContinue"))
{
duk_push_string(ctx, "checkContinue"); // [emit][this][checkContinue]
ILibDuktape_HttpStream_IncomingMessage_PUSH(ctx, header, data->DS->ParentObject); // [emit][this][checkContinue][imsg]
data->bodyStream = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_HttpStream_IncomingMessage_PauseSink, ILibDuktape_HttpStream_IncomingMessage_ResumeSink, ILibDuktape_HttpStream_IncomingMessage_UnshiftBytes, data);
duk_dup(ctx, -3); duk_dup(ctx, -2); // [emit][this][checkContinue][imsg][httpstream][imsg]
duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2IMSG); duk_pop(ctx); // [emit][this][checkContinue][imsg]
ILibDuktape_HttpStream_ServerResponse_PUSH(ctx, data->DS->writableStream->pipedReadable, header, data->DS->ParentObject); // [emit][this][checkContinue][imsg][rsp]
if (duk_pcall_method(ctx, 3) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.httpStream.onReceive->checkContinue(): "); } // [rsp][hadListener]
duk_pop(ctx); // ...
}
else
{
if (!duk_get_boolean(ctx, -1))
{
// No listener, so we must immediately send '100 Continue'
duk_get_prop_string(ctx, -2, "writeContinue"); // [rsp][hadListener][writeContinue]
duk_dup(ctx, -3); // [rsp][hadListener][writeContinue][this]
duk_call_method(ctx, 0); duk_pop(ctx); // [rsp][hadListener]
}
}
duk_pop_2(ctx); // ...
}
else
{
// Nobody listening for 'checkContinue', so we need to respond with 100 Continue
ILibDuktape_HttpStream_ServerResponse_PUSH(ctx, data->DS->writableStream->pipedReadable, header, data->DS->ParentObject); // [emit][this][rsp]
duk_get_prop_string(ctx, -1, "writeContinue"); // [emit][this][rsp][writeContinue]
duk_swap_top(ctx, -2); // [emit][this][writeContinue][this]
duk_call_method(ctx, 0); duk_pop(ctx); // [emit][this]
// Since nobody was listening for 'checkContinue', need to process this as a 'request'
duk_push_string(ctx, "request"); // [emit][this][request]
ILibDuktape_HttpStream_IncomingMessage_PUSH(ctx, header, data->DS->ParentObject); // [emit][this][request][imsg]
data->bodyStream = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_HttpStream_IncomingMessage_PauseSink, ILibDuktape_HttpStream_IncomingMessage_ResumeSink, ILibDuktape_HttpStream_IncomingMessage_UnshiftBytes, data);
duk_dup(ctx, -3); duk_dup(ctx, -2); // [emit][this][request][imsg][httpstream][imsg]
duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2IMSG); duk_pop(ctx); // [emit][this][request][imsg]
ILibDuktape_HttpStream_ServerResponse_PUSH(ctx, data->DS->writableStream->pipedReadable, header, data->DS->ParentObject); // [emit][this][request][imsg][rsp]
if (duk_pcall_method(ctx, 3) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.httpStream.onReceive->request(): "); }
duk_pop(ctx); // ...
}
}
}
else
@@ -2852,6 +2905,11 @@ void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject,
data->bodyStream = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_HttpStream_IncomingMessage_PauseSink, ILibDuktape_HttpStream_IncomingMessage_ResumeSink, ILibDuktape_HttpStream_IncomingMessage_UnshiftBytes, data);
duk_push_pointer(ctx, data);
duk_put_prop_string(ctx, -2, ILibDuktape_IMSG2Ptr);
duk_dup(ctx, -3); // [emit][this][response][imsg][httpstream]
duk_dup(ctx, -2); // [emit][this][response][imsg][httpstream][imsg]
duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2IMSG); // [emit][this][response][imsg][httpstream]
duk_pop(ctx); // [emit][this][response][imsg]
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "~", ILibDuktape_HttpStream_OnReceive_bodyStreamFinalized);
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.httpStream.onReceive->response(): "); }
duk_pop(ctx);
@@ -2874,6 +2932,8 @@ void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject,
if (ILibIsRunningOnChainThread(data->chain) != 0)
{
// We're on the Chain Thread, so we can directly emit the 'end' event
data->bodyStream = NULL;
duk_push_heapptr(ctx, data->DS->ParentObject); // [httpStream]
duk_get_prop_string(ctx, -1, "emit"); // [httpStream][emit]
duk_swap_top(ctx, -2); // [emit][this]
@@ -2884,19 +2944,19 @@ void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject,
else
{
// We're on the wrong thread to dispatch the 'end' event, so we have to context switch
void **tmp = (void**)ILibMemory_Allocate(2 * sizeof(void*), 0, NULL, NULL);
void **tmp = (void**)ILibMemory_Allocate(3 * sizeof(void*), 0, NULL, NULL);
tmp[0] = ctx;
tmp[1] = data->DS->ParentObject;
tmp[1] = data->DS;
tmp[2] = data;
ILibChain_RunOnMicrostackThread(data->chain, ILibDuktape_HttpStream_DispatchEnd, tmp);
}
}
}
duk_ret_t ILibDuktape_HttpStream_Finalizer(duk_context *ctx)
{
duk_del_prop_string(ctx, 0, ILibDuktape_HTTPStream2IMSG);
duk_get_prop_string(ctx, 0, ILibDuktape_HTTPStream2Data);
ILibDuktape_HttpStream_Data *data = (ILibDuktape_HttpStream_Data*)Duktape_GetBuffer(ctx, -1, NULL);
ILibDuktape_InValidatePointer(Duktape_GetChain(ctx), data);
ILibDuktape_InValidateHeapPointer(ctx, 0);
ILibWebClient_DestroyWebClientDataObject(data->WCDO);
return(0);
@@ -2934,9 +2994,7 @@ duk_ret_t ILibduktape_HttpStream_create(duk_context *ctx)
duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2HTTP); // [httpStream]
ILibDuktape_WriteID(ctx, "http.httpStream");
ILibDuktape_EventEmitter *emitter = ILibDuktape_EventEmitter_Create(ctx);
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_HttpStream_Data)); // [httpStream][buffer]
data = (ILibDuktape_HttpStream_Data*)Duktape_GetBuffer(ctx, -1, NULL);
memset(data, 0, sizeof(ILibDuktape_HttpStream_Data));
data = (ILibDuktape_HttpStream_Data*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_HttpStream_Data));
duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2Data); // [httpStream]
ILibDuktape_EventEmitter_CreateEventEx(emitter, "end");
@@ -2960,10 +3018,7 @@ duk_ret_t ILibduktape_HttpStream_create(duk_context *ctx)
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "pipe", ILibDuktape_HttpStream_pipeEvent);
ILibDuktape_CreateEventWithGetter(ctx, "connectionCloseSpecified", ILibDuktape_HttpStream_connectionCloseSpecified);
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_HttpStream_Finalizer);
ILibDuktape_ValidatePointer(Duktape_GetChain(ctx), data);
ILibDuktape_ValidateHeapPointer(ctx, -1);
return(1);
}
duk_ret_t ILibDuktape_HttpStream_Agent_getName(duk_context *ctx)
@@ -3113,10 +3168,14 @@ duk_ret_t ILibDuktape_HttpStream_Agent_keepSocketAlive(duk_context *ctx)
duk_get_prop_string(ctx, -1, "requests"); // [key][Agent][requests]
//ILibDuktape_Log_Object(ctx, -1, "Agent/Requests");
if (duk_has_prop_string(ctx, -1, key))
{
// Has Key, check the Array
duk_get_prop_string(ctx, -1, key); // [key][Agent][requests][Array]
//ILibDuktape_Log_Object(ctx, -1, "Agent/Request/ArrayIndex");
duk_get_prop_string(ctx, -1, "shift"); // [key][Agent][requests][Array][shift]
duk_swap_top(ctx, -2); // [key][Agent][requests][shift][this]
duk_call_method(ctx, 0); // [key][Agent][requests][request]
@@ -3485,8 +3544,11 @@ ILibTransport_DoneState ILibDuktape_httpStream_webSocket_EncodedWriteSink(ILibDu
char* maskingKey = NULL;
int FIN;
unsigned char OPCODE;
unsigned char RSV;
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)user;
if (!ILibMemory_CanaryOK(state)) { return(ILibTransport_DoneState_ERROR); }
if (bufferLen < 2)
{
// We need at least 2 bytes to read enough of the headers to know how long the frame is
@@ -3496,6 +3558,14 @@ ILibTransport_DoneState ILibDuktape_httpStream_webSocket_EncodedWriteSink(ILibDu
hdr = ntohs(((unsigned short*)(buffer))[0]);
FIN = (hdr & WEBSOCKET_FIN) != 0;
OPCODE = (hdr & WEBSOCKET_OPCODE) >> 8;
RSV = (hdr & WEBSOCKET_RSV) >> 8;
if (RSV != 0)
{
char msg[] = "Reserved Field of Websocket was not ZERO";
Duktape_Console_Log(state->ctx, state->chain, ILibDuktape_LogType_Error, msg, sizeof(msg) - 1);
return(ILibTransport_DoneState_ERROR);
}
plen = (unsigned char)(hdr & WEBSOCKET_PLEN);
if (plen == 126)
@@ -3636,7 +3706,8 @@ void ILibDuktape_httpStream_webSocket_EncodedEndSink(ILibDuktape_DuplexStream *s
}
void ILibDuktape_httpStream_webSocket_EncodedPauseSink_Chain(void *chain, void *user)
{
if (chain != NULL && !ILibDuktape_IsPointerValid(chain, user)) { return; }
if (!ILibMemory_CanaryOK(user)) { return; }
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)user;
duk_context *ctx = state->decodedStream->writableStream->ctx;
@@ -3648,7 +3719,7 @@ void ILibDuktape_httpStream_webSocket_EncodedPauseSink_Chain(void *chain, void *
}
void ILibDuktape_httpStream_webSocket_EncodedPauseSink(ILibDuktape_DuplexStream *sender, void *user)
{
printf("WebSocket.Encoded.Pause();\n");
//printf("WebSocket.Encoded.Pause();\n");
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)user;
if (state->decodedStream->writableStream->pipedReadable_native != NULL && state->decodedStream->writableStream->pipedReadable_native->PauseHandler != NULL)
{
@@ -3669,10 +3740,12 @@ void ILibDuktape_httpStream_webSocket_EncodedPauseSink(ILibDuktape_DuplexStream
}
void ILibDuktape_httpStream_webSocket_EncodedResumeSink_Chain(void *chain, void *user)
{
if (chain != NULL && !ILibDuktape_IsPointerValid(chain, user)) { return; }
if (!ILibMemory_CanaryOK(user)) { return; }
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)user;
duk_context *ctx = state->decodedStream->writableStream->ctx;
if (state->decodedStream->writableStream->pipedReadable == NULL) { return; }
duk_push_heapptr(ctx, state->decodedStream->writableStream->pipedReadable); // [readable]
duk_get_prop_string(ctx, -1, "resume"); // [readable][resume]
duk_swap_top(ctx, -2); // [resume][this]
@@ -3681,7 +3754,7 @@ void ILibDuktape_httpStream_webSocket_EncodedResumeSink_Chain(void *chain, void
}
void ILibDuktape_httpStream_webSocket_EncodedResumeSink(ILibDuktape_DuplexStream *sender, void *user)
{
printf("WebSocket.Encoded.Resume();\n");
//printf("WebSocket.Encoded.Resume();\n");
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)user;
if (state->decodedStream->writableStream->pipedReadable_native != NULL && state->decodedStream->writableStream->pipedReadable_native->ResumeHandler != NULL)
{
@@ -3718,7 +3791,8 @@ void ILibDuktape_httpStream_webSocket_DecodedEndSink(ILibDuktape_DuplexStream *s
}
void ILibDuktape_httpStream_webSocket_DecodedPauseSink_Chain(void *chain, void *user)
{
if (chain != NULL && !ILibDuktape_IsPointerValid(chain, user)) { return; }
if (!ILibMemory_CanaryOK(user)) { return; }
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)user;
duk_context *ctx = state->encodedStream->writableStream->ctx;
@@ -3758,7 +3832,7 @@ void ILibDuktape_httpStream_webSocket_DecodedPauseSink(ILibDuktape_DuplexStream
}
void ILibDuktape_httpStream_webSocket_DecodedResumeSink_Chain(void *chain, void *user)
{
if (chain != NULL && !ILibDuktape_IsPointerValid(chain, user)) { return; }
if (!ILibMemory_CanaryOK(user)) { return; }
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)user;
duk_context *ctx = state->encodedStream->writableStream->ctx;
@@ -3802,11 +3876,10 @@ int ILibDuktape_httpStream_webSocket_DecodedUnshiftSink(ILibDuktape_DuplexStream
duk_ret_t ILibDuktape_httpStream_webSocketStream_finalizer(duk_context *ctx)
{
void *chain = Duktape_GetChain(ctx);
duk_get_prop_string(ctx, 0, ILibDuktape_WebSocket_StatePtr);
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)Duktape_GetBuffer(ctx, -1, NULL);
if (state->encodedStream->writableStream->pipedReadable != NULL)
if (state->encodedStream != NULL && state->encodedStream->writableStream->pipedReadable != NULL)
{
duk_push_heapptr(ctx, state->encodedStream->writableStream->pipedReadable); // [readable]
duk_get_prop_string(ctx, -1, "unpipe"); // [readable][unpipe]
@@ -3815,7 +3888,6 @@ duk_ret_t ILibDuktape_httpStream_webSocketStream_finalizer(duk_context *ctx)
duk_call_method(ctx, 1); duk_pop(ctx); // ...
}
ILibDuktape_InValidatePointer(chain, Duktape_GetBuffer(ctx, -1, NULL));
return(0);
}
duk_ret_t ILibDuktape_httpStream_webSocketStream_sendPing(duk_context *ctx)
@@ -3856,17 +3928,24 @@ duk_ret_t ILibDuktape_httpStream_webSocketStream_encodedPiped(duk_context *ctx)
}
return(0);
}
duk_ret_t ILibDuktape_httpStream_webSocketStream_encoded_Finalizer(duk_context *ctx)
{
duk_get_prop_string(ctx, 0, ILibDuktape_WSENC2WS);
duk_get_prop_string(ctx, -1, ILibDuktape_WebSocket_StatePtr);
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)Duktape_GetBuffer(ctx, -1, NULL);
state->encodedStream = NULL;
return(0);
}
duk_ret_t ILibDuktape_httpStream_webSocketStream_new(duk_context *ctx)
{
ILibDuktape_WebSocket_State *state;
duk_push_object(ctx); // [WebSocket]
duk_push_object(ctx); // [WebSocket]
ILibDuktape_WriteID(ctx, "http.WebSocketStream");
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_WebSocket_State)); // [WebSocket][data]
state = (ILibDuktape_WebSocket_State*)Duktape_GetBuffer(ctx, -1, NULL);
memset(state, 0, sizeof(ILibDuktape_WebSocket_State));
duk_put_prop_string(ctx, -2, ILibDuktape_WebSocket_StatePtr); // [WebSocket]
ILibDuktape_ValidatePointer(Duktape_GetChain(ctx), state);
state = (ILibDuktape_WebSocket_State*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_WebSocket_State)); // [WebSocket][data]
duk_put_prop_string(ctx, -2, ILibDuktape_WebSocket_StatePtr); // [WebSocket]
state->ctx = ctx;
state->ObjectPtr = duk_get_heapptr(ctx, -1);
state->chain = Duktape_GetChain(ctx);
@@ -3877,6 +3956,7 @@ duk_ret_t ILibDuktape_httpStream_webSocketStream_new(duk_context *ctx)
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "pipe", ILibDuktape_httpStream_webSocketStream_encodedPiped);
duk_dup(ctx, -2); // [WebSocket][Encoded][WebSocket]
duk_put_prop_string(ctx, -2, ILibDuktape_WSENC2WS); // [WebSocket][Encoded]
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -1, "~", ILibDuktape_httpStream_webSocketStream_encoded_Finalizer);
ILibDuktape_CreateReadonlyProperty(ctx, "encoded"); // [WebSocket]
duk_push_object(ctx); // [WebSocket][Decoded]
@@ -3925,6 +4005,3 @@ void ILibDuktape_HttpStream_Init(duk_context *ctx)
ILibDuktape_ModSearch_AddHandler(ctx, "http", ILibDuktape_HttpStream_http_PUSH);
ILibDuktape_ModSearch_AddHandler(ctx, "https", ILibDuktape_HttpStream_https_PUSH);
}

View File

@@ -153,9 +153,8 @@ duk_ret_t ILibDuktape_MemoryStream_new(duk_context *ctx)
ILibDuktape_MemoryStream *ms;
duk_push_object(ctx); // [ms]
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_MemoryStream)); // [ms][internal]
ms = (ILibDuktape_MemoryStream*)Duktape_GetBuffer(ctx, -1, NULL);
memset(ms, 0, sizeof(ILibDuktape_MemoryStream));
ILibDuktape_WriteID(ctx, "memoryStream");
ms = (ILibDuktape_MemoryStream*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_MemoryStream));
duk_put_prop_string(ctx, -2, ILibDuktape_MemoryStream_Internal); // [ms]
ms->buffer = (char*)ILibMemory_Allocate(initial, 0, NULL, NULL);
ms->bufferSize = (size_t)initial;

View File

@@ -45,4 +45,4 @@ public:
void ILibDuktape_NetworkMonitor_Init(duk_context *ctx);
#endif
#endif

View File

@@ -19,14 +19,33 @@ limitations under the License.
#include "ILibDuktapeModSearch.h"
#include "ILibDuktape_DuplexStream.h"
#include "ILibDuktape_EventEmitter.h"
#include "ILibDuktape_Debugger.h"
#include "../microstack/ILibParsers.h"
#include "../microstack/ILibCrypto.h"
#include "../microstack/ILibRemoteLogging.h"
#define ILibDuktape_Timer_Ptrs "\xFF_DuktapeTimer_PTRS"
#define ILibDuktape_Queue_Ptr "\xFF_Queue"
#define ILibDuktape_Stream_Buffer "\xFF_BUFFER"
#define ILibDuktape_Stream_ReadablePtr "\xFF_ReadablePtr"
#define ILibDuktape_Timer_Ptrs "\xFF_DuktapeTimer_PTRS"
#define ILibDuktape_Queue_Ptr "\xFF_Queue"
#define ILibDuktape_Stream_Buffer "\xFF_BUFFER"
#define ILibDuktape_Stream_ReadablePtr "\xFF_ReadablePtr"
#define ILibDuktape_Stream_WritablePtr "\xFF_WritablePtr"
#define ILibDuktape_Console_Destination "\xFF_Console_Destination"
#define ILibDuktape_Console_LOG_Destination "\xFF_Console_Destination"
#define ILibDuktape_Console_WARN_Destination "\xFF_Console_WARN_Destination"
#define ILibDuktape_Console_ERROR_Destination "\xFF_Console_ERROR_Destination"
#define ILibDuktape_Console_INFO_Level "\xFF_Console_INFO_Level"
#define ILibDuktape_Console_SessionID "\xFF_Console_SessionID"
typedef enum ILibDuktape_Console_DestinationFlags
{
ILibDuktape_Console_DestinationFlags_DISABLED = 0,
ILibDuktape_Console_DestinationFlags_StdOut = 1,
ILibDuktape_Console_DestinationFlags_ServerConsole = 2,
ILibDuktape_Console_DestinationFlags_WebLog = 4,
ILibDuktape_Console_DestinationFlags_LogFile = 8
}ILibDuktape_Console_DestinationFlags;
int g_displayStreamPipeMessages = 0;
int g_displayFinalizerMessages = 0;
@@ -176,24 +195,21 @@ duk_ret_t ILibDuktape_Polyfills_Buffer_alloc(duk_context *ctx)
}
void ILibDuktape_Polyfills_Buffer(duk_context *ctx)
{
//// Polyfill 'Buffer.slice'
//duk_get_prop_string(ctx, -1, "Duktape"); // [g][Duktape]
//duk_get_prop_string(ctx, -1, "Buffer"); // [g][Duktape][Buffer]
//duk_get_prop_string(ctx, -1, "prototype"); // [g][Duktape][Buffer][prototype]
//duk_push_c_function(ctx, ILibDuktape_Pollyfills_Buffer_slice, DUK_VARARGS); // [g][Duktape][Buffer][prototype][func]
//duk_put_prop_string(ctx, -2, "slice"); // [g][Duktape][Buffer][prototype]
//duk_push_c_function(ctx, ILibDuktape_Polyfills_Buffer_readInt32BE, DUK_VARARGS);// [g][Duktape][Buffer][prototype][func]
//duk_put_prop_string(ctx, -2, "readInt32BE"); // [g][Duktape][Buffer][prototype]
//duk_pop_3(ctx); // [g]
char extras[] =
"Object.defineProperty(Buffer.prototype, \"swap32\",\
{\
value: function swap32()\
{\
var a = this.readUInt16BE(0);\
var b = this.readUInt16BE(2);\
this.writeUInt16LE(a, 2);\
this.writeUInt16LE(b, 0);\
return(this);\
}\
});";
duk_eval_string(ctx, extras); duk_pop(ctx);
//// Polyfill 'Buffer.toString()
//duk_get_prop_string(ctx, -1, "Duktape"); // [g][Duktape]
//duk_get_prop_string(ctx, -1, "Buffer"); // [g][Duktape][Buffer]
//duk_get_prop_string(ctx, -1, "prototype"); // [g][Duktape][Buffer][prototype]
//duk_push_c_function(ctx, ILibDuktape_Polyfills_Buffer_toString, DUK_VARARGS); // [g][Duktape][Buffer][prototype][func]
//duk_put_prop_string(ctx, -2, "toString"); // [g][Duktape][Buffer][prototype]
//duk_pop_3(ctx); // [g]
// Polyfill Buffer.from()
duk_get_prop_string(ctx, -1, "Buffer"); // [g][Buffer]
duk_push_c_function(ctx, ILibDuktape_Polyfills_Buffer_from, DUK_VARARGS); // [g][Buffer][func]
@@ -271,13 +287,55 @@ void ILibDuktape_Polyfills_String(duk_context *ctx)
duk_ret_t ILibDuktape_Polyfills_Console_log(duk_context *ctx)
{
int numargs = duk_get_top(ctx);
int i;
int i, x;
int len = 0;
duk_size_t strLen;
char *str;
char *PREFIX = NULL;
char *DESTINATION = NULL;
duk_push_current_function(ctx);
ILibDuktape_LogTypes logType = (ILibDuktape_LogTypes)Duktape_GetIntPropertyValue(ctx, -1, "logType", ILibDuktape_LogType_Normal);
switch (logType)
{
case ILibDuktape_LogType_Warn:
PREFIX = (char*)"WARNING: "; // LENGTH MUST BE <= 9
DESTINATION = ILibDuktape_Console_WARN_Destination;
break;
case ILibDuktape_LogType_Error:
PREFIX = (char*)"ERROR: "; // LENGTH MUST BE <= 9
DESTINATION = ILibDuktape_Console_ERROR_Destination;
break;
case ILibDuktape_LogType_Info1:
case ILibDuktape_LogType_Info2:
case ILibDuktape_LogType_Info3:
duk_push_this(ctx);
i = Duktape_GetIntPropertyValue(ctx, -1, ILibDuktape_Console_INFO_Level, 0);
duk_pop(ctx);
PREFIX = NULL;
if (i >= (((int)logType + 1) - (int)ILibDuktape_LogType_Info1))
{
DESTINATION = ILibDuktape_Console_LOG_Destination;
}
else
{
return(0);
}
break;
default:
PREFIX = NULL;
DESTINATION = ILibDuktape_Console_LOG_Destination;
break;
}
duk_pop(ctx);
// Calculate total length of string
for (i = 0; i < numargs; ++i)
{
if (duk_is_string(ctx, i))
{
printf("%s%s", (i == 0 ? "" : ", "), duk_require_string(ctx, i));
len += (i == 0 ? 0 : 2);
duk_get_lstring(ctx, i, &strLen);
len += (int)strLen;
}
else
{
@@ -286,24 +344,140 @@ duk_ret_t ILibDuktape_Polyfills_Console_log(duk_context *ctx)
{
duk_pop(ctx);
duk_dup(ctx, i);
printf("%s", (i == 0 ? "{" : ", {"));
len += (i == 0 ? 1 : 3);
duk_enum(ctx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY);
int propNum = 0;
while (duk_next(ctx, -1, 1))
{
printf("%s%s: %s", ((propNum++ == 0) ? " " : ", "), (char*)duk_to_string(ctx, -2), (char*)duk_to_string(ctx, -1));
len += 2;
len += (propNum++ == 0 ? 1 : 2);
duk_to_lstring(ctx, -2, &strLen); len += (int)strLen;
duk_to_lstring(ctx, -1, &strLen); len += (int)strLen;
duk_pop_2(ctx);
}
duk_pop(ctx);
printf(" }");
len += 2;
}
else
{
printf("%s%s", (i == 0 ? "" : ", "), duk_to_string(ctx, -1));
len += (i == 0 ? 0 : 2);
duk_get_lstring(ctx, -1, &strLen); len += (int)strLen;
}
}
}
printf("\n");
len += 2; // NULL Terminator and final carriage return
strLen = len;
str = ILibMemory_AllocateA(strLen + ((PREFIX != NULL) ? strnlen_s(PREFIX, 9) : 0));
x = (int)(ILibMemory_AllocateA_Size(str) - strLen);
if (x != 0)
{
strLen += sprintf_s(str, strLen, PREFIX);
}
for (i = 0; i < numargs; ++i)
{
if (duk_is_string(ctx, i))
{
x += sprintf_s(str + x, strLen - x, "%s%s", (i == 0 ? "" : ", "), duk_require_string(ctx, i));
}
else
{
duk_dup(ctx, i);
if (strcmp("[object Object]", duk_to_string(ctx, -1)) == 0)
{
duk_pop(ctx);
duk_dup(ctx, i);
x += sprintf_s(str+x, strLen - x, "%s", (i == 0 ? "{" : ", {"));
duk_enum(ctx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY);
int propNum = 0;
while (duk_next(ctx, -1, 1))
{
x += sprintf_s(str + x, strLen - x, "%s%s: %s", ((propNum++ == 0) ? " " : ", "), (char*)duk_to_string(ctx, -2), (char*)duk_to_string(ctx, -1));
duk_pop_2(ctx);
}
duk_pop(ctx);
x += sprintf_s(str + x, strLen - x, " }");
}
else
{
x += sprintf_s(str + x, strLen - x, "%s%s", (i == 0 ? "" : ", "), duk_to_string(ctx, -1));
}
}
}
x += sprintf_s(str + x, strLen - x, "\n");
duk_push_this(ctx); // [console]
int dest = Duktape_GetIntPropertyValue(ctx, -1, DESTINATION, ILibDuktape_Console_DestinationFlags_StdOut);
if ((dest & ILibDuktape_Console_DestinationFlags_StdOut) == ILibDuktape_Console_DestinationFlags_StdOut)
{
#ifdef WIN32
DWORD writeLen;
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), (void*)str, x, &writeLen, NULL);
#else
ignore_result(write(STDOUT_FILENO, str, x));
#endif
}
if ((dest & ILibDuktape_Console_DestinationFlags_WebLog) == ILibDuktape_Console_DestinationFlags_WebLog)
{
ILibRemoteLogging_printf(ILibChainGetLogger(Duktape_GetChain(ctx)), ILibRemoteLogging_Modules_Microstack_Generic, ILibRemoteLogging_Flags_VerbosityLevel_1, "%s", str);
}
if ((dest & ILibDuktape_Console_DestinationFlags_ServerConsole) == ILibDuktape_Console_DestinationFlags_ServerConsole)
{
if (duk_peval_string(ctx, "require('MeshAgent');") == 0)
{
duk_get_prop_string(ctx, -1, "SendCommand"); // [console][agent][SendCommand]
duk_swap_top(ctx, -2); // [console][SendCommand][this]
duk_push_object(ctx); // [console][SendCommand][this][options]
duk_push_string(ctx, "msg"); duk_put_prop_string(ctx, -2, "action");
duk_push_string(ctx, "console"); duk_put_prop_string(ctx, -2, "type");
duk_push_string(ctx, str); duk_put_prop_string(ctx, -2, "value");
if (duk_has_prop_string(ctx, -4, ILibDuktape_Console_SessionID))
{
duk_get_prop_string(ctx, -4, ILibDuktape_Console_SessionID);
duk_put_prop_string(ctx, -2, "sessionid");
}
duk_call_method(ctx, 1);
}
}
if ((dest & ILibDuktape_Console_DestinationFlags_LogFile) == ILibDuktape_Console_DestinationFlags_LogFile)
{
duk_size_t pathLen;
char *path;
char *tmp = ILibMemory_AllocateA(x + 32);
int tmpx = ILibGetLocalTime(tmp + 1, (int)ILibMemory_AllocateA_Size(tmp) - 1) + 1;
tmp[0] = '[';
tmp[tmpx] = ']';
tmp[tmpx + 1] = ':';
tmp[tmpx + 2] = ' ';
memcpy_s(tmp + tmpx + 3, ILibMemory_AllocateA_Size(tmp) - tmpx - 3, str, x);
duk_eval_string(ctx, "require('fs');");
duk_get_prop_string(ctx, -1, "writeFileSync"); // [fs][writeFileSync]
duk_swap_top(ctx, -2); // [writeFileSync][this]
duk_push_heapptr(ctx, ILibDuktape_GetProcessObject(ctx)); // [writeFileSync][this][process]
duk_get_prop_string(ctx, -1, "execPath"); // [writeFileSync][this][process][execPath]
path = (char*)duk_get_lstring(ctx, -1, &pathLen);
if (path != NULL)
{
if (ILibString_EndsWithEx(path, (int)pathLen, ".exe", 4, 0))
{
duk_get_prop_string(ctx, -1, "substring"); // [writeFileSync][this][process][execPath][substring]
duk_swap_top(ctx, -2); // [writeFileSync][this][process][substring][this]
duk_push_int(ctx, 0); // [writeFileSync][this][process][substring][this][0]
duk_push_int(ctx, (int)(pathLen - 4)); // [writeFileSync][this][process][substring][this][0][len]
duk_call_method(ctx, 2); // [writeFileSync][this][process][path]
}
duk_get_prop_string(ctx, -1, "concat"); // [writeFileSync][this][process][path][concat]
duk_swap_top(ctx, -2); // [writeFileSync][this][process][concat][this]
duk_push_string(ctx, ".jlog"); // [writeFileSync][this][process][concat][this][.jlog]
duk_call_method(ctx, 1); // [writeFileSync][this][process][logPath]
duk_remove(ctx, -2); // [writeFileSync][this][logPath]
duk_push_string(ctx, tmp); // [writeFileSync][this][logPath][log]
duk_push_object(ctx); // [writeFileSync][this][logPath][log][options]
duk_push_string(ctx, "a"); duk_put_prop_string(ctx, -2, "flags");
duk_call_method(ctx, 3);
}
}
return 0;
}
duk_ret_t ILibDuktape_Polyfills_Console_enableWebLog(duk_context *ctx)
@@ -357,9 +531,49 @@ duk_ret_t ILibDuktape_Polyfills_Console_logRefCount(duk_context *ctx)
printf("Reference Count => %s[%p]:%d\n", Duktape_GetStringPropertyValue(ctx, 0, ILibDuktape_OBJID, "UNKNOWN"), duk_require_heapptr(ctx, 0), ILibDuktape_GetReferenceCount(ctx, 0) - 1);
return(0);
}
duk_ret_t ILibDuktape_Polyfills_Console_setDestination(duk_context *ctx)
{
int nargs = duk_get_top(ctx);
int dest = duk_require_int(ctx, 0);
duk_push_this(ctx); // console
if ((dest & ILibDuktape_Console_DestinationFlags_ServerConsole) == ILibDuktape_Console_DestinationFlags_ServerConsole)
{
// Mesh Server Console
if (duk_peval_string(ctx, "require('MeshAgent');") != 0) { return(ILibDuktape_Error(ctx, "Unable to set destination to Mesh Console ")); }
duk_pop(ctx);
if (nargs > 1)
{
duk_dup(ctx, 1);
duk_put_prop_string(ctx, -2, ILibDuktape_Console_SessionID);
}
else
{
duk_del_prop_string(ctx, -1, ILibDuktape_Console_SessionID);
}
}
duk_dup(ctx, 0);
duk_put_prop_string(ctx, -2, ILibDuktape_Console_Destination);
return(0);
}
duk_ret_t ILibDuktape_Polyfills_Console_setInfoLevel(duk_context *ctx)
{
int val = duk_require_int(ctx, 0);
if (val < 0) { return(ILibDuktape_Error(ctx, "Invalid Info Level: %d", val)); }
duk_push_this(ctx);
duk_push_int(ctx, val);
duk_put_prop_string(ctx, -2, ILibDuktape_Console_INFO_Level);
return(0);
}
void ILibDuktape_Polyfills_Console(duk_context *ctx)
{
// Polyfill console.log()
#ifdef WIN32
SetConsoleOutputCP(CP_UTF8);
#endif
if (duk_has_prop_string(ctx, -1, "console"))
{
duk_get_prop_string(ctx, -1, "console"); // [g][console]
@@ -371,11 +585,38 @@ void ILibDuktape_Polyfills_Console(duk_context *ctx)
duk_put_prop_string(ctx, -3, "console"); // [g][console]
}
ILibDuktape_CreateInstanceMethod(ctx, "log", ILibDuktape_Polyfills_Console_log, DUK_VARARGS);
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "logType", (int)ILibDuktape_LogType_Normal, "log", ILibDuktape_Polyfills_Console_log, DUK_VARARGS);
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "logType", (int)ILibDuktape_LogType_Warn, "warn", ILibDuktape_Polyfills_Console_log, DUK_VARARGS);
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "logType", (int)ILibDuktape_LogType_Error, "error", ILibDuktape_Polyfills_Console_log, DUK_VARARGS);
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "logType", (int)ILibDuktape_LogType_Info1, "info1", ILibDuktape_Polyfills_Console_log, DUK_VARARGS);
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "logType", (int)ILibDuktape_LogType_Info2, "info2", ILibDuktape_Polyfills_Console_log, DUK_VARARGS);
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "logType", (int)ILibDuktape_LogType_Info3, "info3", ILibDuktape_Polyfills_Console_log, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "enableWebLog", ILibDuktape_Polyfills_Console_enableWebLog, 1);
ILibDuktape_CreateEventWithGetterAndSetterEx(ctx, "displayStreamPipeMessages", ILibDuktape_Polyfills_Console_displayStreamPipe_getter, ILibDuktape_Polyfills_Console_displayStreamPipe_setter);
ILibDuktape_CreateEventWithGetterAndSetterEx(ctx, "displayFinalizerMessages", ILibDuktape_Polyfills_Console_displayFinalizer_getter, ILibDuktape_Polyfills_Console_displayFinalizer_setter);
ILibDuktape_CreateInstanceMethod(ctx, "logReferenceCount", ILibDuktape_Polyfills_Console_logRefCount, 1);
ILibDuktape_CreateInstanceMethod(ctx, "setDestination", ILibDuktape_Polyfills_Console_setDestination, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "setInfoLevel", ILibDuktape_Polyfills_Console_setInfoLevel, 1);
duk_push_object(ctx);
duk_push_int(ctx, ILibDuktape_Console_DestinationFlags_DISABLED); duk_put_prop_string(ctx, -2, "DISABLED");
duk_push_int(ctx, ILibDuktape_Console_DestinationFlags_StdOut); duk_put_prop_string(ctx, -2, "STDOUT");
duk_push_int(ctx, ILibDuktape_Console_DestinationFlags_ServerConsole); duk_put_prop_string(ctx, -2, "SERVERCONSOLE");
duk_push_int(ctx, ILibDuktape_Console_DestinationFlags_WebLog); duk_put_prop_string(ctx, -2, "WEBLOG");
duk_push_int(ctx, ILibDuktape_Console_DestinationFlags_LogFile); duk_put_prop_string(ctx, -2, "LOGFILE");
ILibDuktape_CreateReadonlyProperty(ctx, "Destinations");
duk_push_int(ctx, ILibDuktape_Console_DestinationFlags_StdOut | ILibDuktape_Console_DestinationFlags_LogFile);
duk_put_prop_string(ctx, -2, ILibDuktape_Console_ERROR_Destination);
duk_push_int(ctx, ILibDuktape_Console_DestinationFlags_StdOut | ILibDuktape_Console_DestinationFlags_LogFile);
duk_put_prop_string(ctx, -2, ILibDuktape_Console_WARN_Destination);
duk_push_int(ctx, 0); duk_put_prop_string(ctx, -2, ILibDuktape_Console_INFO_Level);
duk_pop(ctx); // [g]
}
duk_ret_t ILibDuktape_ntohl(duk_context *ctx)
@@ -448,18 +689,21 @@ duk_ret_t ILibDuktape_Polyfills_timer_finalizer(duk_context *ctx)
{
// Make sure we remove any timers just in case, so we don't leak resources
ILibDuktape_Timer *ptrs;
duk_get_prop_string(ctx, 0, ILibDuktape_Timer_Ptrs);
if (duk_has_prop_string(ctx, 0, "\xFF_callback"))
if (duk_has_prop_string(ctx, 0, ILibDuktape_Timer_Ptrs))
{
duk_del_prop_string(ctx, 0, "\xFF_callback");
}
if (duk_has_prop_string(ctx, 0, "\xFF_argArray"))
{
duk_del_prop_string(ctx, 0, "\xFF_argArray");
}
ptrs = (ILibDuktape_Timer*)Duktape_GetBuffer(ctx, -1, NULL);
duk_get_prop_string(ctx, 0, ILibDuktape_Timer_Ptrs);
if (duk_has_prop_string(ctx, 0, "\xFF_callback"))
{
duk_del_prop_string(ctx, 0, "\xFF_callback");
}
if (duk_has_prop_string(ctx, 0, "\xFF_argArray"))
{
duk_del_prop_string(ctx, 0, "\xFF_argArray");
}
ptrs = (ILibDuktape_Timer*)Duktape_GetBuffer(ctx, -1, NULL);
ILibLifeTime_Remove(ILibGetBaseTimer(Duktape_GetChain(ctx)), ptrs);
ILibLifeTime_Remove(ILibGetBaseTimer(Duktape_GetChain(ctx)), ptrs);
}
return 0;
}
void ILibDuktape_Polyfills_timer_elapsed(void *obj)
@@ -467,8 +711,10 @@ void ILibDuktape_Polyfills_timer_elapsed(void *obj)
ILibDuktape_Timer *ptrs = (ILibDuktape_Timer*)obj;
int argCount, i;
duk_context *ctx = ptrs->ctx;
char *funcName;
duk_push_heapptr(ctx, ptrs->callback); // [func]
funcName = Duktape_GetStringPropertyValue(ctx, -1, "name", "unknown_method");
duk_push_heapptr(ctx, ptrs->object); // [func][this]
duk_push_heapptr(ctx, ptrs->args); // [func][this][argArray]
@@ -480,6 +726,7 @@ void ILibDuktape_Polyfills_timer_elapsed(void *obj)
{
duk_del_prop_string(ctx, -2, "\xFF_callback");
duk_del_prop_string(ctx, -2, "\xFF_argArray");
duk_del_prop_string(ctx, -2, ILibDuktape_Timer_Ptrs);
}
argCount = (int)duk_get_length(ctx, -1);
@@ -489,7 +736,7 @@ void ILibDuktape_Polyfills_timer_elapsed(void *obj)
duk_swap_top(ctx, -2); // [func][this][arg][argArray]
}
duk_pop(ctx); // [func][this][...arg...]
if (duk_pcall_method(ctx, argCount) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "timers.onElapsed() callback handler"); }
if (duk_pcall_method(ctx, argCount) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "timers.onElapsed() callback handler on '%s()' ", funcName); }
duk_pop(ctx); // ...
}
duk_ret_t ILibDuktape_Polyfills_timer_set(duk_context *ctx)
@@ -582,7 +829,14 @@ void ILibDuktape_Polyfills_timer(duk_context *ctx)
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "type", ILibDuktape_Timer_Type_INTERVAL, "clearInterval", ILibDuktape_Polyfills_timer_clear, 1);
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "type", ILibDuktape_Timer_Type_IMMEDIATE, "clearImmediate", ILibDuktape_Polyfills_timer_clear, 1);
}
duk_ret_t ILibDuktape_Polyfills_getJSModule(duk_context *ctx)
{
if (ILibDuktape_ModSearch_GetJSModule(ctx, (char*)duk_require_string(ctx, 0)) == 0)
{
return(ILibDuktape_Error(ctx, "getJSModule(): (%s) not found", (char*)duk_require_string(ctx, 0)));
}
return(1);
}
duk_ret_t ILibDuktape_Polyfills_addModule(duk_context *ctx)
{
duk_size_t moduleLen;
@@ -595,6 +849,14 @@ duk_ret_t ILibDuktape_Polyfills_addModule(duk_context *ctx)
}
return(0);
}
duk_ret_t ILibDuktape_Polyfills_addModuleObject(duk_context *ctx)
{
void *module = duk_require_heapptr(ctx, 1);
char *moduleName = (char*)duk_require_string(ctx, 0);
ILibDuktape_ModSearch_AddModuleObject(ctx, moduleName, module);
return(0);
}
duk_ret_t ILibDuktape_Queue_Finalizer(duk_context *ctx)
{
duk_get_prop_string(ctx, 0, ILibDuktape_Queue_Ptr);
@@ -645,7 +907,12 @@ duk_ret_t ILibDuktape_Queue_DeQueue(duk_context *ctx)
if (peek == 0) { duk_del_prop_string(ctx, -length - 2, Duktape_GetStashKey(h)); }
return(length);
}
duk_ret_t ILibDuktape_Queue_isEmpty(duk_context *ctx)
{
duk_push_this(ctx);
duk_push_boolean(ctx, ILibQueue_IsEmpty((ILibQueue)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Queue_Ptr)));
return(1);
}
duk_ret_t ILibDuktape_Queue_new(duk_context *ctx)
{
duk_push_object(ctx); // [queue]
@@ -656,6 +923,7 @@ duk_ret_t ILibDuktape_Queue_new(duk_context *ctx)
ILibDuktape_CreateInstanceMethod(ctx, "enQueue", ILibDuktape_Queue_EnQueue, DUK_VARARGS);
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "peek", 0, "deQueue", ILibDuktape_Queue_DeQueue, DUK_VARARGS);
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "peek", 1, "peekQueue", ILibDuktape_Queue_DeQueue, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "isEmpty", ILibDuktape_Queue_isEmpty, 0);
return(1);
}
@@ -687,7 +955,7 @@ ILibTransport_DoneState ILibDuktape_DynamicBuffer_WriteSink(ILibDuktape_DuplexSt
void ILibDuktape_DynamicBuffer_WriteSink_ChainThread(void *chain, void *user)
{
ILibDuktape_DynamicBuffer_ContextSwitchData *data = (ILibDuktape_DynamicBuffer_ContextSwitchData*)user;
if (ILibDuktape_IsPointerValid(chain, data->heapptr) != 0)
if(ILibMemory_CanaryOK(data->stream))
{
ILibDuktape_DynamicBuffer_WriteSink(data->stream, data->buffer, data->bufferLen, data->data);
ILibDuktape_DuplexStream_Ready(data->stream);
@@ -727,7 +995,7 @@ ILibTransport_DoneState ILibDuktape_DynamicBuffer_WriteSink(ILibDuktape_DuplexSt
{
tmpSize += 4096;
}
data->buffer = (char*)realloc(data->buffer, tmpSize);
if ((data->buffer = (char*)realloc(data->buffer, tmpSize)) == NULL) { ILIBCRITICALEXIT(254); }
data->bufferLen = tmpSize;
}
}
@@ -772,7 +1040,6 @@ void ILibDuktape_DynamicBuffer_EndSink(ILibDuktape_DuplexStream *stream, void *u
}
duk_ret_t ILibDuktape_DynamicBuffer_Finalizer(duk_context *ctx)
{
ILibDuktape_InValidateHeapPointer(ctx, 0);
duk_get_prop_string(ctx, 0, "\xFF_buffer");
ILibDuktape_DynamicBuffer_data *data = (ILibDuktape_DynamicBuffer_data*)Duktape_GetBuffer(ctx, -1, NULL);
free(data->buffer);
@@ -818,7 +1085,6 @@ duk_ret_t ILibDuktape_DynamicBuffer_new(duk_context *ctx)
ILibDuktape_EventEmitter_CreateEventEx(ILibDuktape_EventEmitter_GetEmitter(ctx, -1), "readable");
ILibDuktape_CreateInstanceMethod(ctx, "read", ILibDuktape_DynamicBuffer_read, DUK_VARARGS);
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_DynamicBuffer_Finalizer);
ILibDuktape_ValidateHeapPointer(ctx, -1);
return(1);
}
@@ -934,11 +1200,9 @@ duk_ret_t ILibDuktape_Stream_Push(duk_context *ctx)
{
duk_push_this(ctx); // [stream]
ILibDuktape_readableStream *RS = (ILibDuktape_readableStream*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Stream_ReadablePtr);
duk_get_prop_string(ctx, -1, ILibDuktape_Stream_Buffer); // [stream][buffer]
duk_del_prop_string(ctx, -2, ILibDuktape_Stream_Buffer); // (Deleting here, because unshift will save it again, if necessary)
duk_size_t bufferLen;
char *buffer = (char*)Duktape_GetBuffer(ctx, -1, &bufferLen);
char *buffer = (char*)Duktape_GetBuffer(ctx, 0, &bufferLen);
duk_push_boolean(ctx, !ILibDuktape_readableStream_WriteDataEx(RS, 0, buffer, (int)bufferLen)); // [stream][buffer][retVal]
return(1);
@@ -970,11 +1234,148 @@ duk_idx_t ILibDuktape_Stream_newReadable(duk_context *ctx)
}
return(1);
}
duk_ret_t ILibDuktape_Stream_Writable_WriteSink_Flush(duk_context *ctx)
{
duk_push_current_function(ctx);
ILibTransport_DoneState *retVal = (ILibTransport_DoneState*)Duktape_GetPointerProperty(ctx, -1, "retval");
if (retVal != NULL)
{
*retVal = ILibTransport_DoneState_COMPLETE;
}
else
{
duk_push_this(ctx);
ILibDuktape_WritableStream *WS = (ILibDuktape_WritableStream*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Stream_WritablePtr);
ILibDuktape_WritableStream_Ready(WS);
}
return(0);
}
ILibTransport_DoneState ILibDuktape_Stream_Writable_WriteSink(struct ILibDuktape_WritableStream *stream, char *buffer, int bufferLen, void *user)
{
void *h;
ILibTransport_DoneState retVal = ILibTransport_DoneState_INCOMPLETE;
duk_push_this(stream->ctx); // [writable]
duk_get_prop_string(stream->ctx, -1, "_write"); // [writable][_write]
duk_swap_top(stream->ctx, -2); // [_write][this]
if (stream->Reserved)
{
duk_push_external_buffer(stream->ctx); // [_write][this][extBuffer]
duk_insert(stream->ctx, -3); // [extBuffer][_write][this]
duk_config_buffer(stream->ctx, -3, buffer, (duk_size_t)bufferLen);
duk_push_buffer_object(stream->ctx, -3, 0, (duk_size_t)bufferLen, DUK_BUFOBJ_NODEJS_BUFFER);// [extBuffer][_write][this][buffer]
}
else
{
duk_push_lstring(stream->ctx, buffer, (duk_size_t)bufferLen); // [_write][this][string]
}
duk_push_c_function(stream->ctx, ILibDuktape_Stream_Writable_WriteSink_Flush, DUK_VARARGS); // [_write][this][string/buffer][callback]
h = duk_get_heapptr(stream->ctx, -1);
duk_push_heap_stash(stream->ctx); // [_write][this][string/buffer][callback][stash]
duk_dup(stream->ctx, -2); // [_write][this][string/buffer][callback][stash][callback]
duk_put_prop_string(stream->ctx, -2, Duktape_GetStashKey(h)); // [_write][this][string/buffer][callback][stash]
duk_pop(stream->ctx); // [_write][this][string/buffer][callback]
duk_push_pointer(stream->ctx, &retVal); // [_write][this][string/buffer][callback][retval]
duk_put_prop_string(stream->ctx, -2, "retval"); // [_write][this][string/buffer][callback]
if (duk_pcall_method(stream->ctx, 2) != 0)
{
ILibDuktape_Process_UncaughtExceptionEx(stream->ctx, "stream.writable.write(): "); retVal = ILibTransport_DoneState_ERROR;
}
duk_pop(stream->ctx); // ...
duk_push_heapptr(stream->ctx, h); // [callback]
duk_del_prop_string(stream->ctx, -1, "retval");
duk_pop(stream->ctx); // ...
duk_push_heap_stash(stream->ctx);
duk_del_prop_string(stream->ctx, -1, Duktape_GetStashKey(h));
duk_pop(stream->ctx);
return(retVal);
}
void ILibDuktape_Stream_Writable_EndSink(struct ILibDuktape_WritableStream *stream, void *user)
{
duk_push_this(stream->ctx); // [writable]
duk_get_prop_string(stream->ctx, -1, "_final"); // [writable][_final]
duk_swap_top(stream->ctx, -2); // [_final][this]
if (duk_pcall_method(stream->ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(stream->ctx, "stream.writable._final(): "); }
duk_pop(stream->ctx); // ...
}
duk_ret_t ILibDuktape_Stream_newWritable(duk_context *ctx)
{
ILibDuktape_WritableStream *WS;
duk_push_object(ctx); // [Writable]
ILibDuktape_WriteID(ctx, "stream.writable");
WS = ILibDuktape_WritableStream_Init(ctx, ILibDuktape_Stream_Writable_WriteSink, ILibDuktape_Stream_Writable_EndSink, NULL);
WS->JSCreated = 1;
duk_push_pointer(ctx, WS);
duk_put_prop_string(ctx, -2, ILibDuktape_Stream_WritablePtr);
if (duk_is_object(ctx, 0))
{
void *h = Duktape_GetHeapptrProperty(ctx, 0, "write");
if (h != NULL) { duk_push_heapptr(ctx, h); duk_put_prop_string(ctx, -2, "_write"); }
h = Duktape_GetHeapptrProperty(ctx, 0, "final");
if (h != NULL) { duk_push_heapptr(ctx, h); duk_put_prop_string(ctx, -2, "_final"); }
}
return(1);
}
void ILibDuktape_Stream_Duplex_PauseSink(ILibDuktape_DuplexStream *stream, void *user)
{
ILibDuktape_Stream_PauseSink(stream->readableStream, user);
}
void ILibDuktape_Stream_Duplex_ResumeSink(ILibDuktape_DuplexStream *stream, void *user)
{
ILibDuktape_Stream_ResumeSink(stream->readableStream, user);
}
int ILibDuktape_Stream_Duplex_UnshiftSink(ILibDuktape_DuplexStream *stream, int unshiftBytes, void *user)
{
return(ILibDuktape_Stream_UnshiftSink(stream->readableStream, unshiftBytes, user));
}
ILibTransport_DoneState ILibDuktape_Stream_Duplex_WriteSink(ILibDuktape_DuplexStream *stream, char *buffer, int bufferLen, void *user)
{
return(ILibDuktape_Stream_Writable_WriteSink(stream->writableStream, buffer, bufferLen, user));
}
void ILibDuktape_Stream_Duplex_EndSink(ILibDuktape_DuplexStream *stream, void *user)
{
ILibDuktape_Stream_Writable_EndSink(stream->writableStream, user);
}
duk_ret_t ILibDuktape_Stream_newDuplex(duk_context *ctx)
{
ILibDuktape_DuplexStream *DS;
duk_push_object(ctx); // [Duplex]
ILibDuktape_WriteID(ctx, "stream.Duplex");
DS = ILibDuktape_DuplexStream_InitEx(ctx, ILibDuktape_Stream_Duplex_WriteSink, ILibDuktape_Stream_Duplex_EndSink, ILibDuktape_Stream_Duplex_PauseSink, ILibDuktape_Stream_Duplex_ResumeSink, ILibDuktape_Stream_Duplex_UnshiftSink, NULL);
DS->writableStream->JSCreated = 1;
duk_push_pointer(ctx, DS->writableStream);
duk_put_prop_string(ctx, -2, ILibDuktape_Stream_WritablePtr);
duk_push_pointer(ctx, DS->readableStream);
duk_put_prop_string(ctx, -2, ILibDuktape_Stream_ReadablePtr);
ILibDuktape_CreateInstanceMethod(ctx, "push", ILibDuktape_Stream_Push, DUK_VARARGS);
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -1, "end", ILibDuktape_Stream_EndSink);
if (duk_is_object(ctx, 0))
{
void *h = Duktape_GetHeapptrProperty(ctx, 0, "write");
if (h != NULL) { duk_push_heapptr(ctx, h); duk_put_prop_string(ctx, -2, "_write"); }
h = Duktape_GetHeapptrProperty(ctx, 0, "final");
if (h != NULL) { duk_push_heapptr(ctx, h); duk_put_prop_string(ctx, -2, "_final"); }
h = Duktape_GetHeapptrProperty(ctx, 0, "read");
if (h != NULL) { duk_push_heapptr(ctx, h); duk_put_prop_string(ctx, -2, "_read"); }
}
return(1);
}
void ILibDuktape_Stream_Init(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [stream
ILibDuktape_WriteID(ctx, "stream");
ILibDuktape_CreateInstanceMethod(ctx, "Readable", ILibDuktape_Stream_newReadable, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "Writable", ILibDuktape_Stream_newWritable, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "Duplex", ILibDuktape_Stream_newDuplex, DUK_VARARGS);
}
void ILibDuktape_Polyfills_debugGC2(duk_context *ctx, void ** args, int argsLen)
{
@@ -996,11 +1397,157 @@ duk_ret_t ILibDuktape_Polyfills_debug(duk_context *ctx)
#endif
return(0);
}
#ifndef MICROSTACK_NOTLS
duk_ret_t ILibDuktape_PKCS7_getSignedDataBlock(duk_context *ctx)
{
char *hash = ILibMemory_AllocateA(UTIL_SHA256_HASHSIZE);
char *pkeyHash = ILibMemory_AllocateA(UTIL_SHA256_HASHSIZE);
unsigned int size, r;
BIO *out = NULL;
PKCS7 *message = NULL;
char* data2 = NULL;
STACK_OF(X509) *st = NULL;
duk_size_t bufferLen;
char *buffer = Duktape_GetBuffer(ctx, 0, &bufferLen);
message = d2i_PKCS7(NULL, (const unsigned char**)&buffer, (long)bufferLen);
if (message == NULL) { return(ILibDuktape_Error(ctx, "PKCS7 Error")); }
// Lets rebuild the original message and check the size
size = i2d_PKCS7(message, NULL);
if (size < (unsigned int)bufferLen) { PKCS7_free(message); return(ILibDuktape_Error(ctx, "PKCS7 Error")); }
out = BIO_new(BIO_s_mem());
// Check the PKCS7 signature, but not the certificate chain.
r = PKCS7_verify(message, NULL, NULL, NULL, out, PKCS7_NOVERIFY);
if (r == 0) { PKCS7_free(message); BIO_free(out); return(ILibDuktape_Error(ctx, "PKCS7 Verify Error")); }
// If data block contains less than 32 bytes, fail.
size = (unsigned int)BIO_get_mem_data(out, &data2);
if (size <= ILibMemory_AllocateA_Size(hash)) { PKCS7_free(message); BIO_free(out); return(ILibDuktape_Error(ctx, "PKCS7 Size Mismatch Error")); }
duk_push_object(ctx); // [val]
duk_push_fixed_buffer(ctx, size); // [val][fbuffer]
duk_dup(ctx, -1); // [val][fbuffer][dup]
duk_put_prop_string(ctx, -3, "\xFF_fixedbuffer"); // [val][fbuffer]
duk_swap_top(ctx, -2); // [fbuffer][val]
duk_push_buffer_object(ctx, -2, 0, size, DUK_BUFOBJ_NODEJS_BUFFER); // [fbuffer][val][buffer]
ILibDuktape_CreateReadonlyProperty(ctx, "data"); // [fbuffer][val]
memcpy_s(Duktape_GetBuffer(ctx, -2, NULL), size, data2, size);
// Get the certificate signer
st = PKCS7_get0_signers(message, NULL, PKCS7_NOVERIFY);
// Get a full certificate hash of the signer
X509_digest(sk_X509_value(st, 0), EVP_sha256(), (unsigned char*)hash, NULL);
X509_pubkey_digest(sk_X509_value(st, 0), EVP_sha256(), (unsigned char*)pkeyHash, NULL);
sk_X509_free(st);
// Check certificate hash with first 32 bytes of data.
if (memcmp(hash, Duktape_GetBuffer(ctx, -2, NULL), ILibMemory_AllocateA_Size(hash)) != 0) { PKCS7_free(message); BIO_free(out); return(ILibDuktape_Error(ctx, "PKCS7 Certificate Hash Mismatch Error")); }
char *tmp = ILibMemory_AllocateA(1 + (ILibMemory_AllocateA_Size(hash) * 2));
util_tohex(hash, (int)ILibMemory_AllocateA_Size(hash), tmp);
duk_push_object(ctx); // [fbuffer][val][cert]
ILibDuktape_WriteID(ctx, "certificate");
duk_push_string(ctx, tmp); // [fbuffer][val][cert][fingerprint]
ILibDuktape_CreateReadonlyProperty(ctx, "fingerprint"); // [fbuffer][val][cert]
util_tohex(pkeyHash, (int)ILibMemory_AllocateA_Size(pkeyHash), tmp);
duk_push_string(ctx, tmp); // [fbuffer][val][cert][publickeyhash]
ILibDuktape_CreateReadonlyProperty(ctx, "publicKeyHash"); // [fbuffer][val][cert]
ILibDuktape_CreateReadonlyProperty(ctx, "signingCertificate"); // [fbuffer][val]
// Approved, cleanup and return.
BIO_free(out);
PKCS7_free(message);
return(1);
}
duk_ret_t ILibDuktape_PKCS7_signDataBlockFinalizer(duk_context *ctx)
{
char *buffer = Duktape_GetPointerProperty(ctx, 0, "\xFF_signature");
if (buffer != NULL) { free(buffer); }
return(0);
}
duk_ret_t ILibDuktape_PKCS7_signDataBlock(duk_context *ctx)
{
duk_get_prop_string(ctx, 1, "secureContext");
duk_get_prop_string(ctx, -1, "\xFF_SecureContext2CertBuffer");
struct util_cert *cert = (struct util_cert*)Duktape_GetBuffer(ctx, -1, NULL);
duk_size_t bufferLen;
char *buffer = (char*)Duktape_GetBuffer(ctx, 0, &bufferLen);
BIO *in = NULL;
PKCS7 *message = NULL;
char *signature = NULL;
int signatureLength = 0;
// Sign the block
in = BIO_new_mem_buf(buffer, (int)bufferLen);
message = PKCS7_sign(cert->x509, cert->pkey, NULL, in, PKCS7_BINARY);
if (message != NULL)
{
signatureLength = i2d_PKCS7(message, (unsigned char**)&signature);
PKCS7_free(message);
}
if (in != NULL) BIO_free(in);
if (signatureLength <= 0) { return(ILibDuktape_Error(ctx, "PKCS7_signDataBlockError: ")); }
duk_push_external_buffer(ctx);
duk_config_buffer(ctx, -1, signature, signatureLength);
duk_push_buffer_object(ctx, -1, 0, signatureLength, DUK_BUFOBJ_NODEJS_BUFFER);
duk_push_pointer(ctx, signature);
duk_put_prop_string(ctx, -2, "\xFF_signature");
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_PKCS7_signDataBlockFinalizer);
return(1);
}
void ILibDuktape_PKCS7_Push(duk_context *ctx, void *chain)
{
duk_push_object(ctx);
ILibDuktape_CreateInstanceMethod(ctx, "getSignedDataBlock", ILibDuktape_PKCS7_getSignedDataBlock, 1);
ILibDuktape_CreateInstanceMethod(ctx, "signDataBlock", ILibDuktape_PKCS7_signDataBlock, DUK_VARARGS);
}
extern uint32_t crc32c(uint32_t crc, const unsigned char* buf, uint32_t len);
duk_ret_t ILibDuktape_Polyfills_crc32c(duk_context *ctx)
{
duk_size_t len;
char *buffer = Duktape_GetBuffer(ctx, 0, &len);
duk_push_int(ctx, crc32c(0, (unsigned char*)buffer, (uint32_t)len));
return(1);
}
#endif
duk_ret_t ILibDuktape_Polyfills_Object_hashCode(duk_context *ctx)
{
duk_push_this(ctx);
duk_push_string(ctx, Duktape_GetStashKey(duk_get_heapptr(ctx, -1)));
return(1);
}
void ILibDuktape_Polyfills_object(duk_context *ctx)
{
// Polyfill Object._hashCode()
duk_get_prop_string(ctx, -1, "Object"); // [g][Object]
duk_get_prop_string(ctx, -1, "prototype"); // [g][Object][prototype]
duk_push_c_function(ctx, ILibDuktape_Polyfills_Object_hashCode, 0); // [g][Object][prototype][func]
ILibDuktape_CreateReadonlyProperty(ctx, "_hashCode"); // [g][Object][prototype]
duk_pop_2(ctx); // [g]
}
void ILibDuktape_Polyfills_Init(duk_context *ctx)
{
ILibDuktape_ModSearch_AddHandler(ctx, "queue", ILibDuktape_Queue_Push);
ILibDuktape_ModSearch_AddHandler(ctx, "DynamicBuffer", ILibDuktape_DynamicBuffer_Push);
ILibDuktape_ModSearch_AddHandler(ctx, "stream", ILibDuktape_Stream_Init);
#ifndef MICROSTACK_NOTLS
ILibDuktape_ModSearch_AddHandler(ctx, "pkcs7", ILibDuktape_PKCS7_Push);
#endif
// Global Polyfills
duk_push_global_object(ctx); // [g]
@@ -1010,13 +1557,20 @@ void ILibDuktape_Polyfills_Init(duk_context *ctx)
ILibDuktape_Polyfills_Console(ctx);
ILibDuktape_Polyfills_byte_ordering(ctx);
ILibDuktape_Polyfills_timer(ctx);
ILibDuktape_Polyfills_object(ctx);
ILibDuktape_CreateInstanceMethod(ctx, "addModuleObject", ILibDuktape_Polyfills_addModuleObject, 2);
ILibDuktape_CreateInstanceMethod(ctx, "addModule", ILibDuktape_Polyfills_addModule, 2);
ILibDuktape_CreateInstanceMethod(ctx, "getJSModule", ILibDuktape_Polyfills_getJSModule, 1);
ILibDuktape_CreateInstanceMethod(ctx, "_debugCrash", ILibDuktape_Polyfills_debugCrash, 0);
ILibDuktape_CreateInstanceMethod(ctx, "_debugGC", ILibDuktape_Polyfills_debugGC, 0);
ILibDuktape_CreateInstanceMethod(ctx, "_debug", ILibDuktape_Polyfills_debug, 0);
#ifndef MICROSTACK_NOTLS
ILibDuktape_CreateInstanceMethod(ctx, "crc32c", ILibDuktape_Polyfills_crc32c, DUK_VARARGS);
#endif
duk_pop(ctx); // ...
ILibDuktape_Debugger_Init(ctx, 9091);
}
#ifdef __DOXY__
@@ -1207,4 +1761,4 @@ public:
*/
static void htonl(buffer, offset, val);
};
#endif
#endif

View File

@@ -23,4 +23,4 @@ extern int g_displayStreamPipeMessages;
extern int g_displayFinalizerMessages;
void ILibDuktape_Polyfills_Init(duk_context *ctx);
#endif
#endif

View File

@@ -1,256 +0,0 @@
#include "duktape.h"
#if defined(WINSOCK2)
#include <winsock2.h>
#include <ws2tcpip.h>
#endif
#include "microstack/ILibParsers.h"
#include "microstack/ILibProcessPipe.h"
#include "ILibDuktape_ProcessPipe.h"
#include "ILibDuktape_Helpers.h"
#include "ILibDuktape_DuplexStream.h"
#include "ILibDuktapeModSearch.h"
#define ILibDuktape_ProcessPipe_Process_ErrorStreamPtr "\xFF_ErrorStreamPtr"
#define ILibDuktape_ProcessPipe_Process_ErrorStreamPtrNative "\xFF_ErrorStreamPtrNative"
#define ILibDuktape_ProcessPipe_Process_PTR "\xFFProcessPtr"
ILibTransport_DoneState ILibDuktape_ProcessPipe_Process_JSOnWrite(ILibDuktape_DuplexStream *stream, char *buffer, int bufferLen, void *user)
{
// Called when JavaScript has written bytes to this object
ILibProcessPipe_Process mProcess = (ILibProcessPipe_Process)user;
return(ILibProcessPipe_Process_WriteStdIn(mProcess, buffer, bufferLen, ILibTransport_MemoryOwnership_USER));
}
void ILibDuktape_ProcessPipe_Process_JSOnEnd(ILibDuktape_DuplexStream *stream, void *user)
{
// Called when JavaScript has specified that it will no longer write data
ILibProcessPipe_Process mProcess = (ILibProcessPipe_Process)user;
if (mProcess != NULL)
{
ILibProcessPipe_Process_KillEx(mProcess);
duk_push_heapptr(stream->readableStream->ctx, stream->ParentObject); // [process]
duk_del_prop_string(stream->readableStream->ctx, -1, ILibDuktape_ProcessPipe_Process_PTR);
duk_pop(stream->readableStream->ctx);
ILibProcessPipe_Process_UpdateUserObject(mProcess, NULL);
stream->user = NULL;
}
}
void ILibDuktape_ProcessPipe_Process_JSPause(ILibDuktape_DuplexStream *sender, void *user)
{
// Called when either JavaScript called Pause, or JavaScript has not attached a reader yet
ILibProcessPipe_Process mProcess = (ILibProcessPipe_Process)user;
ILibProcessPipe_Pipe_Pause(ILibProcessPipe_Process_GetStdOut(mProcess));
}
void ILibDuktape_ProcessPipe_Process_JSResume(ILibDuktape_DuplexStream *sender, void *user)
{
// Called when JavaScript called Resume
ILibProcessPipe_Process mProcess = (ILibProcessPipe_Process)user;
ILibProcessPipe_Pipe_Resume(ILibProcessPipe_Process_GetStdOut(mProcess));
}
void ILibDuktape_ProcessPipe_Process_OnExit(ILibProcessPipe_Process sender, int exitCode, void* user)
{
if (user == NULL) { return; }
// Called when process has exited
ILibDuktape_DuplexStream* stream = (ILibDuktape_DuplexStream*)user;
ILibProcessPipe_Process_UpdateUserObject(sender, NULL);
ILibDuktape_DuplexStream_WriteEnd(stream);
duk_push_heapptr(stream->readableStream->ctx, stream->ParentObject); // [process]
duk_del_prop_string(stream->readableStream->ctx, -1, ILibDuktape_ProcessPipe_Process_PTR);
duk_pop(stream->readableStream->ctx);
}
void ILibDuktape_ProcessPipe_Process_OnStdOut(ILibProcessPipe_Process sender, char *buffer, int bufferLen, int* bytesConsumed, void* user)
{
if (user == NULL) { return; }
// Called when process has written data
ILibDuktape_DuplexStream* ds = (ILibDuktape_DuplexStream*)user;
ILibDuktape_DuplexStream_WriteData(ds, buffer, bufferLen);
*bytesConsumed = bufferLen;
}
void ILibDuktape_ProcessPipe_Process_OnStdErr(ILibProcessPipe_Process sender, char *buffer, int bufferLen, int* bytesConsumed, void* user)
{
if (user == NULL) { return; }
// Called when process has written error data
ILibDuktape_DuplexStream* ds = (ILibDuktape_DuplexStream*)user;
ILibDuktape_readableStream *rs;
duk_push_heapptr(ds->readableStream->ctx, ds->ParentObject); // [process]
duk_get_prop_string(ds->readableStream->ctx, -1, ILibDuktape_ProcessPipe_Process_ErrorStreamPtrNative); // [process][error]
rs = (ILibDuktape_readableStream*)duk_get_pointer(ds->readableStream->ctx, -1);
ILibDuktape_readableStream_WriteData(rs, buffer, bufferLen);
*bytesConsumed = bufferLen;
}
void ILibDuktape_ProcessPipe_Process_OnSendOK(ILibProcessPipe_Process sender, void* user)
{
if (user == NULL) { return; }
//ToDo: Finish this
}
duk_ret_t ILibDuktape_ProcessPipe_Process_Finalizer(duk_context *ctx)
{
ILibProcessPipe_Process mProcess;
duk_dup(ctx, 0);
duk_get_prop_string(ctx, -1, ILibDuktape_ProcessPipe_Process_PTR);
mProcess = (ILibProcessPipe_Process)duk_get_pointer(ctx, -1);
if (mProcess != NULL)
{
ILibProcessPipe_Process_UpdateUserObject(mProcess, NULL);
ILibProcessPipe_Process_KillEx(mProcess);
}
if (duk_has_prop_string(ctx, 0, ILibDuktape_DuplexStream_bufferPtr))
{
duk_get_prop_string(ctx, 0, ILibDuktape_DuplexStream_bufferPtr);
memset(Duktape_GetBuffer(ctx, -1, NULL), 0, sizeof(ILibDuktape_DuplexStream));
}
return 0;
}
void ILibDuktape_ProcessPipe_ErrorStream_Pause(struct ILibDuktape_readableStream *sender, void *user)
{
ILibProcessPipe_Process mProcess = (ILibProcessPipe_Process)user;
ILibProcessPipe_Pipe_Pause(ILibProcessPipe_Process_GetStdErr(mProcess));
}
void ILibDuktape_ProcessPipe_ErrorStream_Resume(struct ILibDuktape_readableStream *sender, void *user)
{
ILibProcessPipe_Process mProcess = (ILibProcessPipe_Process)user;
ILibProcessPipe_Pipe_Resume(ILibProcessPipe_Process_GetStdErr(mProcess));
}
duk_ret_t ILibDuktape_ProcessPipe_ErrorStream_Getter(duk_context *ctx)
{
duk_push_this(ctx);
duk_get_prop_string(ctx, -1, ILibDuktape_ProcessPipe_Process_ErrorStreamPtr);
return 1;
}
duk_ret_t ILibDuktape_ProcessPipe_CreateProcess(duk_context *ctx)
{
ILibProcessPipe_Manager pipeManager;
ILibProcessPipe_Process mProcess;
ILibDuktape_DuplexStream* ds;
ILibDuktape_readableStream *rs;
duk_size_t targetLen;
int nargs = duk_get_top(ctx);
char *target;
char **params = NULL;
int i, x;
ILibProcessPipe_SpawnTypes asUser = ILibProcessPipe_SpawnTypes_DEFAULT;
if (nargs < 1) { duk_push_string(ctx, "ProcessPipe.CreateProcess: Invalid number of args"); duk_throw(ctx); return(DUK_RET_ERROR); }
// Parse Parameters
target = (char*)duk_get_lstring(ctx, 0, &targetLen);
#ifdef WIN32
if (target[0] == '%')
{
size_t evsize;
int pctx = ILibString_IndexOf(target + 1, (int)targetLen - 1, "%", 1);
if (pctx > 0)
{
memcpy_s(ILibScratchPad, sizeof(ILibScratchPad), target + 1, pctx);
ILibScratchPad[pctx] = 0;
getenv_s(&evsize, ILibScratchPad2, sizeof(ILibScratchPad2), ILibScratchPad);
if (evsize > 0)
{
strncpy_s(ILibScratchPad2 + evsize - 1, sizeof(ILibScratchPad2) - evsize, target + pctx + 2, targetLen - pctx - 2);
target = ILibScratchPad2;
}
}
}
#endif
if (nargs > 1)
{
x = 0;
params = (char**)ILibMemory_Allocate((nargs * sizeof(char*)), 0, NULL, NULL);
for (i = 1; i < nargs; ++i)
{
if (duk_is_number(ctx, i))
{
asUser = (ILibProcessPipe_SpawnTypes)duk_require_int(ctx, i);
}
else
{
params[x++] = (char*)duk_require_string(ctx, i);
}
}
params[x] = NULL;
}
duk_push_this(ctx); // [manager]
duk_get_prop_string(ctx, -1, "\xFFPipeManager"); // [manager][pipeManager]
pipeManager = (ILibProcessPipe_Manager)duk_get_pointer(ctx, -1);
mProcess = ILibProcessPipe_Manager_SpawnProcessEx(pipeManager, target, params, asUser);
if (params != NULL) { free(params); }
if (mProcess != NULL)
{
duk_push_object(ctx); // [manager][pipeManager][retVal]
duk_push_pointer(ctx, mProcess); // [manager][pipeManager][retVal][process]
duk_put_prop_string(ctx, -2, ILibDuktape_ProcessPipe_Process_PTR); // [manager][pipeManager][retVal]
ILibDuktape_CreateReadonlyProperty_int(ctx, "pid", ILibProcessPipe_Process_GetPID(mProcess));
ds = ILibDuktape_DuplexStream_Init(ctx, ILibDuktape_ProcessPipe_Process_JSOnWrite,
ILibDuktape_ProcessPipe_Process_JSOnEnd, ILibDuktape_ProcessPipe_Process_JSPause,
ILibDuktape_ProcessPipe_Process_JSResume, mProcess);
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_ProcessPipe_Process_Finalizer);
ILibProcessPipe_Process_AddHandlers(mProcess, 4096, ILibDuktape_ProcessPipe_Process_OnExit,
ILibDuktape_ProcessPipe_Process_OnStdOut, ILibDuktape_ProcessPipe_Process_OnStdErr,
ILibDuktape_ProcessPipe_Process_OnSendOK, ds);
duk_push_object(ctx); // [manager][pipeManager][retVal][error]
ILibDuktape_CreateEventWithGetterEx(ctx, "parent", duk_get_heapptr(ctx, -2));
rs = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_ProcessPipe_ErrorStream_Pause, ILibDuktape_ProcessPipe_ErrorStream_Resume, mProcess);
duk_put_prop_string(ctx, -2, ILibDuktape_ProcessPipe_Process_ErrorStreamPtr); // [manager][pipeManager][retVal]
ILibDuktape_CreateEventWithGetter(ctx, "error", ILibDuktape_ProcessPipe_ErrorStream_Getter);
duk_push_pointer(ctx, rs); // [manager][pipeManager][retVal][ptr]
duk_put_prop_string(ctx, -2, ILibDuktape_ProcessPipe_Process_ErrorStreamPtrNative); // [manager][pipeManager][retVal]
}
else
{
duk_push_null(ctx);
}
return 1;
}
duk_ret_t ILibDuktape_ProcessPipe_Finalizer(duk_context *ctx)
{
ILibProcessPipe_Manager *pipeManager;
duk_dup(ctx, 0); // [obj]
duk_get_prop_string(ctx, -1, "\xFFPipeManager"); // [obj][manager]
pipeManager = (ILibProcessPipe_Manager)duk_get_pointer(ctx, -1);
ILibChain_SafeRemove(((ILibChain_Link*)pipeManager)->ParentChain, pipeManager);
return 0;
}
void ILibDuktape_ProcessPipe_PUSH(duk_context *ctx, void *chain)
{
ILibProcessPipe_Manager pipeManager = ILibProcessPipe_Manager_Create(chain);
duk_push_object(ctx); // [obj]
duk_push_pointer(ctx, pipeManager); // [obj][pipeManager]
duk_put_prop_string(ctx, -2, "\xFFPipeManager"); // [obj]
ILibDuktape_CreateInstanceMethod(ctx, "CreateProcess", ILibDuktape_ProcessPipe_CreateProcess, DUK_VARARGS);
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_ProcessPipe_Finalizer);
Duktape_CreateEnum(ctx, "ILibProcessPipe_SpawnTypes", (char*[]) { "DEFAULT", "USER", "WINLOGON", "TERM" }, (int[]) { 0, 1, 2, 3 }, 4);
}
void ILibDuktape_ProcessPipe_Init(duk_context * ctx, void * chain)
{
ILibDuktape_ModSearch_AddHandler(ctx, "ILibProcessPipe", ILibDuktape_ProcessPipe_PUSH);
}

View File

@@ -1,71 +0,0 @@
#ifndef __DUKTAPE_PROCESSPIPE__
#define __DUKTAPE_PROCESSPIPE__
#include "duktape.h"
#ifdef __DOXY__
/*!
\brief An object that is used to spawn child processes to perform various tasks. <b>Note:</b> To use, must <b>require('ILibProcessPipe')</b>
*/
class ILibProcessPipe
{
public:
/*!
\brief Spawns a child process
*
ILibProcessPipe_Process CreateProcess(target[, spawnType][, ...args]);
\param target \<String\> The target module to execute
\param spawnType <ILibProcessPipe_SpawnTypes> The optional process type to spawn
\param args \<String\> optional paramaters to pass to target on the command line. The first one is argv0, the second is argv1, etc.
\returns \<ILibProcessPipe_Process\> stream attached to child process. NULL if the process could not be spawned.
*/
ILibProcessPipe_Process CreateProcess(target[, spawnType][, ...args]);
/*!
\brief Specifies the type of child process to spawn
*/
enum class ILibProcessPipe_SpawnTypes
{
DEFAULT, /*!< Same as parent*/
USER, /*!< Currently logged on user*/
WINLOGON, /*!< Windows Logon Screen*/
TERM /*!< Terminal*/
};
/*!
\implements DuplexStream
\brief Stream abstraction for a child process of ILibProcessPipe.
*
The underyling ReadableStream is attached to the child process's <b>stdIn</b>. \n
The underlying WritableStream is attached tot he child process's <b>stdOut</b>.
*/
class ILibProcessPipe_Process
{
public:
/*!
\brief The Child's Process ID
*/
int pid;
/*!
\brief The ReadableStream that is attached to the child process's <b>StdErr</b>
*/
ReadableStream error;
/*!
\brief The 'data' event is emitted data is available from the child process's <b>StdOut</b>.
\param chunk A chunk of data. Can be a Buffer or a string.
*/
void data;
/*!
\brief The 'end' event is emitted when the child process has exited.
*/
void end;
};
};
#endif
void ILibDuktape_ProcessPipe_Init(duk_context *ctx, void *chain);
#endif

View File

@@ -192,6 +192,8 @@ int ILibDuktape_readableStream_WriteData_Flush(struct ILibDuktape_WritableStream
if(stream->pipe_pendingCount == 0)
#endif
{
if (stream->emitter->ctx == NULL) { return(1); }
sem_wait(&(stream->pipeLock));
stream->pipeInProgress = 0;
unpipeInProgress = stream->unpipeInProgress;
@@ -259,7 +261,7 @@ int ILibDuktape_readableStream_WriteDataEx(ILibDuktape_readableStream *stream, i
int dispatched = 0;
int needPause = 0;
if (stream == NULL) { return(1); }
if (stream == NULL || !ILibMemory_CanaryOK(stream)) { return(1); }
if (stream->paused != 0)
{
@@ -416,6 +418,7 @@ void ILibDuktape_readableStream_WriteEnd_ChainSink(void *chain, void *user)
int ILibDuktape_readableStream_WriteEnd(ILibDuktape_readableStream *stream)
{
int retVal = 1;
if (!ILibMemory_CanaryOK(stream)) { return(retVal); }
if (ILibIsRunningOnChainThread(stream->chain) == 0)
{
@@ -531,7 +534,7 @@ duk_ret_t ILibDuktape_readableStream_resume(duk_context *ctx)
ptr = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL);
duk_pop(ctx); // [stream]
if (ptr->ResumeHandler == NULL) { return(ILibDuktape_Error(ctx, "Resume not supported")); }
if (!ptr->paused) { return(0); }
if (ILibDuktape_readableStream_resume_flush(ptr) == 0 && ptr->ResumeHandler != NULL) { ptr->paused = 0; ptr->ResumeHandler(ptr, ptr->user); }
return 1;
}
@@ -545,21 +548,20 @@ void ILibDuktape_ReadableStream_pipe_ResumeLater(duk_context *ctx, void **args,
}
void ILibDuktape_readableStream_pipe_later(duk_context *ctx, void **args, int argsLen)
{
duk_push_heapptr(ctx, args[0]); // [readable]
duk_get_prop_string(ctx, -1, ILibDuktape_readableStream_RSPTRS);
ILibDuktape_readableStream *rs = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL);
duk_pop(ctx);
duk_push_heapptr(ctx, rs->pipeImmediate);
duk_del_prop_string(ctx, -1, "dest");
duk_pop(ctx);
rs->pipeImmediate = NULL;
ILibDuktape_readableStream *rs = (ILibDuktape_readableStream*)args[0];
if (!ILibMemory_CanaryOK(rs)) { return; }
duk_push_heapptr(ctx, rs->object); // [readable]
duk_get_prop_string(ctx, -1, "pipe"); // [readable][pipe]
duk_swap_top(ctx, -2); // [pipe][this]
duk_push_heapptr(ctx, args[1]); // [pipe][this][writable]
if (argsLen > 2) { duk_push_heapptr(ctx, args[2]); } // [pipe][this][writable][options]
duk_push_heapptr(ctx, rs->pipeImmediate); // [pipe][this][writable][options][immediate]
duk_del_prop_string(ctx, -1, "dest");
duk_pop(ctx); // [pipe][this][writable][options]
rs->pipeImmediate = NULL;
if (duk_pcall_method(ctx, argsLen - 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "readableStream.pipeLater(): "); }
duk_pop(ctx); // ...
}
@@ -578,11 +580,15 @@ duk_ret_t ILibDuktape_readableStream_pipe(duk_context *ctx)
if (rstream->pipeInProgress != 0)
{
// We must YIELD and try again later, becuase there is an active dispatch going on
duk_push_this(ctx);
rstream->pipeImmediate = ILibDuktape_Immediate(ctx, (void*[]) { duk_get_heapptr(ctx, -1), duk_get_heapptr(ctx, 0), nargs > 1 ? duk_get_heapptr(ctx, 1) : NULL }, 1 + nargs, ILibDuktape_readableStream_pipe_later);
rstream->pipeImmediate = ILibDuktape_Immediate(ctx, (void*[]) { rstream, duk_get_heapptr(ctx, 0), nargs > 1 ? duk_get_heapptr(ctx, 1) : NULL }, 1 + nargs, ILibDuktape_readableStream_pipe_later);
duk_push_heapptr(ctx, rstream->pipeImmediate); // [immediate]
duk_dup(ctx, 0); // [immediate][ws]
duk_put_prop_string(ctx, -2, "dest"); // [immediate]
if (nargs > 1)
{
duk_dup(ctx, 1);
duk_put_prop_string(ctx, -2, "opt");
}
duk_dup(ctx, 0);
sem_post(&(rstream->pipeLock));
return(1);
@@ -668,6 +674,7 @@ void ILibDuktape_readableStream_unpipe_later(duk_context *ctx, void ** args, int
data = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL);
duk_pop_2(ctx); // ...
if (data->emitter->ctx == NULL) { return; }
sem_wait(&(data->pipeLock));
if (data->pipeInProgress != 0)
{
@@ -726,8 +733,11 @@ void ILibDuktape_readableStream_unpipe_later(duk_context *ctx, void ** args, int
duk_call_method(ctx, 2); // [undefined]
duk_pop(ctx); // ...
break;
}
duk_pop_2(ctx); // [array]
}
else
{
duk_pop(ctx); // [array]
}
}
duk_pop(ctx); // ...
break;
@@ -765,6 +775,7 @@ void ILibDuktape_readableStream_unpipe_later(duk_context *ctx, void ** args, int
duk_ret_t ILibDuktape_readableStream_unpipe(duk_context *ctx)
{
int nargs = duk_get_top(ctx);
int onlyItem = 0;
ILibDuktape_readableStream *data;
duk_push_this(ctx); // [readable]
@@ -772,15 +783,35 @@ duk_ret_t ILibDuktape_readableStream_unpipe(duk_context *ctx)
data = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL);
duk_pop(ctx); // [readable]
if (data->emitter->ctx == NULL) { return(0); }
sem_wait(&(data->pipeLock));
data->unpipeInProgress = 1;
if (nargs == 1 && duk_is_object(ctx, 0))
{
void *w = duk_require_heapptr(ctx, 0);
duk_push_heapptr(ctx, data->pipeArray); // [readable][array]
int wcount = (int)duk_get_length(ctx, -1);
duk_enum(ctx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY); // [readable][array][enum]
while (duk_next(ctx, -1, 1))
{ // [readable][array][enum][key][val]
if (duk_get_heapptr(ctx, -1) == w) { onlyItem = 1; }
duk_pop_2(ctx); // [readable][array][enum]
if (onlyItem) { break; }
}
if (onlyItem && wcount > 1) { onlyItem = 0; }
duk_pop_2(ctx); // [readable]
}
sem_post(&(data->pipeLock));
// We need to pause first
duk_push_this(ctx); // [readable]
duk_get_prop_string(ctx, -1, "pause"); // [readable][pause]
duk_dup(ctx, -2); // [readable][pause][this]
duk_call_method(ctx, 0); duk_pop(ctx); // [readable]
if (nargs == 0 || onlyItem != 0)
{
// We need to pause first
duk_push_this(ctx); // [readable]
duk_get_prop_string(ctx, -1, "pause"); // [readable][pause]
duk_dup(ctx, -2); // [readable][pause][this]
duk_call_method(ctx, 0); duk_pop(ctx); // [readable]
}
// We must yield, and do this on the next event loop, because we can't unpipe if we're called from a pipe'ed call
void *imm = ILibDuktape_Immediate(ctx, (void*[]) { duk_get_heapptr(ctx, -1), nargs == 1 ? duk_get_heapptr(ctx, 0) : NULL }, nargs + 1, ILibDuktape_readableStream_unpipe_later);
@@ -867,17 +898,12 @@ ILibDuktape_readableStream* ILibDuktape_ReadableStream_InitEx(duk_context *ctx,
ILibDuktape_readableStream *retVal;
ILibDuktape_EventEmitter *emitter;
ILibDuktape_PointerValidation_Init(ctx);
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_readableStream)); // [obj][buffer]
duk_dup(ctx, -1); // [obj][buffer][buffer]
duk_put_prop_string(ctx, -3, ILibDuktape_readableStream_RSPTRS); // [obj][buffer]
retVal = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL); // [obj][buffer]
memset(retVal, 0, sizeof(ILibDuktape_readableStream));
retVal = (ILibDuktape_readableStream*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_readableStream)); // [obj][buffer]
duk_put_prop_string(ctx, -2, ILibDuktape_readableStream_RSPTRS); // [obj]
duk_pop(ctx); // [obj]
duk_push_array(ctx); // [obj][array]
duk_push_array(ctx); // [obj][array]
retVal->pipeArray = duk_get_heapptr(ctx, -1);
duk_put_prop_string(ctx, -2, ILibDuktape_readableStream_PipeArray); // [obj]
duk_put_prop_string(ctx, -2, ILibDuktape_readableStream_PipeArray); // [obj]
retVal->ctx = ctx;
retVal->chain = Duktape_GetChain(ctx);

View File

@@ -80,4 +80,3 @@ int ILibDuktape_readableStream_WriteEnd(ILibDuktape_readableStream *stream);
void ILibDuktape_readableStream_Closed(ILibDuktape_readableStream *stream);
#endif

View File

@@ -23,6 +23,7 @@ limitations under the License.
#include "../microstack/ILibCrypto.h"
#define ILibDuktape_MD5_PTR "\xFF_MD5PTR"
#define ILibDuktape_SHA1_PTR "\xFF_SHA1PTR"
#define ILibDuktape_SHA256_PTR "\xFF_SHA256PTR"
#define ILibDuktape_SHA512_PTR "\xFF_SHA512PTR"
#define ILibDuktape_SHA256_SIGNER_PTR "\xFF_SHA256_SIGNER_PTR"
@@ -30,14 +31,12 @@ limitations under the License.
#define ILibDuktape_SHA256_SIGNER_CERT_ALLOC "\xFF_SHA256_SIGNER_CERT_ALLOC"
#define ILibDuktape_SHA256_SIGNER_SIGBUFFER "\xFF_SHA256_SIGNER_SIG_BUFFER"
#ifndef MICROSTACK_NOTLS
typedef struct ILibDuktape_SHA256_Data
{
duk_context *ctx;
void *object;
char buffer[33];
char buffer[UTIL_SHA256_HASHSIZE];
SHA256_CTX shctx;
}ILibDuktape_SHA256_Data;
typedef struct ILibDuktape_SHA512_Data
@@ -45,7 +44,7 @@ typedef struct ILibDuktape_SHA512_Data
duk_context *ctx;
void *object;
char buffer[65];
char buffer[UTIL_SHA512_HASHSIZE];
SHA512_CTX shctx;
}ILibDuktape_SHA512_Data;
typedef struct ILibDuktape_MD5_Data
@@ -53,10 +52,20 @@ typedef struct ILibDuktape_MD5_Data
duk_context *ctx;
void *object;
char buffer[33];
char buffer[UTIL_MD5_HASHSIZE];
MD5_CTX mctx;
}ILibDuktape_MD5_Data;
typedef struct ILibDuktape_SHA1_Data
{
duk_context *ctx;
void *object;
char buffer[UTIL_SHA1_HASHSIZE];
SHA_CTX sctx;
}ILibDuktape_SHA1_Data;
#ifndef MICROSTACK_NOTLS
typedef struct ILibDuktape_SHA256_Signer_Data
{
duk_context *ctx;
@@ -67,6 +76,7 @@ typedef struct ILibDuktape_SHA256_Signer_Data
void *OnSignature;
void *OnSignatureString;
}ILibDuktape_SHA256_Signer_Data;
#endif
duk_ret_t ILibDuktape_SHA256_Finalizer(duk_context *ctx)
{
@@ -93,39 +103,29 @@ ILibTransport_DoneState ILibDuktape_SHA384_Write(struct ILibDuktape_WritableStre
void ILibDuktape_SHA256_End(struct ILibDuktape_WritableStream *stream, void *user)
{
ILibDuktape_SHA256_Data *data = (ILibDuktape_SHA256_Data*)user;
data->buffer[32] = 0;
SHA256_Final((unsigned char*)data->buffer, &(data->shctx));
duk_push_external_buffer(data->ctx); // [extBuffer]
duk_config_buffer(data->ctx, -1, data->buffer, 32);
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]['hash']
duk_push_buffer_object(data->ctx, -4, 0, 32, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]['hash'][hash]
duk_push_external_buffer(data->ctx); // [extBuffer]
duk_config_buffer(data->ctx, -1, data->buffer, UTIL_SHA256_HASHSIZE);
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]['hash']
duk_push_buffer_object(data->ctx, -4, 0, UTIL_SHA256_HASHSIZE, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]['hash'][hash]
if (duk_pcall_method(data->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
duk_pop_2(data->ctx); // ...
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hashString"); // [emit][this]['hash']
duk_push_string(data->ctx, util_tohex(data->buffer, 32, ILibScratchPad)); // [emit][this]['hash'][hashString]
if (duk_pcall_method(data->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
duk_pop(data->ctx); // ...
duk_pop_2(data->ctx); // ...
}
void ILibDuktape_SHA384_End(struct ILibDuktape_WritableStream *stream, void *user)
{
ILibDuktape_SHA512_Data *data = (ILibDuktape_SHA512_Data*)user;
data->buffer[48] = 0;
SHA384_Final((unsigned char*)data->buffer, &(data->shctx));
duk_push_external_buffer(data->ctx); // [extBuffer]
duk_config_buffer(data->ctx, -1, data->buffer, 48);
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]['hash']
duk_push_buffer_object(data->ctx, -4, 0, 48, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]['hash'][hash]
duk_push_external_buffer(data->ctx); // [extBuffer]
duk_config_buffer(data->ctx, -1, data->buffer, UTIL_SHA384_HASHSIZE);
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]['hash']
duk_push_buffer_object(data->ctx, -4, 0, UTIL_SHA384_HASHSIZE, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]['hash'][hash]
if (duk_pcall_method(data->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
duk_pop_2(data->ctx); // ...
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hashString"); // [emit][this]['hashString']
duk_push_string(data->ctx, util_tohex(data->buffer, 48, ILibScratchPad)); // [emit][this]['hashString'][hashString]
if (duk_pcall_method(data->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
duk_pop(data->ctx); // ...
duk_pop_2(data->ctx); // ...
}
#ifndef MICROSTACK_NOTLS
duk_ret_t ILibDuktape_SHA256_SIGNER_Finalizer(duk_context *ctx)
{
ILibDuktape_SHA256_Signer_Data *data;
@@ -254,11 +254,8 @@ void ILibDuktape_SHA256_SIGNER_PUSH(duk_context *ctx, void *chain)
{
ILibDuktape_SHA256_Signer_Data* data;
duk_push_object(ctx); // [signer]
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_SHA256_Signer_Data)); // [signer][data]
data = (ILibDuktape_SHA256_Signer_Data*)Duktape_GetBuffer(ctx, -1, NULL);
data = (ILibDuktape_SHA256_Signer_Data*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_SHA256_Signer_Data));
duk_put_prop_string(ctx, -2, ILibDuktape_SHA256_SIGNER_PTR); // [signer]
memset(data, 0, sizeof(ILibDuktape_SHA256_Signer_Data));
data->obj = duk_get_heapptr(ctx, -1);
data->ctx = ctx;
ILibDuktape_CreateInstanceMethod(ctx, "Create", ILibDuktape_SHA256_SIGNER_Create, 1);
@@ -267,15 +264,14 @@ void ILibDuktape_SHA256_VERIFY_PUSH(duk_context *ctx, void *chain)
{
ILibDuktape_SHA256_Signer_Data* data;
duk_push_object(ctx); // [signer]
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_SHA256_Signer_Data)); // [signer][data]
data = (ILibDuktape_SHA256_Signer_Data*)Duktape_GetBuffer(ctx, -1, NULL);
data = (ILibDuktape_SHA256_Signer_Data*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_SHA256_Signer_Data));
duk_put_prop_string(ctx, -2, ILibDuktape_SHA256_SIGNER_PTR); // [signer]
memset(data, 0, sizeof(ILibDuktape_SHA256_Signer_Data));
data->obj = duk_get_heapptr(ctx, -1);
data->ctx = ctx;
ILibDuktape_CreateInstanceMethod(ctx, "Create", ILibDuktape_SHA256_VERIFIER_Create, 1);
}
#endif
duk_ret_t ILibDuktape_SHA256_syncHash(duk_context *ctx)
{
ILibDuktape_SHA256_Data *data;
@@ -289,20 +285,11 @@ duk_ret_t ILibDuktape_SHA256_syncHash(duk_context *ctx)
SHA256_Init(&(data->shctx));
SHA256_Update(&(data->shctx), buffer, bufferLen);
SHA256_Final((unsigned char*)data->buffer, &(data->shctx));
data->buffer[32] = 0;
duk_push_current_function(ctx);
duk_get_prop_string(ctx, -1, "strRet");
if (duk_get_boolean(ctx, -1) == 0)
{
duk_push_external_buffer(ctx);
duk_config_buffer(ctx, -1, data->buffer, 32);
}
else
{
util_tohex(data->buffer, 32, ILibScratchPad);
duk_push_string(ctx, ILibScratchPad);
}
duk_push_external_buffer(ctx);
duk_config_buffer(ctx, -1, data->buffer, UTIL_SHA256_HASHSIZE);
duk_push_buffer_object(ctx, -1, 0, UTIL_SHA256_HASHSIZE, DUK_BUFOBJ_NODEJS_BUFFER);
return(1);
}
duk_ret_t ILibDuktape_SHA384_syncHash(duk_context *ctx)
@@ -318,20 +305,11 @@ duk_ret_t ILibDuktape_SHA384_syncHash(duk_context *ctx)
SHA384_Init(&(data->shctx));
SHA384_Update(&(data->shctx), buffer, bufferLen);
SHA384_Final((unsigned char*)data->buffer, &(data->shctx));
data->buffer[48] = 0;
duk_push_current_function(ctx);
duk_get_prop_string(ctx, -1, "strRet");
if (duk_get_boolean(ctx, -1) == 0)
{
duk_push_external_buffer(ctx);
duk_config_buffer(ctx, -1, data->buffer, 48);
}
else
{
util_tohex(data->buffer, 48, ILibScratchPad);
duk_push_string(ctx, ILibScratchPad);
}
duk_push_external_buffer(ctx);
duk_config_buffer(ctx, -1, data->buffer, UTIL_SHA384_HASHSIZE);
duk_push_buffer_object(ctx, -1, 0, UTIL_SHA384_HASHSIZE, DUK_BUFOBJ_NODEJS_BUFFER);
return(1);
}
@@ -345,26 +323,17 @@ ILibTransport_DoneState ILibDuktape_MD5_Write(struct ILibDuktape_WritableStream
void ILibDuktape_MD5_End(struct ILibDuktape_WritableStream *stream, void *user)
{
ILibDuktape_MD5_Data *data = (ILibDuktape_MD5_Data*)user;
data->buffer[32] = 0;
MD5_Final((unsigned char*)data->buffer, &(data->mctx));
duk_push_external_buffer(data->ctx); // [extBuffer]
duk_config_buffer(data->ctx, -1, data->buffer, 32);
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]["hash"]
duk_push_buffer_object(data->ctx, -4, 0, 32, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]["hash"][buffer]
if (duk_pcall_method(data->ctx, 2) != 0) // [retVal]
duk_push_external_buffer(data->ctx); // [extBuffer]
duk_config_buffer(data->ctx, -1, data->buffer, UTIL_MD5_HASHSIZE);
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]["hash"]
duk_push_buffer_object(data->ctx, -4, 0, UTIL_MD5_HASHSIZE, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]["hash"][buffer]
if (duk_pcall_method(data->ctx, 2) != 0) // [extBuffer][retVal]
{
ILibDuktape_Process_UncaughtException(data->ctx);
}
duk_pop_2(data->ctx); // ...
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hashString"); // [emit][this]["hashString"]
duk_push_string(data->ctx, util_tohex(data->buffer, 32, ILibScratchPad)); // [emit][this]["hashString"][hashString]
if (duk_pcall_method(data->ctx, 2) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(data->ctx);
}
duk_pop(data->ctx); // ...
duk_pop_2(data->ctx); // ...
}
duk_ret_t ILibDuktape_MD5_syncHash(duk_context *ctx)
{
@@ -379,20 +348,11 @@ duk_ret_t ILibDuktape_MD5_syncHash(duk_context *ctx)
MD5_Init(&(data->mctx));
MD5_Update(&(data->mctx), buffer, bufferLen);
MD5_Final((unsigned char*)data->buffer, &(data->mctx));
data->buffer[32] = 0;
duk_push_current_function(ctx);
duk_get_prop_string(ctx, -1, "strRet");
if (duk_get_boolean(ctx, -1) == 0)
{
duk_push_external_buffer(ctx);
duk_config_buffer(ctx, -1, data->buffer, 32);
}
else
{
util_tohex(data->buffer, 32, ILibScratchPad);
duk_push_string(ctx, ILibScratchPad);
}
duk_push_external_buffer(ctx);
duk_config_buffer(ctx, -1, data->buffer, UTIL_MD5_HASHSIZE);
duk_push_buffer_object(ctx, -1, 0, UTIL_MD5_HASHSIZE, DUK_BUFOBJ_NODEJS_BUFFER);
return(1);
}
@@ -402,16 +362,14 @@ duk_ret_t ILibDuktape_MD5_Create(duk_context *ctx)
ILibDuktape_EventEmitter *emitter;
duk_push_object(ctx); // [md5]
ILibDuktape_WriteID(ctx, "MD5Stream");
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_MD5_Data)); // [md5][buffer]
data = (ILibDuktape_MD5_Data*)Duktape_GetBuffer(ctx, -1, NULL);
duk_put_prop_string(ctx, -2, ILibDuktape_MD5_PTR); // [md5]
emitter = ILibDuktape_EventEmitter_Create(ctx);
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 0, "syncHash", ILibDuktape_MD5_syncHash, 1);
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 1, "syncHashString", ILibDuktape_MD5_syncHash, 1);
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hash");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hashString");
data->ctx = ctx;
data->object = duk_get_heapptr(ctx, -1);
@@ -426,6 +384,7 @@ duk_ret_t ILibDuktape_SHA256_Create(duk_context *ctx)
ILibDuktape_EventEmitter *emitter;
duk_push_object(ctx); // [sha]
ILibDuktape_WriteID(ctx, "SHA256Stream");
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_SHA256_Data)); // [sha][buffer]
data = (ILibDuktape_SHA256_Data*)Duktape_GetBuffer(ctx, -1, NULL);
duk_put_prop_string(ctx, -2, ILibDuktape_SHA256_PTR); // [sha]
@@ -433,11 +392,8 @@ duk_ret_t ILibDuktape_SHA256_Create(duk_context *ctx)
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_SHA256_Finalizer);
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 0, "syncHash", ILibDuktape_SHA256_syncHash, 1);
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 1, "syncHashString", ILibDuktape_SHA256_syncHash, 1);
ILibDuktape_CreateInstanceMethod(ctx, "syncHash", ILibDuktape_SHA256_syncHash, 1);
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hash");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hashString");
data->ctx = ctx;
data->object = duk_get_heapptr(ctx, -1);
@@ -447,6 +403,70 @@ duk_ret_t ILibDuktape_SHA256_Create(duk_context *ctx)
return(1);
}
ILibTransport_DoneState ILibDuktape_SHA512_Write(struct ILibDuktape_WritableStream *stream, char *buffer, int bufferLen, void *user)
{
ILibDuktape_SHA512_Data *data = (ILibDuktape_SHA512_Data*)user;
SHA512_Update(&(data->shctx), buffer, bufferLen);
return(ILibTransport_DoneState_COMPLETE);
}
void ILibDuktape_SHA512_End(struct ILibDuktape_WritableStream *stream, void *user)
{
ILibDuktape_SHA512_Data *data = (ILibDuktape_SHA512_Data*)user;
SHA512_Final((unsigned char*)data->buffer, &(data->shctx));
duk_push_external_buffer(data->ctx); // [extBuffer]
duk_config_buffer(data->ctx, -1, data->buffer, UTIL_SHA512_HASHSIZE);
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]['hash']
duk_push_buffer_object(data->ctx, -4, 0, UTIL_SHA512_HASHSIZE, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]['hash'][hash]
if (duk_pcall_method(data->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
duk_pop_2(data->ctx); // ...
}
duk_ret_t ILibDuktape_SHA512_syncHash(duk_context *ctx)
{
ILibDuktape_SHA512_Data *data;
duk_size_t bufferLen;
char *buffer = Duktape_GetBuffer(ctx, 0, &bufferLen);
duk_push_this(ctx); // [sha]
duk_get_prop_string(ctx, -1, ILibDuktape_SHA512_PTR);
data = (ILibDuktape_SHA512_Data*)Duktape_GetBuffer(ctx, -1, NULL);
SHA512_Init(&(data->shctx));
SHA512_Update(&(data->shctx), buffer, bufferLen);
SHA512_Final((unsigned char*)data->buffer, &(data->shctx));
duk_push_external_buffer(ctx);
duk_config_buffer(ctx, -1, data->buffer, UTIL_SHA512_HASHSIZE);
duk_push_buffer_object(ctx, -1, 0, UTIL_SHA512_HASHSIZE, DUK_BUFOBJ_NODEJS_BUFFER);
return(1);
}
duk_ret_t ILibDuktape_SHA512_Create(duk_context *ctx)
{
ILibDuktape_SHA512_Data *data;
ILibDuktape_EventEmitter *emitter;
duk_push_object(ctx); // [sha]
ILibDuktape_WriteID(ctx, "SHA512Stream");
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_SHA512_Data)); // [sha][buffer]
data = (ILibDuktape_SHA512_Data*)Duktape_GetBuffer(ctx, -1, NULL);
duk_put_prop_string(ctx, -2, ILibDuktape_SHA512_PTR); // [sha]
emitter = ILibDuktape_EventEmitter_Create(ctx);
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_SHA384_Finalizer);
ILibDuktape_CreateInstanceMethod(ctx, "syncHash", ILibDuktape_SHA512_syncHash, 1);
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hash");
data->ctx = ctx;
data->object = duk_get_heapptr(ctx, -1);
SHA512_Init(&(data->shctx));
ILibDuktape_WritableStream_Init(ctx, ILibDuktape_SHA512_Write, ILibDuktape_SHA512_End, data);
return(1);
}
duk_ret_t ILibDuktape_SHA384_Create(duk_context *ctx)
{
ILibDuktape_SHA512_Data *data;
@@ -461,11 +481,8 @@ duk_ret_t ILibDuktape_SHA384_Create(duk_context *ctx)
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_SHA384_Finalizer);
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 0, "syncHash", ILibDuktape_SHA384_syncHash, 1);
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 1, "syncHashString", ILibDuktape_SHA384_syncHash, 1);
ILibDuktape_CreateInstanceMethod(ctx, "syncHash", ILibDuktape_SHA384_syncHash, 1);
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hash");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hashString");
data->ctx = ctx;
data->object = duk_get_heapptr(ctx, -1);
@@ -475,6 +492,70 @@ duk_ret_t ILibDuktape_SHA384_Create(duk_context *ctx)
return(1);
}
ILibTransport_DoneState ILibDuktape_SHA1_Write(struct ILibDuktape_WritableStream *stream, char *buffer, int bufferLen, void *user)
{
ILibDuktape_SHA1_Data *data = (ILibDuktape_SHA1_Data*)user;
SHA1_Update(&(data->sctx), buffer, bufferLen);
return(ILibTransport_DoneState_COMPLETE);
}
void ILibDuktape_SHA1_End(struct ILibDuktape_WritableStream *stream, void *user)
{
ILibDuktape_SHA1_Data *data = (ILibDuktape_SHA1_Data*)user;
SHA1_Final((unsigned char*)data->buffer, &(data->sctx));
duk_push_external_buffer(data->ctx); // [extBuffer]
duk_config_buffer(data->ctx, -1, data->buffer, UTIL_SHA1_HASHSIZE);
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]["hash"]
duk_push_buffer_object(data->ctx, -4, 0, UTIL_SHA1_HASHSIZE, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]["hash"][buffer]
if (duk_pcall_method(data->ctx, 2) != 0) // [extBuffer][retVal]
{
ILibDuktape_Process_UncaughtException(data->ctx);
}
duk_pop_2(data->ctx); // ...
}
duk_ret_t ILibDuktape_SHA1_syncHash(duk_context *ctx)
{
ILibDuktape_SHA1_Data *data;
duk_size_t bufferLen;
char *buffer = Duktape_GetBuffer(ctx, 0, &bufferLen);
duk_push_this(ctx); // [sha]
duk_get_prop_string(ctx, -1, ILibDuktape_SHA1_PTR);
data = (ILibDuktape_SHA1_Data*)Duktape_GetBuffer(ctx, -1, NULL);
SHA1_Init(&(data->sctx));
SHA1_Update(&(data->sctx), buffer, bufferLen);
SHA1_Final((unsigned char*)data->buffer, &(data->sctx));
duk_push_external_buffer(ctx);
duk_config_buffer(ctx, -1, data->buffer, UTIL_SHA1_HASHSIZE);
duk_push_buffer_object(ctx, -1, 0, UTIL_SHA1_HASHSIZE, DUK_BUFOBJ_NODEJS_BUFFER);
return(1);
}
duk_ret_t ILibDuktape_SHA1_Create(duk_context *ctx)
{
ILibDuktape_SHA1_Data *data;
ILibDuktape_EventEmitter *emitter;
duk_push_object(ctx); // [SHA]
ILibDuktape_WriteID(ctx, "SHA1Stream");
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_SHA1_Data)); // [SHA][buffer]
data = (ILibDuktape_SHA1_Data*)Duktape_GetBuffer(ctx, -1, NULL);
duk_put_prop_string(ctx, -2, ILibDuktape_SHA1_PTR); // [SHA]
emitter = ILibDuktape_EventEmitter_Create(ctx);
ILibDuktape_CreateInstanceMethod(ctx, "syncHash", ILibDuktape_SHA1_syncHash, 1);
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hash");
data->ctx = ctx;
data->object = duk_get_heapptr(ctx, -1);
SHA1_Init(&(data->sctx));
ILibDuktape_WritableStream_Init(ctx, ILibDuktape_SHA1_Write, ILibDuktape_SHA1_End, data);
return(1);
}
void ILibDuktape_SHA256_PUSH(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [sha]
@@ -485,21 +566,34 @@ void ILibDuktape_SHA384_PUSH(duk_context *ctx, void *chain)
duk_push_object(ctx); // [sha]
ILibDuktape_CreateInstanceMethod(ctx, "create", ILibDuktape_SHA384_Create, 0);
}
void ILibDuktape_SHA512_PUSH(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [sha]
ILibDuktape_CreateInstanceMethod(ctx, "create", ILibDuktape_SHA512_Create, 0);
}
void ILibDuktape_MD5_PUSH(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [md5]
ILibDuktape_CreateInstanceMethod(ctx, "create", ILibDuktape_MD5_Create, 0);
}
#endif
void ILibDuktape_SHA1_PUSH(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [md5]
ILibDuktape_CreateInstanceMethod(ctx, "create", ILibDuktape_SHA1_Create, 0);
}
void ILibDuktape_SHA256_Init(duk_context * ctx)
{
#ifndef MICROSTACK_NOTLS
ILibDuktape_ModSearch_AddHandler(ctx, "SHA256Stream_Signer", ILibDuktape_SHA256_SIGNER_PUSH);
ILibDuktape_ModSearch_AddHandler(ctx, "SHA256Stream_Verifier", ILibDuktape_SHA256_VERIFY_PUSH);
#endif
ILibDuktape_ModSearch_AddHandler(ctx, "SHA512Stream", ILibDuktape_SHA512_PUSH);
ILibDuktape_ModSearch_AddHandler(ctx, "SHA384Stream", ILibDuktape_SHA384_PUSH);
ILibDuktape_ModSearch_AddHandler(ctx, "SHA256Stream", ILibDuktape_SHA256_PUSH);
ILibDuktape_ModSearch_AddHandler(ctx, "MD5Stream", ILibDuktape_MD5_PUSH);
#endif
ILibDuktape_ModSearch_AddHandler(ctx, "SHA1Stream", ILibDuktape_SHA1_PUSH);
}
@@ -567,4 +661,4 @@ public:
*/
void hashString;
};
#endif
#endif

View File

@@ -23,4 +23,4 @@ limitations under the License.
void ILibDuktape_SHA256_Init(duk_context *ctx);
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -114,6 +114,7 @@ public:
typedef enum SCRIPT_ENGINE_SECURITY_FLAGS
{
SCRIPT_ENGINE_NO_DEBUGGER = 0x20000000,
SCRIPT_ENGINE_NO_MESH_AGENT_ACCESS = 0x10000000,
SCRIPT_ENGINE_NO_GENERIC_MARSHAL_ACCESS = 0x08000000,
SCRIPT_ENGINE_NO_PROCESS_SPAWNING = 0x04000000,
@@ -140,7 +141,9 @@ typedef struct SCRIPT_ENGINE_SETTINGS
}SCRIPT_ENGINE_SETTINGS;
void ILibDuktape_ScriptContainer_CheckEmbedded(char **argv, char **script, int *scriptLen);
void ILibDuktape_ScriptContainer_CheckEmbedded(char **script, int *scriptLen);
void ILibDuktape_ScriptContainer_CheckEmbeddedEx(char *exePath, char **script, int *scriptLen);
void ILibDuktape_ScriptContainer_InitMaster(void *chain, char *exePath, ILibProcessPipe_Manager manager);
int ILibDuktape_ScriptContainer_StartSlave(void *chain, ILibProcessPipe_Manager manager);
@@ -149,12 +152,12 @@ duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx3(duk_conte
duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx2(SCRIPT_ENGINE_SETTINGS *settings);
#define ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx(securityFlags, executionTimeout, chain, argList, db, exePath, pipeManager, exitHandler, exitUser) ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx3(ILibDuktape_ScriptContainer_InitializeJavaScriptEngine_minimal(), (securityFlags), (executionTimeout), (chain), (argList), (db), (exePath), (pipeManager), (exitHandler), (exitUser))
#define ILibDuktape_ScriptContainer_InitializeJavaScriptEngine(securityFlags, executionTimeout, chain, pp_argList, db, exitHandler, exitUser) ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx((securityFlags), (executionTimeout), (chain), (pp_argList), (db), NULL, NULL, (exitHandler), (exitUser))
int ILibDuktape_ScriptContainer_DebuggingOK(duk_context *ctx);
SCRIPT_ENGINE_SETTINGS *ILibDuktape_ScriptContainer_GetSettings(duk_context *ctx);
int ILibDuktape_ScriptContainer_CompileJavaScript(duk_context *ctx, char *payload, int payloadLen);
int ILibDuktape_ScriptContainer_CompileJavaScript_FromFile(duk_context *ctx, char *path, int pathLen);
int ILibDuktape_ScriptContainer_CompileJavaScriptEx(duk_context *ctx, char *payload, int payloadLen, char *filename, int filenameLen);
#define ILibDuktape_ScriptContainer_CompileJavaScript(ctx, payload, payloadLen) ILibDuktape_ScriptContainer_CompileJavaScriptEx(ctx, payload, payloadLen, NULL, 0)
int ILibDuktape_ScriptContainer_ExecuteByteCode(duk_context *ctx);
#endif

View File

@@ -125,6 +125,10 @@ duk_ret_t ILibDuktape_SimpleDataStore_Get(duk_context *ctx)
duk_push_string(ctx, buffer);
}
}
else
{
duk_push_buffer_object(ctx, -1, 0, bufferSize, DUK_BUFOBJ_NODEJS_BUFFER);
}
}
return 1;
@@ -295,4 +299,4 @@ public:
*/
static SimpleDataStore Shared();
};
#endif
#endif

View File

@@ -24,4 +24,4 @@ limitations under the License.
void ILibDuktape_SimpleDataStore_init(duk_context *ctx, ILibSimpleDataStore sharedDb);
#endif
#endif

View File

@@ -91,9 +91,9 @@ duk_idx_t ILibWebRTC_Duktape_Connection_AddRemoteCandidate(duk_context *ctx)
if (strcmp(Duktape_GetStringPropertyValue(ctx, 0, "Family", "IPv4"), "IPv4") == 0)
{
candidate = Duktape_IPAddress4_FromString(Duktape_GetStringPropertyValue(ctx, 0, "Address", "127.0.0.1"), (unsigned short)Duktape_GetIntPropertyValue(ctx, 0, "Port", 65535));
username = ILibWrapper_WebRTC_Connection_GetLocalUsername(connection);
ILibORTC_AddRemoteCandidate(ILibWrapper_WebRTC_Connection_GetStunModule(connection), username, candidate);
}
username = ILibWrapper_WebRTC_Connection_GetLocalUsername(connection);
ILibORTC_AddRemoteCandidate(ILibWrapper_WebRTC_Connection_GetStunModule(connection), username, candidate);
return 0;
}
@@ -115,7 +115,7 @@ ILibTransport_DoneState ILibDuktape_WebRTC_DataChannel_Stream_WriteSink(ILibDukt
ILibDuktape_WebRTC_DataChannel *ptrs = (ILibDuktape_WebRTC_DataChannel*)user;
if (ptrs->dataChannel != NULL)
{
return(ILibWrapper_WebRTC_DataChannel_Send(ptrs->dataChannel, buffer, bufferLen));
return(ILibWrapper_WebRTC_DataChannel_SendEx(ptrs->dataChannel, buffer, bufferLen, stream->writableStream->Reserved == 1 ? 51 : 53));
}
else
{
@@ -174,7 +174,7 @@ duk_ret_t ILibDuktape_WebRTC_DataChannel_Finalizer(duk_context *ctx)
ILibDuktape_WebRTC_DataChannel *ptrs = (ILibDuktape_WebRTC_DataChannel*)Duktape_GetBuffer(ctx, -1, NULL);
if (ptrs->dataChannel != NULL)
{
printf("WebRTC Data Channel Finalizer on Connection: %p\n", ptrs->dataChannel->parent);
//printf("WebRTC Data Channel Finalizer on Connection: %p\n", ptrs->dataChannel->parent);
ptrs->dataChannel->userData = NULL;
ILibWrapper_WebRTC_DataChannel_Close(ptrs->dataChannel);
}
@@ -221,7 +221,7 @@ duk_ret_t ILibDuktape_WebRTC_ConnectionFactory_Finalizer(duk_context *ctx)
duk_get_prop_string(ctx, 0, ILibDuktape_WebRTC_ConnectionFactoryPtr);
factory = (ILibWrapper_WebRTC_ConnectionFactory)duk_get_pointer(ctx, -1);
printf("WebRTC Factory Finalizer: %p\n", factory);
//printf("WebRTC Factory Finalizer: %p\n", factory);
if (factory != NULL && ILibIsChainBeingDestroyed(chain) == 0)
{
@@ -299,7 +299,9 @@ void ILibDuktape_WebRTC_Connection_Debug(void* dtlsSession, char* debugField, in
#endif
void ILibDuktape_WebRTC_OnConnection(ILibWrapper_WebRTC_Connection connection, int connected)
{
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_GetExtraMemory(connection, ILibMemory_WebRTC_Connection_CONTAINERSIZE);
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_Extra(connection);
if (!ILibMemory_CanaryOK(ptrs->emitter)) { return; }
if (connected == 0)
{
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "disconnected"); // [emit][this][disconnected]
@@ -348,23 +350,28 @@ void ILibDuktape_WebRTC_OnConnection(ILibWrapper_WebRTC_Connection connection, i
void ILibDuktape_WebRTC_OnDataChannel(ILibWrapper_WebRTC_Connection connection, ILibWrapper_WebRTC_DataChannel *dataChannel)
{
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_GetExtraMemory(connection, ILibMemory_WebRTC_Connection_CONTAINERSIZE);
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "dataChannel"); // [emit][this][dataChannel]
ILibDuktape_WebRTC_DataChannel_PUSH(ptrs->ctx, dataChannel); // [emit][this][dataChannel][dc]
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.connection.onDataChannel(): "); }
duk_pop(ptrs->ctx); // ...
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_Extra(connection);
if (ILibMemory_CanaryOK(ptrs->emitter))
{
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "dataChannel"); // [emit][this][dataChannel]
ILibDuktape_WebRTC_DataChannel_PUSH(ptrs->ctx, dataChannel); // [emit][this][dataChannel][dc]
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.connection.onDataChannel(): "); }
duk_pop(ptrs->ctx); // ...
}
}
void ILibDuktape_WebRTC_offer_onCandidate(ILibWrapper_WebRTC_Connection connection, struct sockaddr_in6* candidate)
{
if (candidate != NULL)
{
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_GetExtraMemory(connection, ILibMemory_WebRTC_Connection_CONTAINERSIZE);
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "candidate"); // [emit][this][candidate]
ILibDuktape_SockAddrToOptions(ptrs->ctx, candidate); // [emit][this][candidate][options]
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.connection.onCandidate(): "); }
duk_pop(ptrs->ctx); // ...
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_Extra(connection);
if (ILibMemory_CanaryOK(ptrs->emitter))
{
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "candidate"); // [emit][this][candidate]
ILibDuktape_SockAddrToOptions(ptrs->ctx, candidate); // [emit][this][candidate][options]
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.connection.onCandidate(): "); }
duk_pop(ptrs->ctx); // ...
}
}
}
duk_ret_t ILibDuktape_WebRTC_generateOffer(duk_context *ctx)
@@ -468,7 +475,7 @@ duk_ret_t ILibDuktape_WebRTC_Connection_Finalizer(duk_context *ctx)
ILibWrapper_WebRTC_Connection connection;
duk_get_prop_string(ctx, 0, ILibDuktape_WebRTC_ConnectionPtr);
connection = (ILibWrapper_WebRTC_Connection)duk_get_pointer(ctx, -1);
printf("WebRTCConnection Finalizer on %p\n", (void*)connection);
//printf("WebRTCConnection Finalizer on %p\n", (void*)connection);
if (connection == NULL) { return 0; }
#ifdef _WEBRTCDEBUG
@@ -495,7 +502,7 @@ duk_ret_t ILibDuktape_WebRTC_CreateConnection(duk_context *ctx)
duk_push_object(ctx); // [factory][connection]
ILibDuktape_WriteID(ctx, "webRTC.peerConnection");
connection = ILibWrapper_WebRTC_ConnectionFactory_CreateConnection2(factory, ILibDuktape_WebRTC_OnConnection, ILibDuktape_WebRTC_OnDataChannel, NULL, sizeof(ILibWebRTC_Duktape_Handlers));
ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_GetExtraMemory(connection, ILibMemory_WebRTC_Connection_CONTAINERSIZE);
ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_Extra(connection);
ptrs->ctx = ctx;
ptrs->ConnectionObject = duk_get_heapptr(ctx, -1);
ptrs->emitter = ILibDuktape_EventEmitter_Create(ctx);
@@ -645,4 +652,4 @@ public:
void ack;
};
};
#endif
#endif

View File

@@ -304,12 +304,8 @@ ILibDuktape_WritableStream* ILibDuktape_WritableStream_Init(duk_context *ctx, IL
ILibDuktape_WritableStream *retVal;
ILibDuktape_EventEmitter *emitter;
ILibDuktape_PointerValidation_Init(ctx);
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_WritableStream)); // [obj][buffer]
retVal = (ILibDuktape_WritableStream*)Duktape_GetBuffer(ctx, -1, NULL); // [obj][buffer]
memset(retVal, 0, sizeof(ILibDuktape_WritableStream));
duk_put_prop_string(ctx, -2, ILibDuktape_WritableStream_WSPTRS); // [obj]
retVal = (ILibDuktape_WritableStream*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_WritableStream)); // [obj][buffer]
duk_put_prop_string(ctx, -2, ILibDuktape_WritableStream_WSPTRS); // [obj]
retVal->ctx = ctx;
retVal->obj = duk_get_heapptr(ctx, -1);

View File

@@ -55,5 +55,4 @@ typedef struct ILibDuktape_WritableStream
ILibDuktape_WritableStream* ILibDuktape_WritableStream_Init(duk_context *ctx, ILibDuktape_WritableStream_WriteHandler WriteHandler, ILibDuktape_WritableStream_EndHandler EndHandler, void *user);
void ILibDuktape_WritableStream_Ready(ILibDuktape_WritableStream *stream);
#endif
#endif

View File

@@ -20,6 +20,7 @@ limitations under the License.
#include <winsock2.h>
#include <ws2tcpip.h>
#include <direct.h>
#include <wchar.h>
#endif
#include "microstack/ILibParsers.h"
@@ -88,6 +89,7 @@ typedef struct ILibDuktape_fs_readStreamData
int bytesRead;
int bytesLeft;
int readLoopActive;
int unshiftedBytes;
char buffer[FS_READSTREAM_BUFFERSIZE];
}ILibDuktape_fs_readStreamData;
@@ -194,7 +196,7 @@ int ILibDuktape_fs_openSyncEx(duk_context *ctx, char *path, char *flags, char *m
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "%d", retVal);
#ifdef WIN32
fopen_s(&f, path, flags);
_wfopen_s(&f, (const wchar_t*)ILibDuktape_String_UTF8ToWide(ctx, path), (const wchar_t*)ILibDuktape_String_UTF8ToWide(ctx, flags));
#else
f = fopen(path, flags);
#endif
@@ -439,6 +441,8 @@ void ILibDuktape_fs_readStream_Pause(struct ILibDuktape_readableStream *sender,
}
void ILibDuktape_fs_readStream_Resume(struct ILibDuktape_readableStream *sender, void *user)
{
if (!ILibMemory_CanaryOK(user)) { return; }
ILibDuktape_fs_readStreamData *data = (ILibDuktape_fs_readStreamData*)user;
int bytesToRead;
@@ -447,14 +451,22 @@ void ILibDuktape_fs_readStream_Resume(struct ILibDuktape_readableStream *sender,
sender->paused = 0;
if (data->bytesRead == -1) { data->bytesRead = 1; }
data->unshiftedBytes = 0;
while (sender->paused == 0 && data->bytesRead > 0 && (data->bytesLeft < 0 || data->bytesLeft > 0))
{
bytesToRead = data->bytesLeft < 0 ? sizeof(data->buffer) : (data->bytesLeft > sizeof(data->buffer) ? sizeof(data->buffer) : data->bytesLeft);
data->bytesRead = (int)fread(data->buffer, 1, bytesToRead, data->fPtr);
bytesToRead = data->bytesLeft < 0 ? (int)sizeof(data->buffer) : (data->bytesLeft > ((int)sizeof(data->buffer) - data->unshiftedBytes) ? (int)sizeof(data->buffer) - data->unshiftedBytes : data->bytesLeft);
data->bytesRead = (int)fread(data->buffer + data->unshiftedBytes, 1, bytesToRead, data->fPtr);
if (data->bytesRead > 0)
{
if (data->bytesLeft > 0) { data->bytesLeft -= data->bytesRead; }
ILibDuktape_readableStream_WriteData(sender, data->buffer, data->bytesRead);
data->bytesRead += data->unshiftedBytes; data->unshiftedBytes = 0;
do
{
int preshift = data->unshiftedBytes == 0 ? data->bytesRead : data->unshiftedBytes;
ILibDuktape_readableStream_WriteData(sender, data->buffer, data->unshiftedBytes>0 ? data->unshiftedBytes : data->bytesRead);
if (data->unshiftedBytes > 0 && data->unshiftedBytes != preshift) { memmove(data->buffer, data->buffer + (preshift - data->unshiftedBytes), data->unshiftedBytes); }
} while (data->unshiftedBytes != 0 && data->unshiftedBytes != data->bytesRead);
data->unshiftedBytes = 0;
if (data->bytesLeft == 0) { data->bytesRead = 0; }
}
}
@@ -502,6 +514,13 @@ duk_ret_t ILibDuktape_fs_readStream_finalizer(duk_context *ctx)
return 0;
}
int ILibDuktape_fs_readStream_unshift(struct ILibDuktape_readableStream *sender, int unshiftBytes, void *user)
{
if (!ILibMemory_CanaryOK(user)) { return(unshiftBytes); }
ILibDuktape_fs_readStreamData *data = (ILibDuktape_fs_readStreamData*)user;
data->unshiftedBytes = unshiftBytes;
return(unshiftBytes);
}
duk_ret_t ILibDuktape_fs_createReadStream(duk_context *ctx)
{
int nargs = duk_get_top(ctx);
@@ -545,9 +564,7 @@ duk_ret_t ILibDuktape_fs_createReadStream(duk_context *ctx)
duk_push_object(ctx); // [readStream]
ILibDuktape_WriteID(ctx, "fs.readStream");
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_fs_readStreamData)); // [readStream][buffer]
data = (ILibDuktape_fs_readStreamData*)Duktape_GetBuffer(ctx, -1, NULL);
memset(data, 0, sizeof(ILibDuktape_fs_readStreamData));
data = (ILibDuktape_fs_readStreamData*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_fs_readStreamData));
duk_put_prop_string(ctx, -2, FS_READSTREAM); // [readStream]
duk_push_this(ctx); // [readStream][fs]
data->fsObject = duk_get_heapptr(ctx, -1);
@@ -560,7 +577,8 @@ duk_ret_t ILibDuktape_fs_createReadStream(duk_context *ctx)
data->ReadStreamObject = duk_get_heapptr(ctx, -1);
data->bytesLeft = end < 0 ? end : (end - start + 1);
data->bytesRead = -1;
data->stream = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_fs_readStream_Pause, ILibDuktape_fs_readStream_Resume, data);
//data->stream = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_fs_readStream_Pause, ILibDuktape_fs_readStream_Resume, data);
data->stream = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_fs_readStream_Pause, ILibDuktape_fs_readStream_Resume, ILibDuktape_fs_readStream_unshift, data);
data->stream->paused = 1;
//printf("readStream [start: %d, end: %d\n", start, end);
@@ -591,8 +609,11 @@ duk_ret_t ILibDuktape_fs_readdirSync(duk_context *ctx)
int i = 0;
#ifdef WIN32
HANDLE h;
WIN32_FIND_DATA data;
char *path = (char*)duk_require_string(ctx, 0);
WIN32_FIND_DATAW data;
duk_size_t pathLen;
char *path = (char*)ILibDuktape_String_AsWide(ctx, 0, &pathLen);
//char *path = (char*)duk_require_string(ctx, 0);
#else
char *path = ILibDuktape_fs_fixLinuxPath((char*)duk_require_string(ctx, 0));
struct dirent *dir;
@@ -602,20 +623,22 @@ duk_ret_t ILibDuktape_fs_readdirSync(duk_context *ctx)
duk_push_array(ctx); // [retVal]
#ifdef WIN32
h = FindFirstFile(path, &data);
h = FindFirstFileW((LPCWSTR)path, &data);
if (h != INVALID_HANDLE_VALUE)
{
if (strcmp(data.cFileName, ".") != 0)
if (wcscmp(data.cFileName, L".") != 0)
{
duk_push_string(ctx, data.cFileName); // [retVal][val]
ILibDuktape_String_PushWideString(ctx, (char*)data.cFileName, 0); // [retVal][val]
//duk_push_string(ctx, data.cFileName); // [retVal][val]
duk_put_prop_index(ctx, -2, i++); // [retVal]
}
while (FindNextFile(h, &data))
while (FindNextFileW(h, &data))
{
if (strcmp(data.cFileName, "..") != 0)
if (wcscmp(data.cFileName, L"..") != 0)
{
duk_push_string(ctx, data.cFileName); // [retVal][val]
duk_put_prop_index(ctx, -2, i++); // [retVal]
ILibDuktape_String_PushWideString(ctx, (char*)data.cFileName, 0); // [retVal][val]
//duk_push_string(ctx, data.cFileName); // [retVal][val]
duk_put_prop_index(ctx, -2, i++); // [retVal]
}
}
FindClose(h);
@@ -627,8 +650,11 @@ duk_ret_t ILibDuktape_fs_readdirSync(duk_context *ctx)
{
while ((dir = readdir(d)) != NULL)
{
duk_push_string(ctx, dir->d_name);
duk_put_prop_index(ctx, -2, i++);
if (strcmp(dir->d_name, ".") != 0 && strcmp(dir->d_name, "..") != 0)
{
duk_push_string(ctx, dir->d_name);
duk_put_prop_index(ctx, -2, i++);
}
}
closedir(d);
}
@@ -671,13 +697,13 @@ char *ILibDuktape_fs_convertTime(uint64_t st, char *dest, int destLen)
duk_ret_t ILibDuktape_fs_statSync(duk_context *ctx)
{
#ifdef WIN32
char *path = (char*)duk_require_string(ctx, 0);
#ifdef WIN32
char *path = ILibDuktape_String_AsWide(ctx, 0, NULL);
char data[4096];
WIN32_FILE_ATTRIBUTE_DATA *attr = (WIN32_FILE_ATTRIBUTE_DATA*)data;
SYSTEMTIME stime;
if(GetFileAttributesEx(path, GetFileExInfoStandard, (void*)data) == 0)
if(GetFileAttributesExW((LPCWSTR)path, GetFileExInfoStandard, (void*)data) == 0)
{
duk_push_string(ctx, "fs.statSync(): Invalid path");
duk_throw(ctx);
@@ -726,6 +752,9 @@ duk_ret_t ILibDuktape_fs_statSync(duk_context *ctx)
duk_push_string(ctx, ILibDuktape_fs_convertTime(result.st_atime, ILibScratchPad, sizeof(ILibScratchPad)));
duk_put_prop_string(ctx, -2, "atime");
duk_push_int(ctx, result.st_mode);
ILibDuktape_CreateReadonlyProperty(ctx, "mode");
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, FS_STAT_METHOD_RETVAL, S_ISDIR(result.st_mode) || S_ISBLK(result.st_mode) ? 1 : 0, "isDirectory", ILibDuktape_fs_statSyncEx, 0);
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, FS_STAT_METHOD_RETVAL, S_ISREG(result.st_mode) ? 1 : 0, "isFile", ILibDuktape_fs_statSyncEx, 0);
@@ -1093,10 +1122,8 @@ duk_ret_t ILibDuktape_fs_watch(duk_context *ctx)
duk_push_object(ctx); // [FSWatcher]
ILibDuktape_WriteID(ctx, "fs.fsWatcher");
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_fs_watcherData)); // [FSWatcher][data]
data = (ILibDuktape_fs_watcherData*)Duktape_GetBuffer(ctx, -1, NULL);
data = (ILibDuktape_fs_watcherData*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_fs_watcherData));
duk_put_prop_string(ctx, -2, FS_WATCHER_DATA_PTR); // [FSWatcher]
memset(data, 0, sizeof(ILibDuktape_fs_watcherData));
data->emitter = ILibDuktape_EventEmitter_Create(ctx);
data->ctx = ctx;
@@ -1156,7 +1183,11 @@ duk_ret_t ILibDuktape_fs_rename(duk_context *ctx)
char *oldPath = (char*)duk_require_string(ctx, 0);
char *newPath = (char*)duk_require_string(ctx, 1);
#ifdef WIN32
if (_wrename((LPCWSTR)ILibDuktape_String_UTF8ToWide(ctx, oldPath), (LPCWSTR)ILibDuktape_String_UTF8ToWide(ctx, newPath)) != 0)
#else
if (rename(oldPath, newPath) != 0)
#endif
{
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "fs.renameSync(): Error renaming %s to %s", oldPath, newPath);
duk_push_string(ctx, ILibScratchPad);
@@ -1168,16 +1199,21 @@ duk_ret_t ILibDuktape_fs_rename(duk_context *ctx)
duk_ret_t ILibDuktape_fs_unlink(duk_context *ctx)
{
#ifdef WIN32
char *path = (char*)duk_require_string(ctx, 0);
char *path = ILibDuktape_String_AsWide(ctx, 0, NULL);
#else
char *path = ILibDuktape_fs_fixLinuxPath((char*)duk_require_string(ctx, 0));
#endif
#ifdef WIN32
if(_wremove((const wchar_t*)path) != 0)
#else
if (remove(path) != 0)
#endif
{
#ifdef WIN32
if (RemoveDirectory(path) != 0) { return 0; }
if (RemoveDirectoryW((LPCWSTR)path) != 0) { return 0; }
#endif
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "fs.unlinkSync(): Error trying to unlink: %s", path);
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "fs.unlinkSync(): Error trying to unlink: %s", ILibDuktape_String_WideToUTF8(ctx, path));
duk_push_string(ctx, ILibScratchPad);
duk_throw(ctx);
return(DUK_RET_ERROR);
@@ -1189,16 +1225,15 @@ duk_ret_t ILibDuktape_fs_mkdirSync(duk_context *ctx)
//int nargs = duk_get_top(ctx);
#ifdef WIN32
char *path = (char*)duk_require_string(ctx, 0);
if (_mkdir(path) != 0)
char *path = ILibDuktape_String_AsWide(ctx, 0, NULL);
ILibDuktape_String_WideToUTF8(ctx, path);
if (_wmkdir((const wchar_t*)path) != 0)
#else
char *path = ILibDuktape_fs_fixLinuxPath((char*)duk_require_string(ctx, 0));
if (mkdir(path, 0777) != 0)
#endif
{
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "fs.mkdirSync(): Unable to create dir: %s", path);
duk_throw(ctx);
return(DUK_RET_ERROR);
return(ILibDuktape_Error(ctx, "fs.mkdirSync(): Unable to create dir: %s", ILibDuktape_String_WideToUTF8(ctx, path)));
}
return 0;
}
@@ -1209,9 +1244,20 @@ duk_ret_t ILibDuktape_fs_readFileSync(duk_context *ctx)
long fileLen;
#ifdef WIN32
fopen_s(&f, filePath, "rbN");
char *flags = "rbN";
#else
f = fopen(filePath, "rb");
char *flags = "rb";
#endif
if (duk_is_object(ctx, 1))
{
flags = Duktape_GetStringPropertyValue(ctx, 1, "flags", flags);
}
#ifdef WIN32
_wfopen_s(&f, (const wchar_t*)ILibDuktape_String_UTF8ToWide(ctx, filePath), (const wchar_t*)ILibDuktape_String_UTF8ToWide(ctx, flags));
#else
f = fopen(filePath, flags);
#endif
if (f == NULL) { return(ILibDuktape_Error(ctx, "fs.readFileSync(): File [%s] not found", filePath)); }
@@ -1219,11 +1265,31 @@ duk_ret_t ILibDuktape_fs_readFileSync(duk_context *ctx)
fseek(f, 0, SEEK_END);
fileLen = ftell(f);
fseek(f, 0, SEEK_SET);
duk_push_fixed_buffer(ctx, (duk_size_t)fileLen);
ignore_result(fread(Duktape_GetBuffer(ctx, -1, NULL), 1, (size_t)fileLen, f));
fclose(f);
duk_push_buffer_object(ctx, -1, 0, (duk_size_t)fileLen, DUK_BUFOBJ_NODEJS_BUFFER);
if(fileLen > 0)
{
duk_push_fixed_buffer(ctx, (duk_size_t)fileLen);
ignore_result(fread(Duktape_GetBuffer(ctx, -1, NULL), 1, (size_t)fileLen, f));
fclose(f);
duk_push_buffer_object(ctx, -1, 0, (duk_size_t)fileLen, DUK_BUFOBJ_NODEJS_BUFFER);
}
else
{
duk_size_t bufferSize = 1024;
char *buffer = (char*)duk_push_dynamic_buffer(ctx, bufferSize); // [dynamicBuffer]
size_t bytesRead = 0;
size_t len = 0;
while ((bytesRead = fread(buffer + len, 1, 1024, f)) > 0)
{
len += bytesRead;
if (bytesRead == 1024)
{
buffer = duk_resize_buffer(ctx, -1, bufferSize + 1024);
bufferSize += 1024;
}
}
fclose(f);
duk_push_buffer_object(ctx, -1, 0, (duk_size_t)len, DUK_BUFOBJ_NODEJS_BUFFER);
}
return(1);
}
@@ -1243,6 +1309,19 @@ duk_ret_t ILibDuktape_fs_existsSync(duk_context *ctx)
}
return(1);
}
#ifdef _POSIX
duk_ret_t ILibduktape_fs_chmodSync(duk_context *ctx)
{
if(chmod((char*)duk_require_string(ctx, 0), (mode_t)duk_require_int(ctx, 1)) != 0)
{
return(ILibDuktape_Error(ctx, "Error calling chmod()"));
}
else
{
return(0);
}
}
#endif
void ILibDuktape_fs_PUSH(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [fs]
@@ -1267,6 +1346,9 @@ void ILibDuktape_fs_PUSH(duk_context *ctx, void *chain)
ILibDuktape_CreateInstanceMethod(ctx, "readDrivesSync", ILibDuktape_fs_readDrivesSync, 0);
ILibDuktape_CreateInstanceMethod(ctx, "readFileSync", ILibDuktape_fs_readFileSync, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "existsSync", ILibDuktape_fs_existsSync, 1);
#ifdef _POSIX
ILibDuktape_CreateInstanceMethod(ctx, "chmodSync", ILibduktape_fs_chmodSync, 2);
#endif
#ifndef _NOFSWATCHER
ILibDuktape_CreateInstanceMethod(ctx, "watch", ILibDuktape_fs_watch, DUK_VARARGS);
#endif
@@ -1275,6 +1357,41 @@ void ILibDuktape_fs_PUSH(duk_context *ctx, void *chain)
ILibDuktape_CreateInstanceMethod(ctx, "mkdirSync", ILibDuktape_fs_mkdirSync, DUK_VARARGS);
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_fs_Finalizer);
char copyFile[] = "exports.copyFile = function copyFile(src, dest)\
{\
var ss = this.createReadStream(src, {flags: 'rb'});\
var ds = this.createWriteStream(dest, {flags: 'wb'});\
ss.fs = this;\
ss.pipe(ds);\
ds.ss = ss;\
if(!this._copyStreams){this._copyStreams = {};this._copyStreamID = 0;}\
ss.id = this._copyStreamID++;\
this._copyStreams[ss.id] = ss;\
if(arguments.length == 3 && typeof arguments[2] === 'function')\
{\
ds.on('close', arguments[2]);\
}\
else if(arguments.length == 4 && typeof arguments[3] === 'function')\
{\
ds.on('close', arguments[3]);\
}\
ds.on('close', function onCopyFileDone(){delete this.ss.fs._copyStreams[this.ss.id];});\
};\
exports.copyFileSync = function copyFileSync(src, dest)\
{\
var buffer = this.readFileSync(src, {flags: 'rb'});\
this.writeFileSync(dest, buffer, {flags: 'wb'});\
};\
exports.writeFileSync = function writeFileSync(dest, data, options)\
{\
var fd = this.openSync(dest, options?options.flags:'wb');\
this.writeSync(fd, data);\
this.closeSync(fd);\
};\
exports.CHMOD_MODES = {S_IRUSR: 0o400, S_IWUSR: 0o200, S_IXUSR: 0o100, S_IRGRP: 0o40, S_IWGRP: 0o20, S_IXGRP: 0o10, S_IROTH: 0o4, S_IWOTH: 0o2, S_IXOTH: 0o1};\
";
ILibDuktape_ModSearch_AddHandler_AlsoIncludeJS(ctx, copyFile, sizeof(copyFile) - 1);
}
void ILibDuktape_fs_init(duk_context * ctx)
@@ -1452,4 +1569,4 @@ public:
void close();
};
};
#endif
#endif

View File

@@ -22,4 +22,4 @@ limitations under the License.
void ILibDuktape_fs_init(duk_context *ctx);
#endif
#endif

View File

@@ -24,6 +24,7 @@ limitations under the License.
#define DIGEST_USERNAME "\xFF_DigestUsername"
#define DIGEST_PASSWORD "\xFF_DigestPassword"
#define DIGEST_AUTHTOKEN "\xFF_DigestAuthToken"
#define HTTP_DIGEST "\xFF_HTTP_DIGEST"
#define DIGEST_CLIENT_REQUEST "\xFF_DIGEST_CLIENT_REQUEST"
#define HTTP_CLIENTREQUEST_DATAPTR "\xFF_CLIENTREQUEST_DATAPTR"
@@ -158,8 +159,10 @@ char *ILibDuktape_httpDigest_generateAuthenticationHeader(duk_context *ctx, void
wwwauth = (char*)Duktape_GetStringPropertyValueEx(ctx, -1, DIGEST2WWWAUTH, NULL, &wwwauthLen);
username = (char*)Duktape_GetStringPropertyValue(ctx, -1, DIGEST_USERNAME, NULL);
password = (char*)Duktape_GetStringPropertyValue(ctx, -1, DIGEST_PASSWORD, NULL);
if (wwwauth == NULL || username == NULL || password == NULL) { duk_pop(ctx); return(NULL); }
if (!duk_has_prop_string(ctx, -1, DIGEST_AUTHTOKEN))
{
if (wwwauth == NULL || username == NULL || password == NULL) { duk_pop(ctx); return(NULL); }
}
duk_push_heapptr(ctx, optionsObj); // [digest][options]
method = (char*)Duktape_GetStringPropertyValue(ctx, -1, "method", NULL);
path = (char*)Duktape_GetStringPropertyValue(ctx, -1, "path", NULL);
@@ -174,9 +177,24 @@ char *ILibDuktape_httpDigest_generateAuthenticationHeader(duk_context *ctx, void
ILibGetEntryEx(table, "opaque", 6, (void**)&opaque, &opaqueLen); if (opaqueLen > 0) { opaque[opaqueLen] = 0; }
ILibGetEntryEx(table, "qop", 3, (void**)&qop, &qopLen); if (qopLen > 0) { qop[qopLen] = 0; }
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s:%s:%s", username, realm, password);
util_md5hex(ILibScratchPad2, tmpLen, result1);
if (duk_has_prop_string(ctx, -1, DIGEST_AUTHTOKEN))
{
duk_size_t authTokenLen;
char *authToken = Duktape_GetStringPropertyValueEx(ctx, -1, DIGEST_AUTHTOKEN, NULL, &authTokenLen);
if (authTokenLen < sizeof(result1))
{
memcpy_s(result1, sizeof(result1), authToken, authTokenLen);
result1[32] = 0;
username = "admin";
tmpLen = (int)authTokenLen;
}
}
else
{
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s:%s:%s", username, realm, password);
util_md5hex(ILibScratchPad2, tmpLen, result1);
}
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s:%s", method, path);
util_md5hex(ILibScratchPad2, tmpLen, result2);
@@ -325,6 +343,11 @@ duk_ret_t ILibDuktape_httpDigest_clientRequest_response(duk_context *ctx)
else
{
duk_push_heapptr(ctx, digestClientPtr); // [digestClientRequest]
duk_del_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST);
duk_push_this(ctx);
duk_del_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST);
duk_pop(ctx);
duk_get_prop_string(ctx, -1, "emit"); // [digestClientRequest][emit]
duk_swap_top(ctx, -2); // [emit][this]
duk_push_string(ctx, "response"); // [emit][this][response]
@@ -579,9 +602,18 @@ duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx)
}
duk_ret_t ILibduktape_httpDigest_create(duk_context *ctx)
{
duk_size_t usernameLen, passwordLen;
char *username = (char*)duk_require_lstring(ctx, 0, &usernameLen), *password = (char*)duk_require_lstring(ctx, 1, &passwordLen);
duk_size_t usernameLen, passwordLen, authTokenLen;
ILibDuktape_EventEmitter *emitter;
char *username = NULL, *password = NULL, *authToken = NULL;
if (duk_get_top(ctx) == 1 && duk_is_object(ctx, 0))
{
if ((authToken = Duktape_GetStringPropertyValueEx(ctx, 0, "authToken", NULL, &authTokenLen)) == NULL) { return(ILibDuktape_Error(ctx, "authToken Required")); }
}
else
{
username = (char*)duk_require_lstring(ctx, 0, &usernameLen), password = (char*)duk_require_lstring(ctx, 1, &passwordLen);
}
duk_push_object(ctx); // [obj]
ILibDuktape_WriteID(ctx, "httpDigest");
@@ -593,10 +625,19 @@ duk_ret_t ILibduktape_httpDigest_create(duk_context *ctx)
ILibDuktape_EventEmitter_CreateEventEx(emitter, "upgrade");
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "isGet", 1, "get", ILibDuktape_httpDigest_http_request, DUK_VARARGS);
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "isGet", 0, "request", ILibDuktape_httpDigest_http_request, DUK_VARARGS);
duk_push_string(ctx, username);
duk_put_prop_string(ctx, -2, DIGEST_USERNAME);
duk_push_string(ctx, password);
duk_put_prop_string(ctx, -2, DIGEST_PASSWORD);
if (authToken == NULL)
{
duk_push_string(ctx, username);
duk_put_prop_string(ctx, -2, DIGEST_USERNAME);
duk_push_string(ctx, password);
duk_put_prop_string(ctx, -2, DIGEST_PASSWORD);
}
else
{
duk_push_lstring(ctx, authToken, authTokenLen);
duk_put_prop_string(ctx, -2, DIGEST_AUTHTOKEN);
}
duk_push_fixed_buffer(ctx, 16);
util_randomtext(16, (char*)Duktape_GetBuffer(ctx, -1, NULL));
((char*)Duktape_GetBuffer(ctx, -1, NULL))[15] = 0;
@@ -610,7 +651,7 @@ duk_ret_t ILibduktape_httpDigest_create(duk_context *ctx)
void ILibDuktape_httpDigest_PUSH(duk_context *ctx, void *chain)
{
duk_push_object(ctx);
ILibDuktape_CreateInstanceMethod(ctx, "create", ILibduktape_httpDigest_create, 2);
ILibDuktape_CreateInstanceMethod(ctx, "create", ILibduktape_httpDigest_create, DUK_VARARGS);
}
duk_ret_t ILibDuktape_httpHeaders(duk_context *ctx)
{
@@ -1087,4 +1128,4 @@ public:
public String minor;
};
};
#endif
#endif

View File

@@ -22,4 +22,3 @@ limitations under the License.
void ILibDuktape_http_init(duk_context *ctx, void *chain);
#endif

View File

@@ -100,6 +100,7 @@ void ILibDuktape_net_socket_OnConnect(ILibAsyncSocket_SocketModule socketModule,
{
ILibDuktape_net_socket *ptrs = (ILibDuktape_net_socket*)((ILibChain_Link*)socketModule)->ExtraMemoryPtr;
struct sockaddr_in6 local;
if (ptrs->ctx == NULL) { return; }
duk_push_heapptr(ptrs->ctx, ptrs->object); // [sockat]
duk_push_false(ptrs->ctx); // [socket][connecting]
@@ -164,14 +165,13 @@ void ILibDuktape_net_socket_OnConnect(ILibAsyncSocket_SocketModule socketModule,
#endif
duk_put_prop_string(ptrs->ctx, -2, "message"); // [emit][this][error][errorObj]
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(ptrs->ctx); }
duk_pop(ptrs->ctx); // ...
if (ptrs->ctx != NULL) { duk_pop(ptrs->ctx); } // ...
}
}
void ILibDuktape_net_socket_OnDisconnect(ILibAsyncSocket_SocketModule socketModule, void *user)
{
ILibDuktape_net_socket *ptrs = (ILibDuktape_net_socket*)((ILibChain_Link*)socketModule)->ExtraMemoryPtr;
if (ILibDuktape_IsPointerValid(ptrs->chain, ptrs->object))
if (ILibMemory_CanaryOK(ptrs->emitter))
{
duk_push_heapptr(ptrs->ctx, ptrs->object); // [sock]
duk_push_string(ptrs->ctx, "0.0.0.0"); // [sock][localAddr]
@@ -379,7 +379,7 @@ duk_ret_t ILibDuktape_net_socket_finalizer(duk_context *ctx)
if (ILibAsyncSocket_IsConnected(ptrs->socketModule) != 0) { ILibAsyncSocket_Disconnect(ptrs->socketModule); }
ILibChain_SafeRemove(chain, ptrs->socketModule);
}
ptrs->ctx = NULL;
return 0;
}
int ILibDuktape_net_socket_unshift(ILibDuktape_DuplexStream *sender, int unshiftBytes, void *user)
@@ -399,7 +399,6 @@ void ILibDuktape_net_socket_PUSH(duk_context *ctx, ILibAsyncSocket_SocketModule
duk_push_object(ctx); // [obj]
ILibDuktape_WriteID(ctx, "net.socket");
ILibDuktape_PointerValidation_Init(ctx);
ptrs->ctx = ctx;
ptrs->chain = ((ILibChain_Link*)module)->ParentChain;
ptrs->object = duk_get_heapptr(ctx, -1);
@@ -493,21 +492,29 @@ duk_ret_t ILibDuktape_net_createConnection(duk_context *ctx)
ILibTransport_DoneState ILibDuktape_net_server_WriteSink(ILibDuktape_DuplexStream *stream, char *buffer, int bufferLen, void *user)
{
ILibDuktape_net_server_session *session = (ILibDuktape_net_server_session*)user;
if (!ILibMemory_CanaryOK(session)) { return(ILibTransport_DoneState_ERROR); }
return((ILibTransport_DoneState)ILibAsyncServerSocket_Send(NULL, session->connection, buffer, bufferLen, ILibAsyncSocket_MemoryOwnership_USER));
}
void ILibDuktape_net_server_EndSink(ILibDuktape_DuplexStream *stream, void *user)
{
ILibDuktape_net_server_session *session = (ILibDuktape_net_server_session*)user;
ILibAsyncServerSocket_Disconnect(NULL, session->connection);
if (!ILibMemory_CanaryOK(session)) { return; }
if (session->connection != NULL) { ILibAsyncServerSocket_Disconnect(NULL, session->connection); }
}
void ILibDuktape_net_server_PauseSink(ILibDuktape_DuplexStream *sender, void *user)
{
ILibDuktape_net_server_session *session = (ILibDuktape_net_server_session*)user;
if (!ILibMemory_CanaryOK(session)) { return; }
ILibAsyncSocket_Pause(session->connection);
}
void ILibDuktape_net_server_ResumeSink(ILibDuktape_DuplexStream *sender, void *user)
{
ILibDuktape_net_server_session *session = (ILibDuktape_net_server_session*)user;
if (!ILibMemory_CanaryOK(session)) { return; }
ILibAsyncSocket_Resume(session->connection);
}
duk_ret_t ILibDuktape_net_server_socket_Finalizer(duk_context *ctx)
@@ -527,6 +534,8 @@ duk_ret_t ILibDuktape_net_server_socket_Finalizer(duk_context *ctx)
int ILibDuktape_net_server_unshiftSink(ILibDuktape_DuplexStream *sender, int unshiftBytes, void *user)
{
ILibDuktape_net_server_session *session = (ILibDuktape_net_server_session*)user;
if (!ILibMemory_CanaryOK(session)) { return(unshiftBytes); }
session->unshiftBytes = unshiftBytes;
return(unshiftBytes);
}
@@ -534,7 +543,12 @@ void ILibDuktape_net_server_OnConnect(ILibAsyncServerSocket_ServerModule AsyncSe
{
ILibDuktape_net_server *ptr = (ILibDuktape_net_server*)((void**)ILibMemory_GetExtraMemory(AsyncServerSocketModule, ILibMemory_ASYNCSERVERSOCKET_CONTAINERSIZE))[0];
ILibDuktape_net_server_session *session;
#ifndef MICROSTACK_NOTLS
int isTLS = ILibAsyncSocket_IsUsingTls(ConnectionToken);
#else
int isTLS = 0;
#endif
if (!ILibMemory_CanaryOK(ptr)) { return; }
duk_push_heapptr(ptr->ctx, ptr->self); // [server]
@@ -545,9 +559,7 @@ void ILibDuktape_net_server_OnConnect(ILibAsyncServerSocket_ServerModule AsyncSe
duk_push_object(ptr->ctx); // [emit][this][connection][socket]
ILibDuktape_WriteID(ptr->ctx, isTLS ? "tls.serverSocketConnection" : "net.serverSocketConnection");
ILibDuktape_CreateFinalizer(ptr->ctx, ILibDuktape_net_server_socket_Finalizer);
duk_push_fixed_buffer(ptr->ctx, sizeof(ILibDuktape_net_server_session)); // [emit][this][connection][socket][buffer]
session = (ILibDuktape_net_server_session*)Duktape_GetBuffer(ptr->ctx, -1, NULL);
memset(session, 0, sizeof(ILibDuktape_net_server_session));
session = Duktape_PushBuffer(ptr->ctx, sizeof(ILibDuktape_net_server_session)); // [emit][this][connection][socket][buffer]
duk_put_prop_string(ptr->ctx, -2, ILibDuktape_net_Server_Session_buffer); // [emit][this][connection][socket]
struct sockaddr_in6 local;
@@ -583,12 +595,19 @@ void ILibDuktape_net_server_OnConnect(ILibAsyncServerSocket_ServerModule AsyncSe
void ILibDuktape_net_server_OnDisconnect(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, ILibAsyncServerSocket_ConnectionToken ConnectionToken, void *user)
{
ILibDuktape_net_server_session *session = (ILibDuktape_net_server_session*)user;
ILibDuktape_DuplexStream_Closed(session->stream);
if (!ILibMemory_CanaryOK(session)) { return; }
if (session->connection != NULL)
{
ILibDuktape_DuplexStream_Closed(session->stream);
session->connection = NULL;
}
}
void ILibDuktape_net_server_OnReceive(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, ILibAsyncServerSocket_ConnectionToken ConnectionToken, char* buffer, int *p_beginPointer, int endPointer, ILibAsyncServerSocket_OnInterrupt *OnInterrupt, void **user, int *PAUSE)
{
ILibDuktape_net_server_session *session = (ILibDuktape_net_server_session*)*user;
if (!ILibMemory_CanaryOK(session)) { *p_beginPointer = endPointer; return; }
session->unshiftBytes = 0;
ILibDuktape_DuplexStream_WriteData(session->stream, buffer + *p_beginPointer, endPointer);
*p_beginPointer = endPointer - session->unshiftBytes;
@@ -599,6 +618,8 @@ void ILibDuktape_net_server_OnInterrupt(ILibAsyncServerSocket_ServerModule Async
void ILibDuktape_net_server_OnSendOK(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, ILibAsyncServerSocket_ConnectionToken ConnectionToken, void *user)
{
ILibDuktape_net_server_session *session = (ILibDuktape_net_server_session*)user;
if (!ILibMemory_CanaryOK(session)) { return; }
ILibDuktape_DuplexStream_Ready(session->stream);
}
duk_ret_t ILibDuktape_net_server_listen(duk_context *ctx)
@@ -777,10 +798,7 @@ duk_ret_t ILibDuktape_net_createServer(duk_context *ctx)
duk_dup(ctx, 0); // [server][Options]
duk_put_prop_string(ctx, -2, ILibDuktape_SERVER2OPTIONS); // [server]
}
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_net_server)); // [server][fbuffer]
server = (ILibDuktape_net_server*)Duktape_GetBuffer(ctx, -1, NULL);
memset(server, 0, sizeof(ILibDuktape_net_server));
server = Duktape_PushBuffer(ctx, sizeof(ILibDuktape_net_server)); // [server][fbuffer]
duk_put_prop_string(ctx, -2, ILibDuktape_net_Server_buffer); // [server]
server->isTLS = isTLS;
@@ -828,6 +846,20 @@ duk_ret_t ILibDuktape_net_createServer(duk_context *ctx)
return 1;
}
duk_ret_t ILibDuktape_net_addr2int(duk_context *ctx)
{
struct sockaddr_in6 addr6;
ILibResolveEx((char*)duk_require_string(ctx, 0), 0, &addr6);
if (addr6.sin6_family == AF_INET)
{
duk_push_int(ctx, ((struct sockaddr_in*)&addr6)->sin_addr.s_addr);
return(1);
}
else
{
return(ILibDuktape_Error(ctx, "Error converting address"));
}
}
void ILibDuktape_net_PUSH_net(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [net]
@@ -843,6 +875,7 @@ void ILibDuktape_net_PUSH_net(duk_context *ctx, void *chain)
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "tls", 0, "createServer", ILibDuktape_net_createServer, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "createConnection", ILibDuktape_net_createConnection, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "connect", ILibDuktape_net_createConnection, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "addr2int", ILibDuktape_net_addr2int, 1);
}
duk_ret_t ILibDuktape_globalTunnel_end(duk_context *ctx)
{
@@ -1003,6 +1036,8 @@ int ILibDuktape_TLS_server_verify(int preverify_ok, X509_STORE_CTX *storectx)
int i;
int retVal = 0;
if (!ILibMemory_CanaryOK(data)) { return(0); }
duk_push_heapptr(data->ctx, data->self); // [Server]
duk_get_prop_string(data->ctx, -1, ILibDuktape_SERVER2OPTIONS); // [Server][Options]
@@ -1026,6 +1061,7 @@ int ILibDuktape_TLS_server_verify(int preverify_ok, X509_STORE_CTX *storectx)
void ILibDuktape_tls_server_OnSSL(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, void *ConnectionToken, SSL* ctx, void **user)
{
ILibDuktape_net_server *server = (ILibDuktape_net_server*)ILibAsyncServerSocket_GetTag(AsyncServerSocketModule);
if (!ILibMemory_CanaryOK(server)) { return; }
if (ctx != NULL && ILibDuktape_TLS_ctx2server)
{
@@ -1036,6 +1072,7 @@ static int ILibDuktape_tls_server_sniCallback(SSL *s, int *ad, void *arg)
{
const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
ILibDuktape_net_server *data = (ILibDuktape_net_server*)SSL_get_ex_data(s, ILibDuktape_TLS_ctx2server);
if (!ILibMemory_CanaryOK(data)) { return(SSL_TLSEXT_ERR_OK); }
duk_push_heapptr(data->ctx, data->self); // [server]
duk_get_prop_string(data->ctx, -1, ILibDuktape_SERVER2ContextTable); // [server][table]
@@ -1471,4 +1508,4 @@ public:
*/
void setTimeout(milliseconds[, timeout]);
};
#endif
#endif

View File

@@ -40,4 +40,4 @@ ILibDuktape_globalTunnel_data* ILibDuktape_GetGlobalTunnel(duk_context *ctx);
ILibDuktape_globalTunnel_data* ILibDuktape_GetNewGlobalTunnelEx(duk_context *ctx, int native);
#define ILibDuktape_GetNewGlobalTunnel(ctx) ILibDuktape_GetNewGlobalTunnelEx(ctx, 1)
#endif
#endif

View File

@@ -714,4 +714,4 @@ void ILibWebServer_DukTape_Init(duk_context* ctx, void *chain)
Duktape_CreateEnum(ctx, "WebServer_DoneFlags", (char* []) { "NOTDONE", "DONE", "PARTIAL", "LASTPARTIAL" }, (int[]) { 0, 1, 10, 11 }, 4);
duk_pop(ctx); // ...
}
}

View File

@@ -21,4 +21,4 @@ limitations under the License.
void ILibWebServer_DukTape_Init(duk_context *ctx, void * chain);
#endif
#endif

View File

@@ -27,12 +27,18 @@ limitations under the License.
#define ILibDuktape_EventEmitter_MaxEventNameLen 255
#define ILibDuktape_EventEmitter_Data "\xFF_EventEmitter_Data"
#define ILibDuktape_EventEmitter_RetVal "\xFF_EventEmitter_RetVal"
#define ILibDuktape_EventEmitter_TempObject "\xFF_EventEmitter_TempObject"
#define ILibDuktape_EventEmitter_DispatcherFunc "\xFF_EventEmitter_DispatcherFunc"
#define ILibDuktape_EventEmitter_SetterFunc ((void*)0xFFFF)
#define ILibDuktape_EventEmitter_HPTR_LIST "\xFF_EventEmitter_HPTR_LIST"
#define ILibDuktape_EventEmitter_Hook ((void*)0xEEEE)
#define ILibDuktape_EventEmitter_LastRetValueTable "\xFF_EventEmitter_LastRetValueTable"
#define ILibDuktape_EventEmitter_GlobalListenerCount "\xFF_EventEmitter_GlobalListenerCount"
#define ILibDuktape_EventEmitter_Forward_SourceName "\xFF_EventEmitter_SourceName"
#define ILibDuktape_EventEmitter_Forward_TargetName "\xFF_EventEmitter_TargetName"
#define ILibDuktape_EventEmitter_Forward_SourceObject "\xFF_EventEmitter_SourceObject"
#define ILibDuktape_EventEmitter_ForwardTable "\xFF_EventEmitter_ForwardTable"
#ifdef __DOXY__
@@ -148,7 +154,7 @@ void ILibDuktape_EventEmitter_FinalizerEx(ILibHashtable sender, void *Key1, char
int ILibDuktape_EventEmitter_HasListeners(ILibDuktape_EventEmitter *emitter, char *eventName)
{
int retVal = 0;
if (emitter->eventTable != NULL)
if(emitter!=NULL && emitter->eventTable != NULL)
{
ILibLinkedList eventList = ILibHashtable_Get(emitter->eventTable, NULL, eventName, (int)strnlen_s(eventName, 255));
if (eventList != NULL)
@@ -171,6 +177,9 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
int i, j;
void **emitList;
char *objid;
int wasReturnSpecified = 0;
duk_require_stack(ctx, 3); // This will make sure we have enough stack space to get the emitter object
duk_push_this(ctx); // [this]
objid = Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "unknown");
@@ -184,7 +193,17 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
if (data->eventTable == NULL) { duk_push_false(ctx); return(1); } // This probably means the finalizer was already run on the eventEmitter
eventList = ILibHashtable_Get(data->eventTable, NULL, name, (int)nameLen);
if (eventList == NULL) { return ILibDuktape_Error(ctx, "EventEmitter.emit(): Event '%s' not found on object '%s'", name, objid); }
if (eventList == NULL)
{
if (data->eventType == ILibDuktape_EventEmitter_Type_IMPLICIT)
{
duk_push_false(ctx); return(1);
}
else
{
return ILibDuktape_Error(ctx, "EventEmitter.emit(): Event '%s' not found on object '%s'", name, objid);
}
}
// Copy the list, so we can enumerate with local memory, so the list can be manipulated while we are dispatching
#ifdef WIN32
@@ -209,10 +228,18 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
}
emitList[i] = NULL;
// Before we dispatch, lets clear our last return values for this event
duk_push_heapptr(ctx, data->retValTable); // [table]
duk_del_prop_lstring(ctx, -1, name, nameLen);
duk_pop(ctx); // ...
// Now that we have all the housekeeping stuff out of the way, we can actually dispatch our events
i = 0;
while ((func = emitList[i++]) != NULL)
{
duk_require_stack(ctx, nargs + 1); // This will make sure that we have enough stack space to make the method call
duk_push_heapptr(ctx, func); // [func]
duk_push_heapptr(ctx, self); // [func][this]
for (j = 1; j < nargs; ++j)
@@ -221,10 +248,39 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
}
if (duk_pcall_method(ctx, nargs - 1) != 0)
{
return(ILibDuktape_Error(ctx, "EventEmitter.emit(): Event dispatch for '%s' on '%s' threw an exception: %s", name, objid, duk_safe_to_string(ctx, -1)));
duk_push_heapptr(ctx, func); // [func]
return(ILibDuktape_Error(ctx, "EventEmitter.emit(): Event dispatch for '%s' on '%s' threw an exception: %s in method '%s()'", name, objid, duk_safe_to_string(ctx, -2), Duktape_GetStringPropertyValue(ctx, -1, "name", "unknown_method")));
}
// Check for return value
if (!duk_is_undefined(ctx, -1))
{
duk_push_heapptr(ctx, data->retValTable); // [retVal][table]
duk_dup(ctx, -2); // [retVal][table][retVal]
duk_put_prop_lstring(ctx, -2, name, nameLen); // [retVal][table]
duk_pop(ctx); // [retVal]
duk_push_heapptr(ctx, self); // [retVal][this]
duk_swap_top(ctx, -2); // [this][retVal]
data->lastReturnValue = duk_get_heapptr(ctx, -1);
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_RetVal); // [this]
duk_pop(ctx); // ...
wasReturnSpecified = 1;
}
duk_pop(ctx); // ...
}
if (wasReturnSpecified == 0)
{
data->lastReturnValue = NULL;
duk_push_heapptr(ctx, self); // [this]
duk_del_prop_string(ctx, -1, ILibDuktape_EventEmitter_RetVal); // [this]
duk_pop(ctx); // ...
duk_push_heapptr(ctx, data->retValTable); // [table]
duk_del_prop_lstring(ctx, -1, name, nameLen);
duk_pop(ctx); // ...
}
duk_push_boolean(ctx, i > 1 ? 1 : 0);
return(1);
}
@@ -326,7 +382,15 @@ duk_ret_t ILibDuktape_EventEmitter_on(duk_context *ctx)
eventList = ILibHashtable_Get(data->eventTable, NULL, propName, (int)propNameLen);
if (eventList == NULL)
{
return(ILibDuktape_Error(ctx, "EventEmitter.on(): Event '%s' not found", propName));
if (data->eventType == ILibDuktape_EventEmitter_Type_IMPLICIT)
{
ILibDuktape_EventEmitter_CreateEventEx(data, propName);
eventList = ILibHashtable_Get(data->eventTable, NULL, propName, (int)propNameLen);
}
else
{
return(ILibDuktape_Error(ctx, "EventEmitter.on(): Event '%s' not found", propName));
}
}
hookHandler = ILibHashtable_Get(data->eventTable, ILibDuktape_EventEmitter_Hook, propName, (int)propNameLen);
@@ -339,6 +403,14 @@ duk_ret_t ILibDuktape_EventEmitter_on(duk_context *ctx)
duk_put_prop_string(ctx, -2, Duktape_GetStashKey(callback)); // Save the callback to the tmp object, so it won't get GC'ed
if (hookHandler != NULL) { hookHandler(data, propName, callback); }
if (!(propNameLen == 10 && strncmp(propName, "_eventHook", 10) == 0))
{
// Only emit '_eventHook' when the event itself isn't '_eventHook'
ILibDuktape_EventEmitter_SetupEmit(ctx, data->object, "_eventHook"); // [emit][this][_eventHook]
duk_push_lstring(ctx, propName, propNameLen); // [emit][this][_eventHook][propName]
duk_push_heapptr(ctx, callback); // [emit][this][_eventHook][propName][callback]
duk_call_method(ctx, 3); duk_pop(ctx); // ...
}
return 0;
}
ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_GetEmitter_fromThis(duk_context *ctx)
@@ -453,6 +525,38 @@ duk_ret_t ILibDuktape_EventEmitter_EmbeddedFinalizer(duk_context *ctx)
memset(data, 0, sizeof(ILibDuktape_EventEmitter));
return(0);
}
duk_ret_t ILibDuktape_EventEmitter_emitReturnValue(duk_context *ctx)
{
int retVal = 1;
int nargs = duk_get_top(ctx);
duk_push_this(ctx); // [this]
switch (nargs)
{
case 0:
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_RetVal); // [this][retVal]
break;
case 1:
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_TempObject); // [this][tmp]
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_LastRetValueTable); // [this][tmp][table]
duk_dup(ctx, 0); // [this][tmp][table][key]
duk_get_prop(ctx, -2); // [this][tmp][table][val]
break;
case 2:
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_TempObject); // [this][tmp]
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_LastRetValueTable); // [this][tmp][table]
duk_dup(ctx, 0); // [this][tmp][table][key]
duk_dup(ctx, 1); // [this][tmp][table][key][value]
duk_put_prop(ctx, -3);
retVal = 0;
break;
default:
retVal = ILibDuktape_Error(ctx, "INVALID Parameter Count");
break;
}
return(retVal);
}
ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
{
ILibDuktape_EventEmitter *retVal;
@@ -466,14 +570,15 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
return retVal;
}
duk_push_object(ctx); // [emitterTmp]
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_EventEmitter)); // [emitterTmp][data]
retVal = (ILibDuktape_EventEmitter*)Duktape_GetBuffer(ctx, -1, NULL);
memset(retVal, 0, sizeof(ILibDuktape_EventEmitter));
duk_push_object(ctx); // [emitterTmp]
retVal = (ILibDuktape_EventEmitter*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_EventEmitter)); // [emitterTmp][data]
retVal->tmpObject = duk_get_heapptr(ctx, -2);
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_Data); // [emitterTmp]
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_TempObject); // [...parent...]
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_Data); // [emitterTmp]
duk_push_object(ctx); // [emitterTmp][retValTable]
retVal->retValTable = duk_get_heapptr(ctx, -1);
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_LastRetValueTable); // [emitterTmp]
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_TempObject); // [...parent...]
retVal->ctx = ctx;
retVal->object = duk_get_heapptr(ctx, -1);
@@ -487,6 +592,7 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
ILibDuktape_CreateInstanceMethod(ctx, "removeListener", ILibDuktape_EventEmitter_removeListener, 2);
ILibDuktape_CreateInstanceMethod(ctx, "removeAllListeners", ILibDuktape_EventEmitter_removeAllListeners, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "emit", ILibDuktape_EventEmitter_emit, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "emit_returnValue", ILibDuktape_EventEmitter_emitReturnValue, DUK_VARARGS);
duk_push_heap_stash(ctx);
if (duk_has_prop_string(ctx, -1, ILibDuktape_EventEmitter_GlobalListenerCount))
@@ -508,6 +614,8 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
duk_push_c_function(ctx, ILibDuktape_EventEmitter_EmbeddedFinalizer, 1);
duk_set_finalizer(ctx, -2);
ILibDuktape_EventEmitter_CreateEventEx(retVal, "_eventHook");
return retVal;
}
@@ -518,6 +626,10 @@ void ILibDuktape_EventEmitter_AddHook(ILibDuktape_EventEmitter *emitter, char *e
ILibHashtable_Put(emitter->eventTable, ILibDuktape_EventEmitter_Hook, eventName, (int)strnlen_s(eventName, 255), handler);
}
}
void ILibDuktape_EventEmitter_ClearHook(ILibDuktape_EventEmitter *emitter, char *eventName)
{
ILibHashtable_Remove(emitter->eventTable, ILibDuktape_EventEmitter_Hook, eventName, (int)strnlen_s(eventName, 255));
}
duk_ret_t ILibDuktape_EventEmitter_SetEvent(duk_context *ctx)
{
char *propName;
@@ -617,7 +729,7 @@ duk_ret_t ILibDuktape_EventEmitter_Inherits_createEvent(duk_context *ctx)
duk_pop(ctx); // [emitterUtils]
ILibDuktape_EventEmitter_CreateEventEx(emitter, name);
return 0;
return(1);
}
duk_ret_t ILibDuktape_EventEmitter_Inherits_addMethod(duk_context *ctx)
{
@@ -658,10 +770,45 @@ duk_ret_t ILibDuktape_EventEmitter_Inherits(duk_context *ctx)
ILibDuktape_EventEmitter_CreateEventEx(emitter, "~");
return 1;
}
duk_ret_t ILibDuktape_EventEmitter_EventEmitter(duk_context *ctx)
{
ILibDuktape_EventEmitter *emitter;
int nargs = duk_get_top(ctx);
int retVal = 0;
duk_push_this(ctx); // [target]
emitter = ILibDuktape_EventEmitter_Create(ctx);
duk_push_object(ctx); // [target][emitterUtils]
duk_dup(ctx, -2); // [target][emitterUtils][target]
duk_put_prop_string(ctx, -2, "\xFF_MainObject"); // [target][emitterUtils]
duk_dup(ctx, -1); // [target][emitterUtils][dup]
duk_put_prop_string(ctx, -3, "\xFF_emitterUtils"); // [target][emitterUtils]
duk_push_pointer(ctx, emitter); // [target][emitterUtils][ptr]
duk_put_prop_string(ctx, -2, "emitter"); // [target][emitterUtils]
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_EventEmitter_EmitterUtils_Finalizer);
if (nargs == 1 && duk_require_boolean(ctx, 0))
{
// Explicit Events
ILibDuktape_CreateInstanceMethod(ctx, "createEvent", ILibDuktape_EventEmitter_Inherits_createEvent, 1);
ILibDuktape_CreateInstanceMethod(ctx, "addMethod", ILibDuktape_EventEmitter_Inherits_addMethod, 2);
retVal = 1;
}
else
{
// Implicit Events
emitter->eventType = ILibDuktape_EventEmitter_Type_IMPLICIT;
}
ILibDuktape_EventEmitter_CreateEventEx(emitter, "~");
return(retVal);
}
void ILibDuktape_EventEmitter_PUSH(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [emitter]
ILibDuktape_CreateInstanceMethod(ctx, "inherits", ILibDuktape_EventEmitter_Inherits, 1);
ILibDuktape_CreateInstanceMethod(ctx, "EventEmitter", ILibDuktape_EventEmitter_EventEmitter, DUK_VARARGS);
}
void ILibDuktape_EventEmitter_Init(duk_context *ctx)
{
@@ -690,48 +837,195 @@ duk_ret_t ILibDuktape_EventEmitter_ForwardEvent_Sink(duk_context *ctx)
duk_ret_t ILibDuktape_EventEmitter_ForwardEvent_Finalizer(duk_context *ctx)
{
duk_push_current_function(ctx); // [func]
duk_get_prop_string(ctx, -1, "fptr"); // [func][fptr]
duk_get_prop_string(ctx, -1, "targetObject"); // [func][fptr][target]
duk_del_prop_string(ctx, -2, "targetObject");
if (g_displayFinalizerMessages) { printf("EventEmitter.Forwarder[%s]: Deleted reference to [%s] RC=%d\n", Duktape_GetStringPropertyValue(ctx, -3, "targetName", "UNKNOWN"), Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "UNKNOWN"), ILibDuktape_GetReferenceCount(ctx, -1) - 1); }
duk_pop_n(ctx, 3);
void *src = NULL;
char *srcName = NULL;
if (g_displayFinalizerMessages)
{
duk_push_this(ctx);
src = duk_get_heapptr(ctx, -1);
srcName = Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "UNKNOWN");
duk_pop(ctx);
}
duk_push_current_function(ctx); // [func]
if (duk_has_prop_string(ctx, -1, "fptr"))
{
duk_get_prop_string(ctx, -1, "fptr"); // [func][fptr]
if (duk_has_prop_string(ctx, -1, "targetObject"))
{
duk_get_prop_string(ctx, -1, "targetObject"); // [func][fptr][target]
duk_del_prop_string(ctx, -2, "targetObject");
if (g_displayFinalizerMessages) { printf("EventEmitter.Forwarder[%s]: Deleted reference to [%s/%p] RC=%d from [%s/%p]\n", Duktape_GetStringPropertyValue(ctx, -3, "targetName", "UNKNOWN"), Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "UNKNOWN"), duk_get_heapptr(ctx, -1), ILibDuktape_GetReferenceCount(ctx, -1) - 1, srcName, src); }
duk_pop_n(ctx, 3);
}
}
if (g_displayFinalizerMessages) { duk_eval_string(ctx, "_debugGC();"); duk_pop(ctx); }
return(0);
}
duk_ret_t ILibDuktape_EventEmitter_ForwardEvent_HookSink(duk_context *ctx)
{
duk_push_current_function(ctx);
duk_size_t sourceLen, targetLen, hookLen;
char *source, *target, *hook;
void *sourceObject, *fptr;
source = Duktape_GetStringPropertyValueEx(ctx, -1, ILibDuktape_EventEmitter_Forward_SourceName, NULL, &sourceLen);
target = Duktape_GetStringPropertyValueEx(ctx, -1, ILibDuktape_EventEmitter_Forward_TargetName, NULL, &targetLen);
sourceObject = Duktape_GetHeapptrProperty(ctx, -1, ILibDuktape_EventEmitter_Forward_SourceObject);
if (source != NULL && target != NULL && sourceObject != NULL)
{
hook = (char*)duk_get_lstring(ctx, 0, &hookLen);
if (!(hookLen == targetLen && strncmp(target, hook, hookLen) == 0))
{
// This hooked event wasn't for us, so let's rehook this logic up for next time
duk_push_this(ctx); // [this]
duk_get_prop_string(ctx, -1, "once"); // [this][once]
duk_swap_top(ctx, -2); // [once][this]
duk_push_string(ctx, "_eventHook"); // [once][this][_eventHook]
duk_push_c_function(ctx, ILibDuktape_EventEmitter_ForwardEvent_HookSink, DUK_VARARGS); // [once][this][_eventHook][func]
duk_push_lstring(ctx, source, sourceLen); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_Forward_SourceName);
duk_push_lstring(ctx, target, targetLen); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_Forward_TargetName);
duk_push_heapptr(ctx, sourceObject); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_Forward_SourceObject);
duk_call_method(ctx, 2); duk_pop(ctx); // ...
}
else
{
// This hooked event is for us
ILibDuktape_EventEmitter_SetupOn(ctx, sourceObject, source); // [on][this][source]
duk_push_c_function(ctx, ILibDuktape_EventEmitter_ForwardEvent_Sink, DUK_VARARGS); // [on][this][source][sink]
fptr = duk_get_heapptr(ctx, -1);
duk_push_this(ctx); duk_put_prop_string(ctx, -2, "targetObject");
duk_push_lstring(ctx, target, targetLen); duk_put_prop_string(ctx, -2, "targetName");
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "EventEmitter_ForwardEvent(): "); }
duk_pop(ctx); // ...
ILibDuktape_EventEmitter_SetupPrependOnce(ctx, sourceObject, "~"); // [prependOnce][this][~]
duk_push_c_function(ctx, ILibDuktape_EventEmitter_ForwardEvent_Finalizer, DUK_VARARGS); // [prependOnce][this]['~'][func]
duk_push_heapptr(ctx, fptr); duk_put_prop_string(ctx, -2, "fptr");
duk_push_lstring(ctx, target, targetLen); duk_put_prop_string(ctx, -2, "targetName");
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "EventEmitter_ForwardEvent_SetFinalizer(): "); }
duk_pop(ctx); // ...
}
}
return(0);
}
void ILibDuktape_EventEmitter_DeleteForwardEvent(duk_context *ctx, duk_idx_t eventSourceIndex, char *sourceEventName)
{
duk_dup(ctx, eventSourceIndex); // [source]
if (duk_has_prop_string(ctx, -1, ILibDuktape_EventEmitter_ForwardTable))
{
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_ForwardTable); // [source][table]
if (duk_has_prop_string(ctx, -1, sourceEventName))
{
duk_get_prop_string(ctx, -1, sourceEventName); // [source][table][sink]
duk_del_prop_string(ctx, -1, "targetObject");
duk_get_prop_string(ctx, -3, "removeListener"); // [source][table][sink][removeListener]
duk_dup(ctx, -4); // [source][table][sink][removeListener][this]
duk_push_string(ctx, sourceEventName); // [source][table][sink][removeListener][this][name]
duk_dup(ctx, -4); // [source][table][sink][removeListener][this][name][sink]
duk_call_method(ctx, 2); duk_pop_2(ctx); // [source][table]
if (duk_has_prop_string(ctx, -1, "~"))
{
duk_get_prop_string(ctx, -1, "~"); // [source][table][sink]
duk_del_prop_string(ctx, -1, "fptr");
duk_get_prop_string(ctx, -3, "removeListener"); // [source][table][sink][removeListener]
duk_dup(ctx, -4); // [source][table][sink][removeListener][this]
duk_push_string(ctx, "~"); // [source][table][sink][removeListener][this][name]
duk_dup(ctx, -4); // [source][table][sink][removeListener][this][name][sink]
duk_call_method(ctx, 2); duk_pop_2(ctx); // [source][table]
}
if (duk_has_prop_string(ctx, -1, "_eventHook"))
{
duk_get_prop_string(ctx, -1, "_eventHook"); // [source][table][sink]
duk_get_prop_string(ctx, -3, "removeListener"); // [source][table][sink][removeListener]
duk_dup(ctx, -4); // [source][table][sink][removeListener][this]
duk_push_string(ctx, "_eventHook"); // [source][table][sink][removeListener][this][name]
duk_dup(ctx, -4); // [source][table][sink][removeListener][this][name][sink]
duk_call_method(ctx, 2); duk_pop_2(ctx); // [source][table]
}
}
duk_pop(ctx); // [source]
}
duk_pop(ctx); // ...
}
void ILibDuktape_EventEmitter_ForwardEvent(duk_context *ctx, duk_idx_t eventSourceIndex, char *sourceEventName, duk_idx_t eventTargetIndex, char *targetEventName)
{
void *fptr;
void *source;
void *target;
duk_dup(ctx, eventTargetIndex); // [targetObject]
void *table = NULL;
duk_dup(ctx, eventTargetIndex); // [targetObject]
target = duk_get_heapptr(ctx, -1);
duk_pop(ctx); // ...
duk_dup(ctx, eventSourceIndex); // [sourceObject]
duk_get_prop_string(ctx, -1, "on"); // [sourceObject][on]
duk_swap_top(ctx, -2); // [on][this]
duk_push_string(ctx, sourceEventName); // [on][this][name]
duk_push_c_function(ctx, ILibDuktape_EventEmitter_ForwardEvent_Sink, DUK_VARARGS); // [on][this][name][sink]
fptr = duk_get_heapptr(ctx, -1);
duk_push_heapptr(ctx, target); // [on][this][name][sink][targetObject]
duk_put_prop_string(ctx, -2, "targetObject"); // [on][this][name][sink]
duk_push_string(ctx, targetEventName); // [on][this][name][sink][targetName]
duk_put_prop_string(ctx, -2, "targetName"); // [on][this][name][sink]
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "EventEmitter_ForwardEvent(): "); }
duk_pop(ctx); // ...
duk_dup(ctx, eventSourceIndex); // [sourceObject]
duk_get_prop_string(ctx, -1, "prependOnceListener"); // [sourceObject][prependOnce]
duk_swap_top(ctx, -2); // [prependOnce][this]
duk_push_string(ctx, "~"); // [prependOnce][this]['~']
duk_push_c_function(ctx, ILibDuktape_EventEmitter_ForwardEvent_Finalizer, DUK_VARARGS); // [prependOnce][this]['~'][func]
duk_push_heapptr(ctx, fptr); // [prependOnce][this]['~'][func][fptr]
duk_put_prop_string(ctx, -2, "fptr"); // [prependOnce][this]['~'][func]
duk_push_string(ctx, targetEventName); // [prependOnce][this]['~'][func][name]
duk_put_prop_string(ctx, -2, "targetName"); // [prependOnce][this]['~'][func]
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "EventEmitter_ForwardEvent_SetFinalizer(): "); }
duk_pop(ctx); // ...
duk_dup(ctx, eventSourceIndex); // [sourceObject]
source = duk_get_heapptr(ctx, -1);
duk_pop(ctx); // ...
duk_push_heapptr(ctx, source); // [source]
ILibDuktape_EventEmitter_DeleteForwardEvent(ctx, -1, sourceEventName);
if (duk_has_prop_string(ctx, -1, ILibDuktape_EventEmitter_ForwardTable))
{
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_ForwardTable); // [source][table]
table = duk_get_heapptr(ctx, -1);
duk_pop(ctx); // [source]
}
else
{
duk_push_object(ctx); // [source][table]
table = duk_get_heapptr(ctx, -1);
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_ForwardTable); // [source]
}
duk_pop(ctx); // ...
duk_push_heapptr(ctx, target); // [target]
if (ILibDuktape_EventEmitter_HasListeners(ILibDuktape_EventEmitter_GetEmitter(ctx, -1), targetEventName) > 0)
{
// Target already has listeners, so we can go ahead and forward events
duk_pop(ctx); // ...
ILibDuktape_EventEmitter_SetupOn(ctx, source, sourceEventName); // [on][this][source]
duk_push_c_function(ctx, ILibDuktape_EventEmitter_ForwardEvent_Sink, DUK_VARARGS); // [on][this][source][sink]
fptr = duk_get_heapptr(ctx, -1);
duk_push_heapptr(ctx, target); duk_put_prop_string(ctx, -2, "targetObject");
duk_push_string(ctx, targetEventName); duk_put_prop_string(ctx, -2, "targetName");
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "EventEmitter_ForwardEvent(): "); }
duk_pop(ctx); // ...
duk_push_heapptr(ctx, table); // [table]
duk_push_heapptr(ctx, fptr); // [table][func]
duk_put_prop_string(ctx, -2, sourceEventName); // [table]
duk_pop(ctx); // ...
ILibDuktape_EventEmitter_SetupPrependOnce(ctx, source, "~"); // [prependOnce][this][~]
duk_push_c_function(ctx, ILibDuktape_EventEmitter_ForwardEvent_Finalizer, DUK_VARARGS); // [prependOnce][this]['~'][func]
duk_push_heapptr(ctx, table); // [prependOnce][this]['~'][func][table]
duk_dup(ctx, -2); // [prependOnce][this]['~'][func][table][func]
duk_put_prop_string(ctx, -2, "~"); // [prependOnce][this]['~'][func][table]
duk_pop(ctx); // [prependOnce][this]['~'][func]
duk_push_heapptr(ctx, fptr); duk_put_prop_string(ctx, -2, "fptr");
duk_push_string(ctx, targetEventName); duk_put_prop_string(ctx, -2, "targetName");
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "EventEmitter_ForwardEvent_SetFinalizer(): "); }
duk_pop(ctx); // ...
}
else
{
// Target has no listeners, so only forward events if someone adds a listener
duk_get_prop_string(ctx, -1, "once"); // [target][once]
duk_swap_top(ctx, -2); // [once][this]
duk_push_string(ctx, "_eventHook"); // [once][this][_eventHook]
duk_push_c_function(ctx, ILibDuktape_EventEmitter_ForwardEvent_HookSink, DUK_VARARGS); // [once][this][_eventHook][func]
duk_push_string(ctx, sourceEventName); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_Forward_SourceName);
duk_push_string(ctx, targetEventName); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_Forward_TargetName);
duk_push_heapptr(ctx, source); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_Forward_SourceObject);
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "Error hooking event: %s ", targetEventName); }
duk_pop(ctx); // ...
}
}
int ILibDuktape_EventEmitter_AddOnEx(duk_context *ctx, duk_idx_t idx, char *eventName, duk_c_function func)
{

View File

@@ -2845,16 +2845,16 @@ typedef struct duk_hthread duk_context;
#undef DUK_USE_DATE_GET_NOW
#undef DUK_USE_DATE_PARSE_STRING
#undef DUK_USE_DATE_PRS_GETDATE
#undef DUK_USE_DEBUG
#undef DUK_USE_DEBUGGER_DUMPHEAP
#undef DUK_USE_DEBUGGER_INSPECT
#undef DUK_USE_DEBUGGER_PAUSE_UNCAUGHT
#undef DUK_USE_DEBUGGER_SUPPORT
//#undef DUK_USE_DEBUG
//#undef DUK_USE_DEBUGGER_DUMPHEAP
//#undef DUK_USE_DEBUGGER_INSPECT
//#undef DUK_USE_DEBUGGER_PAUSE_UNCAUGHT
//#undef DUK_USE_DEBUGGER_SUPPORT
#define DUK_USE_DEBUGGER_THROW_NOTIFY
#undef DUK_USE_DEBUGGER_TRANSPORT_TORTURE
#define DUK_USE_DEBUG_BUFSIZE 65536L
#define DUK_USE_DEBUG_LEVEL 0
#undef DUK_USE_DEBUG_WRITE
//#undef DUK_USE_DEBUG_WRITE
#define DUK_USE_DOUBLE_LINKED_HEAP
#define DUK_USE_DUKTAPE_BUILTIN
#define DUK_USE_ENCODING_BUILTINS
@@ -2917,8 +2917,8 @@ typedef struct duk_hthread duk_context;
#define DUK_USE_HTML_COMMENTS
#define DUK_USE_IDCHAR_FASTPATH
#undef DUK_USE_INJECT_HEAP_ALLOC_ERROR
#undef DUK_USE_INTERRUPT_COUNTER
#undef DUK_USE_INTERRUPT_DEBUG_FIXUP
//#undef DUK_USE_INTERRUPT_COUNTER
//#undef DUK_USE_INTERRUPT_DEBUG_FIXUP
#define DUK_USE_JC
#define DUK_USE_JSON_BUILTIN
#define DUK_USE_JSON_DECNUMBER_FASTPATH

27
microscript/s.h Normal file
View File

@@ -0,0 +1,27 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef __DUKTAPE_SIMPLEDATASTORE__
#define __DUKTAPE_SIMPLEDATASTORE__
#include "duktape.h"
#include "microstack/ILibSimpleDataStore.h"
void ILibDuktape_SimpleDataStore_init(duk_context *ctx, ILibSimpleDataStore sharedDb);
#endif