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 -~----------~----~----~----~------~----~------~--~---
