Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiled code only working if bytenode.compileFile is executed using the dev console #47

Closed
paulr113 opened this issue Jan 25, 2020 · 15 comments

Comments

@paulr113
Copy link

paulr113 commented Jan 25, 2020

I'm running into a very strange issue while using bytenode to compile the .js files of my Electron app.
I have a compile.js file, which will compile all my code into bytecode. If i try to use it by running require("./compile") from any .js file within the render process the compiled code won't work and gives me an error message. If I on the other hand run require("./compile") from the dev tools console the compiled code works just fine.

compile.js:

const bytenode = require("bytenode")
const fs = require('fs');
const v8 = require('v8');

v8.setFlagsFromString('--no-lazy');

bytenode.compileFile("./src/modules/file.js", "./src/modules/file.jsc");

Error message:

#
# Fatal error in , line 0
# ignored
#
#
#
#FailureMessage Object: 0x7ffeee8750900   Electron Framework                  0x0000000108da5a59 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 12223577
1   Electron Framework                  0x0000000108cfe163 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 11537251
2   Electron Framework                  0x000000010aa3771b v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 42180891
3   Electron Framework                  0x000000010aa19823 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) + 42058275
4   Electron Framework                  0x0000000107737f84 v8::internal::Parser::DoParseFunction(v8::internal::Isolate*, v8::internal::ParseInfo*, v8::internal::AstRawString const*) + 340
5   Electron Framework                  0x0000000107737a4c v8::internal::Parser::ParseFunction(v8::internal::Isolate*, v8::internal::ParseInfo*, v8::internal::Handle<v8::internal::SharedFunctionInfo>) + 524
6   Electron Framework                  0x0000000107a7c1e8 v8::internal::parsing::ParseFunction(v8::internal::ParseInfo*, v8::internal::Handle<v8::internal::SharedFunctionInfo>, v8::internal::Isolate*, v8::internal::parsing::ReportErrorsAndStatisticsMode) + 248
7   Electron Framework                  0x00000001077fbae1 v8::internal::Compiler::CollectSourcePositions(v8::internal::Isolate*, v8::internal::Handle<v8::internal::SharedFunctionInfo>) + 1025
8   Electron Framework                  0x0000000107885d32 v8::internal::Factory::NewProperSubString(v8::internal::Handle<v8::internal::String>, int, int) + 2258
9   Electron Framework                  0x0000000107885bb6 v8::internal::Factory::NewProperSubString(v8::internal::Handle<v8::internal::String>, int, int) + 1878
10  Electron Framework                  0x00000001078acd58 v8::internal::Factory::NewStackFrameInfo(v8::internal::Handle<v8::internal::FrameArray>, int) + 264
11  Electron Framework                  0x0000000107a62f39 v8::internal::ScopeInfo::InferredFunctionName() const + 11849
12  Electron Framework                  0x0000000107a623e7 v8::internal::ScopeInfo::InferredFunctionName() const + 8951
13  Electron Framework                  0x000000010765c3b8 v8::StackFrame::GetFunctionName() const + 56
14  Electron Framework                  0x0000000107dba93e v8_inspector::V8StackTraceId::V8StackTraceId(unsigned long, std::__1::pair<long long, long long>) + 78
15  Electron Framework                  0x0000000107da7ae2 v8_inspector::V8StackTraceId::V8StackTraceId() + 21282
16  Electron Framework                  0x0000000107dbb357 v8_inspector::V8StackTraceId::V8StackTraceId(unsigned long, std::__1::pair<long long, long long>) + 2663
17  Electron Framework                  0x0000000107da6056 v8_inspector::V8StackTraceId::V8StackTraceId() + 14486
18  Electron Framework                  0x0000000107da35df v8_inspector::V8StackTraceId::V8StackTraceId() + 3615
19  Electron Framework                  0x0000000107d8a2e3 v8_inspector::DumpAsyncTaskStacksStateForTest(v8_inspector::V8Inspector*) + 30947
20  Electron Framework                  0x0000000107d88694 v8_inspector::DumpAsyncTaskStacksStateForTest(v8_inspector::V8Inspector*) + 23700
21  Electron Framework                  0x0000000107d88753 v8_inspector::DumpAsyncTaskStacksStateForTest(v8_inspector::V8Inspector*) + 23891
22  Electron Framework                  0x00000001077e3444 v8::internal::Accessors::MakeAccessor(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Name>, void (*)(v8::Local<v8::Name>, v8::PropertyCallbackInfo<v8::Value> const&), void (*)(v8::Local<v8::Name>, v8::Local<v8::Value>, v8::PropertyCallbackInfo<v8::Boolean> const&)) + 283572
23  Electron Framework                  0x00000001077ad235 v8::internal::Accessors::MakeAccessor(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Name>, void (*)(v8::Local<v8::Name>, v8::PropertyCallbackInfo<v8::Value> const&), void (*)(v8::Local<v8::Name>, v8::Local<v8::Value>, v8::PropertyCallbackInfo<v8::Boolean> const&)) + 61861
24  Electron Framework                  0x0000000108167fb9 v8::internal::compiler::ZoneStats::ReturnZone(v8::internal::Zone*) + 839161
25  Electron Framework                  0x00000001080ee001 v8::internal::compiler::ZoneStats::ReturnZone(v8::internal::Zone*) + 339521
26  Electron Framework                  0x00000001081186d0 v8::internal::compiler::ZoneStats::ReturnZone(v8::internal::Zone*) + 513296
27  Electron Framework                  0x000000010813c972 v8::internal::compiler::ZoneStats::ReturnZone(v8::internal::Zone*) + 661426
@OsamaAbbas
Copy link
Collaborator

