Repeated module evaluation.

77 views
Skip to first unread message

Jane Chen

unread,
Feb 12, 2019, 8:11:21 PM2/12/19
to v8-users
Embedding v8 6.7.

I found the following test in test-modules.cc:

    CHECK(module->Evaluate(env.local())
              .ToLocalChecked()
              ->StrictEquals(v8_str("gaga")));
    CHECK_EQ(Module::kEvaluated, module->GetStatus());
    CHECK(module->Evaluate(env.local()).ToLocalChecked()->IsUndefined());

and it is consistent with what I'm seeing.  Basically, evaluating an evaluated module returns undefined.  I don't get the rational for this behavior.  Once a module is evaluated, it is no good for evaluation?  Then how am I supposed to re-use a cached module?  Re-instantiating it doesn't seem to help.

Adam Klein

unread,
Feb 20, 2019, 2:54:26 PM2/20/19
to v8-users
Modules are designed (in the JavaScript spec) to only have their top-level code run once. To  "re-use" a cached module, the expectation is that other modules would use imports to access the exports of that module. In particular, in your code snippet, you'd return the already-evaluated module from the ResolveCallback passed to the module that wishes to import from it.

If what you want to do is compile some code and run it multiple times, a v8::Script is probably want you want instead.

--
--
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.
For more options, visit https://groups.google.com/d/optout.

ClearScript Developers

unread,
Jun 13, 2019, 10:12:14 AM6/13/19
to v8-users
Sorry to revive this thread, but we're encountering the same issue.

v8::Script is not a replacement for v8::Module; for one thing, scripts can't import modules :)

In any case, V8's API seems deficient here. Modules can be imported specifically for their side effects. There's even unique syntax for that (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#Import_a_module_for_its_side_effects_only). And since side effects can be local to the evaluation context, it should be possible to evaluate a module in multiple contexts.

Opinions?
To unsubscribe from this group and stop receiving emails from it, send an email to v8-u...@googlegroups.com.

Adam Klein

unread,
Jun 19, 2019, 5:21:43 PM6/19/19
to v8-users
When you say "local to the evaluation context", what do you mean? Modules can't have side-effects on the lexical top-level scope of the importing module; they can only affect the broader "realm" (in ECMAScript spec terms), the v8::Context (in V8 API terms) or the mutable global state (in more common terms). The current API is designed to allow one evaluation per v8::Context, since part of Instantiation is tying a v8::Module to a v8::Context. So if you instantatiate a module in multiple context, multiple evaluations should still work.

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/a7260cfa-cc60-4870-b11d-b2d00c79eb01%40googlegroups.com.

ClearScript Developers

unread,
Jun 20, 2019, 12:27:57 AM6/20/19
to v8-users
"When you say "local to the evaluation context", what do you mean?"

Suppose you have an isolate with two contexts, C1 and C2, and a module whose evaluation produces side effects. Once you've evaluated the module in C1, there's no way to apply its side effects to C2. You can import it into C2, but doing so doesn't replicate the side effects. You can use its exports in C2, but they won't work correctly if they rely on the side effects.

"The current API is designed to allow one evaluation per v8::Context"

But it doesn't do that. It allows one evaluation per isolate. Evaluating a module in one context breaks it for others.
To unsubscribe from this group and stop receiving emails from it, send an email to v8-u...@googlegroups.com.

Adam Klein

unread,
Jun 20, 2019, 1:28:14 PM6/20/19
to v8-users
On Wed, Jun 19, 2019 at 9:27 PM ClearScript Developers <clearsc...@gmail.com> wrote:
"When you say "local to the evaluation context", what do you mean?"
Suppose you have an isolate with two contexts, C1 and C2, and a module whose evaluation produces side effects. Once you've evaluated the module in C1, there's no way to apply its side effects to C2. You can import it into C2, but doing so doesn't replicate the side effects. You can use its exports in C2, but they won't work correctly if they rely on the side effects.

"The current API is designed to allow one evaluation per v8::Context"

But it doesn't do that. It allows one evaluation per isolate. Evaluating a module in one context breaks it for others.

What I'd recommend is to call CompileModule() again to get another Module object; I believe this should hit the in-memory cache and be very fast, and should let you go back through the Instantiate/Evaluate cycle in C2.
 
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/55686a62-e8dc-439b-9acb-f3edb6ddf60c%40googlegroups.com.

ClearScript Developers

unread,
Jun 22, 2019, 9:16:02 PM6/22/19
to v8-users
"What I'd recommend is to call CompileModule() again to get another Module object [...]"

Yes, sure, that should work, and the recompilation overhead is hardly a concern for us. It's just an unfortunate API design that almost invites incorrect usage.

A simple enhancement might be for V8 to throw an exception when an imported module has already been evaluated in a different context.
Reply all
Reply to author
Forward
0 new messages