Re: [v8-users] Check failed: Handle not reset in first callback. How to Reset my Persistent

2018-10-09 Thread J Decker
On Tue, Oct 9, 2018 at 4:40 PM Mike Moening  wrote:

> The example was helpful.   Encapsulating the Persistent in the callacks
> private data object seems to be the way to roll.
>
>
>> // kParameter will pass a void* parameter back to the callback,
>> kInternalFields
>> // will pass the first two internal fields back to the callback,
>> kFinalizer
>> // will pass a void* parameter back, but is invoked before the object is
>> // actually collected, so it can be resurrected. In the last case, it is
>> not
>> // possible to request a second pass callback.
>> enum class WeakCallbackType { kParameter, kInternalFields, kFinalizer };
>
>
> Does that help?
>
> Sorry, but no not really.
> Resurrection?  Sounds like a zombie movie (I probably don't need this)
> *kInternalFields - will pass the first two internal fields back to the
> callback*
>

This would be useful in a Node world, there is a utiility class ObjectWrap
which uses 1 internal field to store the user's class reference (the C++
object to be wrapped in a V8/JS reference).  It could use kInternalFields
type instead of duplicating the value to be passed as a parameter.  (Just a
possible application of that)


>
> How? Why?
>
> There has to be something better that explains the callbacks better.
>

I did this originally to track array buffer content, so I can release the
backing buffer when the typed array evaporates (is garbage collected).
I generalized to object mostly later, but then re-added 'strings' for short
lived strings associated with address/connection objects.

---
struct arrayBufferHolder  {
void *buffer; // resources associated with object
Persistent o;
/*
// other types that this might hold add deallocation handlers in
callback
Persistent s;
Persistent ab;
*/
};
typedef struct arrayBufferHolder ARRAY_BUFFER_HOLDER, *PARRAY_BUFFER_HOLDER;


/* GetHolder() returns a holder from a pool; or allocates a new one... it
reuses previous holders*/



/* ... buf and len are the backing
buffer and length of that buffer */
Local arrayBuffer = ArrayBuffer::New( isolate, buf, len );
PARRAY_BUFFER_HOLDER holder = GetHolder();
holder->o.Reset( isolate, arrayBuffer );
holder->o.SetWeak( holder, releaseBuffer,
WeakCallbackType::kParameter );
holder->buffer = buf;



/* The callback to release associated resources when `arrayBuffer` is
collcted */

void releaseBuffer( const WeakCallbackInfo  ) {
PARRAY_BUFFER_HOLDER holder = info.GetParameter();

if( !holder->o.IsEmpty() ) { // in case this is one of 3 types to release.
holder->o.ClearWeak();
holder->o.Reset();
}
Deallocate( void*, holder->buffer ); // your resource deallocation here
DropHolder( holder );  // returns holder to pool for later use. (delete
holder;?)
}

---




> --
> --
> v8-users mailing list
> v8-users@googlegroups.com
> http://groups.google.com/group/v8-users
> ---
> You received this message because you are subscribed to the Google Groups
> "v8-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to v8-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
-- 
v8-users mailing list
v8-users@googlegroups.com
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [v8-users] Check failed: Handle not reset in first callback. How to Reset my Persistent

2018-10-09 Thread Mike Moening
The example was helpful.   Encapsulating the Persistent in the callacks 
private data object seems to be the way to roll.
 

> // kParameter will pass a void* parameter back to the callback, 
> kInternalFields
> // will pass the first two internal fields back to the callback, kFinalizer
> // will pass a void* parameter back, but is invoked before the object is
> // actually collected, so it can be resurrected. In the last case, it is 
> not
> // possible to request a second pass callback.
> enum class WeakCallbackType { kParameter, kInternalFields, kFinalizer };


Does that help?

