#include #include "V8Context.h" #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" #undef New using namespace v8; static SV *_convert_v8value_to_sv(Handle value) { if (value->IsUndefined()) { return &PL_sv_undef; } else if (value->IsNull()) { return &PL_sv_undef; } else if (value->IsInt32()) { return newSViv(value->Int32Value()); } else if (value->IsBoolean()) { return newSVuv(value->Uint32Value()); } else if (value->IsNumber()) { return newSVnv(value->NumberValue()); } else if (value->IsString()) { SV *sv = newSVpv(*(String::Utf8Value(value)), 0); sv_utf8_decode(sv); return sv; } else { croak("Can not convert js value to a perl one"); return &PL_sv_undef; } } static Handle _convert_sv_to_v8value(SV *sv) { HandleScope scope; if (0) ; else if (SvIOK_UV(sv)) return Uint32::New(SvUV(sv)); else if (SvIOK(sv)) return Integer::New(SvIV(sv)); else if (SvNOK(sv)) return Number::New(SvNV(sv)); else if (SvPOK(sv)) return String::New(SvPV_nolen(sv)); return Undefined(); } static Handle _perl_method(const Arguments &args) { dSP; int count; Handle result = Undefined(); ENTER; SAVETMPS; PUSHMARK(SP); for (int i = 0; i < args.Length(); i ++) { //TODO think about refcounts XPUSHs(_convert_v8value_to_sv(args[i])); } PUTBACK; count = call_sv(INT2PTR(SV*,args.Data()->Int32Value()),G_SCALAR); SPAGAIN; if (count >= 1) { result = _convert_sv_to_v8value(POPs); } PUTBACK; FREETMPS; LEAVE; return result; } void V8Context::bind_function(const char *name,SV* code) { HandleScope scope; TryCatch try_catch; Context::Scope context_scope(context); /*we will decrement the refcnt in the destructor*/ SvREFCNT_inc(code); used.push_back(code); context->Global()->Set( String::New(name), FunctionTemplate::New(_perl_method, Integer::New(PTR2IV(code)))->GetFunction() ); } SV* V8Context::eval(const char* source) { HandleScope handle_scope; Context::Scope context_scope(context); Handle