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


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2697 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 04a63402
......@@ -513,10 +513,36 @@ class V8EXPORT ScriptOrigin {
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 @@ class V8EXPORT Script {
/**
* 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();
......
......@@ -1058,11 +1058,11 @@ ScriptData* ScriptData::New(unsigned* data, int length) {
// --- 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 @@ Local<Script> Script::Compile(v8::Handle<String> source,
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 @@ Local<Value> Script::Run() {
{
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 =
......
......@@ -7738,3 +7738,18 @@ THREADED_TEST(PixelArray) {
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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment