How to retrieve a class defined in a module?

47 views
Skip to first unread message

Ben Ernst

unread,
Nov 16, 2020, 7:11:29 PM11/16/20
to v8-users
I am migrating my V8 code from using "plain scripts" to using "ES6 Modules". There are a few concepts that I am struggling with. 

First, how might I retrieve a class definition defined in a module? Previously I would have used the "global" object on the "context" (i.e. context->Global()), and found the class definition there. I can't find a good example on how to do that in a module. I am experimenting with Module::GetModuleNamespace(), but I'm not sure that I'm on the right track.

Second, am I allowed to take a persistent handle to a module? I am finding that after restoring a module from a persistent handle, I encounter the failure below.

#
# Fatal error in C:\621300de\v8\src/api/api-inl.h, line 128
# Debug check failed: allow_empty_handle || that != nullptr.
#
#
#
#FailureMessage Object: 0000006114FBC2E0
==== C stack trace ===============================

        v8::base::debug::StackTrace::StackTrace [0x0,000,7FF,60D,F82,80B+27]
        v8::platform::DefaultPlatform::PostJob [0x0,000,7FF,60D,F7F,1E1+401]
        V8_Fatal [0x0,000,7FF,60C,251,B87+167]
        v8::base::PrintCheckOperand<unsigned __int64> [0x0,000,7FF,60C,251,683+627]
        v8::Module::GetStatus [0x0,000,7FF,60C,1E0,3FD+141]
        v8::Module::GetModuleNamespace [0x0,000,7FF,60C,1D1,243+19]

Camillo Bruni

unread,
Nov 17, 2020, 4:24:31 AM11/17/20
to v8-users
Hi,

The ModuleNamespace object is the proper choice, you can have a look at the existing tests.
For future reference, you will usually find (a bit hidden and obscure, I agree) existing tests in V8's test-api.cc.

Could you provide some more example code for the error you get with persistent handles?

cheers,
Camillo

--
--
v8-users mailing list
v8-u...@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+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/v8-users/6e1f91bb-9d1b-4e3e-b772-c1cdf71afb06n%40googlegroups.com.
Camillo Bruni | Software Engineer, V8 | Google Germany GmbH | Erika-Mann Str. 33, 80636 München 

Registergericht und -nummer: Hamburg, HRB 86891 | Sitz der Gesellschaft: Hamburg | Geschäftsführer: Paul Manicle, Halimah DeLaine Prado

Diese E-Mail ist vertraulich. Falls Ssie diese fälschlicherweise erhalten haben sollten, leiten Sie diese bitte nicht an jemand anderes weiter, löschen Sie alle Kopien und Anhänge davon und lassen Sie mich bitte wissen, dass die E-Mail an die falsche Person gesendet wurde.  This e-mail is confidential. If you received this communication by mistake, please don't forward it to anyone else, please erase all copies and attachments, and please let me know that it has gone to the wrong person.

Ben Ernst

unread,
Nov 17, 2020, 5:51:25 AM11/17/20
to v8-u...@googlegroups.com
Thank you for the advice Camillo, the test you referred me to is very helpful. I will prepare a good code sample and come back to this conversation.

Regards,
Ben


Ben Ernst

unread,
Nov 22, 2020, 6:44:55 AM11/22/20
to v8-users
Thanks for the advice, that got me back on track. The failure mentioned in my original post only occurs when there's nothing at all exported from the module. I speculate the namespace object gets garbage collected in that situation. When I tested with actual valid modules, everything works fine.
Thanks again,
Ben

Ben Ernst

unread,
Nov 27, 2020, 4:59:00 AM11/27/20
to v8-users
There's one thing I'm struggling with here. Given the simple class definition below, using the V8 C++ API I can call the ordinary function "lamingtonsIsUndefined", but how would I call the accessor "get numberOfLamingtons()"?
Many thanks in advance,
Ben


export class DemonstrationClass {
constructor(lamingtons) {
this.lamingtons = lamingtons
}
get numberOfLamingtons() {
return this.lamingtons
}
lamingtonsIsUndefined(){
return this.lamingtons === undefined
}
}

Alex Kodat

unread,
Nov 27, 2020, 8:04:26 AM11/27/20
to v8-users
You wouldn't call it any more than you "call" it in JavaScript. You just get the value via the Object Get function: 
Local<Value> pastries = object->Get(context, String::NewFromUtf8( isolate, "lamingtons").ToLocalChecked());

Ben Ernst

unread,
Nov 27, 2020, 6:08:26 PM11/27/20
to v8-users
Thanks for that thought Alex! Drafting a reply to you led me to the answer, which is obvious in hindsight.
Yes, I could just get "lamingtons" in this case, but that wouldn't help me if it was a non-trivial accessor. In javascript I would be able to call "instance.numberOfLamingtons". In this case, I can simply call "Get" with value "numberOfLamingtons". Yes, obvious in hindsight. The code ends up looking something like the below. Thanks again, thoroughly appreciate the help.
Ben


    // Call an accessor function on the instance.
    v8::Local<v8::Value> lamingtons;
    CHECK(instance->Get(context, ToV8Value(isolate, "numberOfLamingtons")).ToLocal(&lamingtons));
    std::cout << ConvertTo<double>(*isolate, lamingtons->ToNumber(context).ToLocalChecked()) << std::endl;
Reply all
Reply to author
Forward
0 new messages