forked from gap-system/gap
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bags.c
100 lines (90 loc) · 3.42 KB
/
bags.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/****************************************************************************
**
** This file is part of GAP, a system for computational discrete algebra.
**
** Copyright of GAP belongs to its developers, whose names are too numerous
** to list here. Please refer to the COPYRIGHT file for details.
**
** SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "error.h"
#include "gasman.h"
#include "objects.h" // HACK: for FIRST_IMM_MUT_TNUM; remove this later
/****************************************************************************
**
*V InfoBags[<type>] . . . . . . . . . . . . . . . . . information for bags
*/
#ifdef COUNT_BAGS
TNumInfoBags InfoBags[NUM_TYPES];
#endif
UInt8 SizeAllBags;
#ifdef GAP_KERNEL_DEBUG
void PrecheckRetypeBag(Bag bag, UInt new_type)
{
// If the new type contains an (im)mutability bit, verify that this does
// not remove mutability from an object that was previously mutable --
// something we generally don't allow
if (FIRST_IMM_MUT_TNUM <= new_type && new_type <= LAST_IMM_MUT_TNUM) {
#if !defined(USE_THREADSAFE_COPYING)
// HACK: T_COPYING is used for mutable and immutable objects alike, so
// we can't really determine whether it is "mutable" or not. In
// fact, it is not even a "real" TNUM (it comes after LAST_REAL_TNUM),
// so asking such an object for mutability is not even supported.
//
// In the future, there are at least two ways we could get rid of this
// hack: Either we drop T_COPYING by adopting the copying code from
// HPC-GAP for regular GAP as well. Or we could add an
// IMMUTABLE_OBJ_FLAG which can be used to mark any object as
// immutable, including T_COPYING objects.
if (TNUM_BAG(bag) == T_COPYING)
return;
#endif
#ifndef HPCGAP
// HACK: when using `DeclareGlobalVariable`, the placeholder object of
// type `IsToBeDefinedObj` is immutable, while `InstallValue` also
// accepts mutable values, which are then copied into the placeholder
// *bag* itself, thus turning the placeholder (which is a T_POSOBJ)
// into any different kind of bag, including mutable ones.
if (TNUM_BAG(bag) == T_POSOBJ)
return;
#endif
Int oldImm = !IS_MUTABLE_OBJ(bag);
Int newImm = new_type & IMMUTABLE;
if (oldImm && !newImm) {
ErrorMayQuit(
"RetypeBag: cannot change immutable object to mutable", 0, 0);
}
}
}
#endif
// TODO: perhaps this should become RetypeObj ?
void RetypeBagSM(Bag bag, UInt new_type)
{
if (FIRST_IMM_MUT_TNUM <= new_type && new_type <= LAST_IMM_MUT_TNUM) {
Int oldImm = !IS_MUTABLE_OBJ(bag);
Int newImm = new_type & IMMUTABLE;
if (newImm)
ErrorMayQuit(
"RetypeBagSM: target tnum should not indicate immutability",
0, 0);
if (oldImm)
new_type |= IMMUTABLE;
}
RetypeBag(bag, new_type);
}
#ifdef HPCGAP
void RetypeBagSMIfWritable(Bag bag, UInt new_type)
{
if (FIRST_IMM_MUT_TNUM <= new_type && new_type <= LAST_IMM_MUT_TNUM) {
Int oldImm = !IS_MUTABLE_OBJ(bag);
Int newImm = new_type & IMMUTABLE;
if (newImm)
ErrorMayQuit(
"RetypeBagSM: target tnum should not indicate immutability",
0, 0);
if (oldImm)
new_type |= IMMUTABLE;
}
RetypeBagIfWritable(bag, new_type);
}
#endif