constants for Undefined, Null, True, False

This commit is contained in:
Charles Lowell 2012-06-08 03:56:04 -05:00
parent b54dc3e3c4
commit ae448321e8
7 changed files with 96 additions and 5 deletions

34
ext/v8/constants.cc Normal file
View File

@ -0,0 +1,34 @@
#include "rr.h"
namespace rr {
VALUE Constants::_Undefined;
VALUE Constants::_Null;
VALUE Constants::_True;
VALUE Constants::_False;
void Constants::Init() {
ModuleBuilder("V8::C").
defineSingletonMethod("Undefined", &Undefined).
defineSingletonMethod("Null", &Null).
defineSingletonMethod("True", &True).
defineSingletonMethod("False", &False);
_Undefined = _Null = _True = _False = Qnil;
rb_gc_register_address(&_Undefined);
rb_gc_register_address(&_Null);
rb_gc_register_address(&_True);
rb_gc_register_address(&_False);
}
VALUE Constants::Undefined(VALUE self) {
return cached<Primitive, v8::Primitive>(&_Undefined, v8::Undefined());
}
VALUE Constants::Null(VALUE self) {
return cached<Primitive, v8::Primitive>(&_Null, v8::Null());
}
VALUE Constants::True(VALUE self) {
return cached<Bool, v8::Boolean>(&_True, v8::True());
}
VALUE Constants::False(VALUE self) {
return cached<Bool, v8::Boolean>(&_False, v8::False());
}
}

View File

@ -17,11 +17,13 @@ extern "C" {
Invocation::Init();
Signature::Init();
Value::Init();
Primitive::Init();
String::Init();
Object::Init();
Array::Init();
Function::Init();
Date::Init();
Constants::Init();
External::Init();
Script::Init();
Template::Init();

8
ext/v8/primitive.cc Normal file
View File

@ -0,0 +1,8 @@
#include "rr.h"
namespace rr {
void Primitive::Init() {
ClassBuilder("Primitive", Value::Class).
store(&Class);
}
}

View File

@ -25,6 +25,7 @@ class Bool : public Equiv {
public:
Bool(VALUE val) : Equiv(val) {}
Bool(bool b) : Equiv(b ? Qtrue : Qfalse) {}
Bool(v8::Handle<v8::Boolean> b) : Equiv(b->Value() ? Qtrue : Qfalse) {}
inline operator bool() {return RTEST(value);}
};
@ -103,7 +104,7 @@ public:
Ref(VALUE value) {
this->value = value;
}
Ref(v8::Handle<T> handle) {
Ref(v8::Handle<T> handle, const char* label = "v8::Handle<void>") {
this->handle = handle;
}
virtual operator VALUE() const {
@ -298,6 +299,13 @@ public:
virtual operator VALUE();
};
class Primitive: public Ref<v8::Primitive> {
public:
static void Init();
inline Primitive(VALUE value) : Ref<v8::Primitive>(value) {}
inline Primitive(v8::Handle<v8::Primitive> primitive) : Ref<v8::Primitive>(primitive) {}
};
class String: public Ref<v8::String> {
public:
static void Init();
@ -675,6 +683,27 @@ public:
static VALUE doUnlockCall(VALUE code);
};
class Constants {
public:
static void Init();
static VALUE Undefined(VALUE self);
static VALUE Null(VALUE self);
static VALUE True(VALUE self);
static VALUE False(VALUE self);
private:
template <class R, class V> static VALUE cached(VALUE* storage, v8::Handle<V> value) {
if (!RTEST(*storage)) {
*storage = R(value);
}
return *storage;
}
static VALUE _Undefined;
static VALUE _Null;
static VALUE _True;
static VALUE _False;
};
class V8 {
public:
static void Init();
@ -684,6 +713,7 @@ public:
class ClassBuilder {
public:
ClassBuilder() {};
ClassBuilder(const char* name, VALUE superclass = rb_cObject);
ClassBuilder(const char* name, const char* supername);
ClassBuilder& defineMethod(const char* name, VALUE (*impl)(int, VALUE*, VALUE));
@ -699,10 +729,17 @@ public:
ClassBuilder& defineEnumConst(const char* name, int value);
ClassBuilder& store(VALUE* storage);
inline operator VALUE() {return this->value;}
private:
protected:
VALUE value;
};
class ModuleBuilder : public ClassBuilder {
public:
inline ModuleBuilder(const char* name) {
this->value = rb_eval_string(name);
}
};
}
#endif

View File

@ -3,7 +3,7 @@
namespace rr {
void String::Init() {
ClassBuilder("String", Value::Class).
ClassBuilder("String", Primitive::Class).
defineSingletonMethod("New", &New).
defineSingletonMethod("Concat", &Concat).
defineMethod("Utf8Value", &Utf8Value).

11
spec/c/constants_spec.rb Normal file
View File

@ -0,0 +1,11 @@
require 'spec_helper'
describe V8::C do
it "has constant methods for Undefined, Null, True and False" do
[:Undefined, :Null, :True, :False].each do |name|
constant = V8::C.send(name)
constant.should_not be_nil
V8::C.send(name).should be constant
end
end
end

View File

@ -29,8 +29,7 @@ module Autoscope
def low_level_c_spec?
return false unless described_class
name = described_class.name.split('::').last
return V8::C.const_defined?(name) && V8::C.const_get(name) == described_class
return described_class.name =~ /^V8::C/
end
def explicitly_defines_scope?