seven332 / quickjs-android

QuickJS Android wrapper

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

com.hippo.quickjs.android.JSEvaluationException: null at fib.js:1

bjhexn opened this issue · comments

QuickJS quickJS = new QuickJS.Builder().build();
JSRuntime runtime;
JSContext jsContext;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_quick_jsactivity);

    initJSContent();
    demo();
}

private void initJSContent() {
    runtime = quickJS.createJSRuntime();
    jsContext = runtime.createJSContext();
}

private void demo() {
    String script1 = "" +
            "function fib(n) {" +
            "  return n;" +
            "}";
    jsContext.evaluate(script1, "fib.js");
    int result = jsContext.evaluate("fib(6)", "fib.js", int.class);
    LogUtils.log("demo result = " + result );
}

@Override
public void onClick(View v) {
    int id = v.getId();
    if (id == R.id.btn_quick_js) {
        //initJSContent();
        demo();
    } else if (id == R.id.btn_quick_js2) {
        demo();
    }
}

"demo()" execute in onCreate() is 0K , but tap button execute "demo" happened crash. If initialize " initJSContent();" in onClick, no crash。 “JSContent” may be reused ?

是否有遇到同样的问题? jscontent 是否可以复用?

问题描述:

  1. 在onCreate 创建实例可以运行
  2. 在点击按钮的时候不再次进程初始化,就会报错。
  3. jsContent是否可以复用?如果不新创建JSRuntime, 只创建jsContent又会提示内存溢出。

JSContent 支持复用,JSRuntime 也支持复用。

你遇到的问题是这个吧?
com.hippo.quickjs.android.JSEvaluationException: SyntaxError: stack overflow
at fib.js:1

QuickJS 说堆栈溢出了,但实际上并没有。
QuickJS 通过 __builtin_frame_address 获取当前栈顶指针,在创建 JSRuntime 的时候取当前栈顶指针存到 stack_top 里,之后每次执行 js 脚本的时候,都再取当前栈顶指针,和之前的 stack_top 比较,看两者之差是否超过一个最大值,默认是 256 * 1024。在 PC 里这个逻辑没问题,因为之后的栈顶指针肯定在 stack_top 后面,而在 Android 里不一定,下一次用 JNI,当前栈顶指针和 stack_top 之差可能是负数,用的还是 size_t,就溢出了,导致认为堆栈溢出。

所以这是 QuickJS 在 Android 上的 bug。

简单的解决方法就是禁用堆栈检查,虽有宏来控制,但很难从编译参数上来禁用堆栈检查。
所以直接改源码,quickjs.c 76 行附近,注释掉 CONFIG_STACK_CHECK。

#if !defined(EMSCRIPTEN)
/* enable stack limitation */
// #define CONFIG_STACK_CHECK
#endif

最后说一个和 issue 无关的建议,QuickJS 在 Android 上问题太多,玩一玩就行了,千万别上生产环境。

  1. 现在的问题是可以,可以复用。在onCreate中可以进行初始化和执行js。 但是在点击按钮的时候,就无法执行了,出现上面的异常。 在onClick 里再初始化一次就可以了, 问题比较奇怪,代码比较简单你可以把我上面的demo贴进来试试。

  2. QuickJS 在 Android 上问题多? 有具体的问题吗?或相关文档, 谢谢回复。

JSContent 支持复用,JSRuntime 也支持复用。

你遇到的问题是这个吧?
com.hippo.quickjs.android.JSEvaluationException: SyntaxError: stack overflow
at fib.js:1

QuickJS 说堆栈溢出了,但实际上并没有。
QuickJS 通过 __builtin_frame_address 获取当前栈顶指针,在创建 JSRuntime 的时候取当前栈顶指针存到 stack_top 里,之后每次执行 js 脚本的时候,都再取当前栈顶指针,和之前的 stack_top 比较,看两者之差是否超过一个最大值,默认是 256 * 1024。在 PC 里这个逻辑没问题,因为之后的栈顶指针肯定在 stack_top 后面,而在 Android 里不一定,下一次用 JNI,当前栈顶指针和 stack_top 之差可能是负数,用的还是 size_t,就溢出了,导致认为堆栈溢出。

所以这是 QuickJS 在 Android 上的 bug。

