Skip to content

vm.Script could be used to hide the source by shipping only bytecode. #11842

@hashseed

Description

@hashseed

I was playing with this idea this morning, and @bmeck asked me to put this into words.

vm.Script can be used to produce a cache into a buffer, and also used to load from existing cache produced earlier. With Ignition (bytecode interpreter) launched in V8, we could "abuse" it to only ship bytecode and hide the source.

The thing with Ignition is: once a function has been compiled, we don't need the source code anymore. The optimizing compiler can construct the graph from bytecode alone. So a script can be fully shipped as bytecode. There are a couple things missing though. For a proof-of-concept these issues can be hacked before actually thinking about changing the V8 API to accommodate.

  • Eager compilation: every function must be compiled to bytecode already. V8 doesn't do that out of the box, but there is a command line flag called --serialize_eager that you could turn on to force eager compilation if a code cache is being created.
  • The source. vm.Script expects the script source to be provided always. With Ignition we don't actually need it, but we have a checksum when deserializing to check that the source matches expectation. The checksum is simply the script length at this point. So an empty string with the same length would do.
  • Platform dependency. V8's serializer simply walks and serializes the object graph. In case of code cache, we walk the object graph of the function (SharedFunctionInfo). Depending on whether the platform is 32 or 64 bit, the object layout is different, and the code cache would look different. I'm not 100% sure whether x64 and arm64 would produce the same code cache, either.
  • Version dependency: V8's bytecode is purely internal, and not versioned. So for a different version of V8, the bytecode needs to be recompiled.
  • Function.prototype.toString() would just show a window from whatever the dummy source was provided. Duh.

Once these issues are solved, you could ship bytecode and hide the source, without worrying about crashing the optimizing compiler.

Oh and this would only work on versions where V8 uses Ignition. For example at this shameless plug.

Metadata

Metadata

Assignees

No one assigned

    Labels

    discussIssues opened for discussions and feedbacks.vmIssues and PRs related to the vm subsystem.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions