昨天跟友人一起大块欢饮之后,问了一个比较好玩的问题? JSON.parse 是怎么实现?当时草草的中规中矩的回答了一番,但终究对自己无知不是很满意

今天上午想起来之后,便迅速翻出node的源码来一探究竟!

对js的解析无疑是 v8的专属,但由于v8是由c++编写,我对c++的各种语法了解比较一般,如果有描述错误的地方,还请各位大神斧正.

v8的git地址 https://chromium.googlesource.com/v8/v8.git  需要FQ

node的官网 https://nodejs.org   , 如果速度慢可以直接访问 http://nodejs.cn/

我是在node源码的deps找到的v8的相关代码

chrome浏览器 V8是怎么实现 JSON.parse 的?

在v8的src文件夹中 直接全局搜索 JSON::Parse ( c++的语法 ) 可以找到对应代码编写在 api.cc文件中,具体代码如下:

chrome浏览器 V8是怎么实现 JSON.parse 的?

在刚刚的搜索结果中,找到一个简单的json parse,我们就从这里入手

chrome浏览器 V8是怎么实现 JSON.parse 的?

这个例子里面关键的代码不多,主要是

ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
                               JsonParser(isolate, source).ParseJson(), Object);

对string做处理的是 JSONParse对象的ParseJson函数,然后继续全局搜索 JSONParse,在 json-parser.cc中找到了ParseJson的相关代码

template <bool seq_one_byte>
MaybeHandle<Object> JsonParser<seq_one_byte>::ParseJson() {
  // Advance to the first character (possibly EOS)
  AdvanceSkipWhitespace();
  Handle<Object> result = ParseJsonValue();
  if (result.is_null() || c0_ != kEndOfString) {
    // Some exception (for example stack overflow) is already pending.
    if (isolate_->has_pending_exception()) return Handle<Object>::null();

    // Parse failed. Current character is the unexpected token.
    Factory* factory = this->factory();
    MessageTemplate::Template message;
    Handle<Object> arg1 = Handle<Smi>(Smi::FromInt(position_), isolate());
    Handle<Object> arg2;

    switch (c0_) {
      case kEndOfString:
        message = MessageTemplate::kJsonParseUnexpectedEOS;
        break;
      case '-':
      case '0':
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':
        message = MessageTemplate::kJsonParseUnexpectedTokenNumber;
        break;
      case '"':
        message = MessageTemplate::kJsonParseUnexpectedTokenString;
        break;
      default:
        message = MessageTemplate::kJsonParseUnexpectedToken;
        arg2 = arg1;
        arg1 = factory->LookupSingleCharacterStringFromCode(c0_);
        break;
    }

    Handle<Script> script(factory->NewScript(source_));
    // We should sent compile error event because we compile JSON object in
    // separated source file.
    isolate()->debug()->OnCompileError(script);
    MessageLocation location(script, position_, position_ + 1);
    Handle<Object> error = factory->NewSyntaxError(message, arg1, arg2);
    return isolate()->template Throw<Object>(error, &location);
  }
  return result;
}
ParseJson

相关文章:

  • 2021-09-13
  • 2021-12-06
  • 2021-11-27
  • 2021-08-28
  • 2021-12-08
  • 2021-12-29
  • 2021-12-01
  • 2022-03-12
猜你喜欢
  • 2021-09-03
  • 2023-03-16
  • 2021-12-02
  • 2021-12-31
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案