Skip to content

Commit d64b0ea

Browse files
authored
Move static userflags into pass_opt_t (#4806)
in order to be able to control it distinctly for each compilation and not have it affect every compilation because it is static. This is not strictly necessary for handling user defines in pony-lsp, but it helps avoid surprises should we get to run multiple compilations on different threads at one point.
1 parent 5b6a6b5 commit d64b0ea

File tree

9 files changed

+120
-90
lines changed

9 files changed

+120
-90
lines changed

src/libponyc/options/options.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ static ponyc_opt_process_t special_opt_processing(pass_opt_t *opt)
249249
#if defined(USE_SCHEDULER_SCALING_PTHREADS)
250250
// Defined "scheduler_scaling_pthreads" so that SIGUSR2 is made available for
251251
// use by the signals package when not using signals for scheduler scaling
252-
define_build_flag("scheduler_scaling_pthreads");
252+
define_userflag(opt->user_flags, "scheduler_scaling_pthreads");
253253
#endif
254254

255255
#ifndef NDEBUG
@@ -297,7 +297,7 @@ ponyc_opt_process_t ponyc_opt_process(opt_state_t* s, pass_opt_t* opt,
297297
wants_help = true; break;
298298
case OPT_DEBUG: opt->release = false; break;
299299
case OPT_BUILDFLAG:
300-
define_build_flag(s->arg_val);
300+
define_userflag(opt->user_flags, s->arg_val);
301301
break;
302302
case OPT_STRIP: opt->strip_debug = true; break;
303303
case OPT_PATHS: package_add_paths(s->arg_val, opt); break;

src/libponyc/pass/pass.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "../ast/treecheck.h"
1919
#include "../codegen/codegen.h"
2020
#include "../pkg/program.h"
21+
#include "../pkg/buildflagset.h"
2122
#include "../plugin/plugin.h"
2223
#include "../../libponyrt/mem/pool.h"
2324
#include "ponyassert.h"
@@ -104,6 +105,7 @@ void pass_opt_init(pass_opt_t* options)
104105
options->verbosity = VERBOSITY_INFO;
105106
options->check.errors = errors_alloc();
106107
options->ast_print_width = 80;
108+
options->user_flags = userflags_create();
107109
frame_push(&options->check, NULL);
108110
}
109111

@@ -112,6 +114,10 @@ void pass_opt_done(pass_opt_t* options)
112114
{
113115
plugin_unload(options);
114116

117+
// free userflags if any
118+
userflags_free(options->user_flags);
119+
options->user_flags = NULL;
120+
115121
// Free the error collection.
116122
errors_free(options->check.errors);
117123
options->check.errors = NULL;

src/libponyc/pass/pass.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "../ast/ast.h"
66
#include "../ast/frame.h"
77
#include "../ast/source.h"
8+
#include "../pkg/buildflagset.h"
89

910

1011
PONY_EXTERN_C_BEGIN
@@ -319,6 +320,9 @@ typedef struct pass_opt_t
319320

320321
plugins_t* plugins;
321322

323+
// user flags added via command line -D
324+
userflags_t* user_flags;
325+
322326
void* data; // User-defined data for unit test callbacks.
323327
} pass_opt_t;
324328

src/libponyc/pkg/buildflagset.c

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -574,51 +574,58 @@ const char* buildflagset_print(buildflagset_t* set)
574574
return set->text_buffer;
575575
}
576576

577+
// just a thin wrapper around the private flagtab_t
578+
typedef struct userflags_t {
579+
flagtab_t inner;
580+
} userflags_t;
577581

578-
static flagtab_t* _user_flags = NULL;
579-
580-
bool define_build_flag(const char* name)
582+
userflags_t* userflags_create()
581583
{
582-
pony_assert(name != NULL);
584+
userflags_t* u = POOL_ALLOC(userflags_t);
585+
pony_assert(u != NULL);
586+
flagtab_init(&(u->inner), 4);
587+
return u;
588+
}
583589