简单的解决方法就是禁用堆栈检查,虽有宏来控制,但很难从编译参数上来禁用堆栈检查。
所以直接改源码,quickjs.c 76 行附近,注释掉 CONFIG_STACK_CHECK。

#if !defined(EMSCRIPTEN)
/* enable stack limitation */
// #define CONFIG_STACK_CHECK
#endif

最后说一个和 issue 无关的建议,QuickJS 在 Android 上问题太多,玩一玩就行了,千万别上生产环境。

你遇到的问题是这个吧?
com.hippo.quickjs.android.JSEvaluationException: SyntaxError: stack overflow
at fib.js:1

不是这个问题哈

贴下堆栈?

2021-08-18 11:39:22.556 1932-2766/system_process E/TaskPersister: File error accessing recents directory (directory doesn't exist?).
2021-08-18 11:39:27.184 32190-32190/com.example.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myapplication, PID: 32190
com.hippo.quickjs.android.JSEvaluationException: null
at fib.js:1

    at com.hippo.quickjs.android.JSContext.evaluateInternal(JSContext.java:164)
    at com.hippo.quickjs.android.JSContext.evaluate(JSContext.java:93)
    at com.my.app.webview.quickjs.QuickJSActivity.demo(QuickJSActivity.java:56)
    at com.my.app.webview.quickjs.QuickJSActivity.onClick(QuickJSActivity.java:68)
    at android.view.View.performClick(View.java:7140)
    at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992)
    at android.view.View.performClickInternal(View.java:7117)
    at android.view.View.access$3500(View.java:801)
    at android.view.View$PerformClick.run(View.java:27351)
    at android.os.Handler.handleCallback(Handler.java:883)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7356)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

代码如下
public class QuickJSActivity extends AppCompatActivity implements View.OnClickListener {

public static final String PATH = "/test/quickjs";

private Button btn;

QuickJS quickJS = new QuickJS.Builder().build();
JSRuntime runtime;
JSContext jsContext;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_quick_jsactivity);

    btn = findViewById(R.id.btn_quick_js);
    btn.setOnClickListener(this);
    findViewById(R.id.btn_quick_js2).setOnClickListener(this);

    initJSContent();
    demo();
}

@Override
protected void onResume() {
    super.onResume();
}

private void initJSContent() {
    runtime = quickJS.createJSRuntime();
    jsContext = runtime.createJSContext();
}

private void demo() {
    String script1 = "" +
            "function fib(n) {" +
            "  return n;" +
            "}";
    jsContext.evaluate(script1, "fib.js");
    int result = jsContext.evaluate("fib(6)", "fib.js", int.class);
    LogUtils.log("demo result = " + result );
}

@Override
public void onClick(View v) {
    int id = v.getId();
    if (id == R.id.btn_quick_js) {
        initJSContent();
        demo();
    } else if (id == R.id.btn_quick_js2) {
        demo();
    }
}

}

onCreate 执行没问题,点击 btn2会出现崩溃, 按钮btn1 在进行初始化则不会报错。

不确定是不是同一个问题,你可以试试把 #define CONFIG_STACK_CHECK 注释掉。

请问你用的是什么设备什么系统?

用的模拟器 和小米10 都有问题。

Hi I'm not sure I was able to follow this issue but from looking at the code and from Google Translate, this looks to be a similar issue to something I'm experiencing. Is there something I can try to resolve these somewhat random null pointer exceptions at line 1 and also stackoverflow errors?

@sangpark Remove #define CONFIG_STACK_CHECK in quickjs.c. It may work.

@seven332 Thanks for the info, I'm working on doing that now. But in the meantime, as I look into the issue, I see that the quickjs project has a commit that attempts to detect stack overflows

bellard/quickjs@c8ea4c4

It looks like the version of QuickJS this repo has a snapshot of is a bit out of date. Do you have any plans of bumping the QuickJS version and tagging a new build?

I have quickjs library imported in Android. I dont have access to quickjs.c
So then how can i disable CONFIG_STACK_CHECK?

Also, is there any better library to use instead of quickJs?

I found this library and it is working great. No more exceptions.
api 'io.github.taoweiji.quickjs:quickjs-android:1.3.0'