| Index: src/api.cc
|
| diff --git a/src/api.cc b/src/api.cc
|
| index a6ff52ca2fce9f7625b5830777d14516917bdb6c..c4cd0040a48619cf770d08753bc997ad2d8b7f12 100644
|
| --- a/src/api.cc
|
| +++ b/src/api.cc
|
| @@ -1617,6 +1617,22 @@ ScriptData* ScriptData::New(const char* data, int length) {
|
| Local<Script> Script::New(v8::Handle<String> source,
|
| v8::ScriptOrigin* origin,
|
| v8::ScriptData* pre_data) {
|
| + if (pre_data) {
|
| + return NewAndGenerateScriptDataIfNeeded(source, origin, &pre_data);
|
| + }
|
| + // Don't generate ScriptData; we're not going to pass it to the caller.
|
| + return NewAndGenerateScriptDataIfNeeded(source, origin, NULL);
|
| +}
|
| +
|
| +
|
| +Local<Script> Script::NewAndGenerateScriptDataIfNeeded(
|
| + v8::Handle<String> source, v8::ScriptOrigin* origin,
|
| + v8::ScriptData** pre_data) {
|
| + // pre_data == NULL: we don't have ScriptData and we don't want to.
|
| + // pre_data != NULL and *pre_data == NULL: we don't have ScriptData yet, but
|
| + // we want it to be produced
|
| + // pre_data != NULL and *pre_data != NULL; we already have ScriptData and it
|
| + // should be used when parsing.
|
| i::Handle<i::String> str = Utils::OpenHandle(*source);
|
| i::Isolate* isolate = str->GetIsolate();
|
| ON_BAILOUT(isolate, "v8::Script::New()", return Local<Script>());
|
| @@ -1646,12 +1662,13 @@ Local<Script> Script::New(v8::Handle<String> source,
|
| }
|
| }
|
| EXCEPTION_PREAMBLE(isolate);
|
| - i::ScriptDataImpl* pre_data_impl =
|
| - static_cast<i::ScriptDataImpl*>(pre_data);
|
| + i::ScriptDataImpl* pre_data_impl = pre_data ?
|
| + static_cast<i::ScriptDataImpl*>(*pre_data) : NULL;
|
| // We assert that the pre-data is sane, even though we can actually
|
| // handle it if it turns out not to be in release mode.
|
| ASSERT(pre_data_impl == NULL || pre_data_impl->SanityCheck());
|
| - // If the pre-data isn't sane we simply ignore it
|
| + // If the pre-data isn't sane we simply ignore it. Careful: don't nullify
|
| + // the caller's pointer, since the caller owns the invalid ScriptData.
|
| if (pre_data_impl != NULL && !pre_data_impl->SanityCheck()) {
|
| pre_data_impl = NULL;
|
| }
|
| @@ -1663,11 +1680,15 @@ Local<Script> Script::New(v8::Handle<String> source,
|
| is_shared_cross_origin,
|
| isolate->global_context(),
|
| NULL,
|
| - pre_data_impl,
|
| + pre_data ? &pre_data_impl : NULL,
|
| i::NOT_NATIVES_CODE);
|
| has_pending_exception = result.is_null();
|
| EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
|
| raw_result = *result;
|
| + if (pre_data != NULL && *pre_data == NULL) {
|
| + // Caller wanted us to generate ScriptData.
|
| + *pre_data = pre_data_impl;
|
| + }
|
| }
|
| i::Handle<i::SharedFunctionInfo> result(raw_result, isolate);
|
| return ToApiHandle<Script>(result);
|
| @@ -1703,6 +1724,28 @@ Local<Script> Script::Compile(v8::Handle<String> source,
|
| }
|
|
|
|
|
| +Local<Script> Script::CompileAndGenerateScriptDataIfNeeded(
|
| + v8::Handle<String> source, v8::ScriptOrigin* origin,
|
| + v8::ScriptData** cached_data) {
|
| + i::Handle<i::String> str = Utils::OpenHandle(*source);
|
| + i::Isolate* isolate = str->GetIsolate();
|
| + ON_BAILOUT(isolate, "v8::Script::Compile()", return Local<Script>());
|
| + LOG_API(isolate, "Script::Compile");
|
| + ENTER_V8(isolate);
|
| + Local<Script> generic =
|
| + NewAndGenerateScriptDataIfNeeded(source, origin, cached_data);
|
| + if (generic.IsEmpty()) return generic;
|
| + i::Handle<i::Object> obj = Utils::OpenHandle(*generic);
|
| + i::Handle<i::SharedFunctionInfo> function =
|
| + i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj));
|
| + i::Handle<i::JSFunction> result =
|
| + isolate->factory()->NewFunctionFromSharedFunctionInfo(
|
| + function,
|
| + isolate->global_context());
|
| + return ToApiHandle<Script>(result);
|
| +}
|
| +
|
| +
|
| Local<Script> Script::Compile(v8::Handle<String> source,
|
| v8::Handle<Value> file_name) {
|
| ScriptOrigin origin(file_name);
|
|
|