Simplify external management
This commit is contained in:
Родитель
895a07683a
Коммит
6836f77e56
|
@ -4,4 +4,4 @@ OUTPUT=${OUTPUT:=.}
|
|||
INPUT=${INPUT:=src}
|
||||
QUICKJS=${QUICKJS:=./quickjs}
|
||||
|
||||
emcc -o ${OUTPUT}/quickjs-eval.js ${INPUT}/exports.c ${QUICKJS}/quickjs.c ${QUICKJS}/cutils.c ${QUICKJS}/libregexp.c ${QUICKJS}/libunicode.c -I${QUICKJS} -I${INPUT} -DCONFIG_VERSION="\"1.0.0\"" -s WASM=1 -s SINGLE_FILE -s MODULARIZE=1 -s EXPORT_ES6=1 -s USE_ES6_IMPORT_META=0 -s ENVIRONMENT='web' -lm -Oz -s EXPORTED_FUNCTIONS='["_initSandbox", "_commFun", "_evalInSandbox", "_nukeSandbox", "_dumpMemoryUse"]' -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' -s AGGRESSIVE_VARIABLE_ELIMINATION=1 --closure 1 --js-library ${INPUT}/myjs.js
|
||||
emcc -o ${OUTPUT}/quickjs-eval.js ${INPUT}/exports.c ${QUICKJS}/quickjs.c ${QUICKJS}/cutils.c ${QUICKJS}/libregexp.c ${QUICKJS}/libunicode.c -I${QUICKJS} -I${INPUT} -DCONFIG_VERSION="\"1.0.0\"" -s WASM=1 -s SINGLE_FILE -s MODULARIZE=1 -s EXPORT_ES6=1 -s USE_ES6_IMPORT_META=0 -s ENVIRONMENT='web' -lm -Oz -s EXPORTED_FUNCTIONS='["_init", "_commFun", "_evalInSandbox", "_nukeSandbox", "_dumpMemoryUse"]' -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap", "addFunction", "externalCall"]' -s AGGRESSIVE_VARIABLE_ELIMINATION=1 --closure 1 --js-library ${INPUT}/myjs.js --pre-js ${INPUT}/pre.js
|
||||
|
|
|
@ -107,7 +107,7 @@ void nukeSandbox() {
|
|||
runtime = NULL;
|
||||
}
|
||||
|
||||
BOOL initSandbox(const char* init, int alertOnError) {
|
||||
BOOL init(const char* init, int alertOnError) {
|
||||
JSValue result;
|
||||
|
||||
if (unlikely(runtime)) {
|
||||
|
|
46
src/myjs.js
46
src/myjs.js
|
@ -21,42 +21,20 @@
|
|||
mergeInto(LibraryManager.library, {
|
||||
$externals__postset: "externals();",
|
||||
$externals: function () {
|
||||
const externals = window["sandboxExternals"];
|
||||
_setTimeout = (id, n) => externals["setTimeout"](id, n);
|
||||
_clearTimeout = (id) => externals["clearTimeout"](id);
|
||||
_setInterval = (id, n) => externals["setInterval"](id, n);
|
||||
_clearInterval = (id) => externals["clearInterval"](id);
|
||||
_cleanTimeouts = () => externals["cleanTimeouts"]();
|
||||
_alert = (s) => externals["alert"](UTF8ToString(s));
|
||||
_prompt = (q, d) => {
|
||||
const response = externals["prompt"](UTF8ToString(q), UTF8ToString(d));
|
||||
if (response !== null) {
|
||||
return stringToNewUTF8(response);
|
||||
}
|
||||
_callExternalFunction = (name, args) => {
|
||||
name = UTF8ToString(name);
|
||||
args = args !== null ? UTF8ToString(args) : null;
|
||||
const result = Module["externalCall"](name, args);
|
||||
if (!result) {
|
||||
return null;
|
||||
}
|
||||
_parseURL = (s) => stringToNewUTF8(externals["parseURL"](UTF8ToString(s)));
|
||||
_sendToWindow = (s) => externals["send"](UTF8ToString(s));
|
||||
|
||||
return stringToNewUTF8(result);
|
||||
};
|
||||
},
|
||||
setTimeout: function () {},
|
||||
setTimeout__deps: ["$externals"],
|
||||
clearTimeout: function () {},
|
||||
clearTimeout__deps: ["$externals"],
|
||||
setInterval: function () {},
|
||||
setInterval__deps: ["$externals"],
|
||||
clearInterval: function () {},
|
||||
clearInterval__deps: ["$externals"],
|
||||
cleanTimeouts: function () {},
|
||||
cleanTimeouts__deps: ["$externals"],
|
||||
alert: function () {},
|
||||
alert__deps: ["$externals"],
|
||||
prompt: function () {},
|
||||
prompt__deps: ["$externals", "$stringToNewUTF8"],
|
||||
parseURL: function () {},
|
||||
parseURL__deps: ["$externals", "$stringToNewUTF8"],
|
||||
sendToWindow: function () {},
|
||||
sendToWindow__deps: ["$externals", "$stringToNewUTF8"],
|
||||
debugMe: function (ptr, alert) {
|
||||
callExternalFunction: function () {},
|
||||
callExternalFunction__deps: ["$externals", "$stringToNewUTF8"],
|
||||
dump: function (ptr, alert) {
|
||||
const string = UTF8ToString(ptr);
|
||||
let data;
|
||||
try {
|
||||
|
@ -67,7 +45,7 @@ mergeInto(LibraryManager.library, {
|
|||
if (alert !== 0) {
|
||||
window.alert(string);
|
||||
} else {
|
||||
window.console.log("DEBUGME", data);
|
||||
window.console.log("DUMP", data);
|
||||
}
|
||||
},
|
||||
printError: function (name_ptr, message_ptr, stack_ptr, alertOnError) {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
Module["externalCall"] = () => {};
|
|
@ -18,11 +18,9 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define DEBUG_ME 1
|
||||
#if DEBUG_ME != 0
|
||||
#define DEBUGME JS_CFUNC_DEF("debugMe", 2, js_debugMe ),
|
||||
extern void debugMe(const char*, const int);
|
||||
static JSValue js_debugMe(JSContext *ctx, JSValueConst this_val,
|
||||
#define DUMP JS_CFUNC_DEF("dump", 2, js_dump ),
|
||||
extern void dump(const char*, const int);
|
||||
static JSValue js_dump(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
const char *str;
|
||||
|
@ -30,13 +28,12 @@ static JSValue js_debugMe(JSContext *ctx, JSValueConst this_val,
|
|||
JSValue json;
|
||||
|
||||
if (argc < 1 || argc > 2) {
|
||||
return JS_EXCEPTION;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
json = JS_JSONStringify(ctx, argv[0], JS_UNDEFINED, JS_UNDEFINED);
|
||||
if (JS_IsException(json)) {
|
||||
JS_FreeValue(ctx, json);
|
||||
return JS_EXCEPTION;
|
||||
return json;
|
||||
}
|
||||
str = JS_ToCString(ctx, json);
|
||||
JS_FreeValue(ctx, json);
|
||||
|
@ -48,239 +45,59 @@ static JSValue js_debugMe(JSContext *ctx, JSValueConst this_val,
|
|||
alert = JS_ToBool(ctx, argv[1]);
|
||||
}
|
||||
|
||||
debugMe(str, alert);
|
||||
dump(str, alert);
|
||||
|
||||
JS_FreeCString(ctx, str);
|
||||
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
#else
|
||||
#define DEBUGME
|
||||
#endif
|
||||
|
||||
#define SEND JS_CFUNC_DEF("send", 1, js_send),
|
||||
extern void sendToWindow(const char*);
|
||||
static JSValue js_send(JSContext *ctx, JSValueConst this_val,
|
||||
#define CALLEXTERNALFUNCTION JS_CFUNC_DEF("callExternalFunction", 2, js_callExternalFunction),
|
||||
extern const char* callExternalFunction(const char*, const char*);
|
||||
static JSValue js_callExternalFunction(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
const char *str;
|
||||
JSValue json = JS_JSONStringify(ctx, argv[0], JS_UNDEFINED, JS_UNDEFINED);
|
||||
if (JS_IsException(json)) {
|
||||
JS_FreeValue(ctx, json);
|
||||
const char *name, *str = NULL, *result;
|
||||
JSValue json, obj;
|
||||
|
||||
if (argc < 1 || argc > 2) {
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
name = JS_ToCString(ctx, argv[0]);
|
||||
if (!name) {
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
if (argc == 2) {
|
||||
json = JS_JSONStringify(ctx, argv[1], JS_UNDEFINED, JS_UNDEFINED);
|
||||
if (JS_IsException(json)) {
|
||||
JS_FreeCString(ctx, name);
|
||||
return json;
|
||||
}
|
||||
str = JS_ToCString(ctx, json);
|
||||
JS_FreeValue(ctx, json);
|
||||
|
||||
sendToWindow(str);
|
||||
|
||||
JS_FreeCString(ctx, str);
|
||||
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
#define SETTIMEOUT JS_CFUNC_DEF("setTimeout", 2, js_setTimeout),
|
||||
extern void setTimeout(int32_t, double);
|
||||
static JSValue js_setTimeout(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
int32_t callbackId;
|
||||
double millisecs = 0.;
|
||||
int id;
|
||||
|
||||
if (argc < 1 || argc > 2) {
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
if (argc == 2 && JS_ToFloat64(ctx, &millisecs, argv[1])) {
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
if (JS_ToInt32(ctx, &callbackId, argv[0])) {
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
setTimeout(callbackId, millisecs);
|
||||
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
#define CLEARTIMEOUT JS_CFUNC_DEF("clearTimeout", 1, js_clearTimeout),
|
||||
extern void clearTimeout(int32_t);
|
||||
static JSValue js_clearTimeout(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
int32_t id;
|
||||
|
||||
if (argc != 1) {
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
if (JS_ToInt32(ctx, &id, argv[0])) {
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
clearTimeout(id);
|
||||
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
#define SETINTERVAL JS_CFUNC_DEF("setInterval", 2, js_setInterval),
|
||||
extern void setInterval(int32_t, double);
|
||||
static JSValue js_setInterval(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
int32_t callbackId;
|
||||
double millisecs = 0.;
|
||||
int id;
|
||||
|
||||
if (argc < 1 || argc > 2) {
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
if (argc == 2 && JS_ToFloat64(ctx, &millisecs, argv[1])) {
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
if (JS_ToInt32(ctx, &callbackId, argv[0])) {
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
setInterval(callbackId, millisecs);
|
||||
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
#define CLEARINTERVAL JS_CFUNC_DEF("clearInterval", 1, js_clearInterval),
|
||||
extern void clearInterval(int32_t);
|
||||
static JSValue js_clearInterval(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
int32_t id;
|
||||
|
||||
if (argc != 1) {
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
if (JS_ToInt32(ctx, &id, argv[0])) {
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
clearInterval(id);
|
||||
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
#define CLEANTIMEOUTS JS_CFUNC_DEF("cleanTimeouts", 0, js_cleanTimeouts),
|
||||
extern void cleanTimeouts();
|
||||
static JSValue js_cleanTimeouts(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
cleanTimeouts();
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
|
||||
#define PARSEURL JS_CFUNC_DEF("parseURL", 1, js_parseURL),
|
||||
extern char* parseURL(const char*);
|
||||
static JSValue js_parseURL(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
const char *str;
|
||||
const char *result;
|
||||
size_t resultLen;
|
||||
JSValue obj;
|
||||
|
||||
if (argc != 1) {
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
str = JS_ToCString(ctx, argv[0]);
|
||||
if (!str) {
|
||||
JS_FreeCString(ctx, name);
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
}
|
||||
|
||||
result = parseURL(str);
|
||||
result = callExternalFunction(name, str);
|
||||
JS_FreeCString(ctx, name);
|
||||
JS_FreeCString(ctx, str);
|
||||
resultLen = strlen(result);
|
||||
|
||||
obj = JS_ParseJSON(ctx, result, resultLen, "<input>");
|
||||
if (!result) {
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
obj = JS_ParseJSON(ctx, result, strlen(result), "<output>");
|
||||
#ifdef free
|
||||
#undef free
|
||||
#endif
|
||||
free((void*)result);
|
||||
|
||||
if (JS_IsException(obj)) {
|
||||
JS_FreeValue(ctx, obj);
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
#define ALERT JS_CFUNC_DEF("alert", 1, js_alert),
|
||||
extern void alert(const char*);
|
||||
static JSValue js_alert(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
if (argc != 1) {
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
str = JS_ToCString(ctx, argv[0]);
|
||||
if (!str) {
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
alert(str);
|
||||
|
||||
JS_FreeCString(ctx, str);
|
||||
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
#define PROMPT JS_CFUNC_DEF("prompt", 2, js_prompt),
|
||||
extern const char* prompt(const char*, const char*);
|
||||
static JSValue js_prompt(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
const char *quest, *def, *res;
|
||||
JSValue val;
|
||||
|
||||
if (argc < 1 || argc > 2) {
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
quest = JS_ToCString(ctx, argv[0]);
|
||||
if (!quest) {
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
if (argc == 2) {
|
||||
def = JS_ToCString(ctx, argv[1]);
|
||||
if (!def) {
|
||||
JS_FreeCString(ctx, quest);
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
res = prompt(quest, def);
|
||||
JS_FreeCString(ctx, def);
|
||||
} else {
|
||||
res = prompt(quest, "");
|
||||
}
|
||||
|
||||
JS_FreeCString(ctx, quest);
|
||||
if (res) {
|
||||
val = JS_NewStringLen(ctx, res, strlen(res));
|
||||
|
||||
#ifdef free
|
||||
#undef free
|
||||
#endif
|
||||
free((void*)res);
|
||||
} else {
|
||||
val = JS_NULL;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
#define EXTRA SEND SETTIMEOUT CLEARTIMEOUT SETINTERVAL CLEARINTERVAL CLEANTIMEOUTS PARSEURL ALERT PROMPT DEBUGME
|
||||
#define EXTRA CALLEXTERNALFUNCTION DUMP
|
||||
|
|
Загрузка…
Ссылка в новой задаче