一天 一小步

继上文

ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode)这个函数算是正式脱离webcore进入bingding模块了。先看下这个函数,再分析

// Evaluate a script file in the environment of this proxy.ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode){ String sourceURL = sourceCode.url(); const String* savedSourceURL = m_sourceURL; m_sourceURL = &sourceURL; v8::HandleScope handleScope; v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(m_proxy->frame()); if (v8Context.IsEmpty()) return ScriptValue(); v8::Context::Scope scope(v8Context); RefPtr<Frame> protect(m_frame); v8::Local<v8::Value> object = m_proxy->evaluate(sourceCode, 0); // Evaluating the JavaScript could cause the frame to be deallocated // so we start the keep alive timer here. m_frame->keepAlive(); m_sourceURL = savedSourceURL; if (object.IsEmpty()) return ScriptValue(); return ScriptValue(object);}

这个函数里有很多重要的东西,关于使用V8,,无论是单独编译V8通过官方的测试用例还是在浏览器中使用都是大致相同的使用方法。现在挨着分析重要的部分:

1.先看这句:

v8::HandleScope handleScope;

以后遇到V8::这种,这个来源于V8中的很多源码都是用命名空间控制的,知道就行了:

namespace v8 {namespace internal {//这个是V8里另一个常用的

……

…..

}

}

// Create a handle scope for all local handles.这里创建handleScope对象,该对象销毁后,下面的所有handle就都销毁了。看似下面没有调用这个对象,实质这个对象创建了就已经起作用了。V8中后面还会这样创建handleScope,也是这样使用的。

看下HandleScope的构造函数:

HandleScope::HandleScope() { i::Isolate* isolate = i::Isolate::Current(); API_ENTRY_CHECK(isolate, "HandleScope::HandleScope"); v8::ImplementationUtilities::HandleScopeData* current = isolate->handle_scope_data(); isolate_ = isolate; prev_next_ = current->next; prev_limit_ = current->limit; is_closed_ = false; current->level++;}

取当前的isolate,进入api层的相关检查(主要检查线程锁),这个构造函数里还有一个链表控制的object数据,所以每一样定义一个这样的对象,实质上已经起作用了,即使没有使用这个对象。

2.再看

v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(m_proxy->frame());

这里是创建当前frame的上下文,,这个mainWorldContext(….)会检测传入的frame的proxy,再调用mainWorldContext()函数,这里面有一个比较重要的函数:

v8::Local<v8::Context> V8Proxy::mainWorldContext(){ windowShell()->initContextIfNeeded(); return v8::Local<v8::Context>::New(windowShell()->context());}

windowShell()->initContextIfNeeded();是一个比较重要的函数,下篇再专门分析下这个函数,根据windowshell初始化上下文。windowshell这个东西比较重要,在jsc中创建上下文也与它有关系,JSC中:

JSDOMWindowShell* shell = windowShell(world);ExecState* exec = shell->window()->globalExec();

V8中:

V8DOMWindowShell* windowShell() const { return m_windowShell.get(); }windowShell()->context()

3.再看

v8::Context::Scope scope(v8Context);

这里就是把创建的上下文放入作用域中,可以看下这个构造函数:

explicit inline Scope(Handle<Context> context):context_(context){

context_->Enter();

}

void Context::Enter() { i::Handle<i::Context> env = Utils::OpenHandle(this); i::Isolate* isolate = env->GetIsolate(); if (IsDeadCheck(isolate, "v8::Context::Enter()")) return; ENTER_V8(isolate); isolate->handle_scope_implementer()->EnterContext(env); isolate->handle_scope_implementer()->SaveContext(isolate->context()); isolate->set_context(*env);}

这里就是获取当前上下文环境,并将于作用域关联。

4.最后

v8::Local<v8::Value> object = m_proxy->evaluate(sourceCode, 0);

这里开始准备进入编译和执行源码了。

PS:这里面有一下数据关键和类的继承关系,下次另起一篇介绍

人只要不失去方向,就不会失去自己

一天 一小步

相关文章:

你感兴趣的文章:

标签云: