Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSRPC: Support "serializing" functions by turning them into stubs #1756

Merged
merged 14 commits into from
Mar 5, 2024

Commits on Mar 5, 2024

  1. JSRPC: Don't allow serializing application class instances.

    The default behavior of V8 serialization (and structured clone, I guess) is to serialize a class instance as if it were a plain object, completely ignoring the prototype. This is probably not useful in real use cases since it is lossy. So, we'd prefer that this just fails, both because it's not useful and because we might want to introduce better behavior in the future.
    kentonv committed Mar 5, 2024
    Configuration menu
    Copy the full SHA
    96afb24 View commit details
    Browse the repository at this point in the history
  2. JSRPC: Improve the error message when failing to serialize host objects.

    V8's default implementation of `WriteHostObject()` is pretty bad. It does NOT call `ThrowDataCloneError()`; instead it throws a regular old `Error`. The error message is also very weird, it puts the characters `#<>` around the type name.
    
    This commit changes to throwing a DataCloneError with a nicer error message.
    kentonv committed Mar 5, 2024
    Configuration menu
    Copy the full SHA
    4079859 View commit details
    Browse the repository at this point in the history
  3. JSRPC: Serialize functions as RPC stubs.

    This required a V8 patch to allow functions to be treated as host objects.
    
    This commit constructs the RpcStubs but they are not actually callable yet -- there is more work to be done in subsequent commits.
    kentonv committed Mar 5, 2024
    Configuration menu
    Copy the full SHA
    e5601d9 View commit details
    Browse the repository at this point in the history
  4. JSRPC: Refactor: Pull callImpl() out as standalone function.

    We need to make RpcStub itself callable, so having this as a private method of JsRpcProperty no longer works.
    kentonv committed Mar 5, 2024
    Configuration menu
    Copy the full SHA
    35d4886 View commit details
    Browse the repository at this point in the history
  5. JSRPC: Refactor: Don't template callImpl().

    We can just use an old fashion if statement here.
    kentonv committed Mar 5, 2024
    Configuration menu
    Copy the full SHA
    05a19ec View commit details
    Browse the repository at this point in the history
  6. Configuration menu
    Copy the full SHA
    012ac44 View commit details
    Browse the repository at this point in the history
  7. JSRPC: Monkeypatch assert.rejects to not be confused by callable then…

    …ables.
    
    We're about to make JsRpcPromise be callable, which makes it a function. But `isValidThenable()` in `internal_asserts.ts` thinks that thenables cannot be callable, which means `assert.rejects` doesn't our promises. This commit monkey-patches it to solve the problem, but maybe `isValidThenable()` itself should change...
    kentonv committed Mar 5, 2024
    Configuration menu
    Copy the full SHA
    6c05025 View commit details
    Browse the repository at this point in the history
  8. JSRPC: Change internal_thenable.js isValidThenable() to accept callab…

    …le thenables.
    
    This lets us get rid of the monkey-patch in js-rpc-test.js, but I'm not completely sure if it's correct. It does seem that V8 itself accepts callable thenables, but the check here looks very explicit so I'm not sure if it has a reason.
    
    `isValidThenable()` was also requiring the presence of a `catch` method, but this is not actually a requirement of thenables, so I removed that check as well.
    kentonv committed Mar 5, 2024
    Configuration menu
    Copy the full SHA
    8d0b411 View commit details
    Browse the repository at this point in the history
  9. JSRPC: Make JsRpcStub and JsRpcPromise callable.

    This allows a stub to point to a bare function, and allows an RPC to directly return a bare function.
    kentonv committed Mar 5, 2024
    Configuration menu
    Copy the full SHA
    16fa442 View commit details
    Browse the repository at this point in the history
  10. JSRPC: Allow accessing properties of functions.

    Sometimes people make a "callable object" by creating a function and then giving it properties. We should support this.
    
    I had originally wanted to disallow this if the function's prototype had been tampered with, like:
    
    ```
    let func = () => {};
    func.__proto__ = SomeClass.prototype;
    ```
    
    This technique allows you to create a "callable class instance". In theory we ought to treat it like a user-defined class, i.e., don't support it, unless it extends JsRpcTarget.
    
    Unfortunately, it's sort of hard to distinguish "plain functions". There are multiple prototypes to check for: Function, AsyncFunction, and maybe others. I decided to give up and say that we treat all callable objects as functions.
    kentonv committed Mar 5, 2024
    Configuration menu
    Copy the full SHA
    ca221dd View commit details
    Browse the repository at this point in the history
  11. JSRPC: Make sure JsRpcPromise and JsRpcProperty aren't treated as fun…

    …ctions.
    
    Since these types are callable, `IsFunction()` returns true, but if we want to actually handle "serializing" these, we need it to work very differently. So, make sure we don't count them, and add some tests.
    
    In the future we might decide to actually support these.
    kentonv committed Mar 5, 2024
    Configuration menu
    Copy the full SHA
    3cdedb6 View commit details
    Browse the repository at this point in the history
  12. Configuration menu
    Copy the full SHA
    0bb6c64 View commit details
    Browse the repository at this point in the history
  13. Configuration menu
    Copy the full SHA
    9709be1 View commit details
    Browse the repository at this point in the history
  14. JSRPC: Test that objects with null prototypes are not accessible.

    This should be the same as a class instance of application-defined type.
    kentonv committed Mar 5, 2024
    Configuration menu
    Copy the full SHA
    cfd3d79 View commit details
    Browse the repository at this point in the history