Index: src/api.cc |
diff --git a/src/api.cc b/src/api.cc |
index 43069676838e68123f400b2e78ac7d4c38dadac3..13f5194a63b487d3d2283ae896c40c3372e8f02d 100644 |
--- a/src/api.cc |
+++ b/src/api.cc |
@@ -1611,107 +1611,89 @@ ScriptData* ScriptData::New(const char* data, int length) { |
} |
-// --- S c r i p t --- |
+// --- S c r i p t s --- |
-Local<Script> Script::New(v8::Handle<String> source, |
- v8::ScriptOrigin* origin, |
- v8::ScriptData* pre_data) { |
- i::Handle<i::String> str = Utils::OpenHandle(*source); |
- i::Isolate* isolate = str->GetIsolate(); |
- ON_BAILOUT(isolate, "v8::Script::New()", return Local<Script>()); |
- LOG_API(isolate, "Script::New"); |
- ENTER_V8(isolate); |
- i::SharedFunctionInfo* raw_result = NULL; |
- { i::HandleScope scope(isolate); |
- i::Handle<i::Object> name_obj; |
- int line_offset = 0; |
- int column_offset = 0; |
- bool is_shared_cross_origin = false; |
- if (origin != NULL) { |
- if (!origin->ResourceName().IsEmpty()) { |
- name_obj = Utils::OpenHandle(*origin->ResourceName()); |
- } |
- if (!origin->ResourceLineOffset().IsEmpty()) { |
- line_offset = static_cast<int>(origin->ResourceLineOffset()->Value()); |
- } |
- if (!origin->ResourceColumnOffset().IsEmpty()) { |
- column_offset = |
- static_cast<int>(origin->ResourceColumnOffset()->Value()); |
- } |
- if (!origin->ResourceIsSharedCrossOrigin().IsEmpty()) { |
- v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); |
- is_shared_cross_origin = |
- origin->ResourceIsSharedCrossOrigin() == v8::True(v8_isolate); |
- } |
- } |
- EXCEPTION_PREAMBLE(isolate); |
- i::ScriptDataImpl* pre_data_impl = |
- static_cast<i::ScriptDataImpl*>(pre_data); |
- // 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 (pre_data_impl != NULL && !pre_data_impl->SanityCheck()) { |
- pre_data_impl = NULL; |
- } |
- i::Handle<i::SharedFunctionInfo> result = |
- i::Compiler::CompileScript(str, |
- name_obj, |
- line_offset, |
- column_offset, |
- is_shared_cross_origin, |
- isolate->global_context(), |
- NULL, |
- pre_data_impl, |
- i::NOT_NATIVES_CODE); |
- has_pending_exception = result.is_null(); |
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>()); |
- raw_result = *result; |
- } |
- i::Handle<i::SharedFunctionInfo> result(raw_result, isolate); |
- return ToApiHandle<Script>(result); |
+// Internally, UnboundScript is a SharedFunctionInfo, and Script is a |
+// JSFunction. |
+ |
+ScriptCompiler::Source::Source(Local<String> string, const ScriptOrigin& origin, |
+ const CachedData& data) |
+ : source_string(string), |
+ resource_name(origin.ResourceName()), |
+ resource_line_offset(origin.ResourceLineOffset()), |
+ resource_column_offset(origin.ResourceColumnOffset()), |
+ resource_is_shared_cross_origin(origin.ResourceIsSharedCrossOrigin()), |
+ cached_data(data) {} |
+ |
+ |
+ScriptCompiler::Source::Source(Local<String> string, |
+ const CachedData& data) |
+ : source_string(string), cached_data(data) {} |
+ |
+ |
+Local<Script> UnboundScript::BindToCurrentContext() { |
+ i::Handle<i::HeapObject> obj = |
+ i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this)); |
+ i::Handle<i::SharedFunctionInfo> |
+ function_info(i::SharedFunctionInfo::cast(*obj), obj->GetIsolate()); |
+ i::Handle<i::JSFunction> function = |
+ obj->GetIsolate()->factory()->NewFunctionFromSharedFunctionInfo( |
+ function_info, obj->GetIsolate()->global_context()); |
+ return ToApiHandle<Script>(function); |
} |
-Local<Script> Script::New(v8::Handle<String> source, |
- v8::Handle<Value> file_name) { |
- ScriptOrigin origin(file_name); |
- return New(source, &origin); |
+int UnboundScript::GetId() { |
+ i::Handle<i::HeapObject> obj = |
+ i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this)); |
+ i::Isolate* isolate = obj->GetIsolate(); |
+ ON_BAILOUT(isolate, "v8::UnboundScript::GetId()", return -1); |
+ LOG_API(isolate, "v8::UnboundScript::GetId"); |
+ { |
+ i::HandleScope scope(isolate); |
+ i::Handle<i::SharedFunctionInfo> function_info( |
+ i::SharedFunctionInfo::cast(*obj)); |
+ i::Handle<i::Script> script(i::Script::cast(function_info->script())); |
+ return script->id()->value(); |
+ } |
} |
-Local<Script> Script::Compile(v8::Handle<String> source, |
- v8::ScriptOrigin* origin, |
- v8::ScriptData* pre_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 = New(source, origin, pre_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); |
+int UnboundScript::GetLineNumber(int code_pos) { |
+ i::Handle<i::HeapObject> obj = |
+ i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this)); |
+ i::Isolate* isolate = obj->GetIsolate(); |
+ ON_BAILOUT(isolate, "v8::UnboundScript::GetLineNumber()", return -1); |
+ LOG_API(isolate, "UnboundScript::GetLineNumber"); |
+ if (obj->IsScript()) { |
+ i::Handle<i::Script> script(i::Script::cast(*obj)); |
+ return i::GetScriptLineNumber(script, code_pos); |
+ } else { |
+ return -1; |
+ } |
} |
-Local<Script> Script::Compile(v8::Handle<String> source, |
- v8::Handle<Value> file_name) { |
- ScriptOrigin origin(file_name); |
- return Compile(source, &origin); |
+Handle<Value> UnboundScript::GetScriptName() { |
+ i::Handle<i::HeapObject> obj = |
+ i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this)); |
+ i::Isolate* isolate = obj->GetIsolate(); |
+ ON_BAILOUT(isolate, "v8::UnboundScript::GetName()", |
+ return Handle<String>()); |
+ LOG_API(isolate, "UnboundScript::GetName"); |
+ if (obj->IsScript()) { |
+ i::Object* name = i::Script::cast(*obj)->name(); |
+ return Utils::ToLocal(i::Handle<i::Object>(name, isolate)); |
+ } else { |
+ return Handle<String>(); |
+ } |
} |
Local<Value> Script::Run() { |
- // If execution is terminating, Compile(script)->Run() requires this check. |
+ // If execution is terminating, Compile(..)->Run() requires this |
+ // check. |
if (this == NULL) return Local<Value>(); |
i::Handle<i::HeapObject> obj = |
i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this)); |
@@ -1724,15 +1706,8 @@ Local<Value> Script::Run() { |
i::Object* raw_result = NULL; |
{ |
i::HandleScope scope(isolate); |
- i::Handle<i::JSFunction> fun; |
- if (obj->IsSharedFunctionInfo()) { |
- i::Handle<i::SharedFunctionInfo> |
- function_info(i::SharedFunctionInfo::cast(*obj), isolate); |
- fun = isolate->factory()->NewFunctionFromSharedFunctionInfo( |
- function_info, isolate->global_context()); |
- } else { |
- fun = i::Handle<i::JSFunction>(i::JSFunction::cast(*obj), isolate); |
- } |
+ i::Handle<i::JSFunction> fun = |
+ i::Handle<i::JSFunction>(i::JSFunction::cast(*obj), isolate); |
EXCEPTION_PREAMBLE(isolate); |
i::Handle<i::Object> receiver( |
isolate->context()->global_proxy(), isolate); |
@@ -1746,62 +1721,124 @@ Local<Value> Script::Run() { |
} |
-static i::Handle<i::SharedFunctionInfo> OpenScript(Script* script) { |
- i::Handle<i::Object> obj = Utils::OpenHandle(script); |
- i::Handle<i::SharedFunctionInfo> result; |
- if (obj->IsSharedFunctionInfo()) { |
- result = |
- i::Handle<i::SharedFunctionInfo>(i::SharedFunctionInfo::cast(*obj)); |
- } else { |
- result = |
- i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared()); |
- } |
- return result; |
+Local<UnboundScript> Script::GetUnboundScript() { |
+ i::Handle<i::Object> obj = Utils::OpenHandle(this); |
+ return ToApiHandle<UnboundScript>( |
+ i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared())); |
} |
-int Script::GetId() { |
- i::Handle<i::HeapObject> obj = |
- i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this)); |
- i::Isolate* isolate = obj->GetIsolate(); |
- ON_BAILOUT(isolate, "v8::Script::Id()", return -1); |
- LOG_API(isolate, "Script::Id"); |
- { |
- i::HandleScope scope(isolate); |
- i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this); |
- i::Handle<i::Script> script(i::Script::cast(function_info->script())); |
- return script->id()->value(); |
+Local<UnboundScript> ScriptCompiler::CompileUnbound( |
+ Isolate* v8_isolate, |
+ const Source& source, |
+ CompileOptions options) { |
+ // FIXME(marja): This function cannot yet create cached data (if options | |
+ // produce_data_to_cache is true), but the PreCompile function is still there |
+ // for doing it. |
+ i::Handle<i::String> str = Utils::OpenHandle(*(source.source_string)); |
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); |
+ ON_BAILOUT(isolate, "v8::ScriptCompiler::CompileUnbound()", |
+ return Local<UnboundScript>()); |
+ LOG_API(isolate, "ScriptCompiler::CompileUnbound"); |
+ ENTER_V8(isolate); |
+ i::SharedFunctionInfo* raw_result = NULL; |
+ { i::HandleScope scope(isolate); |
+ i::Handle<i::Object> name_obj; |
+ int line_offset = 0; |
+ int column_offset = 0; |
+ bool is_shared_cross_origin = false; |
+ if (!source.resource_name.IsEmpty()) { |
+ name_obj = Utils::OpenHandle(*source.resource_name); |
+ } |
+ if (!source.resource_line_offset.IsEmpty()) { |
+ line_offset = static_cast<int>(source.resource_line_offset->Value()); |
+ } |
+ if (!source.resource_column_offset.IsEmpty()) { |
+ column_offset = |
+ static_cast<int>(source.resource_column_offset->Value()); |
+ } |
+ if (!source.resource_is_shared_cross_origin.IsEmpty()) { |
+ v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); |
+ is_shared_cross_origin = |
+ source.resource_is_shared_cross_origin == v8::True(v8_isolate); |
+ } |
+ EXCEPTION_PREAMBLE(isolate); |
+ i::ScriptDataImpl* pre_data_impl = NULL; |
+ if (source.cached_data.data) { |
+ // FIXME(marja): Make compiler use CachedData directly. |
+ pre_data_impl = static_cast<i::ScriptDataImpl*>(ScriptData::New( |
+ reinterpret_cast<const char*>(source.cached_data.data), |
+ source.cached_data.length)); |
+ } |
+ // 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 (pre_data_impl != NULL && !pre_data_impl->SanityCheck()) { |
+ delete pre_data_impl; |
+ pre_data_impl = NULL; |
+ } |
+ i::Handle<i::SharedFunctionInfo> result = |
+ i::Compiler::CompileScript(str, |
+ name_obj, |
+ line_offset, |
+ column_offset, |
+ is_shared_cross_origin, |
+ isolate->global_context(), |
+ NULL, |
+ pre_data_impl, |
+ i::NOT_NATIVES_CODE); |
+ has_pending_exception = result.is_null(); |
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<UnboundScript>()); |
+ raw_result = *result; |
+ delete pre_data_impl; |
} |
+ i::Handle<i::SharedFunctionInfo> result(raw_result, isolate); |
+ return ToApiHandle<UnboundScript>(result); |
} |
-int Script::GetLineNumber(int code_pos) { |
- i::Handle<i::HeapObject> obj = |
- i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this)); |
- i::Isolate* isolate = obj->GetIsolate(); |
- ON_BAILOUT(isolate, "v8::Script::GetLineNumber()", return -1); |
- LOG_API(isolate, "Script::GetLineNumber"); |
- if (obj->IsScript()) { |
- i::Handle<i::Script> script = i::Handle<i::Script>(i::Script::cast(*obj)); |
- return i::GetScriptLineNumber(script, code_pos); |
- } else { |
- return -1; |
- } |
+Local<Script> ScriptCompiler::Compile( |
+ Isolate* v8_isolate, |
+ const Source& source, |
+ CompileOptions options) { |
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); |
+ ON_BAILOUT(isolate, "v8::ScriptCompiler::Compile()", |
+ return Local<Script>()); |
+ LOG_API(isolate, "ScriptCompiler::CompiletBound()"); |
+ ENTER_V8(isolate); |
+ Local<UnboundScript> generic = |
+ CompileUnbound(v8_isolate, source, options); |
+ if (generic.IsEmpty()) return Local<Script>(); |
+ return generic->BindToCurrentContext(); |
} |
-Handle<Value> Script::GetScriptName() { |
- i::Handle<i::HeapObject> obj = |
- i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this)); |
- i::Isolate* isolate = obj->GetIsolate(); |
- ON_BAILOUT(isolate, "v8::Script::GetName()", return Handle<String>()); |
- LOG_API(isolate, "Script::GetName"); |
- if (obj->IsScript()) { |
- i::Object* name = i::Script::cast(*obj)->name(); |
- return Utils::ToLocal(i::Handle<i::Object>(name, isolate)); |
- } else { |
- return Handle<String>(); |
+Local<Script> Script::Compile(v8::Handle<String> source, |
+ v8::ScriptOrigin* origin, |
+ ScriptData* script_data) { |
+ i::Handle<i::String> str = Utils::OpenHandle(*source); |
+ ScriptCompiler::CachedData cached_data; |
+ if (script_data) { |
+ cached_data = ScriptCompiler::CachedData( |
+ reinterpret_cast<const uint8_t*>(script_data->Data()), |
+ script_data->Length()); |
+ } |
+ if (origin) { |
+ return ScriptCompiler::Compile( |
+ reinterpret_cast<v8::Isolate*>(str->GetIsolate()), |
+ ScriptCompiler::Source(source, *origin, cached_data)); |
} |
+ return ScriptCompiler::Compile( |
+ reinterpret_cast<v8::Isolate*>(str->GetIsolate()), |
+ ScriptCompiler::Source(source, cached_data)); |
+} |
+ |
+ |
+Local<Script> Script::Compile(v8::Handle<String> source, |
+ v8::Handle<String> file_name) { |
+ ScriptOrigin origin(file_name); |
+ return Compile(source, &origin); |
} |
@@ -4028,7 +4065,9 @@ bool Function::IsBuiltin() const { |
int Function::ScriptId() const { |
i::Handle<i::JSFunction> func = Utils::OpenHandle(this); |
- if (!func->shared()->script()->IsScript()) return v8::Script::kNoScriptId; |
+ if (!func->shared()->script()->IsScript()) { |
+ return v8::UnboundScript::kNoScriptId; |
+ } |
i::Handle<i::Script> script(i::Script::cast(func->shared()->script())); |
return script->id()->value(); |
} |