@@ -240,17 +240,37 @@ void CPythonObject::ThrowIf(v8::Isolate* isolate)
240240 ::PyErr_Clear (); \
241241 ::PyErr_SetString (PyExc_RuntimeError, " execution is terminating" ); \
242242 info.GetReturnValue ().Set (returnValue); \
243- return ; \
243+ return v8::Intercepted:: kNo ; \
244244 }
245245
246246#define TRY_HANDLE_EXCEPTION (value ) _TERMINATE_CALLBACK_EXECUTION_CHECK(value) \
247247 BEGIN_HANDLE_PYTHON_EXCEPTION \
248248 {
249249#define END_HANDLE_EXCEPTION (value ) } \
250250 END_HANDLE_PYTHON_EXCEPTION \
251- info.GetReturnValue ().Set (value);
251+ info.GetReturnValue ().Set (value); \
252+ return v8::Intercepted::kYes ;
253+
254+ #define _TERMINATE_CALLBACK_EXECUTION_CHECK_NO_INTERCEPT (returnValue ) \
255+ if (v8::Isolate::GetCurrent ()->IsExecutionTerminating ()) { \
256+ ::PyErr_Clear (); \
257+ ::PyErr_SetString (PyExc_RuntimeError, " execution is terminating" ); \
258+ info.GetReturnValue ().Set (returnValue); \
259+ return ; \
260+ }
261+
262+ #define TRY_HANDLE_EXCEPTION_NO_INTERCEPT (value ) _TERMINATE_CALLBACK_EXECUTION_CHECK_NO_INTERCEPT(value) \
263+ BEGIN_HANDLE_PYTHON_EXCEPTION \
264+ {
265+ #define END_HANDLE_EXCEPTION_NO_INTERCEPT (value ) } \
266+ END_HANDLE_PYTHON_EXCEPTION \
267+ info.GetReturnValue ().Set (value); \
268+ return ;
269+
270+ #define CALLBACK_RETURN_HANDLED (value ) do { info.GetReturnValue ().Set (value); return v8::Intercepted::kYes ; } while (0 );
271+ #define CALLBACK_RETURN_NOT_HANDLED (value ) do { info.GetReturnValue ().Set (value); return v8::Intercepted::kNo ; } while (0 );
272+ #define CALLBACK_RETURN_NO_INTERCEPT (value ) do { info.GetReturnValue ().Set (value); return ; } while (0 );
252273
253- #define CALLBACK_RETURN (value ) do { info.GetReturnValue ().Set (value); return ; } while (0 );
254274
255275CPythonObject::CPythonObject ()
256276{
@@ -260,7 +280,7 @@ CPythonObject::~CPythonObject()
260280{
261281}
262282
263- void CPythonObject::NamedGetter (v8::Local<v8::Name> prop, const v8::PropertyCallbackInfo<v8::Value>& info)
283+ v8::Intercepted CPythonObject::NamedGetter (v8::Local<v8::Name> prop, const v8::PropertyCallbackInfo<v8::Value>& info)
264284{
265285 v8::HandleScope handle_scope (info.GetIsolate ());
266286
@@ -269,11 +289,12 @@ void CPythonObject::NamedGetter(v8::Local<v8::Name> prop, const v8::PropertyCall
269289 CPythonGIL python_gil;
270290
271291 py::object obj = CJavascriptObject::Wrap (info.Holder ());
292+ if (PyGen_Check (obj.ptr ()))
293+ CALLBACK_RETURN_NOT_HANDLED (v8::Undefined (info.GetIsolate ()));
272294
273295 v8::String::Utf8Value name (info.GetIsolate (), v8::Local<v8::String>::Cast (prop));
274- if (PyGen_Check (obj.ptr ())) CALLBACK_RETURN (v8::Undefined (info.GetIsolate ()));
275-
276- if (*name == nullptr ) CALLBACK_RETURN (v8::Undefined (info.GetIsolate ()));
296+ if (*name == nullptr )
297+ CALLBACK_RETURN_NOT_HANDLED (v8::Undefined (info.GetIsolate ()));
277298
278299 PyObject *value = ::PyObject_GetAttrString (obj.ptr (), *name);
279300
@@ -296,10 +317,11 @@ void CPythonObject::NamedGetter(v8::Local<v8::Name> prop, const v8::PropertyCall
296317 {
297318 py::object result (py::handle<>(::PyMapping_GetItemString (obj.ptr (), *name)));
298319
299- if (!result.is_none ()) CALLBACK_RETURN (Wrap (result));
320+ if (!result.is_none ())
321+ CALLBACK_RETURN_HANDLED (Wrap (result));
300322 }
301323
302- CALLBACK_RETURN (v8::Handle<v8::Value>());
324+ CALLBACK_RETURN_NOT_HANDLED (v8::Handle<v8::Value>());
303325 }
304326
305327 py::object attr = py::object (py::handle<>(value));
@@ -316,13 +338,12 @@ void CPythonObject::NamedGetter(v8::Local<v8::Name> prop, const v8::PropertyCall
316338 }
317339#endif
318340
319- CALLBACK_RETURN (Wrap (attr));
341+ CALLBACK_RETURN_HANDLED (Wrap (attr));
320342
321343 END_HANDLE_EXCEPTION (v8::Undefined (info.GetIsolate ()))
322-
323344}
324345
325- void CPythonObject::NamedSetter (v8::Local<v8::Name> prop, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value >& info)
346+ v8::Intercepted CPythonObject::NamedSetter (v8::Local<v8::Name> prop, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void >& info)
326347{
327348 v8::HandleScope handle_scope (info.GetIsolate ());
328349
@@ -334,7 +355,8 @@ void CPythonObject::NamedSetter(v8::Local<v8::Name> prop, v8::Local<v8::Value> v
334355
335356 v8::String::Utf8Value name (info.GetIsolate (), prop);
336357
337- if (*name == nullptr ) CALLBACK_RETURN (v8::Undefined (info.GetIsolate ()));
358+ if (*name == nullptr )
359+ CALLBACK_RETURN_NOT_HANDLED (v8::Undefined (info.GetIsolate ()));
338360
339361 py::object newval = CJavascriptObject::Wrap (value);
340362
@@ -373,19 +395,19 @@ void CPythonObject::NamedSetter(v8::Local<v8::Name> prop, v8::Local<v8::Value> v
373395
374396 setter (newval);
375397
376- CALLBACK_RETURN (value);
398+ CALLBACK_RETURN_HANDLED (value);
377399 }
378400 }
379401#endif
380402 obj.attr (*name) = newval;
381403 }
382404
383- CALLBACK_RETURN (value);
405+ CALLBACK_RETURN_HANDLED (value);
384406
385407 END_HANDLE_EXCEPTION (v8::Undefined (info.GetIsolate ()));
386408}
387409
388- void CPythonObject::NamedQuery (v8::Local<v8::Name> prop, const v8::PropertyCallbackInfo<v8::Integer>& info)
410+ v8::Intercepted CPythonObject::NamedQuery (v8::Local<v8::Name> prop, const v8::PropertyCallbackInfo<v8::Integer>& info)
389411{
390412 v8::HandleScope handle_scope (info.GetIsolate ());
391413
@@ -403,12 +425,13 @@ void CPythonObject::NamedQuery(v8::Local<v8::Name> prop, const v8::PropertyCallb
403425 exists = PyGen_Check (obj.ptr ()) || ::PyObject_HasAttrString (obj.ptr (), *name) ||
404426 (::PyMapping_Check (obj.ptr ()) && ::PyMapping_HasKeyString (obj.ptr (), *name));
405427
406- if (exists) CALLBACK_RETURN (v8::Integer::New (info.GetIsolate (), v8::None));
428+ if (exists)
429+ CALLBACK_RETURN_HANDLED (v8::Integer::New (info.GetIsolate (), v8::None));
407430
408431 END_HANDLE_EXCEPTION (v8::Handle<v8::Integer>())
409432}
410433
411- void CPythonObject::NamedDeleter (v8::Local<v8::Name> prop, const v8::PropertyCallbackInfo<v8::Boolean>& info)
434+ v8::Intercepted CPythonObject::NamedDeleter (v8::Local<v8::Name> prop, const v8::PropertyCallbackInfo<v8::Boolean>& info)
412435{
413436 v8::HandleScope handle_scope (info.GetIsolate ());
414437
@@ -424,7 +447,7 @@ void CPythonObject::NamedDeleter(v8::Local<v8::Name> prop, const v8::PropertyCal
424447 ::PyMapping_Check (obj.ptr()) &&
425448 ::PyMapping_HasKeyString(obj.ptr(), *name))
426449 {
427- CALLBACK_RETURN (-1 != ::PyMapping_DelItemString (obj.ptr (), *name));
450+ CALLBACK_RETURN_HANDLED (-1 != ::PyMapping_DelItemString (obj.ptr (), *name));
428451 }
429452 else
430453 {
@@ -439,14 +462,14 @@ void CPythonObject::NamedDeleter(v8::Local<v8::Name> prop, const v8::PropertyCal
439462 if (deleter.is_none ())
440463 throw CJavascriptException (" can't delete attribute" , ::PyExc_AttributeError);
441464
442- CALLBACK_RETURN (py::extract<bool >(deleter ()));
465+ CALLBACK_RETURN_HANDLED (py::extract<bool >(deleter ()));
443466 }
444467 else
445468 {
446- CALLBACK_RETURN (-1 != ::PyObject_DelAttrString (obj.ptr (), *name));
469+ CALLBACK_RETURN_HANDLED (-1 != ::PyObject_DelAttrString (obj.ptr (), *name));
447470 }
448471#else
449- CALLBACK_RETURN (-1 != ::PyObject_DelAttrString (obj.ptr (), *name));
472+ CALLBACK_RETURN_HANDLED (-1 != ::PyObject_DelAttrString (obj.ptr (), *name));
450473#endif
451474 }
452475
@@ -459,7 +482,7 @@ void CPythonObject::NamedEnumerator(const v8::PropertyCallbackInfo<v8::Array>& i
459482{
460483 v8::HandleScope handle_scope (info.GetIsolate ());
461484
462- TRY_HANDLE_EXCEPTION (v8::Handle<v8::Array>())
485+ TRY_HANDLE_EXCEPTION_NO_INTERCEPT (v8::Handle<v8::Array>())
463486
464487 CPythonGIL python_gil;
465488
@@ -470,7 +493,7 @@ void CPythonObject::NamedEnumerator(const v8::PropertyCallbackInfo<v8::Array>& i
470493
471494 if (::PySequence_Check (obj.ptr ()))
472495 {
473- CALLBACK_RETURN (v8::Handle<v8::Array>());
496+ CALLBACK_RETURN_NO_INTERCEPT (v8::Handle<v8::Array>());
474497 }
475498 else if (::PyMapping_Check (obj.ptr ()))
476499 {
@@ -515,13 +538,13 @@ void CPythonObject::NamedEnumerator(const v8::PropertyCallbackInfo<v8::Array>& i
515538 result->Set (v8::Isolate::GetCurrent ()->GetCurrentContext (), v8::Uint32::New (info.GetIsolate (), i), Wrap (py::object (py::handle<>(py::borrowed (item)))));
516539 }
517540
518- CALLBACK_RETURN (result);
541+ CALLBACK_RETURN_NO_INTERCEPT (result);
519542 }
520543
521- END_HANDLE_EXCEPTION (v8::Handle<v8::Array>())
544+ END_HANDLE_EXCEPTION_NO_INTERCEPT (v8::Handle<v8::Array>())
522545}
523546
524- void CPythonObject::IndexedGetter (uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info)
547+ v8::Intercepted CPythonObject::IndexedGetter (uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info)
525548{
526549 v8::HandleScope handle_scope (info.GetIsolate ());
527550
@@ -530,16 +553,16 @@ void CPythonObject::IndexedGetter(uint32_t index, const v8::PropertyCallbackInfo
530553 CPythonGIL python_gil;
531554
532555 py::object obj = CJavascriptObject::Wrap (info.Holder ());
533-
534- if ( PyGen_Check (obj. ptr ())) CALLBACK_RETURN (v8::Undefined (info.GetIsolate ()));
556+ if ( PyGen_Check (obj. ptr ()))
557+ CALLBACK_RETURN_NOT_HANDLED (v8::Undefined (info.GetIsolate ()));
535558
536559 if (::PySequence_Check (obj.ptr ()))
537560 {
538561 if ((Py_ssize_t) index < ::PySequence_Size (obj.ptr ()))
539562 {
540563 py::object ret (py::handle<>(::PySequence_GetItem (obj.ptr (), index)));
541564
542- CALLBACK_RETURN (Wrap (ret));
565+ CALLBACK_RETURN_HANDLED (Wrap (ret));
543566 }
544567 }
545568 else if (::PyMapping_Check (obj.ptr ()))
@@ -559,14 +582,14 @@ void CPythonObject::IndexedGetter(uint32_t index, const v8::PropertyCallbackInfo
559582
560583 if (value)
561584 {
562- CALLBACK_RETURN (Wrap (py::object (py::handle<>(value))));
585+ CALLBACK_RETURN_HANDLED (Wrap (py::object (py::handle<>(value))));
563586 }
564587 }
565588
566589 END_HANDLE_EXCEPTION (v8::Undefined (info.GetIsolate ()))
567590}
568591
569- void CPythonObject::IndexedSetter (uint32_t index, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value >& info)
592+ v8::Intercepted CPythonObject::IndexedSetter (uint32_t index, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void >& info)
570593{
571594 v8::HandleScope handle_scope (info.GetIsolate ());
572595
@@ -591,12 +614,12 @@ void CPythonObject::IndexedSetter(uint32_t index, v8::Local<v8::Value> value, co
591614 info.GetIsolate ()->ThrowException (v8::Exception::Error (v8::String::NewFromUtf8 (info.GetIsolate (), " fail to set named value" ).ToLocalChecked ()));
592615 }
593616
594- CALLBACK_RETURN (value);
617+ CALLBACK_RETURN_HANDLED (value);
595618
596619 END_HANDLE_EXCEPTION (v8::Undefined (info.GetIsolate ()))
597620}
598621
599- void CPythonObject::IndexedQuery (uint32_t index, const v8::PropertyCallbackInfo<v8::Integer>& info)
622+ v8::Intercepted CPythonObject::IndexedQuery (uint32_t index, const v8::PropertyCallbackInfo<v8::Integer>& info)
600623{
601624 v8::HandleScope handle_scope (info.GetIsolate ());
602625
@@ -606,13 +629,14 @@ void CPythonObject::IndexedQuery(uint32_t index, const v8::PropertyCallbackInfo<
606629
607630 py::object obj = CJavascriptObject::Wrap (info.Holder ());
608631
609- if (PyGen_Check (obj.ptr ())) CALLBACK_RETURN (v8::Integer::New (info.GetIsolate (), v8::ReadOnly));
632+ if (PyGen_Check (obj.ptr ()))
633+ CALLBACK_RETURN_HANDLED (v8::Integer::New (info.GetIsolate (), v8::ReadOnly));
610634
611635 if (::PySequence_Check (obj.ptr ()))
612636 {
613637 if ((Py_ssize_t) index < ::PySequence_Size (obj.ptr ()))
614638 {
615- CALLBACK_RETURN (v8::Integer::New (info.GetIsolate (), v8::None));
639+ CALLBACK_RETURN_HANDLED (v8::Integer::New (info.GetIsolate (), v8::None));
616640 }
617641 }
618642 else if (::PyMapping_Check (obj.ptr ()))
@@ -624,14 +648,14 @@ void CPythonObject::IndexedQuery(uint32_t index, const v8::PropertyCallbackInfo<
624648 if (::PyMapping_HasKeyString (obj.ptr (), buf) ||
625649 ::PyMapping_HasKey (obj.ptr(), py::long_(index).ptr()))
626650 {
627- CALLBACK_RETURN (v8::Integer::New (info.GetIsolate (), v8::None));
651+ CALLBACK_RETURN_HANDLED (v8::Integer::New (info.GetIsolate (), v8::None));
628652 }
629653 }
630654
631655 END_HANDLE_EXCEPTION (v8::Handle<v8::Integer>())
632656}
633657
634- void CPythonObject::IndexedDeleter (uint32_t index, const v8::PropertyCallbackInfo<v8::Boolean>& info)
658+ v8::Intercepted CPythonObject::IndexedDeleter (uint32_t index, const v8::PropertyCallbackInfo<v8::Boolean>& info)
635659{
636660 v8::HandleScope handle_scope (info.GetIsolate ());
637661
@@ -643,15 +667,15 @@ void CPythonObject::IndexedDeleter(uint32_t index, const v8::PropertyCallbackInf
643667
644668 if (::PySequence_Check (obj.ptr ()) && (Py_ssize_t) index < ::PySequence_Size (obj.ptr ()))
645669 {
646- CALLBACK_RETURN (0 <= ::PySequence_DelItem (obj.ptr (), index));
670+ CALLBACK_RETURN_HANDLED (0 <= ::PySequence_DelItem (obj.ptr (), index));
647671 }
648672 else if (::PyMapping_Check (obj.ptr ()))
649673 {
650674 char buf[65 ];
651675
652676 snprintf (buf, sizeof (buf), " %d" , index);
653677
654- CALLBACK_RETURN (PyMapping_DelItemString (obj.ptr (), buf) == 0 );
678+ CALLBACK_RETURN_HANDLED (PyMapping_DelItemString (obj.ptr (), buf) == 0 );
655679 }
656680
657681 END_HANDLE_EXCEPTION (v8::Handle<v8::Boolean>())
@@ -661,7 +685,7 @@ void CPythonObject::IndexedEnumerator(const v8::PropertyCallbackInfo<v8::Array>&
661685{
662686 v8::HandleScope handle_scope (info.GetIsolate ());
663687
664- TRY_HANDLE_EXCEPTION (v8::Handle<v8::Array>());
688+ TRY_HANDLE_EXCEPTION_NO_INTERCEPT (v8::Handle<v8::Array>());
665689
666690 CPythonGIL python_gil;
667691
@@ -678,9 +702,9 @@ void CPythonObject::IndexedEnumerator(const v8::PropertyCallbackInfo<v8::Array>&
678702 result->Set (context, v8::Integer::New (info.GetIsolate (), i), v8::Integer::New (info.GetIsolate (), i));
679703 }
680704
681- CALLBACK_RETURN (result);
705+ CALLBACK_RETURN_NO_INTERCEPT (result);
682706
683- END_HANDLE_EXCEPTION (v8::Handle<v8::Array>())
707+ END_HANDLE_EXCEPTION_NO_INTERCEPT (v8::Handle<v8::Array>())
684708}
685709
686710#define GEN_ARG (z, n, data ) CJavascriptObject::Wrap(info[n])
@@ -707,11 +731,12 @@ void CPythonObject::IndexedEnumerator(const v8::PropertyCallbackInfo<v8::Array>&
707731 } \
708732 /* */
709733
734+
710735void CPythonObject::Caller (const v8::FunctionCallbackInfo<v8::Value>& info)
711736{
712737 v8::HandleScope handle_scope (info.GetIsolate ());
713738
714- TRY_HANDLE_EXCEPTION (v8::Undefined (info.GetIsolate ()));
739+ TRY_HANDLE_EXCEPTION_NO_INTERCEPT (v8::Undefined (info.GetIsolate ()));
715740
716741 CPythonGIL python_gil;
717742
@@ -736,21 +761,37 @@ void CPythonObject::Caller(const v8::FunctionCallbackInfo<v8::Value>& info)
736761 default :
737762 info.GetIsolate ()->ThrowException (v8::Exception::Error (v8::String::NewFromUtf8 (info.GetIsolate (), " too many arguments" ).ToLocalChecked ()));
738763
739- CALLBACK_RETURN (v8::Undefined (info.GetIsolate ()));
764+ CALLBACK_RETURN_NO_INTERCEPT (v8::Undefined (info.GetIsolate ()));
740765 }
741766
742- CALLBACK_RETURN (Wrap (result));
767+ CALLBACK_RETURN_NO_INTERCEPT (Wrap (result));
743768
744- END_HANDLE_EXCEPTION (v8::Undefined (info.GetIsolate ()))
769+ END_HANDLE_EXCEPTION_NO_INTERCEPT (v8::Undefined (info.GetIsolate ()))
745770}
746771
747772void CPythonObject::SetupObjectTemplate (v8::Isolate *isolate, v8::Handle<v8::ObjectTemplate> clazz)
748773{
749774 v8::HandleScope handle_scope (isolate);
750775
751776 clazz->SetInternalFieldCount (1 );
752- clazz->SetHandler (v8::NamedPropertyHandlerConfiguration (NamedGetter, NamedSetter, NamedQuery, NamedDeleter, NamedEnumerator));
753- clazz->SetHandler (v8::IndexedPropertyHandlerConfiguration (IndexedGetter, IndexedSetter, IndexedQuery, IndexedDeleter, IndexedEnumerator));
777+
778+ clazz->SetHandler (v8::NamedPropertyHandlerConfiguration (
779+ NamedGetter,
780+ NamedSetter,
781+ NamedQuery,
782+ NamedDeleter,
783+ NamedEnumerator)
784+ );
785+
786+ clazz->SetHandler (v8::IndexedPropertyHandlerConfiguration (
787+ IndexedGetter,
788+ IndexedSetter,
789+ IndexedQuery,
790+ IndexedDeleter,
791+ IndexedEnumerator
792+ )
793+ );
794+
754795 clazz->SetCallAsFunctionHandler (Caller);
755796}
756797
0 commit comments