Skip to content
This repository has been archived by the owner on Feb 12, 2022. It is now read-only.

Native Values That Are Not Allowed to Serialize #444

Open
sebmarkbage opened this issue Apr 21, 2017 · 4 comments
Open

Native Values That Are Not Allowed to Serialize #444

sebmarkbage opened this issue Apr 21, 2017 · 4 comments

Comments

@sebmarkbage
Copy link
Contributor

I used to have a magic string for this but we can do better. It would be good to have a materialized value that can be read and used as any other value, but if it ever ends up in the serialized output it should throw.

An example of this is a native file handle. It can be valid to use it during compilation such as in Node's start up phase. However, it will be invalid by the time the application revives. So it can only be temporary.

I used to add this to the module system cache so that if it ever got serialized, I'd know to fix it so that it can be fully cleaned up at the end rather than accidentally live with a bloated output.

@NTillmann
Copy link
Contributor

(Summarizing offline discussion with Sebastian.)
The right way of modeling this would be through abstract values. However, Prepack's symbolic execution machinery isn't complete enough yet.
So in the short term, we could tag a ConcreteValue as not-serializable, and then the serializer could complain if it comes across it. This might work, but is problematic as non-object primitive values only have an incidental identity in Prepack.

@sebmarkbage
Copy link
Contributor Author

I thought of a name for this API: __poison(concreteValue).

@NTillmann
Copy link
Contributor

Recently, ObjectValue got a new internal slot in Prepack: refuseSerialization. This is quite related to the original idea here...

It should be straightforward...

  • to generalize refuseSerialization to potentially apply to all values, and
  • to implement the suggested __poison(concreteValue) API in src/intrinsics/prepack/global.js.

In this approach, without involving AbstractValue, what's a bit shaky is when other values are derived from it. For example, if the poisoned value is a number and we add one to it, I feel like the resulting value should also be poisoned. This is similar to taint tracking. Then we also have to worry about branches getting tainted, and soon the entire heap is tainted... Maybe @sebmarkbage has some more thoughts on this? Is only implementing this for ObjectValue in fact a good compromise?

@sebmarkbage
Copy link
Contributor Author

I think there are two different use cases for primitives to be tainted like this.

  1. To avoid accidentally serialize temporary values such as file handles or user data. Those things probably could get some help from taint tracking.

  2. To avoid accidentally over serializing bloated code that is meant to be folded away. In this scenario, you explicitly want to derive a new value out of the original, but the original shouldn't be reachable once you've done that. For example, you can preevaluate a template string to generate code, but once you've done that you don't need the original template string anymore.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants