Skip to content

Commit

Permalink
Allow compileJS to take optional source map
Browse files Browse the repository at this point in the history
Summary: `compileJS` has an overloaded method to take the source map (optionally).

Reviewed By: jpporto

Differential Revision: D39456752

fbshipit-source-id: c49fa9b65ea34f17c70923c9546ec2f1aa063f7e
  • Loading branch information
jdlehman authored and facebook-github-bot committed Sep 14, 2022
1 parent d449a76 commit aa8f116
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 3 deletions.
17 changes: 15 additions & 2 deletions API/hermes/CompileJS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "hermes/BCGen/HBC/BytecodeProviderFromSrc.h"
#include "hermes/Optimizer/PassManager/Pipeline.h"
#include "hermes/SourceMap/SourceMapParser.h"
#include "hermes/Support/Algorithms.h"

#include "llvh/Support/SHA1.h"
Expand Down Expand Up @@ -47,17 +48,29 @@ bool compileJS(
std::string &bytecode,
bool optimize,
bool emitAsyncBreakCheck,
DiagnosticHandler *diagHandler) {
DiagnosticHandler *diagHandler,
std::optional<std::string_view> sourceMapBuf) {
hbc::CompileFlags flags{};
flags.format = EmitBundle;
flags.emitAsyncBreakCheck = emitAsyncBreakCheck;

std::unique_ptr<hermes::SourceMap> sourceMap{};
// parse the source map if one was provided
if (sourceMapBuf.has_value()) {
hermes::SourceErrorManager sm;
sourceMap = hermes::SourceMapParser::parse(
llvh::StringRef{sourceMapBuf->data(), sourceMapBuf->size()}, sm);
if (!sourceMap) {
return false;
}
}

// Note that we are relying the zero termination provided by str.data(),
// because the parser requires it.
auto res = hbc::BCProviderFromSrc::createBCProviderFromSrc(
std::make_unique<hermes::Buffer>((const uint8_t *)str.data(), str.size()),
sourceURL,
nullptr /* sourceMap */,
std::move(sourceMap),
flags,
{} /* scopeChain */,
diagHandler ? diagHandlerAdapter : nullptr,
Expand Down
5 changes: 4 additions & 1 deletion API/hermes/CompileJS.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#ifndef HERMES_COMPILEJS_H
#define HERMES_COMPILEJS_H

#include <optional>
#include <string>
#include <vector>

Expand Down Expand Up @@ -44,13 +45,15 @@ class DiagnosticHandler {
/// \param emitAsyncBreakCheck this will make the bytecode interruptable.
/// \param diagHandler if not null, receives any and all errors, warnings and
/// notes produced during compilation.
/// \param sourceMapBuf optional source map string.
bool compileJS(
const std::string &str,
const std::string &sourceURL,
std::string &bytecode,
bool optimize,
bool emitAsyncBreakCheck,
DiagnosticHandler *diagHandler);
DiagnosticHandler *diagHandler,
std::optional<std::string_view> sourceMapBuf = std::nullopt);

bool compileJS(
const std::string &str,
Expand Down
59 changes: 59 additions & 0 deletions unittests/API/APITest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,65 @@ TEST_F(HermesRuntimeTest, PreparedJavaScriptBytecodeTest) {
EXPECT_EQ(rt->global().getProperty(*rt, "q").getNumber(), 2);
}

TEST_F(HermesRuntimeTest, CompileWithSourceMapTest) {
/* original source:
const a: number = 12;
class MyClass {
val: number;
constructor(val: number) {
this.val = val;
}
doSomething(a: number, b: number) {
invalidRef.sum = a + b + this.val;
}
}
const c = new MyClass(3);
c.doSomething(a, 15);*/
const char *TestSource = R"#('use strict';
var a = 12;
var MyClass = /** @class */ (function () {
function MyClass(val) {
this.val = val;
}
MyClass.prototype.doSomething = function (a, b) {
invalidRef.sum = a + b + this.val;
};
return MyClass;
}());
var c = new MyClass(3);
c.doSomething(a, 15);
//# sourceMappingURL=script.js.map)#";
const char *TestSourceMap = R"#({
"version":3,
"file":"script.js",
"sourceRoot":"",
"sources":["script.ts"],
"names":[],
"mappings": ";AAAA,IAAM,CAAC,GAAW,EAAE,CAAC;AACrB;IAEI,iBAAY,GAAW;QACnB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACnB,CAAC;IACD,6BAAW,GAAX,UAAY,CAAS,EAAE,CAAS;QAC5B,UAAU,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC;IACtC,CAAC;IACL,cAAC;AAAD,CAAC,AARD,IAQC;AACD,IAAM,CAAC,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;AACzB,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC"
})#";

std::string bytecode;
ASSERT_TRUE(hermes::compileJS(
TestSource,
"script.js",
bytecode,
true,
true,
nullptr,
std::optional<std::string_view>(TestSourceMap)));
EXPECT_TRUE(HermesRuntime::isHermesBytecode(
reinterpret_cast<const uint8_t *>(bytecode.data()), bytecode.size()));
try {
rt->evaluateJavaScript(
std::unique_ptr<StringBuffer>(new StringBuffer(bytecode)), "");
FAIL() << "Expected JSIException";
} catch (const facebook::jsi::JSIException &err) {
EXPECT_STREQ(
"Property 'invalidRef' doesn't exist\n\nReferenceError: Property 'invalidRef' doesn't exist\n at anonymous (script.ts:8:9)\n at global (script.ts:12:14)",
err.what());
}
}

TEST_F(HermesRuntimeTest, JumpTableBytecodeTest) {
std::string code = R"xyz(
(function(){
Expand Down

0 comments on commit aa8f116

Please sign in to comment.