584-
if(_user_flags == NULL)
590+
void userflags_free(userflags_t *flags)
591+
{
592+
if(flags != NULL)
585593
{
586-
// Initialise flags table.
587-
_user_flags = POOL_ALLOC(flagtab_t);
588-
flagtab_init(_user_flags, 8);
594+
flagtab_destroy(&flags->inner);
595+
POOL_FREE(flagtab_t, flags);
589596
}
597+
}
598+
599+
bool define_userflag(userflags_t* flags, const char* name)
600+
{
601+
pony_assert(flags != NULL);
602+
pony_assert(name != NULL);
590603

591604
flag_t f1 = {stringtab(name), false};
592605
size_t index = HASHMAP_UNKNOWN;
593-
flag_t* f2 = flagtab_get(_user_flags, &f1, &index);
606+
flag_t* f2 = flagtab_get(&(flags->inner), &f1, &index);
594607

595608
if(f2 != NULL) // Flag already in our table.
596609
return false;
597610

598611
// Add flag to our table.
599612
// didn't find it in the map but index is where we can put the
600613
// new one without another search
601-
flagtab_putindex(_user_flags, flag_dup(&f1), index);
614+
flagtab_putindex(&(flags->inner), flag_dup(&f1), index);
602615
return true;
603616
}
604617

605618

