Initial support for modules, partially implements #1
This commit is contained in:
parent
1929b3619a
commit
ee5504ea3a
7
Makefile
7
Makefile
|
@ -44,10 +44,10 @@ ASTYLE_FLAGS =\
|
||||||
--lineend=linux
|
--lineend=linux
|
||||||
|
|
||||||
|
|
||||||
all: psharp
|
all: psharp dummy.lib
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f psharp $(ENGINE_OBJS)
|
rm -f psharp $(ENGINE_OBJS) *.lib
|
||||||
|
|
||||||
style:
|
style:
|
||||||
astyle $(ASTYLE_FLAGS) --recursive ./*.c,*.h
|
astyle $(ASTYLE_FLAGS) --recursive ./*.c,*.h
|
||||||
|
@ -57,3 +57,6 @@ psharp: $(ENGINE_OBJS)
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) -c $(INCLUDES) $(CFLAGS) -o $@ -c $<
|
$(CC) -c $(INCLUDES) $(CFLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
dummy.lib: ext/dummy/dummy.c
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -shared -fPIC -o dummy.lib ext/dummy/dummy.c
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
#include "dummy.h"
|
||||||
|
|
||||||
|
#define MODULE_DESC "Dummy module"
|
||||||
|
#define MODULE_VER 1.0
|
||||||
|
|
||||||
|
int psharp_dummy_function(ph7_context *pCtx, int nArg, ph7_value **apArg) {
|
||||||
|
SyString dummy;
|
||||||
|
const char *text = "Hello world from dummy module!";
|
||||||
|
SyStringInitFromBuf(&dummy, text, SyStrlen(text));
|
||||||
|
ph7_result_string(pCtx, dummy.zString, dummy.nByte);
|
||||||
|
return PH7_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
PH7_PRIVATE sxi32 initializeModule(ph7_vm *pVm, ph7_real *ver, SyString *desc) {
|
||||||
|
sxi32 rc;
|
||||||
|
sxu32 n;
|
||||||
|
|
||||||
|
desc->zString = MODULE_DESC;
|
||||||
|
*ver = MODULE_VER;
|
||||||
|
for(n = 0 ; n < SX_ARRAYSIZE(dummyFuncList) ; ++n) {
|
||||||
|
rc = ph7_create_function(&(*pVm), dummyFuncList[n].zName, dummyFuncList[n].xFunc, &(*pVm));
|
||||||
|
if(rc != SXRET_OK) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SXRET_OK;
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef __DUMMY_H__
|
||||||
|
#define __DUMMY_H__
|
||||||
|
|
||||||
|
#include "ph7.h"
|
||||||
|
#include "ph7int.h"
|
||||||
|
|
||||||
|
/* Forward reference & declaration */
|
||||||
|
PH7_PRIVATE sxi32 initializeModule(ph7_vm *pVm, ph7_real *ver, SyString *desc);
|
||||||
|
|
||||||
|
/* Functions provided by DUMMY module */
|
||||||
|
int psharp_dummy_function(ph7_context *pCtx, int nArg, ph7_value **apArg);
|
||||||
|
|
||||||
|
static const ph7_builtin_func dummyFuncList[] = {
|
||||||
|
{"dummy_function", psharp_dummy_function },
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
2
ph7int.h
2
ph7int.h
|
@ -15,6 +15,7 @@
|
||||||
#define __PH7INT_H__
|
#define __PH7INT_H__
|
||||||
#define PH7_PRIVATE
|
#define PH7_PRIVATE
|
||||||
#include "ph7.h"
|
#include "ph7.h"
|
||||||
|
#include <dlfcn.h>
|
||||||
#ifndef PH7_PI
|
#ifndef PH7_PI
|
||||||
/* Value of PI */
|
/* Value of PI */
|
||||||
#define PH7_PI 3.1415926535898
|
#define PH7_PI 3.1415926535898
|
||||||
|
@ -1273,6 +1274,7 @@ struct ph7_vm {
|
||||||
SyBlob sConsumer; /* Default VM consumer [i.e Redirect all VM output to this blob] */
|
SyBlob sConsumer; /* Default VM consumer [i.e Redirect all VM output to this blob] */
|
||||||
SyBlob sWorker; /* General purpose working buffer */
|
SyBlob sWorker; /* General purpose working buffer */
|
||||||
SyBlob sArgv; /* $argv[] collector [refer to the [getopt()] implementation for more information] */
|
SyBlob sArgv; /* $argv[] collector [refer to the [getopt()] implementation for more information] */
|
||||||
|
SySet aModules; /* Set of loaded modules */
|
||||||
SySet aFiles; /* Stack of processed files */
|
SySet aFiles; /* Stack of processed files */
|
||||||
SySet aPaths; /* Set of import paths */
|
SySet aPaths; /* Set of import paths */
|
||||||
SySet aIncluded; /* Set of included files */
|
SySet aIncluded; /* Set of included files */
|
||||||
|
|
73
vm.c
73
vm.c
|
@ -96,6 +96,18 @@ struct VmObEntry {
|
||||||
ph7_value sCallback; /* User defined callback */
|
ph7_value sCallback; /* User defined callback */
|
||||||
SyBlob sOB; /* Output buffer consumer */
|
SyBlob sOB; /* Output buffer consumer */
|
||||||
};
|
};
|
||||||
|
/*
|
||||||
|
* Information about each module library (loaded using [import()] )
|
||||||
|
* is stored in an instance of the following structure.
|
||||||
|
*/
|
||||||
|
typedef struct VmModule VmModule;
|
||||||
|
struct VmModule {
|
||||||
|
void *pHandle; /* Module handler */
|
||||||
|
SyString sName; /* Module name */
|
||||||
|
SyString sFile; /* Module library file */
|
||||||
|
SyString sDesc; /* Module short description */
|
||||||
|
ph7_real fVer; /* Module version */
|
||||||
|
};
|
||||||
/*
|
/*
|
||||||
* Each installed class autoload callback (registered using [register_autoload_handler()] )
|
* Each installed class autoload callback (registered using [register_autoload_handler()] )
|
||||||
* is stored in an instance of the following structure.
|
* is stored in an instance of the following structure.
|
||||||
|
@ -1238,6 +1250,7 @@ PH7_PRIVATE sxi32 PH7_VmInit(
|
||||||
SySetInit(&pVm->aShutdown, &pVm->sAllocator, sizeof(VmShutdownCB));
|
SySetInit(&pVm->aShutdown, &pVm->sAllocator, sizeof(VmShutdownCB));
|
||||||
SySetInit(&pVm->aException, &pVm->sAllocator, sizeof(ph7_exception *));
|
SySetInit(&pVm->aException, &pVm->sAllocator, sizeof(ph7_exception *));
|
||||||
/* Configuration containers */
|
/* Configuration containers */
|
||||||
|
SySetInit(&pVm->aModules, &pVm->sAllocator, sizeof(VmModule));
|
||||||
SySetInit(&pVm->aFiles, &pVm->sAllocator, sizeof(SyString));
|
SySetInit(&pVm->aFiles, &pVm->sAllocator, sizeof(SyString));
|
||||||
SySetInit(&pVm->aPaths, &pVm->sAllocator, sizeof(SyString));
|
SySetInit(&pVm->aPaths, &pVm->sAllocator, sizeof(SyString));
|
||||||
SySetInit(&pVm->aIncluded, &pVm->sAllocator, sizeof(SyString));
|
SySetInit(&pVm->aIncluded, &pVm->sAllocator, sizeof(SyString));
|
||||||
|
@ -10713,6 +10726,64 @@ static sxi32 VmExecIncludedFile(
|
||||||
#endif /* PH7_DISABLE_BUILTIN_FUNC */
|
#endif /* PH7_DISABLE_BUILTIN_FUNC */
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* bool import(string $library)
|
||||||
|
* Loads a P# module library at runtime
|
||||||
|
* Parameters
|
||||||
|
* $library
|
||||||
|
* This parameter is only the module library name that should be loaded.
|
||||||
|
* Return
|
||||||
|
* Returns TRUE on success or FALSE on failure
|
||||||
|
*/
|
||||||
|
static int vm_builtin_import(ph7_context *pCtx, int nArg, ph7_value **apArg) {
|
||||||
|
const char *zStr;
|
||||||
|
VmModule pModule, *pSearch;
|
||||||
|
int nLen;
|
||||||
|
if(nArg != 1 || !ph7_value_is_string(apArg[0])) {
|
||||||
|
/* Missing/Invalid arguments, return FALSE */
|
||||||
|
ph7_result_bool(pCtx, 0);
|
||||||
|
return PH7_OK;
|
||||||
|
}
|
||||||
|
/* Extract the given module name */
|
||||||
|
zStr = ph7_value_to_string(apArg[0], &nLen);
|
||||||
|
if(nLen < 1) {
|
||||||
|
/* Nothing to process, return FALSE */
|
||||||
|
ph7_result_bool(pCtx, 0);
|
||||||
|
return PH7_OK;
|
||||||
|
}
|
||||||
|
while(SySetGetNextEntry(&pCtx->pVm->aModules, (void **)&pSearch) == SXRET_OK) {
|
||||||
|
if(SyMemcmp(pSearch->sName.zString, zStr, 0) == 0) {
|
||||||
|
SySetResetCursor(&pCtx->pVm->aModules);
|
||||||
|
ph7_result_bool(pCtx, 1);
|
||||||
|
return PH7_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SySetResetCursor(&pCtx->pVm->aModules);
|
||||||
|
/* Zero the module entry */
|
||||||
|
SyZero(&pModule, sizeof(VmModule));
|
||||||
|
SyStringInitFromBuf(&pModule.sName, zStr, nLen);
|
||||||
|
const unsigned char *file;
|
||||||
|
snprintf(file, 255, "./%s.lib", zStr);
|
||||||
|
SyStringInitFromBuf(&pModule.sFile, file, nLen);
|
||||||
|
pModule.pHandle = dlopen(pModule.sFile.zString, RTLD_LAZY);
|
||||||
|
if(!pModule.pHandle) {
|
||||||
|
/* Could not load the module library file */
|
||||||
|
ph7_result_bool(pCtx, 0);
|
||||||
|
return PH7_OK;
|
||||||
|
}
|
||||||
|
void (*init)(ph7_vm *, ph7_real *, SyString *) = dlsym(pModule.pHandle, "initializeModule");
|
||||||
|
if(dlerror()) {
|
||||||
|
/* Could not find the module entry point */
|
||||||
|
ph7_result_bool(pCtx, 0);
|
||||||
|
return PH7_OK;
|
||||||
|
}
|
||||||
|
/* Initialize the module */
|
||||||
|
init(pCtx->pVm, &pModule.fVer, &pModule.sDesc);
|
||||||
|
/* Put information about module on top of the modules stack */
|
||||||
|
SySetPut(&pCtx->pVm->aModules, (const void *)&pModule);
|
||||||
|
ph7_result_bool(pCtx, 1);
|
||||||
|
return PH7_OK;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* string get_include_path(void)
|
* string get_include_path(void)
|
||||||
* Gets the current include_path configuration option.
|
* Gets the current include_path configuration option.
|
||||||
|
@ -13705,6 +13776,8 @@ static const ph7_builtin_func aVmFunc[] = {
|
||||||
{"json_encode", vm_builtin_json_encode },
|
{"json_encode", vm_builtin_json_encode },
|
||||||
{"json_last_error", vm_builtin_json_last_error},
|
{"json_last_error", vm_builtin_json_last_error},
|
||||||
{"json_decode", vm_builtin_json_decode },
|
{"json_decode", vm_builtin_json_decode },
|
||||||
|
/* Module loading facility */
|
||||||
|
{ "import", vm_builtin_import },
|
||||||
/* Files/URI inclusion facility */
|
/* Files/URI inclusion facility */
|
||||||
{ "get_include_path", vm_builtin_get_include_path },
|
{ "get_include_path", vm_builtin_get_include_path },
|
||||||
{ "get_included_files", vm_builtin_get_included_files},
|
{ "get_included_files", vm_builtin_get_included_files},
|
||||||
|
|
Loading…
Reference in New Issue