Skip to content

Commit 6d44f64

Browse files
committed
Return strings through an output parameter
1 parent 207a010 commit 6d44f64

File tree

7 files changed

+35
-46
lines changed

7 files changed

+35
-46
lines changed

src/blocks/looksblocks.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -561,25 +561,21 @@ extern "C" double looks_backdrop_number(ExecutionContext *ctx)
561561
return ctx->engine()->stage()->costumeIndex() + 1;
562562
}
563563

564-
extern "C" StringPtr *looks_backdrop_name(ExecutionContext *ctx)
564+
extern "C" void looks_backdrop_name(StringPtr *ret, ExecutionContext *ctx)
565565
{
566566
const std::string &name = ctx->engine()->stage()->currentCostume()->name();
567-
StringPtr *ret = string_pool_new();
568567
string_assign_cstring(ret, name.c_str());
569-
return ret;
570568
}
571569

572570
extern "C" double looks_costume_number(Target *target)
573571
{
574572
return target->costumeIndex() + 1;
575573
}
576574

577-
extern "C" StringPtr *looks_costume_name(Target *target)
575+
extern "C" void looks_costume_name(StringPtr *ret, Target *target)
578576
{
579577
const std::string &name = target->currentCostume()->name();
580-
StringPtr *ret = string_pool_new();
581578
string_assign_cstring(ret, name.c_str());
582-
return ret;
583579
}
584580

585581
extern "C" bool looks_backdrop_promise(ExecutionContext *ctx)

src/blocks/sensingblocks.cpp

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -522,11 +522,9 @@ extern "C" void sensing_askandwait(ExecutionContext *ctx, const StringPtr *quest
522522
ctx->thread()->setPromise(std::make_shared<Promise>());
523523
}
524524

525-
extern "C" StringPtr *sensing_answer(ExecutionContext *ctx)
525+
extern "C" void sensing_answer(StringPtr *ret, ExecutionContext *ctx)
526526
{
527-
StringPtr *ret = string_pool_new();
528527
string_assign(ret, ctx->engine()->answer());
529-
return ret;
530528
}
531529

532530
extern "C" bool sensing_keypressed(ExecutionContext *ctx, const StringPtr *key)
@@ -595,12 +593,10 @@ extern "C" double sensing_costume_number_of_target(Target *target)
595593
return target->costumeIndex() + 1;
596594
}
597595

598-
extern "C" StringPtr *sensing_costume_name_of_target(Target *target)
596+
extern "C" void sensing_costume_name_of_target(StringPtr *ret, Target *target)
599597
{
600598
const std::string &name = target->currentCostume()->name();
601-
StringPtr *ret = string_pool_new();
602599
string_assign_cstring(ret, name.c_str());
603-
return ret;
604600
}
605601

606602
extern "C" double sensing_size_of_sprite(Sprite *sprite)
@@ -659,17 +655,13 @@ extern "C" double sensing_costume_number_of_sprite_with_check(Target *target)
659655
return 0.0;
660656
}
661657

662-
extern "C" StringPtr *sensing_costume_name_of_sprite_with_check(Target *target)
658+
extern "C" void sensing_costume_name_of_sprite_with_check(StringPtr *ret, Target *target)
663659
{
664-
StringPtr *ret = string_pool_new();
665-
666660
if (target && !target->isStage()) {
667661
const std::string &name = target->currentCostume()->name();
668662
string_assign_cstring(ret, name.c_str());
669663
} else
670664
string_assign_cstring(ret, "0");
671-
672-
return ret;
673665
}
674666

675667
extern "C" double sensing_size_of_sprite_with_check(Target *target)
@@ -690,17 +682,13 @@ extern "C" double sensing_backdrop_number_of_stage_with_check(Target *target)
690682
return 0.0;
691683
}
692684

693-
extern "C" StringPtr *sensing_backdrop_name_of_stage_with_check(Target *target)
685+
extern "C" void sensing_backdrop_name_of_stage_with_check(StringPtr *ret, Target *target)
694686
{
695-
StringPtr *ret = string_pool_new();
696-
697687
if (target && target->isStage()) {
698688
const std::string &name = target->currentCostume()->name();
699689
string_assign_cstring(ret, name.c_str());
700690
} else
701691
string_assign_cstring(ret, "");
702-
703-
return ret;
704692
}
705693