Sorry, but no not really.  
Resurrection?  Sounds like a zombie movie (I probably don't need this)
*kInternalFields - will pass the first two internal fields back to the 
callback*
How? Why?

There has to be something better that explains the callbacks better.

-- 
-- 
v8-users mailing list
v8-users@googlegroups.com
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [v8-users] Check failed: Handle not reset in first callback. How to Reset my Persistent

2018-10-09 Thread Jakob Kummerow
On Tue, Oct 9, 2018 at 11:45 AM Mike Moening  wrote:

> With recent versions of v8 the SetWeak method has changed and the
> Persistent* parameter has been dropped from the destructor callback.
> The destructor callback function is **supposed** to Reset() the persistent
> or its a leak.
> If you don't V8 crashes and tells you this:
>
> Check failed: Handle not reset in first callback. See comments on
> |v8::WeakCallbackInfo
>
> Old signature:
> void MyClass::DestructorCallback(Isolate* pIsolate, Persistent*
> value, MyClass* pObj)
>
> New signature
> void MyClass::DestructorCallback(const WeakCallbackInfo& oValue)
>
> If I call it like this:
> Persistent obj(isolate, objLocal);
> obj.SetWeak(pMyObject, MyClass::DestructorCallback,
> WeakCallbackType::kParameter);
>
> How can I pass the Persistent into my DestructorCallback function so I can
> Reset it??
> Persistent cannot be copied.
> So how can I Reset() it in the callback?
> Any help would be great.
>

See this example:
https://cs.chromium.org/chromium/src/v8/src/d8.cc?l=2312=SetWeak
You can often find such hints in the V8 API Changes doc

(just
ask your favorite search engine for "V8 API Changes" to find it).


> Also the WeakCallbackType::kParameter  vs WeakCallbackType::kFinalizer
> thing has me confuzeled too.
> Which is the right type to use?
>

See the documentation:

// kParameter will pass a void* parameter back to the callback,
> kInternalFields
> // will pass the first two internal fields back to the callback, kFinalizer
> // will pass a void* parameter back, but is invoked before the object is
> // actually collected, so it can be resurrected. In the last case, it is
> not
> // possible to request a second pass callback.
> enum class WeakCallbackType { kParameter, kInternalFields, kFinalizer };


Does that help?


>
> Thanks!
>
> --
> --
> v8-users mailing list
> v8-users@googlegroups.com
> http://groups.google.com/group/v8-users
> ---
> You received this message because you are subscribed to the Google Groups
> "v8-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to v8-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
-- 
v8-users mailing list
v8-users@googlegroups.com
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[v8-users] Check failed: Handle not reset in first callback. How to Reset my Persistent

2018-10-09 Thread Mike Moening
With recent versions of v8 the SetWeak method has changed and the 
Persistent* parameter has been dropped from the destructor callback.
The destructor callback function is **supposed** to Reset() the persistent 
or its a leak.
If you don't V8 crashes and tells you this:

Check failed: Handle not reset in first callback. See comments on 
|v8::WeakCallbackInfo

Old signature:
void MyClass::DestructorCallback(Isolate* pIsolate, Persistent* 
value, MyClass* pObj)

New signature
void MyClass::DestructorCallback(const WeakCallbackInfo& oValue)

If I call it like this:
Persistent obj(isolate, objLocal);
obj.SetWeak(pMyObject, MyClass::DestructorCallback, 
WeakCallbackType::kParameter);
   
How can I pass the Persistent into my DestructorCallback function so I can 
Reset it??
Persistent cannot be copied.
So how can I Reset() it in the callback?
Any help would be great.

Also the WeakCallbackType::kParameter  vs WeakCallbackType::kFinalizer 
thing has me confuzeled too.
Which is the right type to use?

Thanks!

-- 
-- 
v8-users mailing list
v8-users@googlegroups.com
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[v8-users] Re: SetCallAsFunctionHandler Error: TypeError: x is not a constructor

2018-10-09 Thread Mike Moening
I found a fix.  See the bug comments for how to fix V8

-- 
-- 
v8-users mailing list
v8-users@googlegroups.com
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[v8-users] Re: SetCallAsFunctionHandler Error: TypeError: x is not a constructor

2018-10-09 Thread Mike Moening
I just found this:

https://bugs.chromium.org/p/v8/issues/detail?id=7670

I'm pretty sure that change broke my code.
How do I back this change out of current sources to get things working 
again?

-- 
-- 
v8-users mailing list
v8-users@googlegroups.com
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[v8-users] SetCallAsFunctionHandler Error: TypeError: x is not a constructor

2018-10-09 Thread Mike Moening
After upgrading to a newer version of V8 the constructorFunctionHandler I 
set with SetCallAsFunctionHandler does not seem to be working. When I try 
to execute the code below it produces this error:

TypeError: RemoteRequest is not a constructor

This sample code is unstructured and ugly, but it will reproduce the error.
It worked properly in past versions v8.
Thanks for the help.

Mike

---
#include 
using namespace v8;
#include "include/libplatform/libplatform.h"

Eternal* pRemoteRequestObjectTemplateEnternal;

class RJSRemoteRequest
{
   public:
   RJSRemoteRequest(){};
   ~RJSRemoteRequest(){};

   static void constructorFunctionHandler(const 
FunctionCallbackInfo& args)
   {
  Local tmplRmtRequest;
  if(pRemoteRequestObjectTemplateEnternal && 
!pRemoteRequestObjectTemplateEnternal->IsEmpty())
  {
 tmplRmtRequest = 
pRemoteRequestObjectTemplateEnternal->Get(args.GetIsolate());
 //Now make an real RemoteRequest C++ object and pass it.
 RJSRemoteRequest* pRemoteRequest = new RJSRemoteRequest();
 Local localObj = tmplRmtRequest->NewInstance();
 localObj->SetInternalField(0, External::New(args.GetIsolate(), 
pRemoteRequest));
 Persistent obj(args.GetIsolate(), localObj);
 obj.SetWeak(pRemoteRequest, 
RJSRemoteRequest::JSRemoteRequest_DestructorCallback, 
WeakCallbackType::kFinalizer);
 args.GetReturnValue().Set(obj);
 return;
  }
  args.GetReturnValue().SetNull();
   };
   static void JSRemoteRequest_DestructorCallback(const 
WeakCallbackInfo& oValue)
   {
  delete oValue.GetParameter();
   };

   static void JSRemoteRequest_execute(const FunctionCallbackInfo& 
args)
   {
  args.GetReturnValue().Set(v8::True(args.GetIsolate()));
  return;
   }
};

int main()
{
   std::string sTestScript("\"use strict\";\nvar rmtRequest = new 
RemoteRequest();\nrmtRequest.execute();");
   
   v8::Platform* pPlatform = platform::CreateDefaultPlatform();
   V8::InitializePlatform(pPlatform);
   V8::Initialize();

   Isolate::CreateParams params;
   params.array_buffer_allocator = 
v8::ArrayBuffer::Allocator::NewDefaultAllocator();
   v8::Isolate* pIsolate = v8::Isolate::New(params);

   v8::Isolate::Scope oIsolateLock(pIsolate); //Automatically handles 
Enter() and Leave() of the Isolate for us.
   v8::HandleScope IsolateScope(pIsolate);
   
   //Create an object template where our users can embed their own objects 
and such.
   //They are then baked into the global when the context is created.
   Handle oObjTemplate = ObjectTemplate::New(pIsolate);

   void* pPrivateData = new unsigned long[10]; //Make up some privates for 
tester.
   pRemoteRequestObjectTemplateEnternal = new Eternal;
   Local tmplRmtRequest;
   tmplRmtRequest = ObjectTemplate::New(pIsolate);
   tmplRmtRequest->SetInternalFieldCount(2);
  
 
tmplRmtRequest->SetCallAsFunctionHandler(RJSRemoteRequest::constructorFunctionHandler,
 
External::New(pIsolate, reinterpret_cast(pPrivateData)));
   tmplRmtRequest->Set(String::NewFromUtf8(pIsolate, "execute"), 
FunctionTemplate::New(pIsolate, RJSRemoteRequest::JSRemoteRequest_execute));
   pRemoteRequestObjectTemplateEnternal->Set(pIsolate, tmplRmtRequest);
   oObjTemplate->Set(v8::String::NewFromUtf8(pIsolate, "RemoteRequest"), 
tmplRmtRequest, ReadOnly);

   Local oContext = Context::New(pIsolate, NULL, oObjTemplate);
   Context::Scope context_scope(oContext);

   TryCatch trycatch(pIsolate);
   MaybeLocal sScript = v8::String::NewFromUtf8(pIsolate, 
sTestScript.c_str(), v8::NewStringType::kNormal, (int)sTestScript.size());
   v8::Local sLocalScriptText;
   sScript.ToLocal();
   v8::ScriptCompiler::Source source(sLocalScriptText);
   MaybeLocal oMaybeScript = 
v8::ScriptCompiler::CompileUnboundScript(pIsolate, , 
v8::ScriptCompiler::kNoCompileOptions);
   Local oScript;
   oMaybeScript.ToLocal();