1
0
Fork 0
mirror of https://github.com/rubyjs/therubyracer synced 2023-03-27 23:21:42 -04:00

add support for Symbols

This commit is contained in:
Charles Lowell 2015-07-10 19:17:06 -05:00
parent 6d667fd1b3
commit 7fee981c94
8 changed files with 189 additions and 1 deletions

View file

@ -16,7 +16,9 @@ extern "C" {
Value::Init();
Object::Init();
Primitive::Init();
Name::Init();
String::Init();
Symbol::Init();
Function::Init();
Script::Init();
ScriptOrigin::Init();

16
ext/v8/name.cc Normal file
View file

@ -0,0 +1,16 @@
#include "rr.h"
namespace rr {
void Name::Init() {
ClassBuilder("Name", Primitive::Class).
defineMethod("GetIdentityHash", &GetIdentityHash).
store(&Class);
}
VALUE Name::GetIdentityHash(VALUE self) {
Name name(self);
Locker lock(name.getIsolate());
return INT2FIX(name->GetIdentityHash());
}
}

15
ext/v8/name.h Normal file
View file

@ -0,0 +1,15 @@
//mode -*- c++ -*-
#ifndef NAME_H
#define NAME_H
namespace rr {
class Name : public Ref<v8::Name> {
public:
static void Init();
static VALUE GetIdentityHash(VALUE self);
Name(VALUE self) : Ref<v8::Name>(self) {}
};
}
#endif /* NAME_H */

View file

@ -39,7 +39,9 @@ inline VALUE not_implemented(const char* message) {
#include "primitive.h"
#include "external.h"
// This one is named v8_string to avoid name collisions with C's string.h
#include "name.h"
#include "rr_string.h"
#include "symbol.h"
#include "script.h"
#include "script-origin.h"

View file

@ -3,7 +3,7 @@
namespace rr {
void String::Init() {
ClassBuilder("String", Primitive::Class).
ClassBuilder("String", Name::Class).
defineSingletonMethod("NewFromUtf8", &NewFromUtf8).
defineSingletonMethod("Concat", &Concat).

74
ext/v8/symbol.cc Normal file
View file

@ -0,0 +1,74 @@
#include "rr.h"
namespace rr {
void Symbol::Init() {
ClassBuilder("Symbol", Name::Class).
defineSingletonMethod("New", &New).
defineSingletonMethod("For", &For).
defineSingletonMethod("ForApi", &ForApi).
defineSingletonMethod("GetIterator", &GetIterator).
defineSingletonMethod("GetUnscopables", &GetUnscopables).
defineSingletonMethod("GetToStringTag", &GetToStringTag).
defineMethod("Name", &Name).
store(&Class);
}
VALUE Symbol::New(int argc, VALUE argv[], VALUE self) {
VALUE rb_isolate, rb_name;
rb_scan_args(argc, argv, "11", &rb_isolate, &rb_name);
Isolate isolate(rb_isolate);
Locker lock(isolate);
v8::HandleScope handle_scope(isolate);
if (RTEST(rb_name)) {
return Symbol(isolate, v8::Symbol::New(isolate, String(rb_name)));
} else {
return Symbol(isolate, v8::Symbol::New(isolate));
}
}
VALUE Symbol::For(VALUE self, VALUE rb_isolate, VALUE name) {
Isolate isolate(rb_isolate);
Locker lock(isolate);
return Symbol(isolate, v8::Symbol::For(isolate, String(name)));
}
VALUE Symbol::ForApi(VALUE self, VALUE rb_isolate, VALUE name) {
Isolate isolate(rb_isolate);
Locker lock(isolate);
return Symbol(isolate, v8::Symbol::ForApi(isolate, String(name)));
}
VALUE Symbol::GetIterator(VALUE self, VALUE rb_isolate) {
Isolate isolate(rb_isolate);
Locker lock(isolate);
return Symbol(isolate, v8::Symbol::GetIterator(isolate));
}
VALUE Symbol::GetUnscopables(VALUE self, VALUE rb_isolate) {
Isolate isolate(rb_isolate);
Locker lock(isolate);
return Symbol(isolate, v8::Symbol::GetUnscopables(isolate));
}
VALUE Symbol::GetToStringTag(VALUE self, VALUE rb_isolate) {
Isolate isolate(rb_isolate);
Locker lock(isolate);
return Symbol(isolate, v8::Symbol::GetToStringTag(isolate));
}
VALUE Symbol::Name(VALUE self) {
Symbol symbol(self);
Isolate isolate(symbol.getIsolate());
Locker lock(isolate);
return Value::handleToRubyObject(isolate, symbol->Name());
}
}

26
ext/v8/symbol.h Normal file
View file

@ -0,0 +1,26 @@
// -*- mode: c++ -*-
#ifndef SYMBOL_H
#define SYMBOL_H
#include "rr.h"
namespace rr {
class Symbol : public Ref<v8::Symbol> {
public:
static void Init();
static VALUE Name(VALUE self);
static VALUE New(int argc, VALUE argv[], VALUE self);
static VALUE For(VALUE self, VALUE isolate, VALUE name);
static VALUE ForApi(VALUE self, VALUE isolate, VALUE name);
static VALUE GetIterator(VALUE self, VALUE isolate);
static VALUE GetUnscopables(VALUE self, VALUE isolate);
static VALUE GetToStringTag(VALUE self, VALUE isolate);
Symbol(VALUE self) : Ref<v8::Symbol>(self) {}
Symbol(v8::Isolate* isolate, v8::Local<v8::Symbol> symbol) :
Ref<v8::Symbol>(isolate, symbol) {}
};
}
#endif /* SYMBOL_H */

53
spec/c/symbol_spec.rb Normal file
View file

@ -0,0 +1,53 @@
require 'c_spec_helper'
describe V8::C::Symbol do
requires_v8_context
describe "without a description" do
let(:symbol) { V8::C::Symbol::New(@isolate)}
it "exists" do
expect(symbol).to be
end
it "has an identity hash" do
expect(symbol.GetIdentityHash()).to be
end
end
describe "with a description" do
let(:description) { V8::C::String::NewFromUtf8(@isolate, "bob") }
let(:symbol) { V8::C::Symbol::New(@isolate, description) }
it "has a name" do
expect(symbol.Name().Utf8Value()).to eql "bob"
end
end
describe "from symbol registries" do
let(:key) { V8::C::String::NewFromUtf8(@isolate, "mysym") }
let(:global) { V8::C::Symbol::For(@isolate, key) }
let(:api) { V8::C::Symbol::ForApi(@isolate, key) }
it "always retrieves the same value for a given key" do
expect(V8::C::Symbol::For(@isolate, key).StrictEquals(global)).to be true
expect(V8::C::Symbol::ForApi(@isolate, key).StrictEquals(api)).to be true
end
it "returns different symbols for different registries" do
expect(global.StrictEquals(api)).to be false
end
end
describe "well-known symbols" do
it "GetIterator" do
expect(V8::C::Symbol::GetIterator(@isolate)).to be_kind_of V8::C::Symbol
end
it "GetUnscopables" do
expect(V8::C::Symbol::GetUnscopables(@isolate)).to be_kind_of V8::C::Symbol
end
it "GetToStringTag" do
expect(V8::C::Symbol::GetToStringTag(@isolate)).to be_kind_of V8::C::Symbol
end
end
end