This commit is contained in:
Calixte Denizet 2020-12-15 15:33:43 +01:00
Родитель 895a07683a
Коммит 6836f77e56
5 изменённых файлов: 76 добавлений и 260 удалений

Просмотреть файл

@ -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)) {

Просмотреть файл

@ -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;
}
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) {

21
src/pre.js Normal file
Просмотреть файл

@ -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,25 +18,22 @@
* 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,
int argc, JSValueConst *argv)
#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;
int alert = 0;
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,
int argc, JSValueConst *argv)
#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)) {
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);
return JS_EXCEPTION;
if (!str) {
JS_FreeCString(ctx, name);
return JS_EXCEPTION;
}
}
str = JS_ToCString(ctx, json);
JS_FreeValue(ctx, json);
sendToWindow(str);
result = callExternalFunction(name, str);
JS_FreeCString(ctx, name);
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 (!result) {
return JS_UNDEFINED;
}
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) {
return JS_EXCEPTION;
}
result = parseURL(str);
JS_FreeCString(ctx, str);
resultLen = strlen(result);
obj = JS_ParseJSON(ctx, result, resultLen, "<input>");
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