Skip to content

Commit f006572

Browse files
committed
Project: Updated choc
1 parent 2607e2a commit f006572

File tree

10 files changed

+119
-28
lines changed

10 files changed

+119
-28
lines changed

modules/3rd_party/choc/choc/containers/choc_ZipFile.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,11 +335,12 @@ struct ZipFile::Item::ZipStream : public std::istream,
335335
private std::streambuf
336336
{
337337
ZipStream (const Item& i)
338-
: std::istream (this),
338+
: std::istream (nullptr),
339339
fileStream (i.owner->source),
340340
compressedSize (static_cast<int64_t> (i.compressedSize)),
341341
fileStartOffset (static_cast<int64_t> (i.fileStartOffset))
342342
{
343+
rdbuf (this);
343344
char entry[30];
344345
i.owner->readChunk (entry, fileStartOffset, 30);
345346

modules/3rd_party/choc/choc/containers/choc_zlib.h

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ class DeflaterStream : public std::ostream,
9696
std::unique_ptr<Pimpl> pimpl;
9797

9898
int overflow (int) override;
99+
std::streamsize xsputn (const char_type* s, std::streamsize n) override;
99100
};
100101

101102

@@ -120,7 +121,7 @@ struct zlib
120121
// I even started trying to improve some of the appalling variable names,
121122
// but honestly, life's too short..
122123

123-
CHOC_REGISTER_OPEN_SOURCE_LICENCE (QuickJS, R"(
124+
CHOC_REGISTER_OPEN_SOURCE_LICENCE (ZLIB, R"(
124125
==============================================================================
125126
ZLIB License:
126127
@@ -910,13 +911,15 @@ struct DeflateStream
910911
/* strstart == 0 is possible when wraparound on 16-bit machine */
911912
s->lookahead = (uint32_t) (s->strstart - max_start);
912913
s->strstart = (uint32_t) max_start;
913-
s->flushBlock (0);
914+
if (! s->flushBlock (false))
915+
return BlockStatus::need_more; // Output buffer full, need to flush
914916
}
915917
/* Flush if we may have to slide, otherwise block_start may become
916918
* negative and the data will be gone:
917919
*/
918920
if (s->strstart - (uint32_t) s->block_start >= s->MAX_DIST())
919-
s->flushBlock (0);
921+
if (! s->flushBlock (false))
922+
return BlockStatus::need_more; // Output buffer full, need to flush
920923
}
921924
s->flushBlock (flush == FlushState::Z_FINISH);
922925
return flush == FlushState::Z_FINISH ? BlockStatus::finish_done
@@ -1498,14 +1501,15 @@ struct DeflateStream
14981501
last_lit = 0;
14991502
}
15001503

1501-
void flushBlock (bool eof)
1504+
bool flushBlock (bool eof)
15021505
{
15031506
flushCurrentBlock (block_start >= 0 ? (uint8_t*) &window[(uint32_t) block_start]
15041507
: (uint8_t*) nullptr,
15051508
(unsigned long) ((long) strstart - block_start),
15061509
eof);
15071510
block_start = (long) strstart;
15081511
flushPending();
1512+
return pending == 0; // Return true if all data was flushed
15091513
}
15101514

15111515
void initialiseTrees()
@@ -3808,9 +3812,10 @@ struct InflaterStream::Pimpl
38083812
};
38093813

38103814
inline InflaterStream::InflaterStream (std::shared_ptr<std::istream> source, FormatType format)
3811-
: std::istream (this),
3815+
: std::istream (nullptr),
38123816
pimpl (std::make_unique<Pimpl> (std::move (source), format))
38133817
{
3818+
rdbuf (this);
38143819
}
38153820

38163821
inline InflaterStream::~InflaterStream() = default;
@@ -3981,14 +3986,21 @@ struct DeflaterStream::Pimpl
39813986
};
39823987

39833988
inline DeflaterStream::DeflaterStream (std::shared_ptr<std::ostream> d, CompressionLevel c, int w)
3984-
: std::ostream (this),
3989+
: std::ostream (nullptr),
39853990
pimpl (std::make_unique<Pimpl> (std::move (d), c, w))
3986-
{}
3991+
{
3992+
rdbuf (this);
3993+
}
39873994

39883995
inline DeflaterStream::~DeflaterStream() = default;
39893996

39903997
inline int DeflaterStream::overflow (int c) { return pimpl->overflow (c); }
39913998

3999+
inline std::streamsize DeflaterStream::xsputn (const char_type* s, std::streamsize n)
4000+
{
4001+
return pimpl->write (reinterpret_cast<const uint8_t*> (s),
4002+
static_cast<size_t> (n)) ? n : 0;
4003+
}
39924004

39934005
} // namespace choc::gzip
39944006