706694
extern "C" double sensing_volume_of_target_with_check(Target *target)

src/engine/internal/llvm/instructions/functions.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@ LLVMInstruction *Functions::buildFunctionCall(LLVMInstruction *ins)
3232
// Variables must be synchronized because the function can read them
3333
m_utils.syncVariables();
3434

35+
// Strings are returned through an output parameter
36+
llvm::Value *stringRet = nullptr;
37+
38+
if (ins->functionReturnReg && ins->functionReturnReg->type() == Compiler::StaticType::String) {
39+
stringRet = m_builder.CreateCall(m_utils.functions().resolve_string_pool_new(), { m_builder.getInt1(true) });
40+
types.push_back(m_utils.getType(Compiler::StaticType::String, false));
41+
args.push_back(stringRet);
42+
}
43+
3544
// Add execution context arg
3645
if (ins->functionCtxArg) {
3746
types.push_back(llvm::PointerType::get(llvm::Type::getInt8Ty(m_utils.llvmCtx()), 0));
@@ -54,15 +63,15 @@ LLVMInstruction *Functions::buildFunctionCall(LLVMInstruction *ins)
5463
llvm::Value *ret = m_builder.CreateCall(m_utils.functions().resolveFunction(ins->functionName, llvm::FunctionType::get(retType, types, false)), args);
5564

5665
if (ins->functionReturnReg) {
57-
if (m_utils.isSingleType(ins->functionReturnReg->type()))
66+
if (ins->functionReturnReg->type() == Compiler::StaticType::String) {
67+
ins->functionReturnReg->value = stringRet;
68+
m_utils.freeStringLater(stringRet);
69+
} else if (m_utils.isSingleType(ins->functionReturnReg->type()))
5870
ins->functionReturnReg->value = ret;
5971
else {
6072
ins->functionReturnReg->value = m_utils.addAlloca(retType);
6173
m_builder.CreateStore(ret, ins->functionReturnReg->value);
6274
}
63-
64-
if (ins->functionReturnReg->type() == Compiler::StaticType::String)
65-
m_utils.freeStringLater(ins->functionReturnReg->value);
6675
}
6776

6877
return ins->next;

src/engine/internal/llvm/llvmbuildutils.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,11 @@ llvm::Type *LLVMBuildUtils::getType(Compiler::StaticType type, bool isReturnType
707707
return m_builder.getInt1Ty();
708708

709709
case Compiler::StaticType::String:
710-
return m_stringPtrType->getPointerTo();
710+
// Strings are returned through an output parameter
711+
if (isReturnType)
712+
return m_builder.getVoidTy();
713+
else
714+
return m_stringPtrType->getPointerTo();
711715

712716
case Compiler::StaticType::Pointer:
713717
return m_builder.getVoidTy()->getPointerTo();

test/blocks/util.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,9 @@ extern "C" bool test_condition()
6868
return conditionReturnValue;
6969
}
7070

71-
extern "C" StringPtr *test_const_string(const StringPtr *str)
71+
extern "C" void test_const_string(StringPtr *ret, const StringPtr *str)
7272
{
73-
StringPtr *ret = string_pool_new();
7473
string_assign(ret, str);
75-
return ret;
7674
}
7775

7876
} // namespace libscratchcpp

test/llvm/testfunctions.cpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,12 @@ extern "C"
6363
std::cout << "no_args" << std::endl;
6464
}
6565

66-
StringPtr *test_function_no_args_ret(Target *target)
66+
void test_function_no_args_ret(StringPtr *ret, Target *target)
6767
{
6868
target->isStage();
6969
std::cout << "no_args_ret" << std::endl;
7070
Value v("no_args_output");
71-
StringPtr *ret = string_pool_new();
7271
value_toStringPtr(&v.data(), ret);
73-
return ret;
7472
}
7573

7674
void test_function_1_arg(Target *target, const StringPtr *arg1)
@@ -79,14 +77,12 @@ extern "C"
7977
std::cout << "1_arg " << utf8::utf16to8(std::u16string(arg1->data)) << std::endl;
8078
}
8179

