| Index: test/cctest/test-api.cc
|
| diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
|
| index 48dc72e7b3d8fc1159ccbb294cffed54996081ef..78e3e24bef53285ca60d5478c81b9a5864b216fb 100644
|
| --- a/test/cctest/test-api.cc
|
| +++ b/test/cctest/test-api.cc
|
| @@ -51,6 +51,7 @@ static bool IsNaN(double x) {
|
| }
|
|
|
| using ::v8::ObjectTemplate;
|
| +using ::v8::FunctionTemplate;
|
| using ::v8::Value;
|
| using ::v8::Context;
|
| using ::v8::Local;
|
| @@ -59,6 +60,16 @@ using ::v8::Script;
|
| using ::v8::Function;
|
| using ::v8::AccessorInfo;
|
| using ::v8::Extension;
|
| +using ::v8::Handle;
|
| +using ::v8::HandleScope;
|
| +using ::v8::Undefined;
|
| +using ::v8::Object;
|
| +using ::v8::TryCatch;
|
| +using ::v8::Message;
|
| +using ::v8::MessageCallback;
|
| +using ::v8::V8;
|
| +using ::v8::StackTrace;
|
| +using ::v8::Arguments;
|
|
|
| namespace i = ::i;
|
|
|
| @@ -7978,6 +7989,128 @@ THREADED_TEST(NamedPropertyHandlerGetterAttributes) {
|
| }
|
|
|
|
|
| +static Handle<Value> ThrowingGetter(Local<String> name,
|
| + const AccessorInfo& info) {
|
| + ApiTestFuzzer::Fuzz();
|
| + ThrowException(Handle<Value>());
|
| + return Undefined();
|
| +}
|
| +
|
| +
|
| +THREADED_TEST(VariousGetPropertiesAndThrowingCallbacks) {
|
| + HandleScope scope;
|
| + LocalContext context;
|
| +
|
| + Local<FunctionTemplate> templ = FunctionTemplate::New();
|
| + Local<ObjectTemplate> instance_templ = templ->InstanceTemplate();
|
| + instance_templ->SetAccessor(v8_str("f"), ThrowingGetter);
|
| +
|
| + Local<Object> instance = templ->GetFunction()->NewInstance();
|
| +
|
| + Local<Object> withJsGetter = CompileRun(
|
| + "o = {};\n"
|
| + "o.__defineGetter__('f', function() { throw undefined; });\n"
|
| + "o\n").As<Object>();
|
| + CHECK(!withJsGetter.IsEmpty());
|
| +
|
| + Local<Object> another = Object::New();
|
| + another->SetPrototype(instance);
|
| +
|
| + TryCatch try_catch;
|
| +
|
| + Local<Value> result = instance->GetRealNamedProperty(v8_str("f"));
|
| + CHECK(try_catch.HasCaught());
|
| + try_catch.Reset();
|
| + CHECK(result.IsEmpty());
|
| +
|
| + result = another->GetRealNamedProperty(v8_str("f"));
|
| + CHECK(try_catch.HasCaught());
|
| + try_catch.Reset();
|
| + CHECK(result.IsEmpty());
|
| +
|
| + result = another->GetRealNamedPropertyInPrototypeChain(v8_str("f"));
|
| + CHECK(try_catch.HasCaught());
|
| + try_catch.Reset();
|
| + CHECK(result.IsEmpty());
|
| +
|
| + result = another->Get(v8_str("f"));
|
| + CHECK(try_catch.HasCaught());
|
| + try_catch.Reset();
|
| + CHECK(result.IsEmpty());
|
| +
|
| + result = withJsGetter->GetRealNamedProperty(v8_str("f"));
|
| + CHECK(try_catch.HasCaught());
|
| + try_catch.Reset();
|
| + CHECK(result.IsEmpty());
|
| +
|
| + result = withJsGetter->Get(v8_str("f"));
|
| + CHECK(try_catch.HasCaught());
|
| + try_catch.Reset();
|
| + CHECK(result.IsEmpty());
|
| +}
|
| +
|
| +
|
| +static Handle<Value> ThrowingCallbackWithTryCatch(const Arguments& args) {
|
| + TryCatch try_catch;
|
| + // Verboseness is important: it triggers message delivery which can call into
|
| + // external code.
|
| + try_catch.SetVerbose(true);
|
| + CompileRun("throw 'from JS';");
|
| + CHECK(try_catch.HasCaught());
|
| + CHECK(!i::Top::has_pending_exception());
|
| + CHECK(!i::Top::has_scheduled_exception());
|
| + return Undefined();
|
| +}
|
| +
|
| +
|
| +static void WithTryCatch(Handle<Message> message, Handle<Value> data) {
|
| + TryCatch try_catch;
|
| +}
|
| +
|
| +
|
| +static void ThrowFromJS(Handle<Message> message, Handle<Value> data) {
|
| + CompileRun("throw 'ThrowInJS';");
|
| +}
|
| +
|
| +
|
| +static void ThrowViaApi(Handle<Message> message, Handle<Value> data) {
|
| + ThrowException(v8_str("ThrowViaApi"));
|
| +}
|
| +
|
| +
|
| +static void WebKitLike(Handle<Message> message, Handle<Value> data) {
|
| + Handle<String> errorMessageString = message->Get();
|
| + CHECK(!errorMessageString.IsEmpty());
|
| + message->GetStackTrace();
|
| + message->GetScriptResourceName();
|
| +}
|
| +
|
| +THREADED_TEST(ExceptionsDoNotPropagatePastTryCatch) {
|
| + HandleScope scope;
|
| + LocalContext context;
|
| +
|
| + Local<Function> func =
|
| + FunctionTemplate::New(ThrowingCallbackWithTryCatch)->GetFunction();
|
| + context->Global()->Set(v8_str("func"), func);
|
| +
|
| + MessageCallback callbacks[] =
|
| + { NULL, WebKitLike, ThrowViaApi, ThrowFromJS, WithTryCatch };
|
| + for (unsigned i = 0; i < sizeof(callbacks)/sizeof(callbacks[0]); i++) {
|
| + MessageCallback callback = callbacks[i];
|
| + if (callback != NULL) {
|
| + V8::AddMessageListener(callback);
|
| + }
|
| + ExpectFalse(
|
| + "var thrown = false;\n"
|
| + "try { func(); } catch(e) { thrown = true; }\n"
|
| + "thrown\n");
|
| + if (callback != NULL) {
|
| + V8::RemoveMessageListeners(callback);
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| static v8::Handle<Value> ParentGetter(Local<String> name,
|
| const AccessorInfo& info) {
|
| ApiTestFuzzer::Fuzz();
|
|
|