3.文字列・数値 - v8 ソースコードリーディング

文字列

文字列を見ていこう。
v8.h の class String 。

  • V8EXPORT int Length() const;
  • V8EXPORT int Utf8Length() const;

があるのが時代を感じる。

文字列の Write も Ascii, UTF16, UTF8 用がある。面白いのは

  • V8EXPORT static v8::Local Empty();

長さがゼロの文字列を static メンバで持っていること。これは真似したいね。


External String というモノがあってどうやら v8 の heap 外に割り当てられた文字列を管理するようなものだ。外部文字列を v8 heap で割り当てられた class で wrap してる。
文字列の割り当ては New で NewSymbol というのもある。シンボルの実体は intern された文字列という実装っぽい。
文字列は特に面白くなかったな。

数値

Number クラス。Value が double なのが JavaScript ならでは。

class Number : public Primitive {
 public:
  V8EXPORT double Value() const;
  V8EXPORT static Local<Number> New(double value);
  static inline Number* Cast(v8::Value* obj);
 private:
  V8EXPORT Number();
  static void CheckCast(v8::Value* obj);
};

Number だけではなくて Integer(符号あり64bit整数)、Int32(符号あり32bit整数)、Uint32もある。どう使い分けているのかな。

Parser

数値リテラルが Parse 時にどう allocate されるかを見れば Number, Integer の使い分けが分かるだろう。
paser.cc を見ると

    case Token::NUMBER: {
      Consume(Token::NUMBER);
      ASSERT(scanner().is_literal_ascii());
      double value = StringToDouble(isolate()->unicode_cache(),
                                    scanner().literal_ascii_string(),
                                    ALLOW_HEX | ALLOW_OCTALS);
      result = NewNumberLiteral(value);
      break;

StringToDouble してる。やはり仕様通り数値は浮動小数として読んでる。
その後 MaybeObject* Heap::NumberFromDouble で数値が整数として表されるならば Smi::FromInt(int_value); を返してる。Smi は 31 ビットに収まる整数。
Integer(64bit) はどこででてくるだろうか?四則演算でも見てみようか。次に続く。