123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- #ifdef JAVASCRIPT_EVAL_ENABLED
- #include "api/javascript_eval.h"
- #include "emscripten.h"
- extern "C" EMSCRIPTEN_KEEPALIVE uint8_t *resize_poolbytearray_and_open_write(PoolByteArray *p_arr, PoolByteArray::Write *r_write, int p_len) {
- p_arr->resize(p_len);
- *r_write = p_arr->write();
- return r_write->ptr();
- }
- Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) {
- union {
- bool b;
- double d;
- char *s;
- } js_data;
- PoolByteArray arr;
- PoolByteArray::Write arr_write;
-
- Variant::Type return_type = static_cast<Variant::Type>(EM_ASM_INT({
- const CODE = $0;
- const USE_GLOBAL_EXEC_CONTEXT = $1;
- const PTR = $2;
- const BYTEARRAY_PTR = $3;
- const BYTEARRAY_WRITE_PTR = $4;
- var eval_ret;
- try {
- if (USE_GLOBAL_EXEC_CONTEXT) {
-
- var global_eval = eval;
- eval_ret = global_eval(UTF8ToString(CODE));
- } else {
- eval_ret = eval(UTF8ToString(CODE));
- }
- } catch (e) {
- console.warn(e);
- eval_ret = null;
- }
- switch (typeof eval_ret) {
- case 'boolean':
- setValue(PTR, eval_ret, 'i32');
- return 1;
- case 'number':
- setValue(PTR, eval_ret, 'double');
- return 3;
- case 'string':
- var array_len = lengthBytesUTF8(eval_ret)+1;
- var array_ptr = _malloc(array_len);
- try {
- if (array_ptr===0) {
- throw new Error('String allocation failed (probably out of memory)');
- }
- setValue(PTR, array_ptr , '*');
- stringToUTF8(eval_ret, array_ptr, array_len);
- return 4;
- } catch (e) {
- if (array_ptr!==0) {
- _free(array_ptr)
- }
- console.warn(e);
-
- }
- break;
- case 'object':
- if (eval_ret === null) {
- break;
- }
- if (ArrayBuffer.isView(eval_ret) && !(eval_ret instanceof Uint8Array)) {
- eval_ret = new Uint8Array(eval_ret.buffer);
- }
- else if (eval_ret instanceof ArrayBuffer) {
- eval_ret = new Uint8Array(eval_ret);
- }
- if (eval_ret instanceof Uint8Array) {
- var bytes_ptr = ccall('resize_poolbytearray_and_open_write', 'number', ['number', 'number' ,'number'], [BYTEARRAY_PTR, BYTEARRAY_WRITE_PTR, eval_ret.length]);
- HEAPU8.set(eval_ret, bytes_ptr);
- return 20;
- }
- break;
- }
- return 0;
- }, p_code.utf8().get_data(), p_use_global_exec_context, &js_data, &arr, &arr_write));
-
- switch (return_type) {
- case Variant::BOOL:
- return js_data.b;
- case Variant::REAL:
- return js_data.d;
- case Variant::STRING: {
- String str = String::utf8(js_data.s);
-
- EM_ASM_({ _free($0); }, js_data.s);
-
- return str;
- }
- case Variant::POOL_BYTE_ARRAY:
- arr_write = PoolByteArray::Write();
- return arr;
- default:
- return Variant();
- }
- }
- #endif
|