modules/3rd_party/choc/choc/javascript/choc_javascript.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,16 @@ namespace choc::javascript
162162
/// Pumps the message loop in an engine-specific way - may have no effect on some platforms.
163163
void pumpMessageLoop();
164164

165+
/// If supported by the engine, attempts to cancel the execution of the JS code.
166+
/// If the JS code is stuck in a blocking call itself, this won't work, but will
167+
/// work if the JS code is running a loop, for example.
168+
/// This obviously has to be called from another thread, so for example if your JS engine
169+
/// is running in a worker thread, the GUI thread can call this.
170+
/// If the cancellation worked, an exception will be thrown.
171+
/// Returns true if cancellation is supported by this engine, or false if not.
172+
/// Currently only implemented in the QuickJS engine.
173+
bool cancel();
174+
165175
//==============================================================================
166176
/// @internal
167177
struct Pimpl;
@@ -235,6 +245,7 @@ struct Context::Pimpl
235245
virtual void pushArg (double) = 0;
236246
virtual void pushArg (bool) = 0;
237247
virtual void pumpMessageLoop() = 0;
248+
virtual bool cancel() { return false; }
238249

239250
void pushArg (const std::string& v) { pushArg (std::string_view (v)); }
240251
void pushArg (const char* v) { pushArg (std::string_view (v)); }
@@ -318,6 +329,12 @@ inline void Context::pumpMessageLoop()
318329
pimpl->pumpMessageLoop();
319330
}
320331

