Skip to content

Commit 6d4158a

Browse files
committed
fix: guarantee stability even if script file is deleted on reloading script
Signed-off-by: Hosung Kim [email protected]
1 parent d77f0c7 commit 6d4158a

File tree

4 files changed

+53
-18
lines changed

4 files changed

+53
-18
lines changed

include/lwnode/lwnode-loader.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include <functional>
2222
#include <memory>
2323
#include <string>
24+
#include <unordered_map>
25+
2426
#include "gc-descriptor.h"
2527

2628
namespace Escargot {
@@ -55,13 +57,28 @@ class SourceReaderInterface {
5557
virtual FileData read(std::string filename, const Encoding encodingHint) = 0;
5658
};
5759

60+
class FileScope {
61+
public:
62+
FileScope(const char* path, const char* mode);
63+
~FileScope();
64+
std::FILE* file() { return file_; }
65+
66+
private:
67+
std::FILE* file_{nullptr};
68+
};
69+
5870
class SourceReader : public SourceReaderInterface {
5971
public:
6072
static SourceReader* getInstance();
6173
FileData read(std::string filename, const Encoding encodingHint) override;
6274

75+
FileScope* getFileScope(const std::string& filename);
76+
77+
void dispose();
78+
6379
private:
6480
SourceReader() = default;
81+
std::unordered_map<std::string, FileScope*> file_scopes_;
6582
};
6683

6784
class Loader {

src/api/engine.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "api/global.h"
2323
#include "handle.h"
24+
#include "lwnode/lwnode-loader.h"
2425
#include "utils/misc.h"
2526
#include "utils/string-util.h"
2627

@@ -411,6 +412,8 @@ void Engine::dispose() {
411412

412413
disposeExternalStrings();
413414

415+
LWNode::SourceReader::getInstance()->dispose();
416+
414417
MemoryUtil::gcFull();
415418
Globals::finalize();
416419
LWNODE_CALL_TRACE_GC_END();

src/lwnode/lwnode-loader.cc

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -78,21 +78,15 @@ bool convertUTF8ToUTF16le(char** buffer,
7878
return true;
7979
}
8080

81-
class FileScope {
82-
public:
83-
FileScope(const char* path, const char* mode) {
84-
file_ = std::fopen(path, mode);
85-
}
86-
~FileScope() {
87-
if (file_) {
88-
std::fclose(file_);
89-
}
90-
}
91-
std::FILE* file() { return file_; }
81+
FileScope::FileScope(const char* path, const char* mode) {
82+
file_ = std::fopen(path, mode);
83+
}
9284

93-
private:
94-
std::FILE* file_{nullptr};
95-
};
85+
FileScope::~FileScope() {
86+
if (file_) {
87+
std::fclose(file_);
88+
}
89+
}
9690

9791
static void tryConvertUTF8ToLatin1(
9892
std::basic_string<uint8_t, std::char_traits<uint8_t>>& latin1String,
@@ -196,9 +190,13 @@ SourceReader* SourceReader::getInstance() {
196190
}
197191

198192
FileData SourceReader::read(std::string filename, const Encoding encodingHint) {
199-
FileScope fileScope(filename.c_str(), "rb");
193+
FileScope* fileScope = getFileScope(filename);
194+
195+
if (fileScope == nullptr) {
196+
return FileData();
197+
}
200198

201-
std::FILE* file = fileScope.file();
199+
std::FILE* file = fileScope->file();
202200

203201
if (file == nullptr) {
204202
return FileData();
@@ -230,6 +228,23 @@ FileData SourceReader::read(std::string filename, const Encoding encodingHint) {
230228
filename, std::move(bufferHolder), bufferSize, encodingHint);
231229
}
232230

231+
FileScope* SourceReader::getFileScope(const std::string& filename) {
232+
auto iter = file_scopes_.find(filename);
233+
if (iter == file_scopes_.end()) {
234+
FileScope* file_scope = new FileScope(filename.c_str(), "rb");
235+
file_scopes_[filename] = file_scope;
236+
return file_scope;
237+
}
238+
return iter->second;
239+
}
240+
241+
void SourceReader::dispose() {
242+
for (auto& file_scope : file_scopes_) {
243+
delete file_scope.second;
244+
}
245+
file_scopes_.clear();
246+
}
247+
233248
Loader::ReloadableSourceData* Loader::ReloadableSourceData::create(
234249
const FileData fileData, SourceReaderInterface* sourceReader) {
235250
// NOTE: data and data->path should be managed by gc

test/cctest/test-internal.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,9 +1055,8 @@ TEST(ReloadableString16) {
10551055
.ToLocalChecked())
10561056
.Check();
10571057

1058-
std::string filename = "./tmp.test-reloadable-string.js";
1059-
10601058
{
1059+
std::string filename = "./tmp.test-reloadable-string1.js";
10611060
const bool isOneByteString = false;
10621061
ReloadableContentScope scope(filename, isOneByteString);
10631062

@@ -1095,6 +1094,7 @@ TEST(ReloadableString16) {
10951094
}
10961095

10971096
{
1097+
std::string filename = "./tmp.test-reloadable-string2.js";
10981098
g_reload_count = 0;
10991099
const bool isOneByteString = false;
11001100
ReloadableContentScope scope(filename, isOneByteString);

0 commit comments

Comments
 (0)