Prepack: Invariant in ResidualHeapSerializer._getTarget()

Created on 27 Apr 2018  路  8Comments  路  Source: facebook/prepack

Minimal repro:

require('react');

__evaluatePureFunction(function() {
  "use strict";

  function FbtResult() {}
  FbtResult.prototype.$$typeof = Symbol.for("react.element");

  function fbt() {};
  function param() {};
  function plural() {
    throw new Error('no');
  }

  var React = require('react');

  function App(props) {
   return React.createElement(
     'div',
     new FbtResult(
       {},
       [param(props.foo), plural(props.bar)],
     )
   );
 }

 __optimizeReactComponentTree(App, {
   firstRenderOnly: true
 });

  module.exports = App;
});

Invariant:

https://github.com/facebook/prepack/blob/30876d5becade1dad7319682a075b6df252341a2/src/serializer/ResidualHeapSerializer.js#L688

This is likely a bug in Prepack, not your code. Feel free to open an issue on GitHub.
    at invariant (/Users/gaearon/p/prepack/src/invariant.js:16:15)
    at ResidualHeapSerializer._getTarget (/Users/gaearon/p/prepack/src/serializer/ResidualHeapSerializer.js:688:15)
    at ResidualHeapSerializer.serializeValue (/Users/gaearon/p/prepack/src/serializer/ResidualHeapSerializer.js:914:23)
    at emitter.emitNowOrAfterWaitingForDependencies (/Users/gaearon/p/prepack/src/serializer/ResidualHeapSerializer.js:328:34)
    at Emitter.emitAfterWaiting (/Users/gaearon/p/prepack/src/serializer/Emitter.js:391:9)
    at Emitter.emitNowOrAfterWaitingForDependencies (/Users/gaearon/p/prepack/src/serializer/Emitter.js:433:10)
    at Emitter._processValue (/Users/gaearon/p/prepack/src/serializer/Emitter.js:241:14)
    at Emitter.endEmitting (/Users/gaearon/p/prepack/src/serializer/Emitter.js:154:12)
    at ResidualHeapSerializer.serializeValue (/Users/gaearon/p/prepack/src/serializer/ResidualHeapSerializer.js:954:18)
    at emitter.emitNowOrAfterWaitingForDependencies (/Users/gaearon/p/prepack/src/serializer/ResidualHeapSerializer.js:352:14)
bug react compiler

All 8 comments

This is failing because Symbol.for("react.element") has been assigned to the object, making the visitor think it's a ReactElement.

Hmm. This is fun.

Can we make it only treat objects that have an own props property as elements (in addition to the brand check)?

@gaearon We can refine the isReactElement check to ensure the object has a type and props too.

Sounds good to me

Why is the failure so obscure? The visitor thought it's an element, and what then?

It's obscure because we skip looking at the prototype if it's a ReactElement, because we don't want to serialize the prototype in the case of using JSX sugar. In this case, we're creating an object via a function constructor, so it goes a different route via the normal serialization of ReactElement, and instead sees it as a function first then object after.

The getTarget issue from this PR will be resolved from https://github.com/facebook/prepack/pull/1810. We then get an invariant from this above test case:

Invariant Violation: an abstract value with an identifier "_$1" was referenced before being declared

Fixed.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

obenjiro picture obenjiro  路  4Comments

matheusml picture matheusml  路  8Comments

sebmarkbage picture sebmarkbage  路  6Comments

jtenner picture jtenner  路  5Comments

phpnode picture phpnode  路  3Comments