提交 2cff6620 编写于 作者: yma16's avatar yma16

update

上级 d9f8feae
...@@ -81,6 +81,8 @@ App({ ...@@ -81,6 +81,8 @@ App({
}, },
// 引入`towxml3.0`解析方法 // 引入`towxml3.0`解析方法
towxml: require('/towxml/index'), towxml: require('/towxml/index'),
// 引入eval 自定义的eval
eval_des: require('/eval-pack/define-function/define-function'),
/** /**
* 转换text * 转换text
* @param {string} text * @param {string} text
......
MIT License
Copyright (c) 2022 Tao Wen
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.
# About
[quick.js](https://bellard.org/quickjs/) based sandbox
```
npm install define-function
```
works in any WebAssembly environment
* node
* browser
* wechat miniprogram
# Usage
define a function dynamically with javascript source code
```js
const def = require('define-function')
const f = await def(`
return 'hello';
`)
f() // 'hello'
```
function can have argument
```js
const def = require('define-function')
const f = await def(`
const [hello, world] = arguments;
return hello + ' ' + world;
`)
f('hello', 'world') // 'hello world'
```
argument can be function
```js
const def = require('define-function')
const f = await def(`
const [print] = arguments;
print('hello')
`)
f((msg) => {
console.log(msg)
}) // 'hello'
```
argument can be async function
```js
const def = require('define-function')
const f = await def(`
const [print, sleep] = arguments;
(async() => {
print('hello')
await sleep(1000);
print('world')
})();
`)
f(
msg => console.log(msg),
milliseconds => new Promise(resolve => setTimeout(resolve, milliseconds))
)
// hello
// world
```
can return promise back to host
```js
const def = require('define-function')
const f = await def(`
const [print, sleep] = arguments;
return (async() => {
print('hello')
await sleep(1000);
print('world')
})();
`)
await f(
msg => console.log(msg),
milliseconds => new Promise(resolve => setTimeout(resolve, milliseconds))
)
console.log('done')
// hello
// world
// done
```
share context between multiple invocations
```js
const { context } = require('define-function')
const ctx = context()
const f = await ctx.def(`
global.counter = (global.counter || 0)+1;
return counter; // counter can be referenced globally
`)
f() // 1
f() // 2
f() // 3
ctx.dispose()
```
inject value and callbacks into global
```js
const { context } = require('define-function')
const ctx = context({ global: {
console,
anwerOfEverything() {
return 42;
}
} }) // inject console and anwerOfEverything to global
const f = await ctx.def(`
console.log(anwerOfEverything());
`)
f() // 42
ctx.dispose();
```
import and export es module
```js
const { context } = require('define-function')
const ctx = context({
loadModuleContent(moduleName) {
if (moduleName !== 'xxx') {
throw new Error('expect xxx');
}
return `export function sayHello() { return 'hello' }`
}
});
const { hello } = await ctx.load(`
import { sayHello } from 'xxx';
export const hello = sayHello();
`)
console.log(hello) // hello
ctx.dispose();
```
# Limit
* function argument does not support Set/Map/Class or anything that can not survive JSON.parse(JSON.stringify), except the argument is a function
* function return value does not support Set/Map/Class or anything that can not survive JSON.parse(JSON.stringify), except promise object
* JSON.stringify and JSON.parse takes time, so the arguments and return value should be as small as possible for best performance
# Similar projects
* https://github.com/justjake/quickjs-emscripten/
* https://github.com/maple3142/wasm-jseval
define-function has a simpler API and support async/await
type sandboxFunctionToken = { __brand: 'sandboxFunctionToken' }
declare const __s__: {
wrapSandboxFunction(f: Function, extra?: { once?: boolean }): sandboxFunctionToken;
deleteSandboxFunction(token: sandboxFunctionToken);
getProp(hostObj: any, prop: string): any;
setProp(hostObj: any, prop: string, value: any): void;
callMethod(hostObj: any, method: string, ...args: any[]): any;
deleteHostObject(hostObj: any): void;
};
\ No newline at end of file
let wasm = undefined;
let nextId = 1;
const contexts = new Map();
// import {a, b} from 'xxx'
// import ab from 'xxx'
// import * as ab from 'xxx'
const re1 = /import\s+[\w\s,\*\}\{]*?\s+from\s+['"]([^'"]+)['"]/g;
// import 'xxx'
const re2 = /import\s+['"]([^'"]+)['"]/g;
// export * from 'xxx'
const re3 = /export\s+[\w\s,\*\}\{]*?\s+from\s+['"]([^'"]+)['"]/g;
const res = [re1, re2, re3];
function* extractImportFroms(script) {
if (!script) {
return
}
for (const re of res) {
for (const match of script.matchAll(re)) {
yield match[1];
}
}
}
class Context {
options = undefined;
ctx = undefined;
moduleContents = {};
createPromise;
invokeSandboxFunction;
deleteSandboxFunction;
hostFunctions = new Map();
constructor(options) {
this.options = options;
this.ctx = wasm._newContext();
contexts.set(this.ctx, this);
this.loadSync(`
global.__s__ = global.__s__ || {
nextId: 1,
promises: new Map(),
callbacks: new Map(),
callbacksLookup: new Map(),
inspectingObjects: new Map(),
currentStack: '',
hostInspect: undefined, // inject later
createPromise() {
const promiseId = this.nextId++;
const result = { __p__: promiseId };
this.promises.set(promiseId, new Promise((resolve, reject) => {
result.resolve = this.wrapSandboxFunction(resolve);
result.reject = this.wrapSandboxFunction(reject);
}));
return result;
},
wrapSandboxFunction(callback, extra) {
let callbackId = this.callbacksLookup.get(callback);
if (callbackId === undefined) {
callbackId = this.nextId++;
this.callbacks.set(callbackId, callback);
this.callbacksLookup.set(callback, callbackId);
}
return { __c__: callbackId, ...extra };
},
getAndDeletePromise(promiseId) {
const promise = this.promises.get(promiseId);
this.promises.delete(promiseId);
return promise;
},
invokeSandboxFunction(callbackToken, args) {
const callbackId = callbackToken.__c__;
if (!callbackId) {
throw new Error('invokeSandboxFunction with invalid token: ' + JSON.stringify(callbackToken));
}
const callback = this.callbacks.get(callbackId);
if (!callback) {
return undefined;
}
return callback.apply(undefined, args);
},
deleteSandboxFunction(callbackToken) {
const callbackId = callbackToken.__c__;
if (!callbackId) {
throw new Error('deleteSandboxFunction with invalid token: ' + JSON.stringify(callbackToken));
}
let callback = this.callbacks.get(callbackId);
if (callback !== undefined) {
this.callbacks.delete(callbackId);
this.callbacksLookup.delete(callback);
}
},
inspect(msg, obj) {
const objId = this.nextId++;
this.inspectingObjects.set(objId, obj);
this.hostInspect(msg, typeof obj === 'object' ? { __o__: objId, keys: Reflect.ownKeys(obj) } : obj);
},
getInspectingObjectProp(objId, prop) {
const val = this.inspectingObjects.get(objId)[prop];
if (val && typeof val === 'object') {
const valObjId = this.nextId++;
this.inspectingObjects.set(valObjId, val);
return { __o__: valObjId, keys: Reflect.ownKeys(val) };
}
return val;
},
asHostFunction(hostFunctionToken) {
return (...args) => {
return this.invokeHostFunction(hostFunctionToken, args);
};
},
invokeHostFunction(hostFunctionToken, args) {
if (!hostFunctionToken.nowrap) {
args = args.map(arg => typeof arg === 'function' ? this.wrapSandboxFunction(arg, { once: true }) : arg);
if (args[0] && typeof args[0] === 'object') {
for (const [k, v] of Object.entries(args[0])) {
if (typeof v === 'function') {
args[0][k] = this.wrapSandboxFunction(v, { once: true });
}
}
}
}
const invokeResult = __invokeHostFunction(JSON.stringify(hostFunctionToken), JSON.stringify(args));
if (hostFunctionToken.returnsHostObject && invokeResult?.__h__) {
return this.asHostFunction(invokeResult);
}
if (invokeResult?.__p__) {
return this.getAndDeletePromise(invokeResult.__p__);
}
return invokeResult;
},
callMethod(hostObj, method, ...args) {
const result = hostObj('callMethod', method, args);
return result?.__h__ ? this.asHostFunction(result) : result;
},
getProp(hostObj, prop) {
return hostObj('getProp', prop);
},
setProp(hostObj, prop, propVal) {
return hostObj('setProp', prop, propVal);
},
deleteHostObject(hostObj) {
return hostObj('delete');
}
};
`);
this.createPromise = this.def(`return __s__.createPromise()`);
this.invokeSandboxFunction = this.def(`return __s__.invokeSandboxFunction(...arguments)`);
this.deleteSandboxFunction = this.def(`return __s__.deleteSandboxFunction(...arguments)`);
this.getInspectingObjectProp = this.def(`return __s__.getInspectingObjectProp(...arguments)`);
this.currentStack = this.def(`return __s__.currentStack`);
if (options?.global) {
this.inject('global', options.global);
for (const [k, v] of Object.entries(options.global)) {
if (typeof v === 'object') {
this.inject(k, v);
}
}
}
this.def(`__s__.hostInspect = arguments[0]`)(this.wrapHostFunction(this.hostInspect.bind(this), { nowrap: true }));
}
dispose() {
if (!this.ctx) {
return; // already disposed
}
for (const pModuleContent of Object.values(this.moduleContents)) {
wasm._free(pModuleContent);
}
wasm._freeContext(this.ctx);
contexts.delete(this.ctx);
this.ctx = undefined;
}
hostInspect(msg, obj) {
obj = this.wrapProxy(obj);
console.warn('inspecting...', msg, obj);
debugger;
}
wrapProxy(obj) {
if (!obj) {
return obj;
}
if (!obj.__o__) {
return obj;
}
const proxy = {};
for (const key of obj.keys) {
Object.defineProperty(proxy, key, {
enumerable: true,
get: () => {
return this.wrapProxy(this.getInspectingObjectProp(obj.__o__, key));
}
});
}
return proxy;
}
asSandboxFunction(callbackToken) {
let calledOnce = false;
return (...args) => {
if (!this.ctx) {
return;
}
if (callbackToken.once) {
if (calledOnce) {
throw new Error(`callback ${JSON.stringify(callbackToken)} can only be callback once, if need to callback multiple times, use __s__.wrapSandboxFunction to manage callback lifetime explicitly`)
}
calledOnce = true;
}
try {
return this.invokeSandboxFunction(callbackToken, args);
} finally {
if (callbackToken.once) {
this.deleteSandboxFunction(callbackToken);
}
}
}
}
inject(target, obj) {
const args = [target];
for (const [k, v] of Object.entries(obj)) {
if (typeof v === 'function') {
args.push(k);
args.push(this.wrapHostFunction(v))
} else {
args.push(k);
args.push(v);
}
}
const f = this.def(`
const obj = global[arguments[0]] = global[arguments[0]] || {};
for (let i = 1; i < arguments.length; i+=2) {
obj[arguments[i]] = arguments[i+1];
}`);
f(...args);
}
async dynamicImport({ctx, argc, argv, resolveFunc, rejectFunc, basename, filename }) {
try {
if (this.options?.loadModuleContent) {
await this.require(basename, filename)
}
} catch(e) {
wasm._call(ctx, rejectFunc, allocateUTF8(JSON.stringify(`failed to dynamicImport: ${e}`)));
wasm._freeJsValue(ctx, resolveFunc);
wasm._freeJsValue(ctx, rejectFunc);
wasm._free(argv);
return;
}
wasm._doDynamicImport(ctx, argc, argv);
wasm._freeJsValue(ctx, resolveFunc);
wasm._freeJsValue(ctx, rejectFunc);
wasm._free(argv);
}
async require(basename, filename) {
if (!this.options?.loadModuleContent) {
throw new Error(`missing options.loadModuleContent can not load content of ${filename} imported by ${basename}`);
}
let moduleName = filename;
if (filename[0] === '.') {
const pBasename = allocateUTF8(basename);
const pFilename = allocateUTF8(filename);
const pModuleName = wasm._pathJoin(this.ctx, pBasename, pFilename);
moduleName = wasm.UTF8ToString(pModuleName);
wasm._free(pModuleName);
}
if (this.moduleContents[moduleName] !== undefined) {
return;
}
this.moduleContents[moduleName] = 0;
const content = await this.options.loadModuleContent(moduleName, { basename, filename });
this.moduleContents[moduleName] = allocateUTF8(content);
const promises = [];
for (const importFrom of extractImportFroms(content)) {
promises.push(this.require(moduleName, importFrom));
}
await Promise.all(promises);
}
loadSync(content, options) {
const filename = options?.filename || `<load${nextId++}>`;
const pScript = allocateUTF8(content);
const pScriptName = allocateUTF8(filename)
const meta = options?.meta || { url: filename };
const pMeta = allocateUTF8(JSON.stringify(meta));
const pError = wasm._load(this.ctx, pScript, pScriptName, pMeta);
if (pError) {
const error = new Error(wasm.UTF8ToString(pError));
wasm._free(pError);
throw error;
}
}
async load(content, options) {
const filename = options?.filename || `<load${nextId++}>`;
const promises = [];
for (const importFrom of extractImportFroms(content)) {
promises.push(this.require(filename, importFrom));
}
await Promise.all(promises);
this.loadSync(content, { ...options, filename });
if (!this._loadModule) {
this._loadModule = await this.def(`
return (async() => {
const [moduleName] = arguments;
const m = await import(moduleName);
const exports = {};
for(const [k, v] of Object.entries(m)) {
if (typeof v === 'function') {
exports[k] = __s__.wrapSandboxFunction(v);
} else {
exports[k] = v;
}
}
return JSON.stringify(exports);
})();
`)
}
const loadedModule = JSON.parse(await this._loadModule(filename));
for (const [k, v] of Object.entries(loadedModule)) {
if (v?.__c__) {
loadedModule[k] = this.asSandboxFunction(v);
}
}
return loadedModule;
}
def(script, options) {
if (!this.ctx) {
throw new Error('context has been disposed');
}
return (...args) => {
if (!this.ctx) {
throw new Error('context has been disposed');
}
const invocation = new Invocation(this, options?.timeout);
const setSuccessToken = invocation.wrapHostFunction(invocation.setSuccess.bind(invocation), { nowrap: true });
const setFailureToken = invocation.wrapHostFunction(invocation.setFailure.bind(invocation), { nowrap: true });
const encodedArgs = args.map((arg, index) => typeof arg === 'function' ? invocation.wrapHostFunction(arg, { argIndex: index}) : arg);
this.loadSync(`
(() => {
const setSuccess = __s__.asHostFunction(${JSON.stringify(setSuccessToken)});
const setFailure = __s__.asHostFunction(${JSON.stringify(setFailureToken)});
const args = ${JSON.stringify(encodedArgs)};
function f() {
${script}
}
try {
const result = f.apply(undefined, args.map(arg => arg?.__h__ ? __s__.asHostFunction(arg) : arg));
if (result && result.then && result.catch) {
result
.then(v => { setSuccess(v); })
.catch(e => { setFailure('' + e + '' + e.stack); })
} else {
setSuccess(result);
}
} catch(e) {
setFailure('' + e + '' + e.stack);
}
})();
`, options);
(async () => {
try {
await invocation.asyncResult;
} catch (e) {
// ignore
} finally {
invocation.dispose();
}
})();
return invocation.syncResult();
}
}
wrapHostFunction(f, extra) {
const hfId = nextId++;
this.hostFunctions.set(hfId, f);
return { __h__: hfId, ...extra }
}
deleteHostFunction(hostFunctionToken) {
const hfId = hostFunctionToken.__h__;
if (!hfId) {
throw new Error('deleteHostFunction with invalid token: ' + JSON.stringify(hostFunctionToken));
}
this.hostFunctions.delete(hfId);
}
invokeHostFunction(hostFunctionToken, args) {
const hfId = hostFunctionToken.__h__;
if (!hfId) {
throw new Error('callHostFunction with invalid token: ' + JSON.stringify(hostFunctionToken));
}
if (!hostFunctionToken.nowrap) {
args = args.map(arg => arg?.__c__ ? this.asSandboxFunction(arg) : arg);
if (args[0] && typeof args[0] === 'object') {
for (const [k, v] of Object.entries(args[0])) {
if (v?.__c__) {
args[0][k] = this.asSandboxFunction(v);
}
}
}
}
const hostFunc = this.hostFunctions.get(hfId);
if (hostFunc === undefined) {
throw new Error('host function not found: ' + JSON.stringify(hostFunctionToken));
}
const invokeResult = hostFunc(...args);
if (invokeResult && invokeResult.then && invokeResult.catch) {
const { __p__, resolve, reject } = this.createPromise();
invokeResult
.then(v => {
if (this.ctx) {
this.invokeSandboxFunction(resolve, [v]);
}
})
.catch(e => {
if (this.ctx) {
this.invokeSandboxFunction(reject, ['' + e]);
}
})
.finally(() => {
if (this.ctx) {
this.deleteSandboxFunction(resolve);
this.deleteSandboxFunction(reject);
}
});
return { __p__ };
}
if (hostFunctionToken.returnsHostObject) {
return this.wrapHostObject(invokeResult);
}
return invokeResult;
}
wrapHostObject(val) {
if (!val) {
return val;
}
if (typeof val !== 'object') {
return val;
}
const token = this.wrapHostFunction((action, prop, args) => {
switch(action) {
case 'callMethod':
return this.wrapHostObject(val[prop](...args));
case 'getProp':
return this.wrapHostObject(val[prop]);
case 'setProp':
val[prop] = args;
return undefined;
case 'delete':
this.deleteHostFunction(token);
return undefined;
}
throw new Error(`unknown action: ${action}`);
})
return token;
}
}
class Invocation {
context;
asyncResult;
syncResult;
resolveAsyncResult;
rejectAsyncResult;
hostFunctionTokens = [];
constructor(context, timeout) {
this.context = context;
this.asyncResult = new Promise((resolve, reject) => {
this.resolveAsyncResult = resolve;
this.rejectAsyncResult = reject;
});
this.syncResult = () => {
return Promise.race([this.asyncResult, (async () => {
if (timeout) {
await new Promise(resolve => setTimeout(resolve, timeout));
throw new Error('execute function timeout');
} else {
const noResult = this.syncResult;
while (this.syncResult === noResult) {
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
})()]);
};
}
dispose() {
for (const hostFunctionToken of this.hostFunctionTokens) {
this.context.deleteHostFunction(hostFunctionToken);
}
}
wrapHostFunction(f, extra) {
const hostFunctionToken = this.context.wrapHostFunction(f, extra);
this.hostFunctionTokens.push(hostFunctionToken);
return hostFunctionToken;
}
setSuccess(value) {
this.syncResult = () => value;
this.resolveAsyncResult(value);
return 0;
}
setFailure(error) {
this.syncResult = () => { throw new Error(error) };
this.rejectAsyncResult(new Error(error));
return 0;
}
}
function allocateUTF8(string) {
if (string === undefined) {
return 0;
}
return wasm.allocateUTF8(string);
}
module.exports = function (wasmProvider) {
async function loadWasm(options) {
if (!wasm) {
wasm = await wasmProvider(options);
wasm.dynamicImport = (ctx, argc, argv, resolveFunc, rejectFunc, basename, filename) => {
basename = wasm.UTF8ToString(basename);
filename = wasm.UTF8ToString(filename);
const context = contexts.get(ctx);
if (!context) {
wasm._call(ctx, rejectFunc, allocateUTF8(JSON.stringify('internal error: context not found')));
wasm._freeJsValue(ctx, resolveFunc);
wasm._freeJsValue(ctx, rejectFunc);
wasm._free(argv);
return;
}
context.dynamicImport({ ctx, argc, argv, resolveFunc, rejectFunc, basename, filename });
}
wasm.getModuleContent = (ctx, filename) => {
filename = wasm.UTF8ToString(filename);
const context = contexts.get(ctx);
if (!context) {
throw new Error(`getModuleContent of ${filename} missing context`)
}
return context.moduleContents[filename];
}
wasm.invokeHostFunction = (ctx, token, args) => {
token = wasm.UTF8ToString(token);
args = wasm.UTF8ToString(args);
const context = contexts.get(ctx);
if (!context) {
throw new Error(`invokeHostFunction missing context`);
}
try {
const result = JSON.stringify(context.invokeHostFunction(JSON.parse(token), JSON.parse(args)));
// eval.c invokeHostFunction will free this memory
return allocateUTF8(result);
} catch(e) {
return allocateUTF8(JSON.stringify({ __e__: e?.stack || `${e}`}));
}
}
}
return wasm;
}
async function defineFunction(script, options) {
await loadWasm(options);
return (...args) => { // start a isolated context for each invocation
const ctx = new Context(options);
function defAndCall() {
const f = ctx.def(script, options);
let result = undefined;
try {
return result = f(...args);
} finally {
if (result && result.finally) {
result.finally(ctx.dispose.bind(ctx));
} else {
ctx.dispose();
}
}
}
return defAndCall();
};
};
defineFunction.context = async (contextOptions) => { // share context between invocations
await loadWasm(contextOptions);
const ctx = new Context(contextOptions);
return {
def(script, options) {
return ctx.def(script, options);
},
load(script, options) {
return ctx.load(script, options)
},
get currentStack() {
return ctx.currentStack();
},
inject(target, obj) {
ctx.inject(target, obj);
},
wrapHostFunction(f, extra) {
return ctx.wrapHostFunction(f, extra);
},
dispose() {
ctx.dispose();
}
}
};
defineFunction.default = defineFunction; // support import default
return defineFunction;
}
\ No newline at end of file
因为 它太大了无法显示 source diff 。你可以改为 查看blob
declare function defineFunction<T extends (...args: any[]) => any>(script: string, options?: {
timeout?: number,
disposeManually?: boolean,
}): Promise<T>;
declare interface Context {
def: typeof defineFunction;
load(script: string, options?: {
filename?: string,
meta?: Record<string, any>
}): Promise<any>;
currentStack: string;
wrapHostFunction(f: Function, options?: { returnsHostObject?: boolean; nowrap?: boolean; }): any;
inject(target: string, obj: Record<string, any>): void;
dispose(): void;
}
declare namespace defineFunction {
var context: (options?: {
wasmFile?: string,
loadModuleContent?: (moduleName: string, extra?: { basename: string, filename: string }) => Promise<string>,
global?: Record<string, any>
}) => Context;
}
export default defineFunction;
\ No newline at end of file
function loadWasm(options) {
return require('./load-eval-wasm')({
async instantiateWasm(info, receiveInstance) {
const buff = require('fs').readFileSync(options?.wasmFile || require('path').join(__dirname, 'eval.wasm'));
const { instance, module } = await WebAssembly.instantiate(buff, info);
receiveInstance(instance, module);
}
});
}
module.exports = require('./define-function')(loadWasm);
\ No newline at end of file
var Module = (() => {
return (
function(Module) {
Module = Module || {};
var Module = typeof Module != "undefined" ? Module : {};
var readyPromiseResolve, readyPromiseReject;
Module["ready"] = new Promise(function(resolve, reject) {
readyPromiseResolve = resolve;
readyPromiseReject = reject;
});
var moduleOverrides = Object.assign({}, Module);
var arguments_ = [];
Object.assign(Module, moduleOverrides);
moduleOverrides = null;
var wasmMemory;
var ABORT = false;
var UTF8Decoder = typeof TextDecoder != "undefined" ? new TextDecoder("utf8") : undefined;
function UTF8ArrayToString(heap, idx, maxBytesToRead) {
var endIdx = idx + maxBytesToRead;
var endPtr = idx;
while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr;
if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) {
return UTF8Decoder.decode(heap.subarray(idx, endPtr));
} else {
var str = "";
while (idx < endPtr) {
var u0 = heap[idx++];
if (!(u0 & 128)) {
str += String.fromCharCode(u0);
continue;
}
var u1 = heap[idx++] & 63;
if ((u0 & 224) == 192) {
str += String.fromCharCode((u0 & 31) << 6 | u1);
continue;
}
var u2 = heap[idx++] & 63;
if ((u0 & 240) == 224) {
u0 = (u0 & 15) << 12 | u1 << 6 | u2;
} else {
u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heap[idx++] & 63;
}
if (u0 < 65536) {
str += String.fromCharCode(u0);
} else {
var ch = u0 - 65536;
str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023);
}
}
}
return str;
}
function UTF8ToString(ptr, maxBytesToRead) {
return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : "";
}
function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) {
if (!(maxBytesToWrite > 0)) return 0;
var startIdx = outIdx;
var endIdx = outIdx + maxBytesToWrite - 1;
for (var i = 0; i < str.length; ++i) {
var u = str.charCodeAt(i);
if (u >= 55296 && u <= 57343) {
var u1 = str.charCodeAt(++i);
u = 65536 + ((u & 1023) << 10) | u1 & 1023;
}
if (u <= 127) {
if (outIdx >= endIdx) break;
heap[outIdx++] = u;
} else if (u <= 2047) {
if (outIdx + 1 >= endIdx) break;
heap[outIdx++] = 192 | u >> 6;
heap[outIdx++] = 128 | u & 63;
} else if (u <= 65535) {
if (outIdx + 2 >= endIdx) break;
heap[outIdx++] = 224 | u >> 12;
heap[outIdx++] = 128 | u >> 6 & 63;
heap[outIdx++] = 128 | u & 63;
} else {
if (outIdx + 3 >= endIdx) break;
heap[outIdx++] = 240 | u >> 18;
heap[outIdx++] = 128 | u >> 12 & 63;
heap[outIdx++] = 128 | u >> 6 & 63;
heap[outIdx++] = 128 | u & 63;
}
}
heap[outIdx] = 0;
return outIdx - startIdx;
}
function lengthBytesUTF8(str) {
var len = 0;
for (var i = 0; i < str.length; ++i) {
var u = str.charCodeAt(i);
if (u >= 55296 && u <= 57343) u = 65536 + ((u & 1023) << 10) | str.charCodeAt(++i) & 1023;
if (u <= 127) ++len; else if (u <= 2047) len += 2; else if (u <= 65535) len += 3; else len += 4;
}
return len;
}
function allocateUTF8(str) {
var size = lengthBytesUTF8(str) + 1;
var ret = _malloc(size);
if (ret) stringToUTF8Array(str, HEAP8, ret, size);
return ret;
}
var buffer, HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
function updateGlobalBufferAndViews(buf) {
buffer = buf;
Module["HEAP8"] = HEAP8 = new Int8Array(buf);
Module["HEAP16"] = HEAP16 = new Int16Array(buf);
Module["HEAP32"] = HEAP32 = new Int32Array(buf);
Module["HEAPU8"] = HEAPU8 = new Uint8Array(buf);
Module["HEAPU16"] = HEAPU16 = new Uint16Array(buf);
Module["HEAPU32"] = HEAPU32 = new Uint32Array(buf);
Module["HEAPF32"] = HEAPF32 = new Float32Array(buf);
Module["HEAPF64"] = HEAPF64 = new Float64Array(buf);
}
var wasmTable;
var __ATPRERUN__ = [];
var __ATINIT__ = [];
var __ATPOSTRUN__ = [];
function preRun() {
callRuntimeCallbacks(__ATPRERUN__);
}
function initRuntime() {
callRuntimeCallbacks(__ATINIT__);
}
function postRun() {
callRuntimeCallbacks(__ATPOSTRUN__);
}
function addOnInit(cb) {
__ATINIT__.unshift(cb);
}
var runDependencies = 0;
var runDependencyWatcher = null;
var dependenciesFulfilled = null;
function addRunDependency(id) {
runDependencies++;
}
function removeRunDependency(id) {
runDependencies--;
if (runDependencies == 0) {
if (runDependencyWatcher !== null) {
clearInterval(runDependencyWatcher);
runDependencyWatcher = null;
}
if (dependenciesFulfilled) {
var callback = dependenciesFulfilled;
dependenciesFulfilled = null;
callback();
}
}
}
Module["preloadedImages"] = {};
Module["preloadedAudios"] = {};
function abort(what) {
what = "Aborted(" + what + ")";
ABORT = true;
EXITSTATUS = 1;
what += ". Build with -s ASSERTIONS=1 for more info.";
var e = new Error(what);
readyPromiseReject(e);
throw e;
}
function createWasm() {
var info = {
"a": asmLibraryArg
};
function receiveInstance(instance, module) {
var exports = instance.exports;
Module["asm"] = exports;
wasmMemory = Module["asm"]["l"];
updateGlobalBufferAndViews(wasmMemory.buffer);
wasmTable = Module["asm"]["p"];
addOnInit(Module["asm"]["m"]);
removeRunDependency("wasm-instantiate");
}
addRunDependency("wasm-instantiate");
if (Module["instantiateWasm"]) {
try {
var exports = Module["instantiateWasm"](info, receiveInstance);
return exports;
} catch (e) {
err("Module.instantiateWasm callback failed with error: " + e);
return false;
}
}
throw new Error('missing instantiateWasm');
}
function _dynamicImport(ctx, argc, argv, resolveFunc, rejectFunc, basename, filename) {
return Module.dynamicImport(ctx, argc, argv, resolveFunc, rejectFunc, basename, filename);
}
function _getModuleContent(ctx, module_name) {
return Module.getModuleContent(ctx, module_name);
}
function _invokeHostFunction(ctx, token, args) {
return Module.invokeHostFunction(ctx, token, args);
}
function callRuntimeCallbacks(callbacks) {
while (callbacks.length > 0) {
var callback = callbacks.shift();
if (typeof callback == "function") {
callback(Module);
continue;
}
var func = callback.func;
if (typeof func == "number") {
if (callback.arg === undefined) {
getWasmTableEntry(func)();
} else {
getWasmTableEntry(func)(callback.arg);
}
} else {
func(callback.arg === undefined ? null : callback.arg);
}
}
}
var wasmTableMirror = [];
function getWasmTableEntry(funcPtr) {
var func = wasmTableMirror[funcPtr];
if (!func) {
if (funcPtr >= wasmTableMirror.length) wasmTableMirror.length = funcPtr + 1;
wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr);
}
return func;
}
function ___assert_fail(condition, filename, line, func) {
abort("Assertion failed: " + UTF8ToString(condition) + ", at: " + [ filename ? UTF8ToString(filename) : "unknown filename", line, func ? UTF8ToString(func) : "unknown function" ]);
}
function __localtime_js(time, tmPtr) {
var date = new Date(HEAP32[time >> 2] * 1e3);
HEAP32[tmPtr >> 2] = date.getSeconds();
HEAP32[tmPtr + 4 >> 2] = date.getMinutes();
HEAP32[tmPtr + 8 >> 2] = date.getHours();
HEAP32[tmPtr + 12 >> 2] = date.getDate();
HEAP32[tmPtr + 16 >> 2] = date.getMonth();
HEAP32[tmPtr + 20 >> 2] = date.getFullYear() - 1900;
HEAP32[tmPtr + 24 >> 2] = date.getDay();
var start = new Date(date.getFullYear(), 0, 1);
var yday = (date.getTime() - start.getTime()) / (1e3 * 60 * 60 * 24) | 0;
HEAP32[tmPtr + 28 >> 2] = yday;
HEAP32[tmPtr + 36 >> 2] = -(date.getTimezoneOffset() * 60);
var summerOffset = new Date(date.getFullYear(), 6, 1).getTimezoneOffset();
var winterOffset = start.getTimezoneOffset();
var dst = (summerOffset != winterOffset && date.getTimezoneOffset() == Math.min(winterOffset, summerOffset)) | 0;
HEAP32[tmPtr + 32 >> 2] = dst;
}
function _tzset_impl(timezone, daylight, tzname) {
var currentYear = new Date().getFullYear();
var winter = new Date(currentYear, 0, 1);
var summer = new Date(currentYear, 6, 1);
var winterOffset = winter.getTimezoneOffset();
var summerOffset = summer.getTimezoneOffset();
var stdTimezoneOffset = Math.max(winterOffset, summerOffset);
HEAP32[timezone >> 2] = stdTimezoneOffset * 60;
HEAP32[daylight >> 2] = Number(winterOffset != summerOffset);
function extractZone(date) {
var match = date.toTimeString().match(/\(([A-Za-z ]+)\)$/);
return match ? match[1] : "GMT";
}
var winterName = extractZone(winter);
var summerName = extractZone(summer);
var winterNamePtr = allocateUTF8(winterName);
var summerNamePtr = allocateUTF8(summerName);
if (summerOffset < winterOffset) {
HEAP32[tzname >> 2] = winterNamePtr;
HEAP32[tzname + 4 >> 2] = summerNamePtr;
} else {
HEAP32[tzname >> 2] = summerNamePtr;
HEAP32[tzname + 4 >> 2] = winterNamePtr;
}
}
function __tzset_js(timezone, daylight, tzname) {
if (__tzset_js.called) return;
__tzset_js.called = true;
_tzset_impl(timezone, daylight, tzname);
}
function _abort() {
abort("");
}
function _emscripten_memcpy_big(dest, src, num) {
HEAPU8.copyWithin(dest, src, src + num);
}
function _emscripten_get_heap_max() {
return 2147483648;
}
function emscripten_realloc_buffer(size) {
try {
wasmMemory.grow(size - buffer.byteLength + 65535 >>> 16);
updateGlobalBufferAndViews(wasmMemory.buffer);
return 1;
} catch (e) {}
}
function _emscripten_resize_heap(requestedSize) {
var oldSize = HEAPU8.length;
requestedSize = requestedSize >>> 0;
var maxHeapSize = _emscripten_get_heap_max();
if (requestedSize > maxHeapSize) {
return false;
}
let alignUp = (x, multiple) => x + (multiple - x % multiple) % multiple;
for (var cutDown = 1; cutDown <= 4; cutDown *= 2) {
var overGrownHeapSize = oldSize * (1 + .2 / cutDown);
overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296);
var newSize = Math.min(maxHeapSize, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536));
var replacement = emscripten_realloc_buffer(newSize);
if (replacement) {
return true;
}
}
return false;
}
function _fd_write(fd, iov, iovcnt, pnum) {
var num = 0;
for (var i = 0; i < iovcnt; i++) {
var ptr = HEAP32[iov >> 2];
var len = HEAP32[iov + 4 >> 2];
iov += 8;
if (typeof process !== 'undefined') {
process.stdout.write(UTF8ToString(ptr, len))
}
num += len;
}
HEAP32[pnum >> 2] = num;
}
function _gettimeofday(ptr) {
var now = Date.now();
HEAP32[ptr >> 2] = now / 1e3 | 0;
HEAP32[ptr + 4 >> 2] = now % 1e3 * 1e3 | 0;
return 0;
}
var asmLibraryArg = {
"a": ___assert_fail,
"h": _dynamicImport,
"i": _getModuleContent,
"j": _invokeHostFunction,
"e": __localtime_js,
"f": __tzset_js,
"b": _abort,
"g": _emscripten_memcpy_big,
"k": _emscripten_resize_heap,
"d": _fd_write,
"c": _gettimeofday
};
var asm = createWasm();
var ___wasm_call_ctors = Module["___wasm_call_ctors"] = function() {
return (___wasm_call_ctors = Module["___wasm_call_ctors"] = Module["asm"]["m"]).apply(null, arguments);
};
var _malloc = Module["_malloc"] = function() {
return (_malloc = Module["_malloc"] = Module["asm"]["n"]).apply(null, arguments);
};
var _free = Module["_free"] = function() {
return (_free = Module["_free"] = Module["asm"]["o"]).apply(null, arguments);
};
var _newContext = Module["_newContext"] = function() {
return (_newContext = Module["_newContext"] = Module["asm"]["q"]).apply(null, arguments);
};
var _freeContext = Module["_freeContext"] = function() {
return (_freeContext = Module["_freeContext"] = Module["asm"]["r"]).apply(null, arguments);
};
var _doDynamicImport = Module["_doDynamicImport"] = function() {
return (_doDynamicImport = Module["_doDynamicImport"] = Module["asm"]["s"]).apply(null, arguments);
};
var _pathJoin = Module["_pathJoin"] = function() {
return (_pathJoin = Module["_pathJoin"] = Module["asm"]["t"]).apply(null, arguments);
};
var _load = Module["_load"] = function() {
return (_load = Module["_load"] = Module["asm"]["u"]).apply(null, arguments);
};
var _call = Module["_call"] = function() {
return (_call = Module["_call"] = Module["asm"]["v"]).apply(null, arguments);
};
var _freeJsValue = Module["_freeJsValue"] = function() {
return (_freeJsValue = Module["_freeJsValue"] = Module["asm"]["w"]).apply(null, arguments);
};
Module["UTF8ToString"] = UTF8ToString;
Module["allocateUTF8"] = allocateUTF8;
var calledRun;
dependenciesFulfilled = function runCaller() {
if (!calledRun) run();
if (!calledRun) dependenciesFulfilled = runCaller;
};
function run(args) {
args = args || arguments_;
if (runDependencies > 0) {
return;
}
preRun();
if (runDependencies > 0) {
return;
}
function doRun() {
if (calledRun) return;
calledRun = true;
Module["calledRun"] = true;
if (ABORT) return;
initRuntime();
readyPromiseResolve(Module);
postRun();
}
{
doRun();
}
}
Module["run"] = run;
run();
return Module.ready
}
);
})();
if (typeof exports === 'object' && typeof module === 'object')
module.exports = Module;
else if (typeof define === 'function' && define['amd'])
define([], function() { return Module; });
else if (typeof exports === 'object')
exports["Module"] = Module;
\ No newline at end of file
{
"name": "define-function",
"version": "2.0.0",
"repository": "https://github.com/taowen/define-function",
"license": "MIT",
"miniprogram": "wechat",
"main": "index.node.js",
"browser": "index.browser.js",
"types": "index.d.ts",
"devDependencies": {
"webpack": "^5.69.1",
"webpack-dev-server": "^4.7.4",
"webpack-cli": "^4.9.2",
"html-webpack-plugin": "^5.5.0",
"typescript": "^4.6.2"
},
"scripts": {
"test:browser": "webpack serve",
"test:node": "node test.node.js",
"test:ts": "cd test-ts && tsc"
},
"files": [
"index.node.js",
"index.browser.js",
"index.d.ts",
"__s__.d.ts",
"define-function.js",
"load-eval-wasm.js",
"eval.wasm",
"wechat/*"
]
}
let wasm = undefined;
let nextId = 1;
const contexts = new Map();
// import {a, b} from 'xxx'
// import ab from 'xxx'
// import * as ab from 'xxx'
const re1 = /import\s+[\w\s,\*\}\{]*?\s+from\s+['"]([^'"]+)['"]/g;
// import 'xxx'
const re2 = /import\s+['"]([^'"]+)['"]/g;
// export * from 'xxx'
const re3 = /export\s+[\w\s,\*\}\{]*?\s+from\s+['"]([^'"]+)['"]/g;
const res = [re1, re2, re3];
function* extractImportFroms(script) {
if (!script) {
return
}
for (const re of res) {
for (const match of script.matchAll(re)) {
yield match[1];
}
}
}
class Context {
options = undefined;
ctx = undefined;
moduleContents = {};
createPromise;
invokeSandboxFunction;
deleteSandboxFunction;
hostFunctions = new Map();
constructor(options) {
this.options = options;
this.ctx = wasm._newContext();
contexts.set(this.ctx, this);
this.loadSync(`
global.__s__ = global.__s__ || {
nextId: 1,
promises: new Map(),
callbacks: new Map(),
callbacksLookup: new Map(),
inspectingObjects: new Map(),
currentStack: '',
hostInspect: undefined, // inject later
createPromise() {
const promiseId = this.nextId++;
const result = { __p__: promiseId };
this.promises.set(promiseId, new Promise((resolve, reject) => {
result.resolve = this.wrapSandboxFunction(resolve);
result.reject = this.wrapSandboxFunction(reject);
}));
return result;
},
wrapSandboxFunction(callback, extra) {
let callbackId = this.callbacksLookup.get(callback);
if (callbackId === undefined) {
callbackId = this.nextId++;
this.callbacks.set(callbackId, callback);
this.callbacksLookup.set(callback, callbackId);
}
return { __c__: callbackId, ...extra };
},
getAndDeletePromise(promiseId) {
const promise = this.promises.get(promiseId);
this.promises.delete(promiseId);
return promise;
},
invokeSandboxFunction(callbackToken, args) {
const callbackId = callbackToken.__c__;
if (!callbackId) {
throw new Error('invokeSandboxFunction with invalid token: ' + JSON.stringify(callbackToken));
}
const callback = this.callbacks.get(callbackId);
if (!callback) {
return undefined;
}
return callback.apply(undefined, args);
},
deleteSandboxFunction(callbackToken) {
const callbackId = callbackToken.__c__;
if (!callbackId) {
throw new Error('deleteSandboxFunction with invalid token: ' + JSON.stringify(callbackToken));
}
let callback = this.callbacks.get(callbackId);
if (callback !== undefined) {
this.callbacks.delete(callbackId);
this.callbacksLookup.delete(callback);
}
},
inspect(msg, obj) {
const objId = this.nextId++;
this.inspectingObjects.set(objId, obj);
this.hostInspect(msg, typeof obj === 'object' ? { __o__: objId, keys: Reflect.ownKeys(obj) } : obj);
},
getInspectingObjectProp(objId, prop) {
const val = this.inspectingObjects.get(objId)[prop];
if (val && typeof val === 'object') {
const valObjId = this.nextId++;
this.inspectingObjects.set(valObjId, val);
return { __o__: valObjId, keys: Reflect.ownKeys(val) };
}
return val;
},
asHostFunction(hostFunctionToken) {
return (...args) => {
return this.invokeHostFunction(hostFunctionToken, args);
};
},
invokeHostFunction(hostFunctionToken, args) {
if (!hostFunctionToken.nowrap) {
args = args.map(arg => typeof arg === 'function' ? this.wrapSandboxFunction(arg, { once: true }) : arg);
if (args[0] && typeof args[0] === 'object') {
for (const [k, v] of Object.entries(args[0])) {
if (typeof v === 'function') {
args[0][k] = this.wrapSandboxFunction(v, { once: true });
}
}
}
}
const invokeResult = __invokeHostFunction(JSON.stringify(hostFunctionToken), JSON.stringify(args));
if (hostFunctionToken.returnsHostObject && invokeResult?.__h__) {
return this.asHostFunction(invokeResult);
}
if (invokeResult?.__p__) {
return this.getAndDeletePromise(invokeResult.__p__);
}
return invokeResult;
},
callMethod(hostObj, method, ...args) {
const result = hostObj('callMethod', method, args);
return result?.__h__ ? this.asHostFunction(result) : result;
},
getProp(hostObj, prop) {
return hostObj('getProp', prop);
},
setProp(hostObj, prop, propVal) {
return hostObj('setProp', prop, propVal);
},
deleteHostObject(hostObj) {
return hostObj('delete');
}
};
`);
this.createPromise = this.def(`return __s__.createPromise()`);
this.invokeSandboxFunction = this.def(`return __s__.invokeSandboxFunction(...arguments)`);
this.deleteSandboxFunction = this.def(`return __s__.deleteSandboxFunction(...arguments)`);
this.getInspectingObjectProp = this.def(`return __s__.getInspectingObjectProp(...arguments)`);
this.currentStack = this.def(`return __s__.currentStack`);
if (options?.global) {
this.inject('global', options.global);
for (const [k, v] of Object.entries(options.global)) {
if (typeof v === 'object') {
this.inject(k, v);
}
}
}
this.def(`__s__.hostInspect = arguments[0]`)(this.wrapHostFunction(this.hostInspect.bind(this), { nowrap: true }));
}
dispose() {
if (!this.ctx) {
return; // already disposed
}
for (const pModuleContent of Object.values(this.moduleContents)) {
wasm._free(pModuleContent);
}
wasm._freeContext(this.ctx);
contexts.delete(this.ctx);
this.ctx = undefined;
}
hostInspect(msg, obj) {
obj = this.wrapProxy(obj);
console.warn('inspecting...', msg, obj);
debugger;
}
wrapProxy(obj) {
if (!obj) {
return obj;
}
if (!obj.__o__) {
return obj;
}
const proxy = {};
for (const key of obj.keys) {
Object.defineProperty(proxy, key, {
enumerable: true,
get: () => {
return this.wrapProxy(this.getInspectingObjectProp(obj.__o__, key));
}
});
}
return proxy;
}
asSandboxFunction(callbackToken) {
let calledOnce = false;
return (...args) => {
if (!this.ctx) {
return;
}
if (callbackToken.once) {
if (calledOnce) {
throw new Error(`callback ${JSON.stringify(callbackToken)} can only be callback once, if need to callback multiple times, use __s__.wrapSandboxFunction to manage callback lifetime explicitly`)
}
calledOnce = true;
}
try {
return this.invokeSandboxFunction(callbackToken, args);
} finally {
if (callbackToken.once) {
this.deleteSandboxFunction(callbackToken);
}
}
}
}
inject(target, obj) {
const args = [target];
for (const [k, v] of Object.entries(obj)) {
if (typeof v === 'function') {
args.push(k);
args.push(this.wrapHostFunction(v))
} else {
args.push(k);
args.push(v);
}
}
const f = this.def(`
const obj = global[arguments[0]] = global[arguments[0]] || {};
for (let i = 1; i < arguments.length; i+=2) {
obj[arguments[i]] = arguments[i+1];
}`);
f(...args);
}
async dynamicImport({ctx, argc, argv, resolveFunc, rejectFunc, basename, filename }) {
try {
if (this.options?.loadModuleContent) {
await this.require(basename, filename)
}
} catch(e) {
wasm._call(ctx, rejectFunc, allocateUTF8(JSON.stringify(`failed to dynamicImport: ${e}`)));
wasm._freeJsValue(ctx, resolveFunc);
wasm._freeJsValue(ctx, rejectFunc);
wasm._free(argv);
return;
}
wasm._doDynamicImport(ctx, argc, argv);
wasm._freeJsValue(ctx, resolveFunc);
wasm._freeJsValue(ctx, rejectFunc);
wasm._free(argv);
}
async require(basename, filename) {
if (!this.options?.loadModuleContent) {
throw new Error(`missing options.loadModuleContent can not load content of ${filename} imported by ${basename}`);
}
let moduleName = filename;
if (filename[0] === '.') {
const pBasename = allocateUTF8(basename);
const pFilename = allocateUTF8(filename);
const pModuleName = wasm._pathJoin(this.ctx, pBasename, pFilename);
moduleName = wasm.UTF8ToString(pModuleName);
wasm._free(pModuleName);
}
if (this.moduleContents[moduleName] !== undefined) {
return;
}
this.moduleContents[moduleName] = 0;
const content = await this.options.loadModuleContent(moduleName, { basename, filename });
this.moduleContents[moduleName] = allocateUTF8(content);
const promises = [];
for (const importFrom of extractImportFroms(content)) {
promises.push(this.require(moduleName, importFrom));
}
await Promise.all(promises);
}
loadSync(content, options) {
const filename = options?.filename || `<load${nextId++}>`;
const pScript = allocateUTF8(content);
const pScriptName = allocateUTF8(filename)
const meta = options?.meta || { url: filename };
const pMeta = allocateUTF8(JSON.stringify(meta));
const pError = wasm._load(this.ctx, pScript, pScriptName, pMeta);
if (pError) {
const error = new Error(wasm.UTF8ToString(pError));
wasm._free(pError);
throw error;
}
}
async load(content, options) {
const filename = options?.filename || `<load${nextId++}>`;
const promises = [];
for (const importFrom of extractImportFroms(content)) {
promises.push(this.require(filename, importFrom));
}
await Promise.all(promises);
this.loadSync(content, { ...options, filename });
if (!this._loadModule) {
this._loadModule = await this.def(`
return (async() => {
const [moduleName] = arguments;
const m = await import(moduleName);
const exports = {};
for(const [k, v] of Object.entries(m)) {
if (typeof v === 'function') {
exports[k] = __s__.wrapSandboxFunction(v);
} else {
exports[k] = v;
}
}
return JSON.stringify(exports);
})();
`)
}
const loadedModule = JSON.parse(await this._loadModule(filename));
for (const [k, v] of Object.entries(loadedModule)) {
if (v?.__c__) {
loadedModule[k] = this.asSandboxFunction(v);
}
}
return loadedModule;
}
def(script, options) {
if (!this.ctx) {
throw new Error('context has been disposed');
}
return (...args) => {
if (!this.ctx) {
throw new Error('context has been disposed');
}
const invocation = new Invocation(this, options?.timeout);
const setSuccessToken = invocation.wrapHostFunction(invocation.setSuccess.bind(invocation), { nowrap: true });
const setFailureToken = invocation.wrapHostFunction(invocation.setFailure.bind(invocation), { nowrap: true });
const encodedArgs = args.map((arg, index) => typeof arg === 'function' ? invocation.wrapHostFunction(arg, { argIndex: index}) : arg);
this.loadSync(`
(() => {
const setSuccess = __s__.asHostFunction(${JSON.stringify(setSuccessToken)});
const setFailure = __s__.asHostFunction(${JSON.stringify(setFailureToken)});
const args = ${JSON.stringify(encodedArgs)};
function f() {
${script}
}
try {
const result = f.apply(undefined, args.map(arg => arg?.__h__ ? __s__.asHostFunction(arg) : arg));
if (result && result.then && result.catch) {
result
.then(v => { setSuccess(v); })
.catch(e => { setFailure('' + e + '' + e.stack); })
} else {
setSuccess(result);
}
} catch(e) {
setFailure('' + e + '' + e.stack);
}
})();
`, options);
(async () => {
try {
await invocation.asyncResult;
} catch (e) {
// ignore
} finally {
invocation.dispose();
}
})();
return invocation.syncResult();
}
}
wrapHostFunction(f, extra) {
const hfId = nextId++;
this.hostFunctions.set(hfId, f);
return { __h__: hfId, ...extra }
}
deleteHostFunction(hostFunctionToken) {
const hfId = hostFunctionToken.__h__;
if (!hfId) {
throw new Error('deleteHostFunction with invalid token: ' + JSON.stringify(hostFunctionToken));
}
this.hostFunctions.delete(hfId);
}
invokeHostFunction(hostFunctionToken, args) {
const hfId = hostFunctionToken.__h__;
if (!hfId) {
throw new Error('callHostFunction with invalid token: ' + JSON.stringify(hostFunctionToken));
}
if (!hostFunctionToken.nowrap) {
args = args.map(arg => arg?.__c__ ? this.asSandboxFunction(arg) : arg);
if (args[0] && typeof args[0] === 'object') {
for (const [k, v] of Object.entries(args[0])) {
if (v?.__c__) {
args[0][k] = this.asSandboxFunction(v);
}
}
}
}
const hostFunc = this.hostFunctions.get(hfId);
if (hostFunc === undefined) {
throw new Error('host function not found: ' + JSON.stringify(hostFunctionToken));
}
const invokeResult = hostFunc(...args);
if (invokeResult && invokeResult.then && invokeResult.catch) {
const { __p__, resolve, reject } = this.createPromise();
invokeResult
.then(v => {
if (this.ctx) {
this.invokeSandboxFunction(resolve, [v]);
}
})
.catch(e => {
if (this.ctx) {
this.invokeSandboxFunction(reject, ['' + e]);
}
})
.finally(() => {
if (this.ctx) {
this.deleteSandboxFunction(resolve);
this.deleteSandboxFunction(reject);
}
});
return { __p__ };
}
if (hostFunctionToken.returnsHostObject) {
return this.wrapHostObject(invokeResult);
}
return invokeResult;
}
wrapHostObject(val) {
if (!val) {
return val;
}
if (typeof val !== 'object') {
return val;
}
const token = this.wrapHostFunction((action, prop, args) => {
switch(action) {
case 'callMethod':
return this.wrapHostObject(val[prop](...args));
case 'getProp':
return this.wrapHostObject(val[prop]);
case 'setProp':
val[prop] = args;
return undefined;
case 'delete':
this.deleteHostFunction(token);
return undefined;
}
throw new Error(`unknown action: ${action}`);
})
return token;
}
}
class Invocation {
context;
asyncResult;
syncResult;
resolveAsyncResult;
rejectAsyncResult;
hostFunctionTokens = [];
constructor(context, timeout) {
this.context = context;
this.asyncResult = new Promise((resolve, reject) => {
this.resolveAsyncResult = resolve;
this.rejectAsyncResult = reject;
});
this.syncResult = () => {
return Promise.race([this.asyncResult, (async () => {
if (timeout) {
await new Promise(resolve => setTimeout(resolve, timeout));
throw new Error('execute function timeout');
} else {
const noResult = this.syncResult;
while (this.syncResult === noResult) {
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
})()]);
};
}
dispose() {
for (const hostFunctionToken of this.hostFunctionTokens) {
this.context.deleteHostFunction(hostFunctionToken);
}
}
wrapHostFunction(f, extra) {
const hostFunctionToken = this.context.wrapHostFunction(f, extra);
this.hostFunctionTokens.push(hostFunctionToken);
return hostFunctionToken;
}
setSuccess(value) {
this.syncResult = () => value;
this.resolveAsyncResult(value);
return 0;
}
setFailure(error) {
this.syncResult = () => { throw new Error(error) };
this.rejectAsyncResult(new Error(error));
return 0;
}
}
function allocateUTF8(string) {
if (string === undefined) {
return 0;
}
return wasm.allocateUTF8(string);
}
module.exports = function (wasmProvider) {
async function loadWasm(options) {
if (!wasm) {
wasm = await wasmProvider(options);
wasm.dynamicImport = (ctx, argc, argv, resolveFunc, rejectFunc, basename, filename) => {
basename = wasm.UTF8ToString(basename);
filename = wasm.UTF8ToString(filename);
const context = contexts.get(ctx);
if (!context) {
wasm._call(ctx, rejectFunc, allocateUTF8(JSON.stringify('internal error: context not found')));
wasm._freeJsValue(ctx, resolveFunc);
wasm._freeJsValue(ctx, rejectFunc);
wasm._free(argv);
return;
}
context.dynamicImport({ ctx, argc, argv, resolveFunc, rejectFunc, basename, filename });
}
wasm.getModuleContent = (ctx, filename) => {
filename = wasm.UTF8ToString(filename);
const context = contexts.get(ctx);
if (!context) {
throw new Error(`getModuleContent of ${filename} missing context`)
}
return context.moduleContents[filename];
}
wasm.invokeHostFunction = (ctx, token, args) => {
token = wasm.UTF8ToString(token);
args = wasm.UTF8ToString(args);
const context = contexts.get(ctx);
if (!context) {
throw new Error(`invokeHostFunction missing context`);
}
try {
const result = JSON.stringify(context.invokeHostFunction(JSON.parse(token), JSON.parse(args)));
// eval.c invokeHostFunction will free this memory
return allocateUTF8(result);
} catch(e) {
return allocateUTF8(JSON.stringify({ __e__: e?.stack || `${e}`}));
}
}
}
return wasm;
}
async function defineFunction(script, options) {
await loadWasm(options);
return (...args) => { // start a isolated context for each invocation
const ctx = new Context(options);
function defAndCall() {
const f = ctx.def(script, options);
let result = undefined;
try {
return result = f(...args);
} finally {
if (result && result.finally) {
result.finally(ctx.dispose.bind(ctx));
} else {
ctx.dispose();
}
}
}
return defAndCall();
};
};
defineFunction.context = async (contextOptions) => { // share context between invocations
await loadWasm(contextOptions);
const ctx = new Context(contextOptions);
return {
def(script, options) {
return ctx.def(script, options);
},
load(script, options) {
return ctx.load(script, options)
},
get currentStack() {
return ctx.currentStack();
},
inject(target, obj) {
ctx.inject(target, obj);
},
wrapHostFunction(f, extra) {
return ctx.wrapHostFunction(f, extra);
},
dispose() {
ctx.dispose();
}
}
};
defineFunction.default = defineFunction; // support import default
return defineFunction;
}
\ No newline at end of file
function loadWasm(options) {
return require('./load-eval-wasm')({
async instantiateWasm(info, receiveInstance) {
const { instance, module } = await WXWebAssembly.instantiate(
options?.wasmFile || '/miniprogram_npm/define-function/eval.wasm.br', info);
receiveInstance(instance, module);
}
});
}
module.exports = require('./define-function')(loadWasm);
\ No newline at end of file
var Module = (() => {
return (
function(Module) {
Module = Module || {};
var Module = typeof Module != "undefined" ? Module : {};
var readyPromiseResolve, readyPromiseReject;
Module["ready"] = new Promise(function(resolve, reject) {
readyPromiseResolve = resolve;
readyPromiseReject = reject;
});
var moduleOverrides = Object.assign({}, Module);
var arguments_ = [];
Object.assign(Module, moduleOverrides);
moduleOverrides = null;
var wasmMemory;
var ABORT = false;
var UTF8Decoder = typeof TextDecoder != "undefined" ? new TextDecoder("utf8") : undefined;
function UTF8ArrayToString(heap, idx, maxBytesToRead) {
var endIdx = idx + maxBytesToRead;
var endPtr = idx;
while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr;
if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) {
return UTF8Decoder.decode(heap.subarray(idx, endPtr));
} else {
var str = "";
while (idx < endPtr) {
var u0 = heap[idx++];
if (!(u0 & 128)) {
str += String.fromCharCode(u0);
continue;
}
var u1 = heap[idx++] & 63;
if ((u0 & 224) == 192) {
str += String.fromCharCode((u0 & 31) << 6 | u1);
continue;
}
var u2 = heap[idx++] & 63;
if ((u0 & 240) == 224) {
u0 = (u0 & 15) << 12 | u1 << 6 | u2;
} else {
u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heap[idx++] & 63;
}
if (u0 < 65536) {
str += String.fromCharCode(u0);
} else {
var ch = u0 - 65536;
str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023);
}
}
}
return str;
}
function UTF8ToString(ptr, maxBytesToRead) {
return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : "";
}
function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) {
if (!(maxBytesToWrite > 0)) return 0;
var startIdx = outIdx;
var endIdx = outIdx + maxBytesToWrite - 1;
for (var i = 0; i < str.length; ++i) {
var u = str.charCodeAt(i);
if (u >= 55296 && u <= 57343) {
var u1 = str.charCodeAt(++i);
u = 65536 + ((u & 1023) << 10) | u1 & 1023;
}
if (u <= 127) {
if (outIdx >= endIdx) break;
heap[outIdx++] = u;
} else if (u <= 2047) {
if (outIdx + 1 >= endIdx) break;
heap[outIdx++] = 192 | u >> 6;
heap[outIdx++] = 128 | u & 63;
} else if (u <= 65535) {
if (outIdx + 2 >= endIdx) break;
heap[outIdx++] = 224 | u >> 12;
heap[outIdx++] = 128 | u >> 6 & 63;
heap[outIdx++] = 128 | u & 63;
} else {
if (outIdx + 3 >= endIdx) break;
heap[outIdx++] = 240 | u >> 18;
heap[outIdx++] = 128 | u >> 12 & 63;
heap[outIdx++] = 128 | u >> 6 & 63;
heap[outIdx++] = 128 | u & 63;
}
}
heap[outIdx] = 0;
return outIdx - startIdx;
}
function lengthBytesUTF8(str) {
var len = 0;
for (var i = 0; i < str.length; ++i) {
var u = str.charCodeAt(i);
if (u >= 55296 && u <= 57343) u = 65536 + ((u & 1023) << 10) | str.charCodeAt(++i) & 1023;
if (u <= 127) ++len; else if (u <= 2047) len += 2; else if (u <= 65535) len += 3; else len += 4;
}
return len;
}
function allocateUTF8(str) {
var size = lengthBytesUTF8(str) + 1;
var ret = _malloc(size);
if (ret) stringToUTF8Array(str, HEAP8, ret, size);
return ret;
}
var buffer, HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
function updateGlobalBufferAndViews(buf) {
buffer = buf;
Module["HEAP8"] = HEAP8 = new Int8Array(buf);
Module["HEAP16"] = HEAP16 = new Int16Array(buf);
Module["HEAP32"] = HEAP32 = new Int32Array(buf);
Module["HEAPU8"] = HEAPU8 = new Uint8Array(buf);
Module["HEAPU16"] = HEAPU16 = new Uint16Array(buf);
Module["HEAPU32"] = HEAPU32 = new Uint32Array(buf);
Module["HEAPF32"] = HEAPF32 = new Float32Array(buf);
Module["HEAPF64"] = HEAPF64 = new Float64Array(buf);
}
var wasmTable;
var __ATPRERUN__ = [];
var __ATINIT__ = [];
var __ATPOSTRUN__ = [];
function preRun() {
callRuntimeCallbacks(__ATPRERUN__);
}
function initRuntime() {
callRuntimeCallbacks(__ATINIT__);
}
function postRun() {
callRuntimeCallbacks(__ATPOSTRUN__);
}
function addOnInit(cb) {
__ATINIT__.unshift(cb);
}
var runDependencies = 0;
var runDependencyWatcher = null;
var dependenciesFulfilled = null;
function addRunDependency(id) {
runDependencies++;
}
function removeRunDependency(id) {
runDependencies--;
if (runDependencies == 0) {
if (runDependencyWatcher !== null) {
clearInterval(runDependencyWatcher);
runDependencyWatcher = null;
}
if (dependenciesFulfilled) {
var callback = dependenciesFulfilled;
dependenciesFulfilled = null;
callback();
}
}
}
Module["preloadedImages"] = {};
Module["preloadedAudios"] = {};
function abort(what) {
what = "Aborted(" + what + ")";
ABORT = true;
EXITSTATUS = 1;
what += ". Build with -s ASSERTIONS=1 for more info.";
var e = new Error(what);
readyPromiseReject(e);
throw e;
}
function createWasm() {
var info = {
"a": asmLibraryArg
};
function receiveInstance(instance, module) {
var exports = instance.exports;
Module["asm"] = exports;
wasmMemory = Module["asm"]["l"];
updateGlobalBufferAndViews(wasmMemory.buffer);
wasmTable = Module["asm"]["p"];
addOnInit(Module["asm"]["m"]);
removeRunDependency("wasm-instantiate");
}
addRunDependency("wasm-instantiate");
if (Module["instantiateWasm"]) {
try {
var exports = Module["instantiateWasm"](info, receiveInstance);
return exports;
} catch (e) {
err("Module.instantiateWasm callback failed with error: " + e);
return false;
}
}
throw new Error('missing instantiateWasm');
}
function _dynamicImport(ctx, argc, argv, resolveFunc, rejectFunc, basename, filename) {
return Module.dynamicImport(ctx, argc, argv, resolveFunc, rejectFunc, basename, filename);
}
function _getModuleContent(ctx, module_name) {
return Module.getModuleContent(ctx, module_name);
}
function _invokeHostFunction(ctx, token, args) {
return Module.invokeHostFunction(ctx, token, args);
}
function callRuntimeCallbacks(callbacks) {
while (callbacks.length > 0) {
var callback = callbacks.shift();
if (typeof callback == "function") {
callback(Module);
continue;
}
var func = callback.func;
if (typeof func == "number") {
if (callback.arg === undefined) {
getWasmTableEntry(func)();
} else {
getWasmTableEntry(func)(callback.arg);
}
} else {
func(callback.arg === undefined ? null : callback.arg);
}
}
}
var wasmTableMirror = [];
function getWasmTableEntry(funcPtr) {
var func = wasmTableMirror[funcPtr];
if (!func) {
if (funcPtr >= wasmTableMirror.length) wasmTableMirror.length = funcPtr + 1;
wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr);
}
return func;
}
function ___assert_fail(condition, filename, line, func) {
abort("Assertion failed: " + UTF8ToString(condition) + ", at: " + [ filename ? UTF8ToString(filename) : "unknown filename", line, func ? UTF8ToString(func) : "unknown function" ]);
}
function __localtime_js(time, tmPtr) {
var date = new Date(HEAP32[time >> 2] * 1e3);
HEAP32[tmPtr >> 2] = date.getSeconds();
HEAP32[tmPtr + 4 >> 2] = date.getMinutes();
HEAP32[tmPtr + 8 >> 2] = date.getHours();
HEAP32[tmPtr + 12 >> 2] = date.getDate();
HEAP32[tmPtr + 16 >> 2] = date.getMonth();
HEAP32[tmPtr + 20 >> 2] = date.getFullYear() - 1900;
HEAP32[tmPtr + 24 >> 2] = date.getDay();
var start = new Date(date.getFullYear(), 0, 1);
var yday = (date.getTime() - start.getTime()) / (1e3 * 60 * 60 * 24) | 0;
HEAP32[tmPtr + 28 >> 2] = yday;
HEAP32[tmPtr + 36 >> 2] = -(date.getTimezoneOffset() * 60);
var summerOffset = new Date(date.getFullYear(), 6, 1).getTimezoneOffset();
var winterOffset = start.getTimezoneOffset();
var dst = (summerOffset != winterOffset && date.getTimezoneOffset() == Math.min(winterOffset, summerOffset)) | 0;
HEAP32[tmPtr + 32 >> 2] = dst;
}
function _tzset_impl(timezone, daylight, tzname) {
var currentYear = new Date().getFullYear();
var winter = new Date(currentYear, 0, 1);
var summer = new Date(currentYear, 6, 1);
var winterOffset = winter.getTimezoneOffset();
var summerOffset = summer.getTimezoneOffset();
var stdTimezoneOffset = Math.max(winterOffset, summerOffset);
HEAP32[timezone >> 2] = stdTimezoneOffset * 60;
HEAP32[daylight >> 2] = Number(winterOffset != summerOffset);
function extractZone(date) {
var match = date.toTimeString().match(/\(([A-Za-z ]+)\)$/);
return match ? match[1] : "GMT";
}
var winterName = extractZone(winter);
var summerName = extractZone(summer);
var winterNamePtr = allocateUTF8(winterName);
var summerNamePtr = allocateUTF8(summerName);
if (summerOffset < winterOffset) {
HEAP32[tzname >> 2] = winterNamePtr;
HEAP32[tzname + 4 >> 2] = summerNamePtr;
} else {
HEAP32[tzname >> 2] = summerNamePtr;
HEAP32[tzname + 4 >> 2] = winterNamePtr;
}
}
function __tzset_js(timezone, daylight, tzname) {
if (__tzset_js.called) return;
__tzset_js.called = true;
_tzset_impl(timezone, daylight, tzname);
}
function _abort() {
abort("");
}
function _emscripten_memcpy_big(dest, src, num) {
HEAPU8.copyWithin(dest, src, src + num);
}
function _emscripten_get_heap_max() {
return 2147483648;
}
function emscripten_realloc_buffer(size) {
try {
wasmMemory.grow(size - buffer.byteLength + 65535 >>> 16);
updateGlobalBufferAndViews(wasmMemory.buffer);
return 1;
} catch (e) {}
}
function _emscripten_resize_heap(requestedSize) {
var oldSize = HEAPU8.length;
requestedSize = requestedSize >>> 0;
var maxHeapSize = _emscripten_get_heap_max();
if (requestedSize > maxHeapSize) {
return false;
}
let alignUp = (x, multiple) => x + (multiple - x % multiple) % multiple;
for (var cutDown = 1; cutDown <= 4; cutDown *= 2) {
var overGrownHeapSize = oldSize * (1 + .2 / cutDown);
overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296);
var newSize = Math.min(maxHeapSize, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536));
var replacement = emscripten_realloc_buffer(newSize);
if (replacement) {
return true;
}
}
return false;
}
function _fd_write(fd, iov, iovcnt, pnum) {
var num = 0;
for (var i = 0; i < iovcnt; i++) {
var ptr = HEAP32[iov >> 2];
var len = HEAP32[iov + 4 >> 2];
iov += 8;
if (typeof process !== 'undefined') {
process.stdout.write(UTF8ToString(ptr, len))
}
num += len;
}
HEAP32[pnum >> 2] = num;
}
function _gettimeofday(ptr) {
var now = Date.now();
HEAP32[ptr >> 2] = now / 1e3 | 0;
HEAP32[ptr + 4 >> 2] = now % 1e3 * 1e3 | 0;
return 0;
}
var asmLibraryArg = {
"a": ___assert_fail,
"h": _dynamicImport,
"i": _getModuleContent,
"j": _invokeHostFunction,
"e": __localtime_js,
"f": __tzset_js,
"b": _abort,
"g": _emscripten_memcpy_big,
"k": _emscripten_resize_heap,
"d": _fd_write,
"c": _gettimeofday
};
var asm = createWasm();
var ___wasm_call_ctors = Module["___wasm_call_ctors"] = function() {
return (___wasm_call_ctors = Module["___wasm_call_ctors"] = Module["asm"]["m"]).apply(null, arguments);
};
var _malloc = Module["_malloc"] = function() {
return (_malloc = Module["_malloc"] = Module["asm"]["n"]).apply(null, arguments);
};
var _free = Module["_free"] = function() {
return (_free = Module["_free"] = Module["asm"]["o"]).apply(null, arguments);
};
var _newContext = Module["_newContext"] = function() {
return (_newContext = Module["_newContext"] = Module["asm"]["q"]).apply(null, arguments);
};
var _freeContext = Module["_freeContext"] = function() {
return (_freeContext = Module["_freeContext"] = Module["asm"]["r"]).apply(null, arguments);
};
var _doDynamicImport = Module["_doDynamicImport"] = function() {
return (_doDynamicImport = Module["_doDynamicImport"] = Module["asm"]["s"]).apply(null, arguments);
};
var _pathJoin = Module["_pathJoin"] = function() {
return (_pathJoin = Module["_pathJoin"] = Module["asm"]["t"]).apply(null, arguments);
};
var _load = Module["_load"] = function() {
return (_load = Module["_load"] = Module["asm"]["u"]).apply(null, arguments);
};
var _call = Module["_call"] = function() {
return (_call = Module["_call"] = Module["asm"]["v"]).apply(null, arguments);
};
var _freeJsValue = Module["_freeJsValue"] = function() {
return (_freeJsValue = Module["_freeJsValue"] = Module["asm"]["w"]).apply(null, arguments);
};
Module["UTF8ToString"] = UTF8ToString;
Module["allocateUTF8"] = allocateUTF8;
var calledRun;
dependenciesFulfilled = function runCaller() {
if (!calledRun) run();
if (!calledRun) dependenciesFulfilled = runCaller;
};
function run(args) {
args = args || arguments_;
if (runDependencies > 0) {
return;
}
preRun();
if (runDependencies > 0) {
return;
}
function doRun() {
if (calledRun) return;
calledRun = true;
Module["calledRun"] = true;
if (ABORT) return;
initRuntime();
readyPromiseResolve(Module);
postRun();
}
{
doRun();
}
}
Module["run"] = run;
run();
return Module.ready
}
);
})();
if (typeof exports === 'object' && typeof module === 'object')
module.exports = Module;
else if (typeof define === 'function' && define['amd'])
define([], function() { return Module; });
else if (typeof exports === 'object')
exports["Module"] = Module;
\ No newline at end of file
...@@ -8,8 +8,6 @@ Component({ ...@@ -8,8 +8,6 @@ Component({
addGlobalClass: true, addGlobalClass: true,
}, },
/** /**
* 组件的属性列表 * 组件的属性列表
*/ */
...@@ -22,19 +20,21 @@ Component({ ...@@ -22,19 +20,21 @@ Component({
*/ */
data: { data: {
baseUrl: 'https://yongma16.xyz', baseUrl: 'https://yongma16.xyz',
runJsPath: '/common-api/searchOpenAiText/', runJsPath: '/common-api/runJs/',
config: { config: {
title: '运行js', title: '运行js',
runCodePlaceholderText: '请输入js', runCodePlaceholderText: '请输入js',
loading: true, loading: true,
runBtnText: '运行', runBtnText: '运行',
formatBtnText: '格式化', formatBtnText: '格式化',
clearBtnText:'清空',
htmlNode: '' htmlNode: ''
}, },
codeVal: '', codeVal: '',
loading: false, loading: false,
runCodeRes: '结果集', runCodeRes: '',
htmlNode: '结果集' htmlNode: '',
prefixRes:'结果:'
}, },
...@@ -50,22 +50,51 @@ Component({ ...@@ -50,22 +50,51 @@ Component({
htmlNode: app.changeHtmlText(val) htmlNode: app.changeHtmlText(val)
}) })
}, },
async eval_js(val) {
try {
const res = await app.eval_des(`${val}`)
console.log(res, 'res')
console.log(res())
this.setData({
runCodeRes: res,
htmlNode: app.changeHtmlText(res)
})
} catch (r) {
const rText = JSON.stringify(r)
this.setData({
runCodeRes: rText,
htmlNode: app.changeHtmlText(rText)
})
}
},
formatCode(){
},
clearCode(){
this.setData({
codeVal:''
})
},
runCode() { runCode() {
const codeVal = this.data.codeVal const codeVal = this.data.codeVal
console.log('运行代码', codeVal) console.log('运行代码', codeVal)
const thisBack = this const thisBack = this
if (codeVal) { if (codeVal) {
// let obj =(new Function("return "+""+codeVal+""))(); // this.eval_js(codeVal)
const data = { const data = {
coontent: codeVal content: codeVal
} }
const headers = { 'Content-Type': 'application/json;charset=UTF-8' }
wx.request({ wx.request({
url: this.data.baseUrl + this.data.runJsPath, url: this.data.baseUrl + this.data.runJsPath,
headers:headers,
method: 'POST', method: 'POST',
data: data, data: data,
success: res => { success: res => {
console.log(res, 'res') let resText=res.data.data
const resText=res.data if(res.data.code===0){
resText=res.data.msg
}
thisBack.setData({ thisBack.setData({
runCodeRes:resText , runCodeRes:resText ,
htmlNode: app.changeHtmlText(resText) htmlNode: app.changeHtmlText(resText)
......
...@@ -8,11 +8,13 @@ ...@@ -8,11 +8,13 @@
<view class="container-box-show"> <view class="container-box-show">
<view class="container-box-show-btn"> <view class="container-box-show-btn">
<button type="primary" loading="{{loading}}" size="mini" bindtap="runCode">{{config.runBtnText}}</button> <button type="primary" loading="{{loading}}" size="mini" bindtap="runCode">{{config.runBtnText}}</button>
<button type="primary" loading="{{loading}}" size="mini" bindtap="runCode" class="format-btn">{{config.formatBtnText}}</button> <button type="primary" loading="{{loading}}" size="mini" bindtap="formatCode" class="format-btn">{{config.formatBtnText}}</button>
<button type="primary" loading="{{loading}}" size="mini" bindtap="clearCode" class="format-btn">{{config.clearBtnText}}</button>
</view> </view>
<view class="container-box-show-response"> <view class="container-box-show-response">
<view class="container-html"> <view class="container-html">
<towxml nodes="{{htmlNode}}" /> {{prefixRes}}{{runCodeRes}}
<!-- <towxml nodes="{{htmlNode}}" /> -->
</view> </view>
</view> </view>
</view> </view>
......
...@@ -51,8 +51,9 @@ ...@@ -51,8 +51,9 @@
width: 100%; width: 100%;
height: 50%; height: 50%;
background: rgba(255, 255, 255, .2); background: rgba(255, 255, 255, .2);
border: 1px solid rgb(8, 183, 252); border: 1px solid rgba(16, 116, 187);
box-shadow: 0 2rpx 5rpx 5rpx rgba(255, 255, 255, .2); box-shadow: 0 2rpx 5rpx 5rpx rgba(255, 255, 255, .2);
padding: 2px;
} }
.section{ .section{
position: relative; position: relative;
...@@ -67,5 +68,5 @@ ...@@ -67,5 +68,5 @@
color: #333; color: #333;
user-select: text; user-select: text;
overflow: auto; overflow: auto;
border: 1px solid rgb(8, 183, 252); border: 1px solid rgba(16, 116, 187);
} }
\ No newline at end of file
...@@ -62,6 +62,7 @@ page { ...@@ -62,6 +62,7 @@ page {
left: 0; left: 0;
z-index: 1; z-index: 1;
width:50%; width:50%;
transition: 2s;
font-size: 12px; font-size: 12px;
height:100%; height:100%;
background-color: rgba(0, 0, 0,.8); background-color: rgba(0, 0, 0,.8);
...@@ -76,6 +77,7 @@ page { ...@@ -76,6 +77,7 @@ page {
right: 0; right: 0;
z-index: 1; z-index: 1;
width:50%; width:50%;
transition: 2s;
height:100%; height:100%;
background-color: rgba(0, 0, 0,.5); background-color: rgba(0, 0, 0,.5);
overflow: hidden; overflow: hidden;
...@@ -84,6 +86,7 @@ page { ...@@ -84,6 +86,7 @@ page {
.container-menu-expand{ .container-menu-expand{
position: absolute; position: absolute;
transition: 2s;
left: 0; left: 0;
z-index: 1; z-index: 1;
} }
......
...@@ -15,9 +15,11 @@ ...@@ -15,9 +15,11 @@
<image class="avatar" class="user-image" src="{{userImageUrl}}"></image> <image class="avatar" class="user-image" src="{{userImageUrl}}"></image>
</button> </button>
<view style="display: flex;width:100%;text-align: center;"> <view style="display: flex;width:100%;text-align: center;">
<!-- <view style="width: 30%;text-align: right;"> <!-- <view style="width: 30%;text-align: right;">
{{userPrefix}} {{userPrefix}}
</view> --> </view> -->
<view style="width:100%;text-align: center;"> <view style="width:100%;text-align: center;">
<input type="nickname" class="weui-input" value="{{userName}}" bindinput="bindKeyInput" placeholder-style="color: #fff" style="width: 100%;border-bottom: 1px solid #ffffff;" placeholder="{{designPlaceholder}}" /> <input type="nickname" class="weui-input" value="{{userName}}" bindinput="bindKeyInput" placeholder-style="color: #fff" style="width: 100%;border-bottom: 1px solid #ffffff;" placeholder="{{designPlaceholder}}" />
</view> </view>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册