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

can now insert primitives into the global context from Ruby.

This commit is contained in:
Bill Robertson 2009-11-13 23:27:48 -05:00
parent e18fd52c7c
commit 2652edbe3c
4 changed files with 77 additions and 64 deletions

61
v8.cpp
View file

@ -2,6 +2,7 @@
#include "generic_data.h"
#include "v8_data.h"
#include "v8_context.h"
#include "v8_standalone.h"
#include <stdio.h>
@ -15,60 +16,6 @@ extern "C" {
VALUE rb_mModule;
VALUE rb_cV8;
VALUE ruby_call_symbol;
VALUE ruby_respond_to_ID;
bool is_callable(VALUE& object) {
return Qtrue == rb_funcall(object, ruby_respond_to_ID, 1, ruby_call_symbol);
}
VALUE v8_what_is_this(VALUE self, VALUE object) {
VALUE boolean;
switch (TYPE(object)) {
case T_NIL:
printf("nil\n");
break;
case T_OBJECT:
printf("ordinary object\n");
if (responds_to(object, "call")) {
printf("responds to call!<br/>");
}
break;
case T_CLASS:
printf("class[%s]<br/>", rb_class2name(object));
break;
case T_MODULE: printf("module\n"); break;
case T_FLOAT: printf("floating point number\n"); break;
case T_STRING: printf("string\n"); break;
case T_REGEXP: printf("regular expression\n"); break;
case T_ARRAY: printf("array\n"); break;
case T_FIXNUM: printf("Fixnum(31bit integer)\n"); break;
case T_HASH: printf("associative array\n"); break;
case T_STRUCT: printf("(Ruby) structure\n"); break;
case T_BIGNUM: printf("multi precision integer\n"); break;
case T_FILE: printf("IO\n"); break;
case T_TRUE: printf("true\n"); break;
case T_FALSE: printf("false\n"); break;
case T_DATA:
printf("data... inspecting\n");
if (responds_to(object, "call")) {
printf("Responds to call!<br/>");
} else {
printf("Does *NOT* respond to call<br/>");
}
v8_what_is_this(Qnil, RDATA(object)->basic.klass);
break;
case T_SYMBOL: printf("symbol\n"); break;
default:
printf("I have no idea!!!\n");
rb_raise(rb_eTypeError, "not valid value");
break;
}
return Qnil;
}
extern "C" {
void Init_v8() {
@ -76,14 +23,20 @@ extern "C" {
ruby_respond_to_ID = rb_intern("respond_to?");
rb_mModule = rb_define_module("V8");
// context setup
rb_cV8 = rb_define_class_under(rb_mModule, "Context", rb_cObject);
rb_define_alloc_func(rb_cV8, v8_context_allocate);
rb_define_method(rb_cV8, "eval", (VALUE(*)(...)) v8_context_eval, 1);
rb_define_method(rb_cV8, "[]=", (VALUE(*)(...)) v8_context_inject, 2);
// js object setup
rb_cV8_JSObject = rb_define_class_under(rb_mModule, "JSObject", rb_cObject);
rb_define_alloc_func(rb_cV8_JSObject, v8_object_allocate);
rb_define_method(rb_cV8_JSObject, "[]", (VALUE(*)(...)) v8_object_hash_access, 1);
rb_define_method(rb_cV8_JSObject, "[]=", (VALUE(*)(...)) v8_object_hash_assignment, 2);
// stand alone methods
rb_define_singleton_method(rb_mModule, "what_is_this?",(VALUE(*)(...)) v8_what_is_this, 1);
}
}

View file

@ -1,8 +1,9 @@
#include "ruby_data.h"
#include "v8_data.h"
#include "generic_data.h"
#include "v8_context.h"
#include <ruby_data.h>
#include <v8_data.h>
#include <generic_data.h>
#include <v8_context.h>
#include<stdio.h>
using namespace v8;
@ -37,12 +38,32 @@ VALUE v8_context_eval(VALUE self, VALUE javascript) {
const std::string source(tostring.push(javascript));
Local<Script> script = Script::Compile(String::New(source.c_str()));
// printf("Before Script->Run()<br/>");
Local<Value> result = script->Run();
// printf("After Script->Run()<br/>");
V8HandleSource<RubyDest, VALUE> toValue;
// printf("Result: %s", *String::AsciiValue(result->ToString()));
return toValue.push(result);
}
VALUE v8_context_inject(VALUE self, VALUE key, VALUE value) {
v8_context* context = 0;
Data_Get_Struct(self, struct v8_context, context);
Context::Scope enter(context->handle);
HandleScope handles;
RubyValueSource<StringDest, std::string> tostring;
RubyValueSource<V8HandleDest, Persistent<Value> > toHandle;
const std::string key_string(tostring.push(key));
const std::string value_string(tostring.push(value));
// does this need to be a persistent handle ?
Persistent<Value> key_handle(String::New(key_string.c_str()));
Persistent<Value> value_handle(toHandle.push(value));
Local<Object> global = context->handle->Global();
global->Set(key_handle, value_handle);
return Qnil;
}

View file

@ -41,5 +41,6 @@ void v8_context_free(v8_context *context);
//methods
VALUE v8_context_eval(VALUE self, VALUE javascript);
VALUE v8_context_inject(VALUE self, VALUE key, VALUE injectee);
#endif

View file

@ -6,7 +6,6 @@
#include <stdio.h>
#include <string>
template<class T, class R> class V8HandleSource {
T dest;
@ -65,4 +64,43 @@ template<class T, class R> class V8HandleSource {
};
/**
* 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 V8HandleDest {
public:
V8HandleDest();
~V8HandleDest();
v8::Persistent<v8::Value> pushString(const std::string& value, const char* name=0) {
return v8::Persistent<v8::Value>::New(v8::String::New(value.c_str()));
}
v8::Persistent<v8::Value> pushInt(int64_t value, const char* name=0) {
return v8::Persistent<v8::Value>::New(v8::Integer::New(value));
}
v8::Persistent<v8::Value> pushDouble(double value, const char* name=0) {
return v8::Persistent<v8::Value>::New(v8::Number::New(value));
}
v8::Persistent<v8::Value> pushBool(bool value, const char* name=0) {
return v8::Persistent<v8::Value>::New(v8::Boolean::New(value));
}
v8::Persistent<v8::Value> pushNull(const char* name=0) {
return v8::Persistent<v8::Value>::New(v8::Integer::New(0)); // so WRONG!! not sure how to make a null from API
}
v8::Persistent<v8::Value> pushUndefined(const char* name=0) {
return v8::Persistent<v8::Value>::New(v8::Integer::New(0)); // so WRONG!! not sure how to make a null from API
}
};
#endif