-
Notifications
You must be signed in to change notification settings - Fork 645
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
9,270 additions
and
2 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
// This code was adapted from https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.h | ||
//----------------------------------------------------------------------------- | ||
// MurmurHash3 was written by Austin Appleby, and is placed in the public | ||
// domain. The author hereby disclaims copyright to this source code. | ||
#include "MurmurHash.h" | ||
#include <stdlib.h> | ||
|
||
#if defined(_MSC_VER) | ||
|
||
#define FORCE_INLINE __forceinline | ||
#define ROTL64(x, y) _rotl64(x, y) | ||
#define BIG_CONSTANT(x) (x) | ||
|
||
#else // defined(_MSC_VER) | ||
|
||
#define FORCE_INLINE inline __attribute__((always_inline)) | ||
inline uint64_t rotl64(uint64_t x, int8_t r) { | ||
return (x << r) | (x >> (64 - r)); | ||
} | ||
#define ROTL64(x, y) rotl64(x, y) | ||
#define BIG_CONSTANT(x) (x##LLU) | ||
|
||
#endif // !defined(_MSC_VER) | ||
|
||
using namespace std; | ||
|
||
FORCE_INLINE uint64_t fmix64(uint64_t k) { | ||
k ^= k >> 33; | ||
k *= BIG_CONSTANT(0xff51afd7ed558ccd); | ||
k ^= k >> 33; | ||
k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53); | ||
k ^= k >> 33; | ||
|
||
return k; | ||
} | ||
|
||
bool isAscii(uint64_t k) { | ||
return (k & 0x8080808080808080) == 0ull; | ||
} | ||
|
||
bool MurmurHash3_x64_128(const void *key, const int len, const uint32_t seed, void *out) { | ||
const uint8_t *data = (const uint8_t *)key; | ||
const int nblocks = len / 16; | ||
|
||
uint64_t h1 = seed; | ||
uint64_t h2 = seed; | ||
|
||
const uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5); | ||
const uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f); | ||
|
||
//---------- | ||
// body | ||
|
||
const uint64_t *blocks = (const uint64_t *)(data); | ||
|
||
bool isAsciiString{true}; | ||
for (int i = 0; i < nblocks; i++) { | ||
uint64_t k1 = blocks[i * 2 + 0]; | ||
uint64_t k2 = blocks[i * 2 + 1]; | ||
|
||
isAsciiString &= isAscii(k1) && isAscii(k2); | ||
|
||
k1 *= c1; | ||
k1 = ROTL64(k1, 31); | ||
k1 *= c2; | ||
h1 ^= k1; | ||
|
||
h1 = ROTL64(h1, 27); | ||
h1 += h2; | ||
h1 = h1 * 5 + 0x52dce729; | ||
|
||
k2 *= c2; | ||
k2 = ROTL64(k2, 33); | ||
k2 *= c1; | ||
h2 ^= k2; | ||
|
||
h2 = ROTL64(h2, 31); | ||
h2 += h1; | ||
h2 = h2 * 5 + 0x38495ab5; | ||
} | ||
|
||
//---------- | ||
// tail | ||
|
||
const uint8_t *tail = (const uint8_t *)(data + nblocks * 16); | ||
|
||
for (auto i = 0; i < len % 16; i++) { | ||
if (tail[i] > 127) { | ||
isAsciiString = false; | ||
break; | ||
} | ||
} | ||
|
||
uint64_t k1 = 0; | ||
uint64_t k2 = 0; | ||
|
||
switch (len & 15) { | ||
case 15: | ||
k2 ^= ((uint64_t)tail[14]) << 48; | ||
case 14: | ||
k2 ^= ((uint64_t)tail[13]) << 40; | ||
case 13: | ||
k2 ^= ((uint64_t)tail[12]) << 32; | ||
case 12: | ||
k2 ^= ((uint64_t)tail[11]) << 24; | ||
case 11: | ||
k2 ^= ((uint64_t)tail[10]) << 16; | ||
case 10: | ||
k2 ^= ((uint64_t)tail[9]) << 8; | ||
case 9: | ||
k2 ^= ((uint64_t)tail[8]) << 0; | ||
k2 *= c2; | ||
k2 = ROTL64(k2, 33); | ||
k2 *= c1; | ||
h2 ^= k2; | ||
|
||
case 8: | ||
k1 ^= ((uint64_t)tail[7]) << 56; | ||
case 7: | ||
k1 ^= ((uint64_t)tail[6]) << 48; | ||
case 6: | ||
k1 ^= ((uint64_t)tail[5]) << 40; | ||
case 5: | ||
k1 ^= ((uint64_t)tail[4]) << 32; | ||
case 4: | ||
k1 ^= ((uint64_t)tail[3]) << 24; | ||
case 3: | ||
k1 ^= ((uint64_t)tail[2]) << 16; | ||
case 2: | ||
k1 ^= ((uint64_t)tail[1]) << 8; | ||
case 1: | ||
k1 ^= ((uint64_t)tail[0]) << 0; | ||
k1 *= c1; | ||
k1 = ROTL64(k1, 31); | ||
k1 *= c2; | ||
h1 ^= k1; | ||
}; | ||
|
||
//---------- | ||
// finalization | ||
|
||
h1 ^= len; | ||
h2 ^= len; | ||
|
||
h1 += h2; | ||
h2 += h1; | ||
|
||
h1 = fmix64(h1); | ||
h2 = fmix64(h2); | ||
|
||
h1 += h2; | ||
h2 += h1; | ||
|
||
((uint64_t *)out)[0] = h1; | ||
((uint64_t *)out)[1] = h2; | ||
|
||
return isAsciiString; | ||
} | ||
|
||
bool murmurhash(const uint8_t *key, size_t length, uint64_t &hash) { | ||
uint64_t hashes[2]; | ||
|
||
bool isAscii = MurmurHash3_x64_128(key, length, 31, &hashes); | ||
|
||
hash = hashes[0]; | ||
|
||
return isAscii; | ||
} |
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,10 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
#pragma once | ||
|
||
#include <cstddef> | ||
#include <cstdint> | ||
|
||
// Computes the hash of key using MurmurHash3 algorithm, the value is planced in the "hash" output parameter | ||
// The function returns whether or not key is comprised of only ASCII characters (<=127) | ||
bool murmurhash(const uint8_t *key, size_t length, uint64_t &hash); |
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,79 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
#pragma once | ||
|
||
#include <jsi/jsi.h> | ||
#include <memory> | ||
|
||
namespace facebook { | ||
namespace jsi { | ||
|
||
// Integer type as it's persist friendly. | ||
using ScriptVersion_t = uint64_t; // It should be std::optional<uint64_t> once we have c++17 available everywhere. Until | ||
// then, 0 implies versioning not available. | ||
using JSRuntimeVersion_t = uint64_t; // 0 implies version can't be computed. We assert whenever that happens. | ||
|
||
struct VersionedBuffer { | ||
std::shared_ptr<const facebook::jsi::Buffer> buffer; | ||
ScriptVersion_t version; | ||
}; | ||
|
||
struct ScriptSignature { | ||
std::string url; | ||
ScriptVersion_t version; | ||
}; | ||
|
||
struct JSRuntimeSignature { | ||
std::string runtimeName; // e.g. Chakra, V8 | ||
JSRuntimeVersion_t version; | ||
}; | ||
|
||
// Most JSI::Runtime implementation offer some form of prepared JavaScript which offers better performance | ||
// characteristics when loading comparing to plain JavaScript. Embedders can provide an instance of this interface | ||
// (through JSI::Runtime implementation's factory method), to enable persistance of the prepared script and retrieval on | ||
// subsequent evaluation of a script. | ||
struct PreparedScriptStore { | ||
virtual ~PreparedScriptStore() = default; | ||
|
||
// Try to retrieve the prepared javascript for a given combination of script & runtime. | ||
// scriptSignature : Javascript url and version | ||
// RuntimeSignature : Javascript engine type and version | ||
// prepareTag : Custom tag to uniquely identify JS engine specific preparation schemes. It is usually useful while | ||
// experimentation and can be null. It is possible that no prepared script is available for a given script & runtime | ||
// signature. This method should null if so | ||
virtual std::shared_ptr<const facebook::jsi::Buffer> tryGetPreparedScript( | ||
const ScriptSignature &scriptSignature, | ||
const JSRuntimeSignature &runtimeSignature, | ||
const char *prepareTag // Optional tag. For e.g. eagerly evaluated vs lazy cache. | ||
) noexcept = 0; | ||
|
||
// Persist the prepared javascript for a given combination of script & runtime. | ||
// scriptSignature : Javascript url and version | ||
// RuntimeSignature : Javascript engine type and version | ||
// prepareTag : Custom tag to uniquely identify JS engine specific preparation schemes. It is usually useful while | ||
// experimentation and can be null. It is possible that no prepared script is available for a given script & runtime | ||
// signature. This method should null if so Any failure in persistance should be identified during the subsequent | ||
// retrieval through the integrity mechanism which must be put into the storage. | ||
virtual void persistPreparedScript( | ||
std::shared_ptr<const facebook::jsi::Buffer> preparedScript, | ||
const ScriptSignature &scriptMetadata, | ||
const JSRuntimeSignature &runtimeMetadata, | ||
const char *prepareTag // Optional tag. For e.g. eagerly evaluated vs lazy cache. | ||
) noexcept = 0; | ||
}; | ||
|
||
// JSI::Runtime implementation must be provided an instance on this interface to enable version sensitive capabilities | ||
// such as usage of pre-prepared javascript script. Alternatively, this entity can be used to directly provide the | ||
// Javascript buffer and rich metadata to the JSI::Runtime instance. | ||
struct ScriptStore { | ||
virtual ~ScriptStore() = default; | ||
|
||
// Return the Javascript buffer and version corresponding to a given url. | ||
virtual VersionedBuffer getVersionedScript(const std::string &url) noexcept = 0; | ||
|
||
// Return the version of the Javascript buffer corresponding to a given url. | ||
virtual ScriptVersion_t getScriptVersion(const std::string &url) noexcept = 0; | ||
}; | ||
|
||
} // namespace jsi | ||
} // namespace facebook |
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,85 @@ | ||
/* | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
#ifndef HERMES_HERMES_API_H | ||
#define HERMES_HERMES_API_H | ||
|
||
#include "js_runtime_api.h" | ||
|
||
EXTERN_C_START | ||
|
||
typedef struct hermes_local_connection_s *hermes_local_connection; | ||
typedef struct hermes_remote_connection_s *hermes_remote_connection; | ||
|
||
//============================================================================= | ||
// jsr_runtime | ||
//============================================================================= | ||
|
||
JSR_API hermes_dump_crash_data(jsr_runtime runtime, int32_t fd); | ||
JSR_API hermes_sampling_profiler_enable(); | ||
JSR_API hermes_sampling_profiler_disable(); | ||
JSR_API hermes_sampling_profiler_add(jsr_runtime runtime); | ||
JSR_API hermes_sampling_profiler_remove(jsr_runtime runtime); | ||
JSR_API hermes_sampling_profiler_dump_to_file(const char *filename); | ||
|
||
//============================================================================= | ||
// jsr_config | ||
//============================================================================= | ||
|
||
JSR_API hermes_config_enable_default_crash_handler( | ||
jsr_config config, | ||
bool value); | ||
|
||
//============================================================================= | ||
// Setting inspector singleton | ||
//============================================================================= | ||
|
||
typedef int32_t(NAPI_CDECL *hermes_inspector_add_page_cb)( | ||
const char *title, | ||
const char *vm, | ||
void *connectFunc); | ||
|
||
typedef void(NAPI_CDECL *hermes_inspector_remove_page_cb)(int32_t page_id); | ||
|
||
JSR_API hermes_set_inspector( | ||
hermes_inspector_add_page_cb add_page_cb, | ||
hermes_inspector_remove_page_cb remove_page_cb); | ||
|
||
//============================================================================= | ||
// Local and remote inspector connections. | ||
// Local is defined in Hermes VM, Remote is defined by inspector outside of VM. | ||
//============================================================================= | ||
|
||
typedef void(NAPI_CDECL *hermes_remote_connection_send_message_cb)( | ||
hermes_remote_connection remote_connection, | ||
const char *message); | ||
|
||
typedef void(NAPI_CDECL *hermes_remote_connection_disconnect_cb)( | ||
hermes_remote_connection remote_connection); | ||
|
||
JSR_API hermes_create_local_connection( | ||
void *connect_func, | ||
hermes_remote_connection remote_connection, | ||
hermes_remote_connection_send_message_cb on_send_message_cb, | ||
hermes_remote_connection_disconnect_cb on_disconnect_cb, | ||
jsr_data_delete_cb on_delete_cb, | ||
void *deleter_data, | ||
hermes_local_connection *local_connection); | ||
|
||
JSR_API hermes_delete_local_connection( | ||
hermes_local_connection local_connection); | ||
|
||
JSR_API hermes_local_connection_send_message( | ||
hermes_local_connection local_connection, | ||
const char *message); | ||
|
||
JSR_API hermes_local_connection_disconnect( | ||
hermes_local_connection local_connection); | ||
|
||
EXTERN_C_END | ||
|
||
#endif // !HERMES_HERMES_API_H |
Oops, something went wrong.