Search code examples
c++v8embedded-v8

v8::Script::Compile(v8::String::New(".make.some.syntax.errors"), v8::String::New("main"))->Run() causes segmentation fault


Let say I have this code:

Local<Script> script = Script::Compile(String::New("x1 = 1;"), String::New("main.js"));
printf("before run\n");
script->Run();
printf("after run\n");

Context was created and entered before.
Output of this code is:

before run
after run

Which is as expected. But if put some javascript code into source which contains syntax errors (eg, ".x11 = 1") then output is:

main.js:0: Uncaught SyntaxError: Unexpected token .
before execution.
Segmentation fault (core dumped)

Maybe I should not call Run if compilation has errors but how to check it?

In addition: (code from Getting Starget - Chrome V8 + code with syntax errors = the same thing)

#include <v8.h>

using namespace v8;

int main(int argc, char* argv[]) {  

// Get the default Isolate created at startup.  

Isolate* isolate = Isolate::GetCurrent();  

// Create a stack-allocated handle scope.

HandleScope handle_scope(isolate);  

// Create a new context.  

Handle<Context> context = Context::New(isolate);  

// Here's how you could create a Persistent handle to the context, if needed.  

Persistent<Context> persistent_context(isolate, context); 


// Enter the created context for compiling and  

// running the hello world script.   

Context::Scope context_scope(context);  

// Create a string containing the JavaScript source code.  

Handle<String> source = String::New(".>make.some.syntax.errors<");  

// Compile the source code.  

Handle<Script> script = Script::Compile(source);  

// Run the script to get the result.  

Handle<Value> result = script->Run(); 

// The persistent handle needs to be eventually disposed.  

persistent_context.Dispose();  

// Convert the result to an ASCII string and print it.  

String::AsciiValue ascii(result);  

printf("%s\n", *ascii);  

return 0;

}

Solution

  • After a some time of headache I found a way around it.

    When script compilation is failed it returns nothing to v8::Handle. So, in this case, script.IsEmpty() returns true.

    To make this clear I made some modifications in Google's Hello World code:

    #include <v8.h>
    
    using namespace v8;
    
    int main(int argc, char* argv[]) {  
    
    // Get the default Isolate created at startup.  
    
    Isolate* isolate = Isolate::GetCurrent();  
    
    // Create a stack-allocated handle scope.
    
    HandleScope handle_scope(isolate);  
    
    // Create a new context.  
    
    Handle<Context> context = Context::New(isolate);  
    
    // Here's how you could create a Persistent handle to the context, if needed.  
    
    Persistent<Context> persistent_context(isolate, context); 
    
    
    // Enter the created context for compiling and  
    
    // running the hello world script.   
    
    Context::Scope context_scope(context);  
    
    // Create a string containing the JavaScript source code.  
    
    Handle<String> source = String::New(".>no.matter.what.code.is<");  
    
    // Compile the source code.  
    
    Handle<Script> script = Script::Compile(source);  
    if(!script.IsEmpty()) // is script compiled ?
    {
      // Run the script to get the result.  
    
      Handle<Value> result = script->Run(); 
    
      // Convert the result to an ASCII string and print it.  
      String::AsciiValue ascii(result);  
    
      printf("%s\n", *ascii);  
    }
    
    // The persistent handle needs to be eventually disposed.  
    
    persistent_context.Dispose();      
    
    return 0;
    
    }