A change (https://bugs.webkit.org/show_bug.cgi?id=84094) landed recently 
that requires the following (see http://goo.gl/UsXm6 for details):

// C++ calls into script contexts which are "owned" by WebKit (created in a
// process where WebKit.cpp initializes v8) must declare their type:
//
//   1. Calls into page/author script from a frame
//   2. Calls into page/author script from a worker
//   3. Calls into internal script (typically setup/teardown work)
//
// Debug-time checking of this is enforced via this class.
//
// Calls of type (1) should generally go through V8Proxy, as inspector
// instrumentation is needed. Calls of type (2) should always 
stack-allocate a
// V8RecursionScope in the same block as the call into script. Calls of 
type (3)
// should stack allocate a V8RecursionScope::MicrotaskSuppression -- this
// skips work that is spec'd to happen at the end of the outer-most script 
stack
// frame of calls into page script:
//
// 
http://www.whatwg.org/specs/web-apps/current-work/#perform-a-microtask-checkpoint

I think my v8 extension falls into (3) and it started crashing in debug 
mode. One possible fix is to include conditional dependency on WebKit in my 
project and invoke the following to avoid crash:

WebKit::WebScopedMicrotaskSuppression suppression;

I would like to avoid adding WebKit dependency if possible. The library 
currently only depends on v8 and ICU (for internationalization).

My code uses standard v8 extension approach:

1. Binding
v8::Handle<v8::FunctionTemplate> Extension::GetNativeFunction(
    v8::Handle<v8::String> name) {
 if (name->Equals(v8::String::New("NativeJSCollator"))) {
    return v8::FunctionTemplate::New(Collator::*JSCollator*);
...
}

2. Creating JS object, defining some methods on that object, inserting a 
C++ object and returning the result
v8::Persistent<v8::FunctionTemplate> Collator::collator_template_;
...
v8::Handle<v8::Value> Collator::*JSCollator*(const v8::Arguments& args) {
if (collator_template_.IsEmpty()) {
  v8::Local<v8::FunctionTemplate> raw_template(v8::FunctionTemplate::New());
  raw_template->SetClassName(v8::String::New("v8Locale.Collator"));

  // Define internal field count on instance template.
  v8::Local<v8::ObjectTemplate> object_template =
      raw_template->InstanceTemplate();

  // Set aside internal fields for icu collator.
  object_template->SetInternalFieldCount(1);

  // Define all of the prototype methods on prototype template.
  v8::Local<v8::ObjectTemplate> proto = raw_template->PrototypeTemplate();
  proto->Set(v8::String::New("compare"),
             v8::FunctionTemplate::New(CollatorCompare));

  collator_template_ =
      v8::Persistent<v8::FunctionTemplate>::New(raw_template);
}

// Create an empty object wrapper.
v8::Local<v8::Object> local_object =
    collator_template_->GetFunction()->NewInstance();
v8::Persistent<v8::Object> wrapper =
    v8::Persistent<v8::Object>::New(local_object);

// Set collator as internal field of the resulting JS object.
wrapper->SetPointerInInternalField(0, collator);

// Make object handle weak so we can delete iterator once GC kicks in.
wrapper.MakeWeak(NULL, DeleteCollator);

return wrapper;
}

I assume one of the operations (related to templates) under 2. invokes JS 
script in the background which triggers the debug assert.

Is there a way to avoid running scripts while still getting the same 
functionality, like manually constructing the object?

Regards,
  Nebojša Ćirić

-- 
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users

Reply via email to