support catching javascript exceptions
This commit is contained in:
parent
e1a21538a4
commit
a5812812bc
|
@ -24,5 +24,8 @@ extern "C" {
|
|||
External::Init();
|
||||
Script::Init();
|
||||
Template::Init();
|
||||
Stack::Init();
|
||||
Message::Init();
|
||||
TryCatch::Init();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
|
||||
void Message::Init() {
|
||||
ClassBuilder("Message").
|
||||
defineMethod("Get", &Get).
|
||||
defineMethod("GetSourceLine", &GetSourceLine).
|
||||
defineMethod("GetScriptResourceName", &GetScriptResourceName).
|
||||
defineMethod("GetScriptData", &GetScriptData).
|
||||
defineMethod("GetStackTrace", &GetStackTrace).
|
||||
defineMethod("GetLineNumber", &GetLineNumber).
|
||||
defineMethod("GetStartPosition", &GetStartPosition).
|
||||
defineMethod("GetEndPosition", &GetEndPosition).
|
||||
defineMethod("GetStartColumn", &GetEndColumn).
|
||||
defineSingletonMethod("kNoLineNumberInfo", &kNoLineNumberInfo).
|
||||
defineSingletonMethod("kNoColumnInfo", &kNoColumnInfo).
|
||||
store(&Class);
|
||||
}
|
||||
|
||||
VALUE Message::Get(VALUE self) {
|
||||
return String(Message(self)->Get());
|
||||
}
|
||||
VALUE Message::GetSourceLine(VALUE self) {
|
||||
return String(Message(self)->GetSourceLine());
|
||||
}
|
||||
VALUE Message::GetScriptResourceName(VALUE self) {
|
||||
return Value(Message(self)->GetScriptResourceName());
|
||||
}
|
||||
VALUE Message::GetScriptData(VALUE self) {
|
||||
return Value(Message(self)->GetScriptData());
|
||||
}
|
||||
VALUE Message::GetStackTrace(VALUE self) {
|
||||
return Stack::Trace(Message(self)->GetStackTrace());
|
||||
}
|
||||
VALUE Message::GetLineNumber(VALUE self) {
|
||||
return INT2FIX(Message(self)->GetLineNumber());
|
||||
}
|
||||
VALUE Message::GetStartPosition(VALUE self) {
|
||||
return INT2FIX(Message(self)->GetStartPosition());
|
||||
}
|
||||
VALUE Message::GetEndPosition(VALUE self) {
|
||||
return INT2FIX(Message(self)->GetEndPosition());
|
||||
}
|
||||
VALUE Message::GetStartColumn(VALUE self) {
|
||||
return INT2FIX(Message(self)->GetStartColumn());
|
||||
}
|
||||
VALUE Message::GetEndColumn(VALUE self) {
|
||||
return INT2FIX(Message(self)->GetEndColumn());
|
||||
}
|
||||
}
|
123
ext/v8/rr.h
123
ext/v8/rr.h
|
@ -209,6 +209,40 @@ public:
|
|||
class Value : public Ref<v8::Value> {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE IsUndefined(VALUE self);
|
||||
static VALUE IsNull(VALUE self);
|
||||
static VALUE IsTrue(VALUE self);
|
||||
static VALUE IsFalse(VALUE self);
|
||||
static VALUE IsString(VALUE self);
|
||||
static VALUE IsFunction(VALUE self);
|
||||
static VALUE IsArray(VALUE self);
|
||||
static VALUE IsObject(VALUE self);
|
||||
static VALUE IsBoolean(VALUE self);
|
||||
static VALUE IsNumber(VALUE self);
|
||||
static VALUE IsExternal(VALUE self);
|
||||
static VALUE IsInt32(VALUE self);
|
||||
static VALUE IsUint32(VALUE self);
|
||||
static VALUE IsDate(VALUE self);
|
||||
static VALUE IsBooleanObject(VALUE self);
|
||||
static VALUE IsNumberObject(VALUE self);
|
||||
static VALUE IsStringObject(VALUE self);
|
||||
static VALUE IsNativeError(VALUE self);
|
||||
static VALUE IsRegExp(VALUE self);
|
||||
// VALUE ToBoolean(VALUE self);
|
||||
// VALUE ToNumber(VALUE self);
|
||||
static VALUE ToString(VALUE self);
|
||||
static VALUE ToDetailString(VALUE self);
|
||||
static VALUE ToObject(VALUE self);
|
||||
// static VALUE ToInteger(VALUE self);
|
||||
// static VALUE ToUint32(VALUE self);
|
||||
// static VALUE ToInt32(VALUE self);
|
||||
// static VALUE ToArrayIndex(VALUE self);
|
||||
static VALUE BooleanValue(VALUE self);
|
||||
static VALUE NumberValue(VALUE self);
|
||||
static VALUE IntegerValue(VALUE self);
|
||||
static VALUE Uint32Value(VALUE self);
|
||||
static VALUE Int32Value(VALUE self);
|
||||
|
||||
static VALUE Equals(VALUE self, VALUE other);
|
||||
static VALUE StrictEquals(VALUE self, VALUE other);
|
||||
inline Value(VALUE value) : Ref<v8::Value>(value) {}
|
||||
|
@ -480,10 +514,99 @@ public:
|
|||
inline FunctionTemplate(v8::Handle<v8::FunctionTemplate> t) : Ref<v8::FunctionTemplate>(t) {}
|
||||
};
|
||||
|
||||
class Message : public Ref<v8::Message> {
|
||||
public:
|
||||
static void Init();
|
||||
inline Message(v8::Handle<v8::Message> message) : Ref<v8::Message>(message) {}
|
||||
inline Message(VALUE value) : Ref<v8::Message>(value) {}
|
||||
|
||||
static VALUE Get(VALUE self);
|
||||
static VALUE GetSourceLine(VALUE self);
|
||||
static VALUE GetScriptResourceName(VALUE self);
|
||||
static VALUE GetScriptData(VALUE self);
|
||||
static VALUE GetStackTrace(VALUE self);
|
||||
static VALUE GetLineNumber(VALUE self);
|
||||
static VALUE GetStartPosition(VALUE self);
|
||||
static VALUE GetEndPosition(VALUE self);
|
||||
static VALUE GetStartColumn(VALUE self);
|
||||
static VALUE GetEndColumn(VALUE self);
|
||||
static inline VALUE kNoLineNumberInfo(VALUE self) {return INT2FIX(v8::Message::kNoLineNumberInfo);}
|
||||
static inline VALUE kNoColumnInfo(VALUE self) {return INT2FIX(v8::Message::kNoColumnInfo);}
|
||||
};
|
||||
|
||||
class Stack {
|
||||
public:
|
||||
static void Init();
|
||||
|
||||
class Trace : public Ref<v8::StackTrace> {
|
||||
public:
|
||||
class StackTraceOptions : public Enum<v8::StackTrace::StackTraceOptions> {
|
||||
public:
|
||||
inline StackTraceOptions(VALUE value) : Enum<v8::StackTrace::StackTraceOptions>(value, v8::StackTrace::kOverview) {}
|
||||
};
|
||||
public:
|
||||
inline Trace(v8::Handle<v8::StackTrace> trace) : Ref<v8::StackTrace>(trace) {}
|
||||
inline Trace(VALUE value) : Ref<v8::StackTrace>(value) {}
|
||||
static inline VALUE kLineNumber(VALUE self) {return INT2FIX(v8::StackTrace::kLineNumber);}
|
||||
static inline VALUE kColumnOffset(VALUE self) {return INT2FIX(v8::StackTrace::kColumnOffset);}
|
||||
static inline VALUE kScriptName(VALUE self) {return INT2FIX(v8::StackTrace::kScriptName);}
|
||||
static inline VALUE kFunctionName(VALUE self) {return INT2FIX(v8::StackTrace::kFunctionName);}
|
||||
static inline VALUE kIsEval(VALUE self) {return INT2FIX(v8::StackTrace::kIsEval);}
|
||||
static inline VALUE kIsConstructor(VALUE self) {return INT2FIX(v8::StackTrace::kIsConstructor);}
|
||||
static inline VALUE kScriptNameOrSourceURL(VALUE self) {return INT2FIX(v8::StackTrace::kScriptNameOrSourceURL);}
|
||||
static inline VALUE kOverview(VALUE self) {return INT2FIX(v8::StackTrace::kOverview);}
|
||||
static inline VALUE kDetailed(VALUE self) {return INT2FIX(v8::StackTrace::kDetailed);}
|
||||
|
||||
static VALUE GetFrame(VALUE self, VALUE index);
|
||||
static VALUE GetFrameCount(VALUE self);
|
||||
static VALUE AsArray(VALUE self);
|
||||
static VALUE CurrentStackTrace(int argc, VALUE argv[], VALUE self);
|
||||
};
|
||||
class Frame : public Ref<v8::StackFrame> {
|
||||
public:
|
||||
inline Frame(v8::Handle<v8::StackFrame> frame) : Ref<v8::StackFrame>(frame) {}
|
||||
inline Frame(VALUE value) : Ref<v8::StackFrame>(value) {}
|
||||
static VALUE GetLineNumber(VALUE self);
|
||||
static VALUE GetColumn(VALUE self);
|
||||
static VALUE GetScriptName(VALUE self);
|
||||
static VALUE GetScriptNameOrSourceURL(VALUE self);
|
||||
static VALUE GetFunctionName(VALUE self);
|
||||
static VALUE IsEval(VALUE self);
|
||||
static VALUE IsConstructor(VALUE self);
|
||||
};
|
||||
};
|
||||
|
||||
class TryCatch {
|
||||
public:
|
||||
static void Init();
|
||||
TryCatch();
|
||||
TryCatch(VALUE value);
|
||||
~TryCatch();
|
||||
operator VALUE();
|
||||
inline v8::TryCatch* operator->() {return this->impl;}
|
||||
static VALUE HasCaught(VALUE self);
|
||||
static VALUE CanContinue(VALUE self);
|
||||
static VALUE ReThrow(VALUE self);
|
||||
static VALUE Exception(VALUE self);
|
||||
static VALUE StackTrace(VALUE self);
|
||||
static VALUE Message(VALUE self);
|
||||
static VALUE Reset(VALUE self);
|
||||
static VALUE SetVerbose(VALUE self, VALUE value);
|
||||
static VALUE SetCaptureMessage(VALUE self, VALUE value);
|
||||
private:
|
||||
static VALUE doTryCatch(int argc, VALUE argv[], VALUE self);
|
||||
static VALUE setupAndCall(int* state, VALUE code);
|
||||
static VALUE doCall(VALUE code);
|
||||
static VALUE Class;
|
||||
v8::TryCatch* impl;
|
||||
bool allocated;
|
||||
};
|
||||
|
||||
class V8 {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE IdleNotification(VALUE self);
|
||||
static VALUE SetCaptureStackTraceForUncaughtExceptions(int argc, VALUE argv[], VALUE self);
|
||||
};
|
||||
|
||||
class ClassBuilder {
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
void Stack::Init() {
|
||||
ClassBuilder("StackTrace").
|
||||
defineSingletonMethod("kLineNumber", &Trace::kLineNumber).
|
||||
defineSingletonMethod("kColumnOffset", &Trace::kColumnOffset).
|
||||
defineSingletonMethod("kScriptName", &Trace::kScriptName).
|
||||
defineSingletonMethod("kFunctionName", &Trace::kFunctionName).
|
||||
defineSingletonMethod("kIsEval", &Trace::kIsEval).
|
||||
defineSingletonMethod("kIsConstructor", &Trace::kIsConstructor).
|
||||
defineSingletonMethod("kScriptNameOrSourceURL", &Trace::kScriptNameOrSourceURL).
|
||||
defineSingletonMethod("kOverview", &Trace::kOverview).
|
||||
defineSingletonMethod("kDetailed", &Trace::kDetailed).
|
||||
defineSingletonMethod("CurrentStackTrace", &Trace::CurrentStackTrace).
|
||||
defineMethod("GetFrame", &Trace::GetFrame).
|
||||
defineMethod("GetFrameCount", &Trace::GetFrameCount).
|
||||
defineMethod("AsArray", &Trace::AsArray).
|
||||
store(&Trace::Class);
|
||||
ClassBuilder("StackFrame").
|
||||
defineMethod("GetLineNumber", &Frame::GetLineNumber).
|
||||
defineMethod("GetColumn", &Frame::GetColumn).
|
||||
defineMethod("GetScriptName", &Frame::GetScriptName).
|
||||
defineMethod("GetScriptNameOrSourceURL", &Frame::GetScriptNameOrSourceURL).
|
||||
defineMethod("IsEval", &Frame::IsEval).
|
||||
defineMethod("IsConstructor", &Frame::IsConstructor).
|
||||
store(&Frame::Class);
|
||||
}
|
||||
|
||||
VALUE Stack::Trace::GetFrame(VALUE self, VALUE index) {
|
||||
return Frame(Trace(self)->GetFrame(NUM2UINT(index)));
|
||||
}
|
||||
|
||||
VALUE Stack::Trace::GetFrameCount(VALUE self) {
|
||||
return INT2FIX(Trace(self)->GetFrameCount());
|
||||
}
|
||||
|
||||
VALUE Stack::Trace::AsArray(VALUE self) {
|
||||
return Array(Trace(self)->AsArray());
|
||||
}
|
||||
|
||||
VALUE Stack::Trace::CurrentStackTrace(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE frame_limit; VALUE options;
|
||||
rb_scan_args(argc, argv, "11", &frame_limit, &options);
|
||||
return Trace(v8::StackTrace::CurrentStackTrace(NUM2INT(frame_limit), StackTraceOptions(options)));
|
||||
}
|
||||
|
||||
VALUE Stack::Frame::GetLineNumber(VALUE self) {
|
||||
return INT2FIX(Frame(self)->GetLineNumber());
|
||||
}
|
||||
|
||||
VALUE Stack::Frame::GetColumn(VALUE self) {
|
||||
return INT2FIX(Frame(self)->GetColumn());
|
||||
}
|
||||
|
||||
VALUE Stack::Frame::GetScriptName(VALUE self) {
|
||||
return String(Frame(self)->GetScriptName());
|
||||
}
|
||||
|
||||
VALUE Stack::Frame::GetScriptNameOrSourceURL(VALUE self) {
|
||||
return String(Frame(self)->GetScriptNameOrSourceURL());
|
||||
}
|
||||
|
||||
VALUE Stack::Frame::GetFunctionName(VALUE self) {
|
||||
return String(Frame(self)->GetFunctionName());
|
||||
}
|
||||
|
||||
VALUE Stack::Frame::IsEval(VALUE self) {
|
||||
return Bool(Frame(self)->IsEval());
|
||||
}
|
||||
|
||||
VALUE Stack::Frame::IsConstructor(VALUE self) {
|
||||
return Bool(Frame(self)->IsConstructor());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
#include "rr.h"
|
||||
|
||||
namespace rr {
|
||||
VALUE TryCatch::Class;
|
||||
|
||||
void TryCatch::Init() {
|
||||
ClassBuilder("TryCatch").
|
||||
defineMethod("HasCaught", &HasCaught).
|
||||
defineMethod("CanContinue", &CanContinue).
|
||||
defineMethod("ReThrow", &ReThrow).
|
||||
defineMethod("Exception", &Exception).
|
||||
defineMethod("StackTrace", &StackTrace).
|
||||
defineMethod("Message", &Message).
|
||||
defineMethod("Reset", &Reset).
|
||||
defineMethod("SetVerbose", &SetVerbose).
|
||||
defineMethod("SetCaptureMessage", &SetCaptureMessage).
|
||||
store(&Class);
|
||||
VALUE v8 = rb_define_module("V8");
|
||||
VALUE c = rb_define_module_under(v8, "C");
|
||||
rb_define_singleton_method(c, "TryCatch", (VALUE (*)(...))&doTryCatch, -1);
|
||||
}
|
||||
|
||||
TryCatch::TryCatch() : impl(new v8::TryCatch()), allocated(true) {}
|
||||
TryCatch::TryCatch(VALUE value) : allocated(false) {
|
||||
Data_Get_Struct(value, class v8::TryCatch, impl);
|
||||
}
|
||||
TryCatch::~TryCatch() {
|
||||
if (this->allocated) {
|
||||
delete this->impl;
|
||||
}
|
||||
}
|
||||
TryCatch::operator VALUE() {
|
||||
return Data_Wrap_Struct(Class, 0, 0, impl);
|
||||
}
|
||||
|
||||
VALUE TryCatch::HasCaught(VALUE self) {
|
||||
return Bool(TryCatch(self)->HasCaught());
|
||||
}
|
||||
VALUE TryCatch::CanContinue(VALUE self) {
|
||||
return Bool(TryCatch(self)->CanContinue());
|
||||
}
|
||||
VALUE TryCatch::ReThrow(VALUE self) {
|
||||
return Value(TryCatch(self)->ReThrow());
|
||||
}
|
||||
VALUE TryCatch::Exception(VALUE self) {
|
||||
return Value(TryCatch(self)->Exception());
|
||||
}
|
||||
VALUE TryCatch::StackTrace(VALUE self) {
|
||||
return Value(TryCatch(self)->StackTrace());
|
||||
}
|
||||
VALUE TryCatch::Message(VALUE self) {
|
||||
return rr::Message(TryCatch(self)->Message());
|
||||
}
|
||||
VALUE TryCatch::Reset(VALUE self) {
|
||||
Void(TryCatch(self)->Reset());
|
||||
}
|
||||
VALUE TryCatch::SetVerbose(VALUE self, VALUE value) {
|
||||
Void(TryCatch(self)->SetVerbose(Bool(value)));
|
||||
}
|
||||
VALUE TryCatch::SetCaptureMessage(VALUE self, VALUE value) {
|
||||
Void(TryCatch(self)->SetCaptureMessage(Bool(value)));
|
||||
}
|
||||
|
||||
VALUE TryCatch::doTryCatch(int argc, VALUE argv[], VALUE self) {
|
||||
if (!rb_block_given_p()) {
|
||||
return Qnil;
|
||||
}
|
||||
int state = 0;
|
||||
VALUE code;
|
||||
rb_scan_args(argc,argv,"00&", &code);
|
||||
VALUE result = setupAndCall(&state, code);
|
||||
if (state != 0) {
|
||||
rb_jump_tag(state);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
VALUE TryCatch::setupAndCall(int* state, VALUE code) {
|
||||
return rb_protect(&doCall, code, state);
|
||||
}
|
||||
|
||||
VALUE TryCatch::doCall(VALUE code) {
|
||||
TryCatch trycatch;
|
||||
return rb_funcall(code, rb_intern("call"), 1, (VALUE)trycatch);
|
||||
}
|
||||
}
|
10
ext/v8/v8.cc
10
ext/v8/v8.cc
|
@ -4,11 +4,19 @@ namespace rr {
|
|||
|
||||
void V8::Init() {
|
||||
ClassBuilder("V8").
|
||||
defineSingletonMethod("IdleNotification", &IdleNotification);
|
||||
defineSingletonMethod("IdleNotification", &IdleNotification).
|
||||
defineSingletonMethod("SetCaptureStackTraceForUncaughtExceptions", &SetCaptureStackTraceForUncaughtExceptions);
|
||||
}
|
||||
|
||||
VALUE V8::IdleNotification(VALUE self) {
|
||||
return Bool(v8::V8::IdleNotification());
|
||||
}
|
||||
|
||||
VALUE V8::SetCaptureStackTraceForUncaughtExceptions(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE should_capture; VALUE frame_limit; VALUE options;
|
||||
rb_scan_args(argc, argv, "12", &should_capture, &frame_limit, &options);
|
||||
int limit = RTEST(frame_limit) ? NUM2INT(frame_limit) : 10;
|
||||
Void(v8::V8::SetCaptureStackTraceForUncaughtExceptions(Bool(should_capture), limit, Stack::Trace::StackTraceOptions(options)));
|
||||
}
|
||||
|
||||
}
|
137
ext/v8/value.cc
137
ext/v8/value.cc
|
@ -4,11 +4,148 @@ namespace rr {
|
|||
|
||||
void Value::Init() {
|
||||
ClassBuilder("Value").
|
||||
defineMethod("IsUndefined", &IsUndefined).
|
||||
defineMethod("IsNull", &IsNull).
|
||||
defineMethod("IsTrue", &IsTrue).
|
||||
defineMethod("IsFalse", &IsFalse).
|
||||
defineMethod("IsString", &IsString).
|
||||
defineMethod("IsFunction", &IsFunction).
|
||||
defineMethod("IsArray", &IsArray).
|
||||
defineMethod("IsObject", &IsObject).
|
||||
defineMethod("IsBoolean", &IsBoolean).
|
||||
defineMethod("IsNumber", &IsNumber).
|
||||
defineMethod("IsExternal", &IsExternal).
|
||||
defineMethod("IsInt32", &IsInt32).
|
||||
defineMethod("IsUint32", &IsUint32).
|
||||
defineMethod("IsDate", &IsDate).
|
||||
defineMethod("IsBooleanObject", &IsBooleanObject).
|
||||
defineMethod("IsNumberObject", &IsNumberObject).
|
||||
defineMethod("IsStringObject", &IsStringObject).
|
||||
defineMethod("IsNativeError", &IsNativeError).
|
||||
defineMethod("IsRegExp", &IsRegExp).
|
||||
defineMethod("ToString", &ToString).
|
||||
defineMethod("ToDetailString", &ToDetailString).
|
||||
defineMethod("ToObject", &ToObject).
|
||||
defineMethod("BooleanValue", &BooleanValue).
|
||||
defineMethod("NumberValue", &NumberValue).
|
||||
defineMethod("IntegerValue", &IntegerValue).
|
||||
defineMethod("Uint32Value", &Uint32Value).
|
||||
defineMethod("IntegerValue", &IntegerValue).
|
||||
defineMethod("Equals", &Equals).
|
||||
defineMethod("StrictEquals", &StrictEquals)
|
||||
.store(&Class);
|
||||
}
|
||||
|
||||
VALUE Value::IsUndefined(VALUE self) {
|
||||
return Bool(Value(self)->IsUndefined());
|
||||
}
|
||||
VALUE Value::IsNull(VALUE self) {
|
||||
return Bool(Value(self)->IsNull());
|
||||
}
|
||||
VALUE Value::IsTrue(VALUE self) {
|
||||
return Bool(Value(self)->IsTrue());
|
||||
}
|
||||
VALUE Value::IsFalse(VALUE self) {
|
||||
return Bool(Value(self)->IsFalse());
|
||||
}
|
||||
VALUE Value::IsString(VALUE self) {
|
||||
return Bool(Value(self)->IsString());
|
||||
}
|
||||
VALUE Value::IsFunction(VALUE self) {
|
||||
return Bool(Value(self)->IsFunction());
|
||||
}
|
||||
VALUE Value::IsArray(VALUE self) {
|
||||
return Bool(Value(self)->IsArray());
|
||||
}
|
||||
VALUE Value::IsObject(VALUE self) {
|
||||
return Bool(Value(self)->IsObject());
|
||||
}
|
||||
VALUE Value::IsBoolean(VALUE self) {
|
||||
return Bool(Value(self)->IsBoolean());
|
||||
}
|
||||
VALUE Value::IsNumber(VALUE self) {
|
||||
return Bool(Value(self)->IsNumber());
|
||||
}
|
||||
VALUE Value::IsExternal(VALUE self) {
|
||||
return Bool(Value(self)->IsExternal());
|
||||
}
|
||||
VALUE Value::IsInt32(VALUE self) {
|
||||
return Bool(Value(self)->IsInt32());
|
||||
}
|
||||
VALUE Value::IsUint32(VALUE self) {
|
||||
return Bool(Value(self)->IsUint32());
|
||||
}
|
||||
VALUE Value::IsDate(VALUE self) {
|
||||
return Bool(Value(self)->IsDate());
|
||||
}
|
||||
VALUE Value::IsBooleanObject(VALUE self) {
|
||||
return Bool(Value(self)->IsBooleanObject());
|
||||
}
|
||||
VALUE Value::IsNumberObject(VALUE self) {
|
||||
return Bool(Value(self)->IsNumberObject());
|
||||
}
|
||||
VALUE Value::IsStringObject(VALUE self) {
|
||||
return Bool(Value(self)->IsStringObject());
|
||||
}
|
||||
VALUE Value::IsNativeError(VALUE self) {
|
||||
return Bool(Value(self)->IsNativeError());
|
||||
}
|
||||
VALUE Value::IsRegExp(VALUE self) {
|
||||
return Bool(Value(self)->IsRegExp());
|
||||
}
|
||||
|
||||
// VALUE Value::ToBoolean(VALUE self) {
|
||||
// return Boolean(Value(self)->ToBoolean());
|
||||
// }
|
||||
|
||||
// VALUE Value::ToNumber(VALUE self) {
|
||||
// return Number(Value(self)->ToNumber());
|
||||
// }
|
||||
VALUE Value::ToString(VALUE self) {
|
||||
return String(Value(self)->ToString());
|
||||
}
|
||||
|
||||
VALUE Value::ToDetailString(VALUE self) {
|
||||
return String(Value(self)->ToDetailString());
|
||||
}
|
||||
|
||||
VALUE Value::ToObject(VALUE self) {
|
||||
return Object(Value(self)->ToObject());
|
||||
}
|
||||
|
||||
// VALUE Value::ToInteger(VALUE self) {
|
||||
// return Integer(Value(self)->ToInteger());
|
||||
// }
|
||||
|
||||
// VALUE Value::ToUint32(VALUE self) {
|
||||
// return Uint32(Value(self)->ToUint32());
|
||||
// }
|
||||
|
||||
// VALUE Value::ToInt32(VALUE self) {
|
||||
// return Int32(Value(self)->ToInt32());
|
||||
// }
|
||||
|
||||
|
||||
// VALUE Value::ToArrayIndex(VALUE self) {
|
||||
// return Uint32(Value(self)->ToArrayIndex());
|
||||
// }
|
||||
|
||||
VALUE Value::BooleanValue(VALUE self) {
|
||||
return Bool(Value(self)->BooleanValue());
|
||||
}
|
||||
VALUE Value::NumberValue(VALUE self) {
|
||||
return rb_float_new(Value(self)->NumberValue());
|
||||
}
|
||||
VALUE Value::IntegerValue(VALUE self) {
|
||||
return INT2NUM(Value(self)->IntegerValue());
|
||||
}
|
||||
VALUE Value::Uint32Value(VALUE self) {
|
||||
return UINT2NUM(Value(self)->Uint32Value());
|
||||
}
|
||||
VALUE Value::Int32Value(VALUE self) {
|
||||
return INT2FIX(Value(self)->Int32Value());
|
||||
}
|
||||
|
||||
VALUE Value::Equals(VALUE self, VALUE other) {
|
||||
return Bool(Value(self)->Equals(Value(other)));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe V8::C::External do
|
||||
before do
|
||||
@cxt = V8::C::Context::New()
|
||||
@cxt.Enter()
|
||||
end
|
||||
after do
|
||||
@cxt.Exit()
|
||||
end
|
||||
it "can catch javascript exceptions" do
|
||||
V8::C::V8::SetCaptureStackTraceForUncaughtExceptions(true, 99, V8::C::StackTrace::kDetailed)
|
||||
V8::C::TryCatch() do |trycatch|
|
||||
V8::C::HandleScope() do
|
||||
source = V8::C::String::New(<<-JS)
|
||||
function one() {
|
||||
two()
|
||||
}
|
||||
function two() {
|
||||
three()
|
||||
}
|
||||
function three() {
|
||||
boom()
|
||||
}
|
||||
function boom() {
|
||||
throw new Error('boom!')
|
||||
}
|
||||
eval('one()')
|
||||
JS
|
||||
filename = V8::C::String::New("<eval>")
|
||||
script = V8::C::Script::New(source, filename)
|
||||
result = script.Run()
|
||||
trycatch.HasCaught().should be_true
|
||||
trycatch.CanContinue().should be_true
|
||||
exception = trycatch.Exception()
|
||||
exception.should_not be_nil
|
||||
exception.IsNativeError().should be_true
|
||||
trycatch.StackTrace().Utf8Value().should match /boom.*three.*two.*one/m
|
||||
message = trycatch.Message();
|
||||
message.should_not be_nil
|
||||
message.Get().Utf8Value().should eql "Uncaught Error: boom!"
|
||||
message.GetSourceLine().Utf8Value().should eql " throw new Error('boom!')"
|
||||
message.GetScriptResourceName().Utf8Value().should eql "<eval>"
|
||||
message.GetLineNumber().should eql 11
|
||||
stack = message.GetStackTrace()
|
||||
stack.should_not be_nil
|
||||
stack.GetFrameCount().should eql 6
|
||||
frame = stack.GetFrame(0)
|
||||
frame.GetLineNumber().should eql 11
|
||||
frame.GetColumn().should eql 17
|
||||
frame.GetScriptName().Utf8Value().should eql "<eval>"
|
||||
frame.GetScriptNameOrSourceURL().Utf8Value().should eql "<eval>"
|
||||
frame.IsEval().should be_false
|
||||
stack.GetFrame(4).IsEval().should be_true
|
||||
frame.IsConstructor().should be_false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue