Revision: 2697
Author: [email protected]
Date: Mon Aug 17 04:41:00 2009
Log: Context-independent script compilation.
Added Script::New calls that create a new context-independent
(boilerplate) script which can be executed in any context, unlike the
current scripts which bind the context in which they're compiled.

Review URL: http://codereview.chromium.org/172043

http://code.google.com/p/v8/source/detail?r=2697

Modified:
  /branches/bleeding_edge/include/v8.h
  /branches/bleeding_edge/src/api.cc
  /branches/bleeding_edge/test/cctest/test-api.cc

=======================================
--- /branches/bleeding_edge/include/v8.h        Thu Aug 13 02:35:51 2009
+++ /branches/bleeding_edge/include/v8.h        Mon Aug 17 04:41:00 2009
@@ -513,10 +513,36 @@
  class V8EXPORT Script {
   public:

+   /**
+    * Compiles the specified script. The ScriptOrigin* and ScriptData*
+    * parameters are owned by the caller of Script::Compile. No
+    * references to these objects are kept after compilation finishes.
+    *
+    * The script object returned is context independent; when run it
+    * will use the currently entered context.
+    */
+   static Local<Script> New(Handle<String> source,
+                            ScriptOrigin* origin = NULL,
+                            ScriptData* pre_data = NULL);
+
+   /**
+    * Compiles the specified script using the specified file name
+    * object (typically a string) as the script's origin.
+    *
+    * The script object returned is context independent; when run it
+    * will use the currently entered context.
+    */
+   static Local<Script> New(Handle<String> source,
+                            Handle<Value> file_name);
+
    /**
     * Compiles the specified script. The ScriptOrigin* and ScriptData*
     * parameters are owned by the caller of Script::Compile. No
     * references to these objects are kept after compilation finishes.
+   *
+   * The script object returned is bound to the context that was active
+   * when this function was called.  When run it will always use this
+   * context.
     */
    static Local<Script> Compile(Handle<String> source,
                                 ScriptOrigin* origin = NULL,
@@ -525,12 +551,20 @@
    /**
     * Compiles the specified script using the specified file name
     * object (typically a string) as the script's origin.
+   *
+   * The script object returned is bound to the context that was active
+   * when this function was called.  When run it will always use this
+   * context.
     */
    static Local<Script> Compile(Handle<String> source,
                                 Handle<Value> file_name);

    /**
-   * Runs the script returning the resulting value.
+   * Runs the script returning the resulting value.  If the script is
+   * context independent (created using ::New) it will be run in the
+   * currently entered context.  If it is context specific (created
+   * using ::Compile) it will be run in the context in which it was
+   * compiled.
     */
    Local<Value> Run();

=======================================
--- /branches/bleeding_edge/src/api.cc  Thu Aug 13 15:13:45 2009
+++ /branches/bleeding_edge/src/api.cc  Mon Aug 17 04:41:00 2009
@@ -1058,11 +1058,11 @@
  // --- S c r i p t ---


-Local<Script> Script::Compile(v8::Handle<String> source,
-                              v8::ScriptOrigin* origin,
-                              v8::ScriptData* script_data) {
-  ON_BAILOUT("v8::Script::Compile()", return Local<Script>());
-  LOG_API("Script::Compile");
+Local<Script> Script::New(v8::Handle<String> source,
+                          v8::ScriptOrigin* origin,
+                          v8::ScriptData* script_data) {
+  ON_BAILOUT("v8::Script::New()", return Local<Script>());
+  LOG_API("Script::New");
    ENTER_V8;
    i::Handle<i::String> str = Utils::OpenHandle(*source);
    i::Handle<i::Object> name_obj;
@@ -1096,6 +1096,27 @@
                                                                pre_data);
    has_pending_exception = boilerplate.is_null();
    EXCEPTION_BAILOUT_CHECK(Local<Script>());
+  return Local<Script>(ToApi<Script>(boilerplate));
+}
+
+
+Local<Script> Script::New(v8::Handle<String> source,
+                          v8::Handle<Value> file_name) {
+  ScriptOrigin origin(file_name);
+  return New(source, &origin);
+}
+
+
+Local<Script> Script::Compile(v8::Handle<String> source,
+                              v8::ScriptOrigin* origin,
+                              v8::ScriptData* script_data) {
+  ON_BAILOUT("v8::Script::Compile()", return Local<Script>());
+  LOG_API("Script::Compile");
+  ENTER_V8;
+  Local<Script> generic = New(source, origin, script_data);
+  if (generic.IsEmpty())
+    return generic;
+  i::Handle<i::JSFunction> boilerplate = Utils::OpenHandle(*generic);
    i::Handle<i::JSFunction> result =
        i::Factory::NewFunctionFromBoilerplate(boilerplate,
                                               i::Top::global_context());
@@ -1118,6 +1139,10 @@
    {
      HandleScope scope;
      i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
+    if (fun->IsBoilerplate()) {
+      fun = i::Factory::NewFunctionFromBoilerplate(fun,
+                                                    
i::Top::global_context());
+    }
      EXCEPTION_PREAMBLE();
      i::Handle<i::Object> receiver(i::Top::context()->global_proxy());
      i::Handle<i::Object> result =
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc     Thu Aug  6 06:35:21 2009
+++ /branches/bleeding_edge/test/cctest/test-api.cc     Mon Aug 17 04:41:00 2009
@@ -7738,3 +7738,18 @@

    free(pixel_data);
  }
+
+THREADED_TEST(ScriptContextDependence) {
+  v8::HandleScope scope;
+  LocalContext c1;
+  const char *source = "foo";
+  v8::Handle<v8::Script> dep =  
v8::Script::Compile(v8::String::New(source));
+  v8::Handle<v8::Script> indep = v8::Script::New(v8::String::New(source));
+  c1->Global()->Set(v8::String::New("foo"), v8::Integer::New(100));
+  CHECK_EQ(dep->Run()->Int32Value(), 100);
+  CHECK_EQ(indep->Run()->Int32Value(), 100);
+  LocalContext c2;
+  c2->Global()->Set(v8::String::New("foo"), v8::Integer::New(101));
+  CHECK_EQ(dep->Run()->Int32Value(), 100);
+  CHECK_EQ(indep->Run()->Int32Value(), 101);
+}

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to