Skip to content

Commit 4d3f979

Browse files
committed
Pass unsafe constants to CompilerContext
1 parent 553b309 commit 4d3f979

5 files changed

Lines changed: 40 additions & 7 deletions

File tree

‎include/scratchcpp/compiler.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ class LIBSCRATCHCPP_EXPORT Compiler
164164

165165
const std::unordered_set<std::string> &unsupportedBlocks() const;
166166

167-
static std::shared_ptr<CompilerContext> createContext(IEngine *engine, Target *target);
167+
static std::shared_ptr<CompilerContext> createContext(IEngine *engine, Target *target, const std::unordered_set<std::string> &unsafeConstants);
168168

169169
private:
170170
spimpl::unique_impl_ptr<CompilerPrivate> impl;

‎src/engine/compiler.cpp‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -751,8 +751,8 @@ const std::unordered_set<std::string> &Compiler::unsupportedBlocks() const
751751
}
752752

753753
/*! Creates a compiler context for the given target. */
754-
std::shared_ptr<CompilerContext> Compiler::createContext(IEngine *engine, Target *target)
754+
std::shared_ptr<CompilerContext> Compiler::createContext(IEngine *engine, Target *target, const std::unordered_set<std::string> &unsafeConstants)
755755
{
756756
CompilerPrivate::initBuilderFactory();
757-
return CompilerPrivate::builderFactory()->createCtx(engine, target);
757+
return CompilerPrivate::builderFactory()->createCtx(engine, target, unsafeConstants);
758758
}

‎src/engine/compiler_p.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ CompilerPrivate::CompilerPrivate(CompilerContext *ctx) :
1818
}
1919

2020
CompilerPrivate::CompilerPrivate(IEngine *engine, Target *target) :
21-
ctxPtr(Compiler::createContext(engine, target)),
21+
ctxPtr(Compiler::createContext(engine, target, {})), // NOTE: This constructor is only used in tests, so we can leave unsafe constants empty
2222
ctx(ctxPtr.get())
2323
{
2424
initBuilderFactory();

‎src/engine/internal/engine.cpp‎

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ void Engine::clear()
8585
m_broadcastMap.clear();
8686
m_broadcastSenders.clear();
8787
m_sortedDrawables.clear();
88+
m_unsafeConstants.clear();
8889
m_threads.clear();
8990
m_threadsToStop.clear();
9091
m_scripts.clear();
@@ -245,10 +246,41 @@ void Engine::compile()
245246
// Resolve entities by ID
246247
resolveIds();
247248

249+
// Find unsafe constants (string numerals) in costume and sound names
250+
m_unsafeConstants.clear();
251+
252+
for (auto target : m_targets) {
253+
IEngine *engine = target->engine();
254+
255+
if (engine) {
256+
auto checkConstant = [this](const std::string &str) {
257+
Value stringValue(str);
258+
Value numberValue(stringValue.toDouble());
259+
260+
if (stringValue.isValidNumber() && str == numberValue.toString())
261+
m_unsafeConstants.insert(str);
262+
};
263+
264+
const auto &targets = engine->targets();
265+
bool found = false;
266+
267+
for (const auto &target : targets) {
268+
const auto &costumes = target->costumes();
269+
const auto &sounds = target->sounds();
270+
271+
for (const auto &costume : costumes)
272+
checkConstant(costume->name());
273+
274+
for (const auto &sound : sounds)
275+
checkConstant(sound->name());
276+
}
277+
}
278+
}
279+
248280
// Compile scripts
249281
for (auto target : m_targets) {
250282
std::cout << "Compiling scripts in target " << target->name() << "..." << std::endl;
251-
auto ctx = Compiler::createContext(this, target.get());
283+
auto ctx = Compiler::createContext(this, target.get(), m_unsafeConstants);
252284
m_compilerContexts[target.get()] = ctx;
253285
Compiler compiler(ctx.get());
254286
const auto &blocks = target->blocks();
@@ -1789,7 +1821,7 @@ void Engine::compileMonitor(std::shared_ptr<Monitor> monitor)
17891821
auto ext = blockExtension(block->opcode());
17901822

17911823
if (ext) {
1792-
auto ctx = Compiler::createContext(this, target);
1824+
auto ctx = Compiler::createContext(this, target, m_unsafeConstants);
17931825
Compiler compiler(ctx.get());
17941826
MonitorNameFunc nameFunc = resolveMonitorNameFunc(ext, block->opcode());
17951827

‎src/engine/internal/engine.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,8 @@ class LIBSCRATCHCPP_TEST_EXPORT Engine : public IEngine
241241
std::unordered_map<Broadcast *, Thread *> m_broadcastSenders; // used for resolving broadcast promises
242242
std::vector<std::shared_ptr<Monitor>> m_monitors;
243243
std::vector<std::string> m_extensions;
244-
std::vector<Drawable *> m_sortedDrawables; // sorted by layer (reverse order of execution)
244+
std::vector<Drawable *> m_sortedDrawables; // sorted by layer (reverse order of execution)
245+
std::unordered_set<std::string> m_unsafeConstants; // string numerals which shouldn't be optimized
245246
std::vector<std::shared_ptr<Thread>> m_threads;
246247
std::vector<std::shared_ptr<Thread>> m_threadsToStop;
247248
std::shared_ptr<Thread> m_activeThread;

0 commit comments

Comments
 (0)