606-
bool remove_build_flags(const char* flags[])
619+
bool remove_userflags(userflags_t* flags, const char* flags_to_remove[])
607620
{
608621
pony_assert(flags != NULL);
609-
610-
if(_user_flags == NULL)
611-
{
612-
// Initialise flags table.
613-
_user_flags = POOL_ALLOC(flagtab_t);
614-
flagtab_init(_user_flags, 8);
615-
}
622+
pony_assert(flags_to_remove != NULL);
616623

617624
size_t removed = 0;
618-
for(const char** next = flags; *next != NULL; next += 1)
625+
for(const char** next = flags_to_remove; *next != NULL; next += 1)
619626
{
620627
flag_t f1 = {stringtab(*next), false};
621-
flag_t* found = flagtab_remove(_user_flags, &f1);
628+
flag_t* found = flagtab_remove(&(flags->inner), &f1);
622629
if(found != NULL)
623630
{
624631
flag_free(found);
@@ -630,27 +637,20 @@ bool remove_build_flags(const char* flags[])
630637
}
631638

632639

633-
bool is_build_flag_defined(const char* name)
640+
bool is_userflag_defined(userflags_t* flags, const char* name)
634641
{
642+
pony_assert(flags != NULL);
635643
pony_assert(name != NULL);
636644

637-
if(_user_flags == NULL)
638-
// Table is not initialised, so no flags are defined.
639-
return false;
640-
641645
flag_t f1 = { stringtab(name), false };
642646
size_t index = HASHMAP_UNKNOWN;
643-
flag_t* f2 = flagtab_get(_user_flags, &f1, &index);
647+
flag_t* f2 = flagtab_get(&(flags->inner), &f1, &index);
644648

645649
return f2 != NULL;
646650
}
647651

648-
void clear_build_flags()
652+
void clear_userflags(userflags_t* flags)
649653
{
650-
if(_user_flags != NULL)
651-
{
652-
flagtab_destroy(_user_flags);
653-
POOL_FREE(flagtab_t, _user_flags);
654-
_user_flags = NULL;
655-
}
654+
pony_assert(flags != NULL);
655+
flagtab_destroy(&(flags->inner));
656656
}

src/libponyc/pkg/buildflagset.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,20 +78,25 @@ const char* buildflagset_print(buildflagset_t* set);
7878

7979
// User build flags are defined on the ponyc command line and used to select
8080
// code options with ifdef expressions.
81+
typedef struct userflags_t userflags_t;
82+
83+
userflags_t* userflags_create();
84+
85+
void userflags_free(userflags_t* flags);
8186

8287
// Define the given user build flag.
8388
// Returns: true on success, false on duplicate flag.
84-
bool define_build_flag(const char* name);
89+
bool define_userflag(userflags_t* flags, const char* name);
8590

8691
// Report whether the given user build flag is defined.
87-
bool is_build_flag_defined(const char* name);
92+
bool is_userflag_defined(userflags_t* flags, const char* name);
8893

8994
// Remove all flags in the null terminated list
9095
// Returns: true if one or more of the flags were removed
91-
bool remove_build_flags(const char* flags[]);
96+
bool remove_userflags(userflags_t* flags, const char* flags_to_remove[]);
9297

9398
// Remove all flags.
94-
void clear_build_flags();
99+
void clear_userflags(userflags_t* flags);
95100

96101
PONY_EXTERN_C_END
97102

src/libponyc/pkg/ifdef.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ static bool cond_eval(ast_t* ast, buildflagset_t* config, bool release,
155155
}
156156

157157
// Not a platform flag, must be a user flag.
158-
return is_build_flag_defined(name);
158+
return is_userflag_defined(opt->user_flags, name);
159159
}
160160

161161
default:

test/libponyc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ add_executable(libponyc.tests
5050
type_check_bind.cc
5151
type_check_subtype.cc
5252
use.cc
53+
userflags.cc
5354
util.cc
5455
verify.cc
5556
with.cc

test/libponyc/buildflagset.cc

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -154,53 +154,3 @@ TEST(BuildFlagSetTest, MultipleFlags)
154154

155155
buildflagset_free(set);
156156
}
157-
158-
159-
TEST(BuildFlagSetTest, UserFlagNoneDefined)
160-
{
161-
clear_build_flags();
162-
ASSERT_FALSE(is_build_flag_defined("foo"));
163-
}
164-
165-
166-
TEST(BuildFlagSetTest, UserFlagDefined)
167-
{
168-
clear_build_flags();
169-
define_build_flag("foo");
170-
171-
ASSERT_TRUE(is_build_flag_defined("foo"));
172-
}
173-
174-
175-
TEST(BuildFlagSetTest, UserFlagNotDefined)
176-
{
177-
clear_build_flags();
178-
define_build_flag("foo");
179-
180-
ASSERT_TRUE(is_build_flag_defined("foo"));
181-
ASSERT_FALSE(is_build_flag_defined("bar"));
182-
}
183-
184-
185-
TEST(BuildFlagSetTest, UserFlagCaseSensitive)
186-
{
187-
clear_build_flags();
188-
define_build_flag("foo");
189-
190-
ASSERT_TRUE(is_build_flag_defined("foo"));
191-
ASSERT_FALSE(is_build_flag_defined("FOO"));
192-
}
193-
194-
195-
TEST(BuildFlagSetTest, UserFlagMultiple)
196-
{
197-
clear_build_flags();
198-
define_build_flag("foo");
199-
define_build_flag("BAR");
200-
define_build_flag("Wombat");
201-
202-
ASSERT_TRUE(is_build_flag_defined("foo"));
203-
ASSERT_TRUE(is_build_flag_defined("BAR"));
204-
ASSERT_FALSE(is_build_flag_defined("aardvark"));
205-
ASSERT_TRUE(is_build_flag_defined("Wombat"));
206-
}

test/libponyc/userflags.cc

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#include <gtest/gtest.h>
2+
#include <platform.h>
3+
4+
#include <pkg/buildflagset.h>
5+
6+
class UserFlagsTest: public testing::Test
7+
{};
8+
9+
TEST(UserFlagsTest, UserFlagNoneDefined)
10+
{
11+
userflags_t* flags = userflags_create();
12+
13+
define_userflag(flags, "foo");
14+
clear_userflags(flags);
15+
ASSERT_FALSE(is_userflag_defined(flags, "foo"));
16+
userflags_free(flags);
17+
}
18+
19+
20+
TEST(UserFlagsTest, UserFlagDefined)
21+
{
22+
userflags_t* flags = userflags_create();
23+
define_userflag(flags, "foo");
24+
25+
ASSERT_TRUE(is_userflag_defined(flags, "foo"));
26+
userflags_free(flags);
27+
}
28+
29+
30+
TEST(UserFlagsTest, UserFlagNotDefined)
31+
{
32+
userflags_t* flags = userflags_create();
33+
define_userflag(flags, "foo");
34+
35+
ASSERT_TRUE(is_userflag_defined(flags, "foo"));
36+
ASSERT_FALSE(is_userflag_defined(flags, "bar"));
37+
userflags_free(flags);
38+
}
39+
40+
41+
TEST(UserFlagsTest, UserFlagCaseSensitive)
42+
{
43+
userflags_t* flags = userflags_create();
44+
define_userflag(flags, "foo");
45+
46+
ASSERT_TRUE(is_userflag_defined(flags, "foo"));
47+
ASSERT_FALSE(is_userflag_defined(flags, "FOO"));
48+
userflags_free(flags);
49+
}
50+
51+
52+
TEST(UserFlagsTest, UserFlagMultiple)
53+
{
54+
userflags_t* flags = userflags_create();
55+
define_userflag(flags, "foo");
56+
define_userflag(flags, "BAR");
57+
define_userflag(flags, "Wombat");
58+
59+
ASSERT_TRUE(is_userflag_defined(flags, "foo"));
60+
ASSERT_TRUE(is_userflag_defined(flags, "BAR"));
61+
ASSERT_FALSE(is_userflag_defined(flags, "aardvark"));
62+
ASSERT_TRUE(is_userflag_defined(flags, "Wombat"));
63+
userflags_free(flags);
64+
}

0 commit comments

Comments
 (0)