diff options
author | 2021-07-30 00:50:29 -0700 | |
---|---|---|
committer | 2021-07-30 00:50:29 -0700 | |
commit | 7245f90b2dd686acacb9c8ee03f5d8fb05e09aeb (patch) | |
tree | 120d6d093ba609f93f1514fde16c0a3402855336 /src/javascript/jsc/bindings/ZigSourceProvider.cpp | |
parent | ba743d776a6a417bdf42755b62a7868b15ebfe73 (diff) | |
download | bun-7245f90b2dd686acacb9c8ee03f5d8fb05e09aeb.tar.gz bun-7245f90b2dd686acacb9c8ee03f5d8fb05e09aeb.tar.zst bun-7245f90b2dd686acacb9c8ee03f5d8fb05e09aeb.zip |
little bit of errors, little bit of bytecode caching. neither finished
Former-commit-id: c774c395136d58330aa7cad7e9fa434bcef7d5c6
Diffstat (limited to 'src/javascript/jsc/bindings/ZigSourceProvider.cpp')
-rw-r--r-- | src/javascript/jsc/bindings/ZigSourceProvider.cpp | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/src/javascript/jsc/bindings/ZigSourceProvider.cpp b/src/javascript/jsc/bindings/ZigSourceProvider.cpp new file mode 100644 index 000000000..6a08e1057 --- /dev/null +++ b/src/javascript/jsc/bindings/ZigSourceProvider.cpp @@ -0,0 +1,134 @@ +#include "ZigSourceProvider.h" +#include "helpers.h" +#include <JavaScriptCore/BytecodeCacheError.h> +#include <JavaScriptCore/CodeCache.h> + +#include <JavaScriptCore/Completion.h> +#include <sys/stat.h> +#include <wtf/FileSystem.h> +#include <wtf/Scope.h> +#include <wtf/text/StringHash.h> + +namespace Zig { + +using Base = JSC::SourceProvider; +using BytecodeCacheGenerator = JSC::BytecodeCacheGenerator; +using UnlinkedFunctionExecutable = JSC::UnlinkedFunctionExecutable; +using CachedBytecode = JSC::CachedBytecode; +using UnlinkedFunctionCodeBlock = JSC::UnlinkedFunctionCodeBlock; +using SourceCode = JSC::SourceCode; +using CodeSpecializationKind = JSC::CodeSpecializationKind; +using SourceOrigin = JSC::SourceOrigin; +using String = WTF::String; +using SourceProviderSourceType = JSC::SourceProviderSourceType; + +Ref<SourceProvider> SourceProvider::create(ResolvedSource resolvedSource) { + return adoptRef(*new SourceProvider( + resolvedSource, + JSC::SourceOrigin(WTF::URL::fileURLWithFileSystemPath(toString(resolvedSource.source_url))), + toStringNotConst(resolvedSource.source_url), TextPosition(), + JSC::SourceProviderSourceType::Module)); +} + +unsigned SourceProvider::getHash() { + if (m_hash) { return m_hash; } + + m_hash = WTF::StringHash::hash(WTF::String(WTF::StringImpl::createWithoutCopying( + m_resolvedSource.source_code.ptr, m_resolvedSource.source_code.len))); + return m_hash; +} + +void SourceProvider::updateCache(const UnlinkedFunctionExecutable *executable, const SourceCode &, + CodeSpecializationKind kind, + const UnlinkedFunctionCodeBlock *codeBlock) { + if (!m_resolvedSource.bytecodecache_fd || !m_cachedBytecode) return; + + JSC::BytecodeCacheError error; + RefPtr<JSC::CachedBytecode> cachedBytecode = + JSC::encodeFunctionCodeBlock(executable->vm(), codeBlock, error); + if (cachedBytecode && !error.isValid()) + m_cachedBytecode->addFunctionUpdate(executable, kind, *cachedBytecode); +} + +void SourceProvider::cacheBytecode(const BytecodeCacheGenerator &generator) { + if (!m_resolvedSource.bytecodecache_fd) return; + + if (!m_cachedBytecode) m_cachedBytecode = JSC::CachedBytecode::create(); + auto update = generator(); + if (update) m_cachedBytecode->addGlobalUpdate(*update); +} +void SourceProvider::commitCachedBytecode() { + if (!m_resolvedSource.bytecodecache_fd || !m_cachedBytecode || !m_cachedBytecode->hasUpdates()) + return; + + auto clearBytecode = WTF::makeScopeExit([&] { m_cachedBytecode = nullptr; }); + const auto fd = m_resolvedSource.bytecodecache_fd; + + auto fileSize = FileSystem::fileSize(fd); + if (!fileSize) return; + + size_t cacheFileSize; + if (!WTF::convertSafely(*fileSize, cacheFileSize) || cacheFileSize != m_cachedBytecode->size()) { + // The bytecode cache has already been updated + return; + } + + if (!FileSystem::truncateFile(fd, m_cachedBytecode->sizeForUpdate())) return; + + m_cachedBytecode->commitUpdates([&](off_t offset, const void *data, size_t size) { + long long result = FileSystem::seekFile(fd, offset, FileSystem::FileSeekOrigin::Beginning); + ASSERT_UNUSED(result, result != -1); + size_t bytesWritten = static_cast<size_t>(FileSystem::writeToFile(fd, data, size)); + ASSERT_UNUSED(bytesWritten, bytesWritten == size); + }); +} + +bool SourceProvider::isBytecodeCacheEnabled() const { + return m_resolvedSource.bytecodecache_fd > 0; +} + +void SourceProvider::readOrGenerateByteCodeCache(JSC::VM &vm, const JSC::SourceCode &sourceCode) { + auto status = this->readCache(vm, sourceCode); + switch (status) { + case -1: { + m_resolvedSource.bytecodecache_fd = 0; + break; + } + case 0: { + JSC::BytecodeCacheError err; + m_cachedBytecode = + JSC::generateModuleBytecode(vm, sourceCode, m_resolvedSource.bytecodecache_fd, err); + + if (err.isValid()) { + m_resolvedSource.bytecodecache_fd = 0; + m_cachedBytecode = JSC::CachedBytecode::create(); + } + } + } +} +int SourceProvider::readCache(JSC::VM &vm, const JSC::SourceCode &sourceCode) { + if (m_resolvedSource.bytecodecache_fd == 0) return -1; + if (!FileSystem::isHandleValid(m_resolvedSource.bytecodecache_fd)) return -1; + const auto fd = m_resolvedSource.bytecodecache_fd; + + bool success; + FileSystem::MappedFileData mappedFile(fd, FileSystem::MappedFileMode::Shared, success); + if (!success) return -1; + + const uint8_t *fileData = reinterpret_cast<const uint8_t *>(mappedFile.data()); + unsigned fileTotalSize = mappedFile.size(); + if (fileTotalSize == 0) return 0; + + Ref<JSC::CachedBytecode> cachedBytecode = JSC::CachedBytecode::create(WTFMove(mappedFile)); + auto key = JSC::sourceCodeKeyForSerializedModule(vm, sourceCode); + if (isCachedBytecodeStillValid(vm, cachedBytecode.copyRef(), key, + JSC::SourceCodeType::ModuleType)) { + m_cachedBytecode = WTFMove(cachedBytecode); + return 1; + } else { + FileSystem::truncateFile(fd, 0); + return 0; + } +} + +}; // namespace Zig
\ No newline at end of file |