Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(241)

Unified Diff: Source/bindings/v8/custom/V8PromiseCustom.cpp

Issue 174073009: [Promise] Avoid crash in stack exhausted circumstance. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/bindings/v8/custom/V8PromiseCustom.cpp
diff --git a/Source/bindings/v8/custom/V8PromiseCustom.cpp b/Source/bindings/v8/custom/V8PromiseCustom.cpp
index 14200e2541949968394eeac583b2fa28360c0c6f..4e57af31f5ed3b9260bc0aa7f230e3aa912a8cea 100644
--- a/Source/bindings/v8/custom/V8PromiseCustom.cpp
+++ b/Source/bindings/v8/custom/V8PromiseCustom.cpp
@@ -31,7 +31,6 @@
#include "config.h"
#include "bindings/v8/custom/V8PromiseCustom.h"
-#include <v8.h>
#include "V8Promise.h"
#include "bindings/v8/DOMRequestState.h"
#include "bindings/v8/ScopedPersistent.h"
@@ -52,6 +51,12 @@
#include "wtf/Functional.h"
#include "wtf/Noncopyable.h"
#include "wtf/PassOwnPtr.h"
+#include <v8.h>
+
+#define RETURN_IF_EMPTY(handle, result) \
haraken 2014/02/21 04:19:21 I don't know if this macro is worth adding. We nor
yhirano 2014/02/21 07:32:51 Done.
+ if ((handle).IsEmpty()) { \
+ return (result); \
+ }
namespace WebCore {
@@ -141,6 +146,7 @@ v8::Local<v8::Object> promiseAllEnvironment(v8::Handle<v8::Object> promise, v8::
{
v8::Local<v8::ObjectTemplate> objectTemplate = promiseAllEnvironmentObjectTemplate(isolate);
v8::Local<v8::Object> environment = objectTemplate->NewInstance();
+ RETURN_IF_EMPTY(environment, v8::Local<v8::Object>());
environment->SetInternalField(V8PromiseCustom::PromiseAllEnvironmentPromiseIndex, promise);
environment->SetInternalField(V8PromiseCustom::PromiseAllEnvironmentCountdownIndex, countdownWrapper);
@@ -491,11 +497,10 @@ void V8Promise::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>& inf
return;
}
v8::Local<v8::Function> init = info[0].As<v8::Function>();
- v8::Local<v8::Object> promise = V8PromiseCustom::createPromise(info.Holder(), isolate);
- v8::Handle<v8::Value> argv[] = {
- createClosure(promiseResolveCallback, promise, isolate),
- createClosure(promiseRejectCallback, promise, isolate)
- };
+ V8TRYCATCH_VOID(v8::Local<v8::Object>, promise, V8PromiseCustom::createPromise(info.Holder(), isolate));
+ V8TRYCATCH_VOID(v8::Handle<v8::Value>, resolve, createClosure(promiseResolveCallback, promise, isolate));
+ V8TRYCATCH_VOID(v8::Handle<v8::Value>, reject, createClosure(promiseRejectCallback, promise, isolate));
+ v8::Handle<v8::Value> argv[] = { resolve, reject };
v8::TryCatch trycatch;
if (V8ScriptRunner::callFunction(init, currentExecutionContext(isolate), v8::Undefined(isolate), WTF_ARRAY_LENGTH(argv), argv, isolate).IsEmpty()) {
// An exception is thrown. Reject the promise if its resolved flag is unset.
@@ -552,7 +557,7 @@ void V8Promise::resolveMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& i
if (info.Length() > 0)
result = info[0];
- v8::Local<v8::Object> promise = V8PromiseCustom::createPromise(info.Holder(), isolate);
+ V8TRYCATCH_VOID(v8::Local<v8::Object>, promise, V8PromiseCustom::createPromise(info.Holder(), isolate));
V8PromiseCustom::resolve(promise, result, isolate);
v8SetReturnValue(info, promise);
}
@@ -566,7 +571,7 @@ void V8Promise::rejectMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& in
if (info.Length() > 0)
result = info[0];
- v8::Local<v8::Object> promise = V8PromiseCustom::createPromise(info.Holder(), isolate);
+ V8TRYCATCH_VOID(v8::Local<v8::Object>, promise, V8PromiseCustom::createPromise(info.Holder(), isolate));
V8PromiseCustom::reject(promise, result, isolate);
v8SetReturnValue(info, promise);
}
@@ -574,7 +579,7 @@ void V8Promise::rejectMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& in
void V8Promise::raceMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
v8::Isolate* isolate = info.GetIsolate();
- v8::Local<v8::Object> promise = V8PromiseCustom::createPromise(info.Holder(), isolate);
+ V8TRYCATCH_VOID(v8::Local<v8::Object>, promise, V8PromiseCustom::createPromise(info.Holder(), isolate));
if (!info.Length() || !info[0]->IsArray()) {
v8SetReturnValue(info, promise);
@@ -583,8 +588,8 @@ void V8Promise::raceMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info
// FIXME: Now we limit the iterable type to the Array type.
v8::Local<v8::Array> iterable = info[0].As<v8::Array>();
- v8::Local<v8::Function> onFulfilled = createClosure(promiseResolveCallback, promise, isolate);
- v8::Local<v8::Function> onRejected = createClosure(promiseRejectCallback, promise, isolate);
+ V8TRYCATCH_VOID(v8::Local<v8::Function>, onFulfilled, createClosure(promiseResolveCallback, promise, isolate));
+ V8TRYCATCH_VOID(v8::Local<v8::Function>, onRejected, createClosure(promiseRejectCallback, promise, isolate));
for (unsigned i = 0, length = iterable->Length(); i < length; ++i) {
// Array-holes should not be skipped by for-of iteration semantics.
@@ -598,7 +603,7 @@ void V8Promise::raceMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info
void V8Promise::allMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
v8::Isolate* isolate = info.GetIsolate();
- v8::Local<v8::Object> promise = V8PromiseCustom::createPromise(info.Holder(), isolate);
+ V8TRYCATCH_VOID(v8::Local<v8::Object>, promise, V8PromiseCustom::createPromise(info.Holder(), isolate));
v8::Local<v8::Array> results = v8::Array::New(info.GetIsolate());
if (!info.Length() || !info[0]->IsArray()) {
@@ -617,14 +622,14 @@ void V8Promise::allMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
}
v8::Local<v8::ObjectTemplate> objectTemplate = primitiveWrapperObjectTemplate(isolate);
- v8::Local<v8::Object> countdownWrapper = objectTemplate->NewInstance();
+ V8TRYCATCH_VOID(v8::Local<v8::Object>, countdownWrapper, objectTemplate->NewInstance());
countdownWrapper->SetInternalField(V8PromiseCustom::PrimitiveWrapperPrimitiveIndex, v8::Integer::New(isolate, iterable->Length()));
- v8::Local<v8::Function> onRejected = createClosure(promiseRejectCallback, promise, isolate);
+ V8TRYCATCH_VOID(v8::Local<v8::Function>, onRejected, createClosure(promiseRejectCallback, promise, isolate));
for (unsigned i = 0, length = iterable->Length(); i < length; ++i) {
// Array-holes should not be skipped by for-of iteration semantics.
- v8::Local<v8::Object> environment = promiseAllEnvironment(promise, countdownWrapper, i, results, isolate);
- v8::Local<v8::Function> onFulfilled = createClosure(promiseAllFulfillCallback, environment, isolate);
+ V8TRYCATCH_VOID(v8::Local<v8::Object>, environment, promiseAllEnvironment(promise, countdownWrapper, i, results, isolate));
+ V8TRYCATCH_VOID(v8::Local<v8::Function>, onFulfilled, createClosure(promiseAllFulfillCallback, environment, isolate));
V8TRYCATCH_VOID(v8::Local<v8::Value>, nextValue, iterable->Get(i));
v8::Local<v8::Object> nextPromise = V8PromiseCustom::toPromise(nextValue, isolate);
V8PromiseCustom::then(nextPromise, onFulfilled, onRejected, isolate);
@@ -638,6 +643,7 @@ v8::Local<v8::Object> V8PromiseCustom::createPromise(v8::Handle<v8::Object> crea
{
v8::Local<v8::ObjectTemplate> internalTemplate = internalObjectTemplate(isolate);
v8::Local<v8::Object> internal = internalTemplate->NewInstance();
+ RETURN_IF_EMPTY(internal, v8::Local<v8::Object>());
v8::Local<v8::Object> promise = V8DOMWrapper::createWrapper(creationContext, &V8Promise::wrapperTypeInfo, 0, isolate);
clearDerived(internal, isolate);
@@ -799,10 +805,12 @@ v8::Local<v8::Object> V8PromiseCustom::coerceThenable(v8::Handle<v8::Object> the
ASSERT(!thenable.IsEmpty());
ASSERT(!then.IsEmpty());
v8::Local<v8::Object> promise = createPromise(v8::Handle<v8::Object>(), isolate);
- v8::Handle<v8::Value> argv[] = {
- createClosure(promiseResolveCallback, promise, isolate),
- createClosure(promiseRejectCallback, promise, isolate)
- };
+ v8::Handle<v8::Value> onFulfilled = createClosure(promiseResolveCallback, promise, isolate);
+ RETURN_IF_EMPTY(onFulfilled, v8::Local<v8::Object>());
+ v8::Handle<v8::Value> onRejected = createClosure(promiseRejectCallback, promise, isolate);
+ RETURN_IF_EMPTY(onRejected, v8::Local<v8::Object>());
+ v8::Handle<v8::Value> argv[] = { onFulfilled, onRejected };
+
v8::TryCatch trycatch;
if (V8ScriptRunner::callFunction(then, currentExecutionContext(isolate), thenable, WTF_ARRAY_LENGTH(argv), argv, isolate).IsEmpty()) {
reject(promise, trycatch.Exception(), isolate);
« Source/bindings/v8/V8Initializer.cpp ('K') | « Source/bindings/v8/V8Initializer.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698