代码之家  ›  专栏  ›  技术社区  ›  Victor.Palyvoda

v8::Script::Compile(v8::String::New(“.make.some.syntax.errors”),v8::String::New((“main”))->Run()导致分段错误

  •  3
  • Victor.Palyvoda  · 技术社区  · 12 年前

    假设我有这样的代码:

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

    上下文是在之前创建和输入的。
    此代码的输出为:

    before run
    after run
    

    正如预期的那样。但如果将一些javascript代码放入 source 其包含语法错误(例如, ".x11 = 1" )则输出为:

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

    也许我不该打电话 Run 如果编译有错误,但如何检查?

    此外:(代码来自 Getting Starget - Chrome V8 +有语法错误的代码=相同的东西)

    #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;
    
    }
    
    2 回复  |  直到 12 年前
        1
  •  1
  •   Victor.Palyvoda    12 年前

    头痛了一段时间后,我找到了解决问题的方法。

    当脚本编译失败时,它不会向 v8::Handle 因此,在这种情况下, script.IsEmpty() 返回true。

    为了明确这一点,我对谷歌的Hello World代码进行了一些修改:

    #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;
    
    }
    
        2
  •  0
  •   wangfeng    6 年前

    基于samples/process.cc的v8源代码:

      // catch any exceptions the script might throw.
      TryCatch try_catch(GetIsolate());
    
      // Compile the script and check for errors.
      Local<Script> compiled_script;
      if (!Script::Compile(context, script).ToLocal(&compiled_script)) {
        String::Utf8Value error(GetIsolate(), try_catch.Exception());
        Log(*error);
        // The script failed to compile; bail out.
        return false;
      }
    
      // Run the script!
      Local<Value> result;
      if (!compiled_script->Run(context).ToLocal(&result)) {
        // The TryCatch above is still in effect and will have caught the error.
        String::Utf8Value error(GetIsolate(), try_catch.Exception());
        Log(*error);
        // Running the script failed; bail out.
        return false;
      }
    

    我希望这是有益的。