include/v8.h
プリミティブ型の定義があるので見てみよう。
Handle
Local
- 軽量な Handle
- スタックに allocate される
- HandleScope で寿命管理される
Persistent
- Handle
HandleScope
- scope とは Handle のコンテナ
- スタックに allocate される
Script
- コンパイル済み JavaScript 。
- Script::compile でコンパイル。
- Run
- New で作られた Script は Context independent
- Compile で作られた Script は Context に依存
StackTrace
- The information collected is a snapshot of the execution stack and the information remains valid after execution continues.
- とあるから実行時オーバーヘッドがあるってことかな。
StackFrame
StackFrame までクラスなのね。内部表現は違うだろうけど。
Value
JavaScript の全ての値、オブジェクトの親クラス。継承ありきなら即値 integer とかないのかな。
- V8EXPORT bool IsUndefined() const; なんてメソッドも。
- V8EXPORT Local
ToBoolean() const; - V8EXPORT Local
ToNumber() const; - この手のメソッドは Mosh でも同じだ
Primitive
class Primitive : public Value { };
Boolean
少し詳細を追ってみよう。
class Boolean : public Primitive { public: V8EXPORT bool Value() const; static inline Handle<Boolean> New(bool value); };
Boolean オブジェクト作る
Handle<Boolean> Boolean::New(bool value) { return value ? True() : False(); }
True() は
v8::Handle<Boolean> True() { i::Isolate* isolate = i::Isolate::Current(); if (!EnsureInitializedForIsolate(isolate, "v8::True()")) { return v8::Handle<Boolean>(); } return v8::Handle<Boolean>( ToApi<Boolean>(isolate->factory()->true_value())); }
true_value() はマクロで定義されている heap.h
V(Object, true_value, TrueValue)
実体はここかな
{ MaybeObject* maybe_obj = CreateOddball("true", Smi::FromInt(1), Oddball::kTrue); if (!maybe_obj->ToObject(&obj)) return false; } set_true_value(obj);
CreateOddball の引数は順に to_string, to_number, byte kind.
Oddball は null, undefined, true, false を表すクラスらしい。定数だし即値オブジェクトであると予想。
k prefix は定数だよね。
static const byte kFalse = 0; static const byte kTrue = 1; static const byte kNotBooleanMask = ~1; static const byte kTheHole = 2; static const byte kNull = 3; static const byte kArgumentMarker = 4; static const byte kUndefined = 5; static const byte kOther = 6;
Oddball::Initialize は Oddball::set_kind などに値を渡すだけ。
MaybeObject* Oddball::Initialize(const char* to_string, Object* to_number, byte kind) {
本丸は近い。
void Oddball::set_kind(byte value) { WRITE_BYTE_FIELD(this, kKindOffset, value); }
#define WRITE_BYTE_FIELD(p, offset, value) \ (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value) #define FIELD_ADDR(p, offset) \ (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
結局 (byte*)this + kKindOffset(定数) - kHeapObjectTag に1byte書き込んでると。即値オブジェクトだ。
kHeapObjectTag を引いているので HeapObject は heap に割り当てられるオブジェクトでポインタ末尾にタグがあるのだろう。Gauche や Mosh と同じ。