Could you please start with something similar to this example? That example uses a very simple logic that can be easily adapted to your needs, and it works with no issues.

Let me know if this solves your issue.

@paulr113
Copy link
Author

I have used your example to compile all .js files needed for my main process (worked fine). My problem is, that I'm trying to compile the .js files needed for my render process.

@OsamaAbbas
Copy link
Collaborator

OsamaAbbas commented Jan 27, 2020

I guess your problem is that you are trying to run your compiled code inside the browser v8 engine, not node v8 engine. The compiled code depends on the APIs that node exposes, so without them it won't run.

So, if we have a setup like this, it WON'T work after compilation:

<!-- index.html -->
<script src="/path/to/jquery.js"></script>
<script>
  const bytenode = require('bytenode');
  require('./compiled-file.jsc');
</script>
// compiled-file.js
$(document).ready(function() {
  $("#target1").css("color", "red");
});

If you want to make it work, you have to use a setup like this:

<!-- index.html -->
<script src="/path/to/jquery.js"></script>
<script>
  const bytenode = require('bytenode');
  require('./compiled-file.jsc')(document, jQuery); // or you can pass the window object itself, or whatever suits your needs.
</script>
// compiled-file.js
module.exports = function(document, $) {
  $(document).ready(function() {
    $("#target1").css("color", "red");
  });
}

@paulr113
Copy link
Author

This didn't fix my issue. It might be worth pointing out, that my BrowserWindows is using nodeIntegration: true. The file I'm trying to compile is using various node features such as fs, child_process and util.promisify

@OsamaAbbas
Copy link
Collaborator

Could you please provide a minimal app that reproduce the problem?

@paulr113
Copy link
Author

paulr113 commented Jan 28, 2020

I have uploaded an example to https://github.com/paulr113/bytenode_bug_example. Im pretty sure setTimeout is causing the crash.

@OsamaAbbas
Copy link
Collaborator

I can reproduce the error. Promise.delay too causes the same crash, not only setTimeout.

@paulr113
Copy link
Author

Do you have any idea why this is happening?

@OsamaAbbas
Copy link
Collaborator

OsamaAbbas commented Jan 29, 2020

Still investigating...

@paulr113
Copy link
Author

paulr113 commented Jan 29, 2020

I looks like the issue isn't related to setTimeout but to async arrow functions in general.
This code works:

document.getElementById("testBtn").onclick = (ev) => {
    document.getElementById("testP").innerHTML = "Before delay"
    delay(1000).then(() => {
        document.getElementById("testP").innerHTML = "After delay"
    })
}

This code works aswell:

document.getElementById("testBtn").onclick = async function (ev) {
    document.getElementById("testP").innerHTML = "Before delay"
    await delay(1000);
    document.getElementById("testP").innerHTML = "After delay"
}

This code will result in a crash:

document.getElementById("testBtn").onclick = async (ev) => {
    document.getElementById("testP").innerHTML = "Before delay"
    await delay(1000);
    document.getElementById("testP").innerHTML = "After delay"
}

delay():

function delay(delay) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            return resolve();
        }, delay)
    })
}

@OsamaAbbas
Copy link
Collaborator

Thank you for your analysis. I added this to the list of know limitations.

@paulr113
Copy link
Author

I have made a new pull request (#49 ) which fixes the issue.

@kousiksatish
Copy link

@OsamaAbbas So, there is no work around for this other than not using async arrow functions?

@OsamaAbbas
Copy link
Collaborator

OsamaAbbas commented Aug 19, 2020

@OsamaAbbas So, there is no work around for this other than not using async arrow functions?

Check the pull request by paulr113 (#49), he managed to achieve what you are looking for by using babel.

@Griffork
Copy link

Is there an open electron issue that I can follow for this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants