mirror of
https://github.com/rubyjs/therubyracer
synced 2023-03-27 23:21:42 -04:00
constants for Undefined, Null, True, False
This commit is contained in:
parent
b54dc3e3c4
commit
ae448321e8
7 changed files with 96 additions and 5 deletions
34
ext/v8/constants.cc
Normal file
34
ext/v8/constants.cc
Normal 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());
|
||||
}
|
||||
}
|
|
@ -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
8
ext/v8/primitive.cc
Normal file
|
@ -0,0 +1,8 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
void Primitive::Init() {
|
||||
ClassBuilder("Primitive", Value::Class).
|
||||
store(&Class);
|
||||
}
|
||||
}
|
41
ext/v8/rr.h
41
ext/v8/rr.h
|
@ -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
|
||||
|
|
|
@ -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
11
spec/c/constants_spec.rb
Normal 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
|
|
@ -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?
|
||||
|
|
Loading…
Reference in a new issue