mirror of
https://github.com/rubyjs/therubyracer
synced 2023-03-27 23:21:42 -04:00
remove C++ thunking layer. conversions happen in ruby.
This commit is contained in:
parent
5a89e05e38
commit
f7a1e0a9f8
15 changed files with 1 additions and 437 deletions
|
@ -1,8 +0,0 @@
|
|||
#include "convert_ruby.h"
|
||||
|
||||
|
||||
RubyValueDest::RubyValueDest() {
|
||||
}
|
||||
|
||||
RubyValueDest::~RubyValueDest() {
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
#ifndef __convert_ruby_h__
|
||||
#define __convert_ruby_h__
|
||||
|
||||
#include <ruby.h>
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* A RubyValueSource takes a Destination class and a return
|
||||
* type as a template argument, it converts a Ruby Value to
|
||||
* the appropriate intermediate type and feed it to an
|
||||
* instance Destination type.
|
||||
*
|
||||
* The destination type should have a default constructor,
|
||||
* and provide the methods detailed in data_conversion.txt
|
||||
* \tparam DEST destination type for the converted data
|
||||
* \tparam RET is the return type of T's methods
|
||||
*/
|
||||
|
||||
template<class DEST, class RET> class RubyValueSource {
|
||||
|
||||
/**
|
||||
* An instance of the destination class
|
||||
*/
|
||||
DEST dest;
|
||||
|
||||
public:
|
||||
RubyValueSource() {}
|
||||
~RubyValueSource() {}
|
||||
|
||||
|
||||
bool operator() (VALUE& value, RET& result) {
|
||||
switch (TYPE(value)) {
|
||||
case T_FIXNUM:
|
||||
result = dest.pushInt(FIX2INT(value));
|
||||
return true;
|
||||
case T_FLOAT:
|
||||
result = dest.pushDouble(NUM2DBL(value));
|
||||
return true;
|
||||
case T_STRING:
|
||||
result = convertString(value);
|
||||
return true;
|
||||
case T_NIL:
|
||||
result = dest.pushNull();
|
||||
return true;
|
||||
case T_TRUE:
|
||||
result = dest.pushBool(true);
|
||||
return true;
|
||||
case T_FALSE:
|
||||
result = dest.pushBool(false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
RET convertString(VALUE& value) {
|
||||
std::string stringValue(RSTRING_PTR(value));
|
||||
return dest.pushString(stringValue);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A RubyValueDest class receives on of the types defined in
|
||||
* data_conversion.txt, and converts it to the appropriate
|
||||
* Ruby VALUE.
|
||||
*/
|
||||
class RubyValueDest {
|
||||
|
||||
public:
|
||||
RubyValueDest();
|
||||
~RubyValueDest();
|
||||
|
||||
VALUE pushString(const std::string& value) {
|
||||
return rb_str_new2(value.c_str());
|
||||
}
|
||||
|
||||
VALUE pushInt(int64_t value) {
|
||||
return INT2FIX(value);
|
||||
}
|
||||
|
||||
VALUE pushDouble(double value) {
|
||||
return rb_float_new(value);
|
||||
}
|
||||
|
||||
VALUE pushBool(bool value) {
|
||||
return value ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
VALUE pushNull() {
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
VALUE pushUndefined() {
|
||||
return Qnil;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -1,10 +0,0 @@
|
|||
#include "convert_string.h"
|
||||
|
||||
StringDest::StringDest() {
|
||||
}
|
||||
|
||||
StringDest::~StringDest(){
|
||||
}
|
||||
|
||||
const std::string StringDest::TRUE("true");
|
||||
const std::string StringDest::FALSE("false");
|
|
@ -1,73 +0,0 @@
|
|||
#ifndef __convert_string_h__
|
||||
#define __convert_string_h__
|
||||
|
||||
#include "v8.h"
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* StringDest is a data type conversion destination that converts
|
||||
* any argument into a string. It should have all methods listed
|
||||
* in data_conversion.txt so it can be used as a template argument
|
||||
* for a conversion source class.
|
||||
*/
|
||||
class StringDest {
|
||||
|
||||
public:
|
||||
StringDest();
|
||||
~StringDest();
|
||||
|
||||
std::string pushString(const std::string& value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
#ifdef FIGURED_OUT_INT_ISSUES
|
||||
const char* pushInt(int32_t value) {
|
||||
char buffer[64];
|
||||
sprintf(buffer, "%d", value);
|
||||
convertedValue = buffer;
|
||||
return convertedValue.c_str();
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string pushInt(int64_t value) {
|
||||
char buffer[64];
|
||||
sprintf(buffer, "%lld", value);
|
||||
std::string convertedValue(buffer);
|
||||
return convertedValue;
|
||||
}
|
||||
|
||||
std::string pushDouble(double value) {
|
||||
char buffer[64];
|
||||
sprintf(buffer, "%g", value);
|
||||
std::string convertedValue(buffer);
|
||||
return convertedValue;
|
||||
}
|
||||
|
||||
std::string pushBool(bool value) {
|
||||
std::string convertedValue(value ? TRUE : FALSE);
|
||||
return convertedValue;
|
||||
}
|
||||
|
||||
std::string pushNull() {
|
||||
printf("I bet we aren't even getting here<br/>");
|
||||
return ""; // this kind of sucks
|
||||
}
|
||||
|
||||
std::string pushUndefined() {
|
||||
return "undefined"; // this too
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* constant "true" used for pushBool
|
||||
*/
|
||||
static const std::string TRUE;
|
||||
|
||||
/**
|
||||
* constant "false" used for pushBool
|
||||
*/
|
||||
static const std::string FALSE;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,9 +0,0 @@
|
|||
#include "convert_v8.h"
|
||||
|
||||
V8LocalDest::V8LocalDest() {
|
||||
|
||||
}
|
||||
|
||||
V8LocalDest::~V8LocalDest() {
|
||||
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
#ifndef __convert_v8_h__
|
||||
#define __convert_v8_h__
|
||||
|
||||
#include <v8.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
template<class T, class R> class V8HandleSource {
|
||||
|
||||
T dest;
|
||||
|
||||
public:
|
||||
|
||||
V8HandleSource() {}
|
||||
~V8HandleSource() {}
|
||||
|
||||
bool operator() (v8::Handle<v8::Value>& value, R& result) {
|
||||
|
||||
// a bit klunky, but alternative is to evaluate what type the
|
||||
// object is twice, which is unappealing
|
||||
|
||||
if (value.IsEmpty()) {
|
||||
result = dest.pushNull();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (value->IsUndefined()) {
|
||||
result = dest.pushNull();
|
||||
return true;
|
||||
}
|
||||
|
||||
if(value->IsNull()) {
|
||||
result = dest.pushNull();
|
||||
return true;
|
||||
}
|
||||
|
||||
if(value->IsTrue()) {
|
||||
result = dest.pushBool(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(value->IsFalse()) {
|
||||
result = dest.pushBool(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(value->IsString()) {
|
||||
v8::Local<v8::String> str = value->ToString();
|
||||
result = convertString(str);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(value->IsInt32()) {
|
||||
result = dest.pushInt(value->Int32Value());
|
||||
return true;
|
||||
}
|
||||
|
||||
if(value->IsNumber()) {
|
||||
result = dest.pushDouble(value->NumberValue());
|
||||
return true;
|
||||
}
|
||||
|
||||
result = dest.pushNull();
|
||||
return false;
|
||||
}
|
||||
|
||||
R convertString(v8::Local<v8::String>& str) {
|
||||
char buffer[1024];
|
||||
size_t total = 0;
|
||||
size_t remaining = str->Length();
|
||||
std::string output;
|
||||
while (remaining > 0) {
|
||||
size_t toCopy = remaining > sizeof(buffer) ? sizeof(buffer) : remaining;
|
||||
str->WriteAscii(buffer, total, toCopy);
|
||||
output.append(buffer, toCopy);
|
||||
total += toCopy;
|
||||
remaining -= toCopy;
|
||||
}
|
||||
return dest.pushString(output);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* StringDest is a data type conversion destination that converts
|
||||
* any argument into a string. It should have all methods listed
|
||||
* in data_conversion.txt so it can be used as a template argument
|
||||
* for a conversion source class.
|
||||
*/
|
||||
class V8LocalDest {
|
||||
|
||||
public:
|
||||
V8LocalDest();
|
||||
~V8LocalDest();
|
||||
|
||||
v8::Local<v8::Value> pushString(const std::string& value) {
|
||||
return v8::Local<v8::Value>::New(v8::String::New(value.c_str()));
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> pushInt(int64_t value) {
|
||||
return v8::Local<v8::Value>::New(v8::Integer::New(value));
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> pushDouble(double value) {
|
||||
return v8::Local<v8::Value>::New(v8::Number::New(value));
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> pushBool(bool value) {
|
||||
return v8::Local<v8::Value>::New(v8::Boolean::New(value));
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> pushNull() {
|
||||
return v8::Local<v8::Value>::New(v8::Null());
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> pushUndefined() {
|
||||
return v8::Local<v8::Value>::New(v8::Undefined());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -1,84 +0,0 @@
|
|||
#include "converters.h"
|
||||
#include "v8_ref.h"
|
||||
#include "v8_obj.h"
|
||||
#include "v8_cxt.h"
|
||||
#include "v8_func.h"
|
||||
#include "v8_template.h"
|
||||
#include "v8_external.h"
|
||||
|
||||
using namespace v8;
|
||||
|
||||
namespace {
|
||||
std::string UNDEFINED_STR("undefined");
|
||||
}
|
||||
|
||||
VALUE V82RB(Handle<Value>& value) {
|
||||
convert_v8_to_rb_t convert;
|
||||
VALUE result;
|
||||
VALUE type = rr_cV8_C_Object;
|
||||
if(convert(value, result)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (value->IsArray()) {
|
||||
Local<Array> array(Array::Cast(*value));
|
||||
VALUE rb_array = rb_ary_new2(array->Length());
|
||||
for (unsigned int i = 0; i < array->Length(); i++) {
|
||||
Local<Value> value = array->Get(Integer::New(i));
|
||||
rb_ary_push(rb_array, V82RB(value));
|
||||
}
|
||||
return rb_array;
|
||||
}
|
||||
|
||||
if (value->IsFunction()) {
|
||||
type = rr_cV8_C_Function;
|
||||
}
|
||||
|
||||
if (value->IsObject()) {
|
||||
Local<Object> object(Object::Cast(*value));
|
||||
Local<Value> peer = object->GetHiddenValue(String::New("TheRubyRacer::RubyObject"));
|
||||
if (peer.IsEmpty()) {
|
||||
VALUE context_ref = V8_Ref_Create(V8_C_Context, Context::GetEntered());
|
||||
object->SetHiddenValue(String::New("TheRubyRacer::Context"), rr_v8_external_create(context_ref));
|
||||
return V8_Ref_Create(type, value, context_ref);
|
||||
} else {
|
||||
return (VALUE)External::Unwrap(peer);
|
||||
}
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
Local<Value> RB2V8(VALUE value) {
|
||||
VALUE valueClass = rb_class_of(value);
|
||||
// if(valueClass == rb_cProc || valueClass == rb_cMethod) {
|
||||
// Local<FunctionTemplate> t = FunctionTemplate::New(RacerRubyInvocationCallback, rr_v8_external_create(value));
|
||||
// return t->GetFunction();
|
||||
// }
|
||||
convert_rb_to_v8_t convert;
|
||||
Local<Value> result;
|
||||
if (convert(value, result)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Local<Object> o = Racer_Create_V8_ObjectTemplate(value)->NewInstance();
|
||||
// o->SetHiddenValue(String::New("TheRubyRacer::RubyObject"), rr_v8_external_create(value));
|
||||
return Object::New();
|
||||
}
|
||||
|
||||
std::string V82String(Handle<Value>& value) {
|
||||
convert_v8_to_string_t convert;
|
||||
std::string result;
|
||||
if(convert(value, result)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (value->IsObject()) {
|
||||
Local<Object> object(Object::Cast(*value));
|
||||
Local<String> str = object->ToString();
|
||||
if(convert(value, result)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return UNDEFINED_STR;
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
#ifndef __converters_h__
|
||||
#define __converters_h__
|
||||
|
||||
#include "convert_ruby.h"
|
||||
#include "convert_string.h"
|
||||
#include "convert_v8.h"
|
||||
#include <cstring>
|
||||
|
||||
typedef RubyValueSource<V8LocalDest, v8::Local<v8::Value> > convert_rb_to_v8_t;
|
||||
typedef V8HandleSource<RubyValueDest, VALUE> convert_v8_to_rb_t;
|
||||
|
||||
typedef RubyValueSource<StringDest, std::string> convert_rb_to_string_t;
|
||||
typedef V8HandleSource<StringDest, std::string> convert_v8_to_string_t;
|
||||
|
||||
VALUE V82RB(v8::Handle<v8::Value>& value);
|
||||
v8::Local<v8::Value> RB2V8(VALUE value);
|
||||
|
||||
std::string RB2String(VALUE value);
|
||||
std::string V82String(v8::Handle<v8::Value>& value);
|
||||
|
||||
#endif
|
|
@ -3,7 +3,6 @@
|
|||
#include "v8_msg.h"
|
||||
#include "v8_template.h"
|
||||
#include "v8_external.h"
|
||||
#include "converters.h"
|
||||
|
||||
using namespace v8;
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
#include "converters.h"
|
||||
#include "v8_func.h"
|
||||
#include "v8_obj.h"
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#include "converters.h"
|
||||
#include "v8_msg.h"
|
||||
#include "v8_ref.h"
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include "v8_value.h"
|
||||
#include "v8_template.h"
|
||||
#include "v8_external.h"
|
||||
#include "converters.h"
|
||||
|
||||
using namespace v8;
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include "v8.h"
|
||||
#include "v8_ref.h"
|
||||
#include "v8_script.h"
|
||||
#include "converters.h"
|
||||
|
||||
using namespace v8;
|
||||
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
#include <ruby.h>
|
||||
#include <v8.h>
|
||||
#include "rr.h"
|
||||
#include "v8_ref.h"
|
||||
#include "v8_func.h"
|
||||
#include "v8_template.h"
|
||||
#include "v8_external.h"
|
||||
#include "v8_callbacks.h"
|
||||
#include "converters.h"
|
||||
|
||||
using namespace v8;
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include "v8_value.h"
|
||||
#include "v8_ref.h"
|
||||
#include "converters.h"
|
||||
|
||||
using namespace v8;
|
||||
namespace {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue