From 827146302ad8d6ce5e41307461c822a29a6dcb37 Mon Sep 17 00:00:00 2001 From: Sapan Bhatia Date: Tue, 18 Sep 2018 13:40:51 -0700 Subject: [PATCH] Helper to inspect values at a particular AST node (#2554) Summary: This is a helper for inspecting values at a particular node in the AST. E.g. ```js let n = global.__abstract ? __abstract("number", "10") : 10; let x = {foo:1}; let y = {foo:2}; let c = __abstract("boolean", "c"); let i = 0; let obj = {}; do { i++; obj.j = i; obj.foo = c ? x : y; } while (i < n); __debugValue(obj); // Breaks with obj in context inspect = function() { return i + " " + obj.j; }; ``` Pull Request resolved: https://github.com/facebook/prepack/pull/2554 Differential Revision: D9922908 Pulled By: sb98052 fbshipit-source-id: dab9cae64a461283d8dec7f0bb7f8fae87a01c78 --- src/intrinsics/prepack/global.js | 19 +++++++++++++++++++ src/serializer/ResidualOperationSerializer.js | 3 +++ src/utils/generator.js | 1 + test/serializer/abstract/DebugValue.js | 9 +++++++++ 4 files changed, 32 insertions(+) create mode 100644 test/serializer/abstract/DebugValue.js diff --git a/src/intrinsics/prepack/global.js b/src/intrinsics/prepack/global.js index 7785c1005..881a5aa54 100644 --- a/src/intrinsics/prepack/global.js +++ b/src/intrinsics/prepack/global.js @@ -398,6 +398,25 @@ export default function(realm: Realm): void { }) ); + // Helper function for Prepack developers inspect a value + // when interpreting a particular node in the AST. + global.$DefineOwnProperty( + "__debugValue", + new PropertyDescriptor({ + value: createNativeFunctionForResidualInjection( + "__debugValue", + ([v, s]): void => { + debugger; // eslint-disable-line no-debugger + }, + createOperationDescriptor("NOOP"), + 2 + ), + writable: true, + enumerable: false, + configurable: true, + }) + ); + // Helper function that identifies a computation that must remain part of the residual program and cannot be partially evaluated, // e.g. because it contains a loop over abstract values. // __residual(typeNameOrTemplate, function, arg0, arg1, ...) creates a new abstract value diff --git a/src/serializer/ResidualOperationSerializer.js b/src/serializer/ResidualOperationSerializer.js index 5b18648e3..0a8394f08 100644 --- a/src/serializer/ResidualOperationSerializer.js +++ b/src/serializer/ResidualOperationSerializer.js @@ -133,6 +133,9 @@ export class ResidualOperationSerializer { case "LOCAL_ASSIGNMENT": babelNode = this._serializeLocalAssignment(data, nodes, context, valuesToProcess); break; + case "NOOP": + babelNode = t.emptyStatement(); + break; case "OBJECT_SET_PARTIAL": babelNode = this._serializeObjectSetPartial(data, nodes); break; diff --git a/src/utils/generator.js b/src/utils/generator.js index 3d0be7f9e..53b28a44f 100644 --- a/src/utils/generator.js +++ b/src/utils/generator.js @@ -103,6 +103,7 @@ export type OperationDescriptorType = | "LOGICAL_PROPERTY_ASSIGNMENT" | "MODULES_REQUIRE" | "NEW_EXPRESSION" + | "NOOP" | "OBJECT_ASSIGN" | "OBJECT_GET_PARTIAL" | "OBJECT_PROTO_GET_OWN_PROPERTY_DESCRIPTOR" diff --git a/test/serializer/abstract/DebugValue.js b/test/serializer/abstract/DebugValue.js new file mode 100644 index 000000000..27dc5b2f0 --- /dev/null +++ b/test/serializer/abstract/DebugValue.js @@ -0,0 +1,9 @@ +let x = global.__abstract ? __abstract("boolean", "true") : true; +let ob = x ? { a: 1 } : { b: 2 }; + +global.__abstract ? __debugValue(ob) : {}; +global.__abstract ? __debugValue([ob, x]) : {}; + +inspect = function() { + return true; +};