332+
inline bool Context::cancel()
333+
{
334+
CHOC_ASSERT (pimpl != nullptr); // cannot call this on a moved-from context!
335+
return pimpl->cancel();
336+
}
337+
321338
inline std::string makeSafeIdentifier (std::string s)
322339
{
323340
constexpr static std::string_view reservedWords[] =

modules/3rd_party/choc/choc/javascript/choc_javascript_Duktape.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#ifndef CHOC_JAVASCRIPT_DUKTAPE_HEADER_INCLUDED
2020
#define CHOC_JAVASCRIPT_DUKTAPE_HEADER_INCLUDED
2121

22+
#include <atomic>
2223
#include "choc_javascript.h"
2324

2425
/**
@@ -3220,7 +3221,7 @@ typedef struct duk_hthread duk_context;
32203221
#undef DUK_USE_EXEC_INDIRECT_BOUND_CHECK
32213222
#undef DUK_USE_EXEC_PREFER_SIZE
32223223
#define DUK_USE_EXEC_REGCONST_OPTIMIZE
3223-
#undef DUK_USE_EXEC_TIMEOUT_CHECK
3224+
#define DUK_USE_EXEC_TIMEOUT_CHECK(udata) (static_cast<std::atomic<bool>*> (udata)->load())
32243225
#undef DUK_USE_EXPLICIT_NULL_INIT
32253226
#undef DUK_USE_EXTSTR_FREE
32263227
#undef DUK_USE_EXTSTR_INTERN_CHECK
@@ -3262,7 +3263,7 @@ typedef struct duk_hthread duk_context;
32623263
#define DUK_USE_HTML_COMMENTS
32633264
#define DUK_USE_IDCHAR_FASTPATH
32643265
#undef DUK_USE_INJECT_HEAP_ALLOC_ERROR
3265-
#undef DUK_USE_INTERRUPT_COUNTER
3266+
#define DUK_USE_INTERRUPT_COUNTER
32663267
#undef DUK_USE_INTERRUPT_DEBUG_FIXUP
32673268
#define DUK_USE_JC
32683269
#define DUK_USE_JSON_BUILTIN
@@ -104989,7 +104990,7 @@ DUK_INTERNAL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr) {
104989104990
//==============================================================================
104990104991
struct DuktapeContext : public Context::Pimpl
104991104992
{
104992-
DuktapeContext() : context (duktape::duk_create_heap (nullptr, nullptr, nullptr, nullptr, fatalError))
104993+
DuktapeContext() : context (duktape::duk_create_heap (nullptr, nullptr, nullptr, &shouldCancel, fatalError))
104993104994
{
104994104995
CHOC_ASSERT (context != nullptr);
104995104996
}
@@ -105001,6 +105002,12 @@ struct DuktapeContext : public Context::Pimpl
105001105002

105002105003
void pumpMessageLoop() override {}
105003105004

105005+
bool cancel() override
105006+
{
105007+
shouldCancel.store (true);
105008+
return true;
105009+
}
105010+
105004105011
void resetStack()
105005105012
{
105006105013
while (duk_get_top (context))
@@ -105018,6 +105025,8 @@ struct DuktapeContext : public Context::Pimpl
105018105025

105019105026
void evalString (std::string_view code)
105020105027
{
105028+
shouldCancel.store (false);
105029+
105021105030
if (duk_peval_lstring (context, code.data(), code.length()) != DUK_EXEC_SUCCESS)
105022105031
throwError();
105023105032
}
@@ -105310,6 +105319,7 @@ struct DuktapeContext : public Context::Pimpl
105310105319
duktape::duk_context* context = nullptr;
105311105320
std::vector<std::unique_ptr<RegisteredFunction>> registeredFunctions;
105312105321
duktape::duk_idx_t numFunctionArgs = 0;
105322+
std::atomic<bool> shouldCancel { false };
105313105323

105314105324
static constexpr const char* objectNameAttribute = "_objectName";
105315105325
};

modules/3rd_party/choc/choc/javascript/choc_javascript_QuickJS.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include <time.h>
5252
#include <fenv.h>
5353
#include <math.h>
54+
#include <atomic>
5455
#if defined(__APPLE__)
5556
#include <malloc/malloc.h>
5657
#elif defined(__linux__)
@@ -64052,10 +64053,30 @@ struct QuickJSContext : public Context::Pimpl
6405264053
context = JS_NewContext (runtime);
6405364054
CHOC_ASSERT (context != nullptr);
6405464055
JS_SetContextOpaque (context, this);
64056+
64057+
JS_SetInterruptHandler (runtime, [] (JSRuntime*, void* opaque)
64058+
{
64059+
if (auto qjctx = static_cast<QuickJSContext*> (opaque))
64060+
{
64061+
if (qjctx->shouldCancel.load())
64062+
{
64063+
qjctx->shouldCancel.store (false);
64064+
return 1;
64065+
}
64066+
}
64067+
64068+
return 0;
64069+
}, this);
6405564070
}
6405664071

6405764072
void pumpMessageLoop() override {}
6405864073

64074+
bool cancel() override
64075+
{
64076+
shouldCancel.store (true);
64077+
return true;
64078+
}
64079+
6405964080
void pushObjectOrArray (const choc::value::ValueView& v) override { functionArgs.push_back (valueToJS (v).release()); }
6406064081
void pushArg (std::string_view v) override { functionArgs.push_back (stringToJS (v).release()); }
6406164082
void pushArg (int32_t v) override { functionArgs.push_back (JS_NewInt32 (context, v)); }
@@ -64350,6 +64371,7 @@ struct QuickJSContext : public Context::Pimpl
6435064371
std::vector<Context::NativeFunction> registeredFunctions;
6435164372
std::vector<JSValue> functionArgs;
6435264373
JSAtom functionToCall = {};
64374+
std::atomic<bool> shouldCancel { false };
6435364375

6435464376
static constexpr const char* objectNameAttribute = "_objectName";
6435564377
};

modules/3rd_party/choc/choc/platform/choc_DetectDebugger.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ inline bool choc::isDebuggerActive()
7171
}
7272

7373
//==============================================================================
74-
#elif CHOC_LINUX
74+
#elif CHOC_LINUX || CHOC_ANDROID
7575

7676
#include "../text/choc_Files.h"
7777
#include "../text/choc_StringUtilities.h"
@@ -80,15 +80,22 @@ inline bool choc::isDebuggerActive()
8080
{
8181
auto readStatusFileItem = [] (std::string_view filename, std::string_view item) -> std::string
8282
{
83-
auto lines = choc::text::splitIntoLines (choc::file::loadFileAsString (std::string (filename)), false);
83+
// Need to read /proc files without either seeking or throwing exceptions (which would
84+
// break the debugger we're trying to detect), so avoid using loadFileAsString() here
85+
std::ifstream stream (std::string (filename), std::ios::binary);
86+
87+
auto content = std::string { std::istreambuf_iterator<char> (stream),
88+
std::istreambuf_iterator<char>() };
89+
90+
auto lines = choc::text::splitIntoLines (content, false);
8491

8592
for (auto i = lines.rbegin(); i != lines.rend(); ++i)
8693
{
8794
auto line = choc::text::trimStart (std::string_view (*i));
8895

8996
if (choc::text::startsWith (line, item))
9097
{
91-
auto remainder = choc::text::trimStart (item.substr (item.length()));
98+
auto remainder = choc::text::trimStart (line.substr (item.length()));
9299

93100
if (! remainder.empty() && remainder[0] == ':')
94101
return std::string (choc::text::trim (remainder.substr (1)));

modules/3rd_party/choc/choc/platform/choc_DisableAllWarnings.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
#pragma warning (disable: 2440)
8686
#pragma warning (disable: 2664)
8787
#pragma warning (disable: 4244)
88+
#pragma warning (disable: 4245)
8889
#pragma warning (disable: 4701)
8990
#pragma warning (disable: 4702)
9091
#pragma warning (disable: 4706)
@@ -99,5 +100,7 @@
99100
#pragma warning (disable: 6340)
100101
#pragma warning (disable: 6385)
101102
#pragma warning (disable: 6386)
103+
#pragma warning (disable: 26437)
104+
#pragma warning (disable: 26816)
102105
#pragma warning (disable: 28182)
103106
#endif

modules/3rd_party/choc/choc/text/choc_Files.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@
2121

2222
#include <fstream>
2323
#include <functional>
24+
#include <cstring>
2425
#include <cwctype>
2526
#include <stdexcept>
2627
#include <random>
2728
#include <filesystem>
29+
#include "../platform/choc_Platform.h"
2830
#include "../text/choc_UTF8.h"
2931

3032
namespace choc::file
@@ -145,28 +147,26 @@ size_t readFileContent (const std::filesystem::path& filename, GetDestBufferFn&&
145147

146148
auto fileSize = stream.tellg();
147149

148-
if (fileSize < 0)
149-
throw Error ("Failed to read from file: " + filename.string());
150-
151150
if (fileSize == 0)
152-
return {};
151+
return 0;
153152

154-
if (auto destBuffer = getBuffer (static_cast<uint64_t> (fileSize)))
153+
if (fileSize > 0)
155154
{
156-
stream.seekg (0);
157-
158-
if (stream.read (static_cast<std::ifstream::char_type*> (destBuffer), static_cast<std::streamsize> (fileSize)))
159-
return static_cast<size_t> (fileSize);
155+
if (auto destBuffer = getBuffer (static_cast<uint64_t> (fileSize)))
156+
{
157+
stream.seekg (0);
160158

161-
throw Error ("Failed to read from file: " + filename.string());
159+
if (stream.read (static_cast<std::ifstream::char_type*> (destBuffer), static_cast<std::streamsize> (fileSize)))
160+
return static_cast<size_t> (fileSize);
161+
}
162162
}
163+
164+
throw Error ("Failed to read from file: " + filename.string());
163165
}
164166
catch (const std::ios_base::failure& e)
165167
{
166168
throw Error ("Failed to read from file: " + filename.string() + ": " + e.what());
167169
}
168-
169-
return 0;
170170
}
171171

172172
inline std::string loadFileAsString (const std::filesystem::path& filename)

modules/3rd_party/choc/tests/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
7171

7272
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
7373

74-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /W4 /WX -DWIN32 /bigobj ")
74+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /W4 /WX /w14355 -DWIN32 /bigobj ")
7575
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
7676
endif()
7777

modules/3rd_party/choc/tests/choc_tests.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,18 @@ inline void testFileUtilities (choc::test::TestProgress& progress)
724724
CHOC_EXPECT_TRUE (p4.matches ("abcd.x"));
725725
CHOC_EXPECT_FALSE (p4.matches ("abcd.X") || p4.matches ("abcdd.x") || p4.matches ("abc.x"));
726726
}
727+
728+
#if CHOC_LINUX || CHOC_ANDROID
729+
{
730+
CHOC_TEST (ProcFileReading)
731+
732+
// /proc files report 0 size but contain data - test that loadFileAsString handles this
733+
auto content = choc::file::loadFileAsString ("/proc/self/status");
734+
CHOC_EXPECT_FALSE (content.empty());
735+
CHOC_EXPECT_TRUE (content.find ("Name:") != std::string::npos);
736+
CHOC_EXPECT_TRUE (content.find ("TracerPid:") != std::string::npos);
737+
}
738+
#endif
727739
}
728740

729741
//==============================================================================
@@ -2631,7 +2643,14 @@ inline void testWebview (choc::test::TestProgress& progress)
26312643

26322644
CHOC_EXPECT_EQ (result, "[1234, 5678]");
26332645
CHOC_EXPECT_TRUE (error1.empty());
2634-
CHOC_EXPECT_EQ (choc::json::toString (value1), R"({"x": [1, 2, 3], "y": 987, "z": true})");
2646+
// Check individual properties since JSON object order is not guaranteed
2647+
CHOC_EXPECT_TRUE (value1.isObject());
2648+
CHOC_EXPECT_TRUE (value1.hasObjectMember ("x"));
2649+
CHOC_EXPECT_TRUE (value1.hasObjectMember ("y"));
2650+
CHOC_EXPECT_TRUE (value1.hasObjectMember ("z"));
2651+
CHOC_EXPECT_EQ (choc::json::toString (value1["x"]), "[1, 2, 3]");
2652+
CHOC_EXPECT_EQ (value1["y"].get<int>(), 987);
2653+
CHOC_EXPECT_EQ (value1["z"].get<bool>(), true);
26352654
#if ! CHOC_WINDOWS
26362655
CHOC_EXPECT_TRUE (! error2.empty()); // Windows browser seems to not do this one correctly
26372656
#endif

0 commit comments

Comments
 (0)