82-
StringPtr *test_function_1_arg_ret(Target *target, const StringPtr *arg1)
80+
void test_function_1_arg_ret(StringPtr *ret, Target *target, const StringPtr *arg1)
8381
{
8482
target->isStage();
8583
std::cout << "1_arg_ret " << utf8::utf16to8(std::u16string(arg1->data)) << std::endl;
8684
Value v("1_arg_output");
87-
StringPtr *ret = string_pool_new();
8885
value_toStringPtr(&v.data(), ret);
89-
return ret;
9086
}
9187

9288
void test_function_3_args(Target *target, const StringPtr *arg1, const StringPtr *arg2, const StringPtr *arg3)
@@ -95,14 +91,12 @@ extern "C"
9591
std::cout << "3_args " << utf8::utf16to8(std::u16string(arg1->data)) << " " << utf8::utf16to8(std::u16string(arg2->data)) << " " << utf8::utf16to8(std::u16string(arg3->data)) << std::endl;
9692
}
9793

98-
StringPtr *test_function_3_args_ret(Target *target, const StringPtr *arg1, const StringPtr *arg2, const StringPtr *arg3)
94+
void test_function_3_args_ret(StringPtr *ret, Target *target, const StringPtr *arg1, const StringPtr *arg2, const StringPtr *arg3)
9995
{
10096
target->isStage();
10197
std::cout << "3_args " << utf8::utf16to8(std::u16string(arg1->data)) << " " << utf8::utf16to8(std::u16string(arg2->data)) << " " << utf8::utf16to8(std::u16string(arg3->data)) << std::endl;
10298
Value v("3_args_output");
103-
StringPtr *ret = string_pool_new();
10499
value_toStringPtr(&v.data(), ret);
105-
return ret;
106100
}
107101

108102
const void *test_function_1_ptr_arg_ret(Target *target, const int *arg1)
@@ -138,11 +132,9 @@ extern "C"
138132
return v;
139133
}
140134

141-
StringPtr *test_const_string(const StringPtr *v)
135+
void test_const_string(StringPtr *ret, const StringPtr *v)
142136
{
143-
StringPtr *ret = string_pool_new();
144137
string_assign(ret, v);
145-
return ret;
146138
}
147139

148140
ValueData test_const_unknown(const ValueData *v)

test/llvm/testfunctions.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#include <scratchcpp/valuedata.h>
4+
35
namespace libscratchcpp
46
{
57

@@ -21,11 +23,11 @@ extern "C"
2123
void test_ctx_function(ExecutionContext *ctx, const StringPtr *arg);
2224

2325
void test_function_no_args(Target *target);
24-
StringPtr *test_function_no_args_ret(Target *target);
26+
void test_function_no_args_ret(StringPtr *ret, Target *target);
2527
void test_function_1_arg(Target *target, const StringPtr *arg1);
26-
StringPtr *test_function_1_arg_ret(Target *target, const StringPtr *arg1);
28+
void test_function_1_arg_ret(StringPtr *ret, Target *target, const StringPtr *arg1);
2729
void test_function_3_args(Target *target, const StringPtr *arg1, const StringPtr *arg2, const StringPtr *arg3);
28-
StringPtr *test_function_3_args_ret(Target *target, const StringPtr *arg1, const StringPtr *arg2, const StringPtr *arg3);
30+
void test_function_3_args_ret(StringPtr *ret, Target *target, const StringPtr *arg1, const StringPtr *arg2, const StringPtr *arg3);
2931

3032
const void *test_function_1_ptr_arg_ret(Target *target, const int *arg1);
3133

@@ -35,7 +37,7 @@ extern "C"
3537

3638
double test_const_number(double v);
3739
bool test_const_bool(bool v);
38-
StringPtr *test_const_string(const StringPtr *v);
40+
void test_const_string(StringPtr *ret, const StringPtr *v);
3941
ValueData test_const_unknown(const ValueData *v);
4042
const void *test_const_pointer(const void *v);
4143

0 commit comments

Comments
 (0)