码迷,mamicode.com
首页 > 其他好文 > 详细

V8引擎之Binding

时间:2015-03-02 20:57:59      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:v8

继上文

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:这里面有一下数据关键和类的继承关系,下次另起一篇介绍

V8引擎之Binding

标签:v8

原文地址:http://blog.csdn.net/jiangnanyidiao/article/details/44022467

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!