forked from facebook/hermes
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
IR instrumentation support for dynamic checking
Summary: IR instrumentation allows customizable hooks to emit code before and after certain expressions. The list of supported expressions and statements will expand, this is just adding initial support for the basic ones. In this prototype, the instrumentation calls methods on a global property, passing the input values and the result. The property is added to the global object whenever IR instrumentation support is compiled in. Currently, the only application-exposed way to build instrumented bytecode is through the `--instrument-ir` flag. Running from source or `eval` will therefore not be instrumented. Reviewed By: tmikov Differential Revision: D19206572 fbshipit-source-id: abbdfbc5512d8ea6ab6700878748b455a96b1934
- Loading branch information
1 parent
5cdc068
commit c3cc14c
Showing
19 changed files
with
499 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
/* | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
#include "IRInstrument.h" | ||
|
||
namespace hermes { | ||
|
||
#ifdef HERMES_ENABLE_IR_INSTRUMENTATION | ||
IRInstrument::IRInstrument(hermes::Module *M, hermes::IRBuilder &builder) | ||
: builder_(builder), | ||
globalName_(builder.getLiteralString("__instrument")), | ||
M_(M), | ||
enabled_(M->getContext().getCodeGenerationSettings().instrumentIR) {} | ||
|
||
IRInstrument::~IRInstrument() = default; | ||
|
||
Value *IRInstrument::getIID(ESTree::Node *node) { | ||
auto start = node->getStartLoc(); | ||
if (!start.isValid()) | ||
return builder_.getLiteralUndefined(); | ||
|
||
auto &sem = M_->getContext().getSourceErrorManager(); | ||
auto *buffer = sem.findBufferForLoc(start); | ||
uint64_t bufferId = sem.findBufferIdForLoc(start); | ||
uint64_t offset = (uint64_t)( | ||
(uintptr_t)start.getPointer() - (uintptr_t)buffer->getBufferStart()); | ||
|
||
double id = (double)((bufferId << 32) | offset); | ||
return builder_.getLiteralNumber(id); | ||
} | ||
|
||
Value *IRInstrument::invokeHook( | ||
llvm::StringRef name, | ||
llvm::ArrayRef<Value *> args) { | ||
TryLoadGlobalPropertyInst *instrument = | ||
builder_.createTryLoadGlobalPropertyInst(globalName_); | ||
auto *hook = builder_.createLoadPropertyInst(instrument, name); | ||
return builder_.createCallInst(hook, instrument, args); | ||
} | ||
|
||
Value *IRInstrument::preBinaryExpression( | ||
ESTree::BinaryExpressionNode *node, | ||
Value *left, | ||
Value *right) { | ||
if (!enabled_) | ||
return nullptr; | ||
|
||
auto *opStr = builder_.getLiteralString(node->_operator->str()); | ||
return invokeHook("preBinary", {getIID(node), opStr, left, right}); | ||
} | ||
|
||
Value *IRInstrument::postBinaryExpression( | ||
ESTree::BinaryExpressionNode *node, | ||
Value *cookie, | ||
Value *result, | ||
Value *left, | ||
Value *right) { | ||
if (!enabled_) | ||
return result; | ||
|
||
auto *opStr = builder_.getLiteralString(node->_operator->str()); | ||
return invokeHook( | ||
"postBinary", | ||
{getIID(node), undefinedIfNull(cookie), opStr, result, left, right}); | ||
return result; | ||
} | ||
|
||
Value *IRInstrument::preUnaryExpression( | ||
ESTree::UnaryExpressionNode *node, | ||
Value *operand) { | ||
if (!enabled_) | ||
return nullptr; | ||
|
||
auto *opStr = builder_.getLiteralString(node->_operator->str()); | ||
return invokeHook("preUnary", {getIID(node), opStr, operand}); | ||
} | ||
Value *IRInstrument::postUnaryExpression( | ||
ESTree::UnaryExpressionNode *node, | ||
Value *cookie, | ||
Value *result, | ||
Value *operand) { | ||
if (!enabled_) | ||
return result; | ||
|
||
auto *opStr = builder_.getLiteralString(node->_operator->str()); | ||
return invokeHook( | ||
"postUnary", | ||
{getIID(node), undefinedIfNull(cookie), opStr, result, operand}); | ||
} | ||
|
||
Value *IRInstrument::preAssignment( | ||
ESTree::AssignmentExpressionNode *node, | ||
Value *left, | ||
Value *right) { | ||
if (!enabled_) | ||
return nullptr; | ||
|
||
auto *opStr = builder_.getLiteralString(node->_operator->str()); | ||
return invokeHook( | ||
"preAssignment", {getIID(node), opStr, undefinedIfNull(left), right}); | ||
} | ||
|
||
Value *IRInstrument::postAssignment( | ||
ESTree::AssignmentExpressionNode *node, | ||
Value *cookie, | ||
Value *result, | ||
Value *left, | ||
Value *right) { | ||
if (!enabled_) | ||
return result; | ||
|
||
auto *opStr = builder_.getLiteralString(node->_operator->str()); | ||
return invokeHook( | ||
"postAssignment", | ||
{getIID(node), | ||
undefinedIfNull(cookie), | ||
opStr, | ||
result, | ||
undefinedIfNull(left), | ||
right}); | ||
} | ||
#endif // HERMES_ENABLE_IR_INSTRUMENTATION | ||
|
||
} // namespace hermes |
Oops, something went wrong.