Skip to content

Commit 199101f

Browse files
committed
Strings are nullable in AS3. Gross
1 parent c108178 commit 199101f

File tree

18 files changed

+288
-138
lines changed

18 files changed

+288
-138
lines changed

Native/BytecodeEditor/include/ABC/ABCFile.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "ABC/Script.hpp"
1111
#include <algorithm>
1212
#include <limits>
13+
#include <optional>
1314
#include <stdint.h>
1415
#include <string>
1516

@@ -21,7 +22,7 @@ namespace SWFABC
2122
std::vector<int64_t> ints;
2223
std::vector<uint64_t> uints;
2324
std::vector<double> doubles;
24-
std::vector<std::string> strings;
25+
std::vector<std::optional<std::string>> strings;
2526
std::vector<Namespace> namespaces;
2627
std::vector<std::vector<int32_t>> namespaceSets;
2728
std::vector<Multiname> multinames;
@@ -50,7 +51,7 @@ namespace SWFABC
5051
uints = {NULL_UINT};
5152
doubles = {NULL_DOUBLE};
5253

53-
strings = {""};
54+
strings = {std::nullopt};
5455
namespaces = {{}};
5556
namespaceSets = {{}};
5657
multinames = {{}};

Native/BytecodeEditor/include/ABC/ABCWriter.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ namespace SWFABC
7272
_abc.doubles, [this](auto v) { writeD64(v); }, 1);
7373
writeU30(oneToZero(_abc.strings.size()));
7474
writeTable(
75-
_abc.strings, [this](auto v) { writeString(v); }, 1);
75+
_abc.strings, [this](auto v) { writeString(v.value()); }, 1);
7676
writeU30(oneToZero(_abc.namespaces.size()));
7777
writeTable(
7878
_abc.namespaces, [this](auto v) { writeNamespace(v); }, 1);

Native/BytecodeEditor/include/ASASM/AStoABC.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace ASASM
2222
ValuePool<int64_t> ints;
2323
ValuePool<uint64_t> uints;
2424
ValuePool<double> doubles;
25-
ValuePool<std::string> strings;
25+
ValuePool<std::optional<std::string>> strings;
2626
ValuePool<ASASM::Namespace> namespaces;
2727
ValuePool<std::vector<ASASM::Namespace>> namespaceSets;
2828
ValuePool<ASASM::Multiname> multinames;
@@ -38,7 +38,7 @@ namespace ASASM
3838

3939
void visitDouble(double v) { doubles.add(v); }
4040

41-
void visitString(const std::string& v) { strings.add(v); }
41+
void visitString(const std::optional<std::string>& v) { strings.add(v); }
4242

4343
void visitNamespace(const Namespace& ns)
4444
{

Native/BytecodeEditor/include/ASASM/Instruction.hpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ namespace ASASM
2222
struct Argument
2323
{
2424
private:
25-
std::variant<std::monostate, int8_t, uint8_t, int64_t, uint64_t, double, std::string,
26-
Namespace, Multiname, std::shared_ptr<Class>, std::shared_ptr<Method>,
27-
SWFABC::Label, std::vector<SWFABC::Label>>
25+
std::variant<std::monostate, int8_t, uint8_t, int64_t, uint64_t, double,
26+
std::optional<std::string>, Namespace, Multiname, std::shared_ptr<Class>,
27+
std::shared_ptr<Method>, SWFABC::Label, std::vector<SWFABC::Label>>
2828
data;
2929

3030
public:
@@ -58,11 +58,17 @@ namespace ASASM
5858

5959
void doublev(const double& v) { data = v; }
6060

61-
[[nodiscard]] std::string& stringv() { return std::get<std::string>(data); }
61+
[[nodiscard]] std::optional<std::string>& stringv()
62+
{
63+
return std::get<std::optional<std::string>>(data);
64+
}
6265

63-
[[nodiscard]] const std::string& stringv() const { return std::get<std::string>(data); }
66+
[[nodiscard]] const std::optional<std::string>& stringv() const
67+
{
68+
return std::get<std::optional<std::string>>(data);
69+
}
6470

65-
void stringv(const std::string& v) { data = v; }
71+
void stringv(const std::optional<std::string>& v) { data = v; }
6672

6773
[[nodiscard]] Namespace& namespacev() { return std::get<Namespace>(data); }
6874

Native/BytecodeEditor/include/ASASM/Metadata.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ namespace ASASM
88
{
99
struct Metadata
1010
{
11-
std::string name;
12-
std::vector<std::pair<std::string, std::string>> data;
11+
std::optional<std::string> name;
12+
std::vector<std::pair<std::optional<std::string>, std::optional<std::string>>> data;
1313

1414
auto operator<=>(const Metadata&) const noexcept = default;
1515
bool operator==(const Metadata&) const noexcept = default;

Native/BytecodeEditor/include/ASASM/Method.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ namespace ASASM
1515
{
1616
std::vector<Multiname> paramTypes;
1717
Multiname returnType;
18-
std::string name;
18+
std::optional<std::string> name;
1919
uint8_t flags = 0;
2020
std::vector<Value> options;
21-
std::vector<std::string> paramNames;
21+
std::vector<std::optional<std::string>> paramNames;
2222

2323
uint32_t id = 0;
2424

2525
std::optional<MethodBody> vbody;
2626

27-
std::string toString() const { return name; }
27+
std::string toString() const { return name.value_or("<unnamed_method>"); }
2828

2929
auto operator<=>(const Method&) const noexcept = default;
3030
bool operator==(const Method&) const noexcept = default;

Native/BytecodeEditor/include/ASASM/Multiname.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <algorithm>
88
#include <memory>
9+
#include <optional>
910
#include <stdint.h>
1011
#include <variant>
1112
#include <vector>
@@ -17,15 +18,15 @@ namespace ASASM
1718
struct _QName
1819
{
1920
Namespace ns;
20-
std::string name;
21+
std::optional<std::string> name;
2122

2223
auto operator<=>(const _QName&) const noexcept = default;
2324
bool operator==(const _QName&) const noexcept = default;
2425
};
2526

2627
struct _RTQName
2728
{
28-
std::string name;
29+
std::optional<std::string> name;
2930
auto operator<=>(const _RTQName&) const noexcept = default;
3031
bool operator==(const _RTQName&) const noexcept = default;
3132
};
@@ -38,7 +39,7 @@ namespace ASASM
3839

3940
struct _Multiname
4041
{
41-
std::string name;
42+
std::optional<std::string> name;
4243
std::vector<Namespace> nsSet;
4344
auto operator<=>(const _Multiname&) const noexcept = default;
4445
bool operator==(const _Multiname&) const noexcept = default;

Native/BytecodeEditor/include/ASASM/Namespace.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace ASASM
1111
struct Namespace
1212
{
1313
ABCType kind = ABCType::Void;
14-
std::string name;
14+
std::optional<std::string> name;
1515

1616
int id = 0;
1717

Native/BytecodeEditor/include/ASASM/Value.hpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include "ASASM/Namespace.hpp"
44
#include "enums/ABCType.hpp"
55

6+
#include <optional>
7+
#include <string>
68
#include <variant>
79

810
namespace ASASM
@@ -29,11 +31,17 @@ namespace ASASM
2931

3032
void vdouble(const double& v) { data = v; }
3133

32-
[[nodiscard]] std::string& vstring() { return std::get<std::string>(data); }
34+
[[nodiscard]] std::optional<std::string>& vstring()
35+
{
36+
return std::get<std::optional<std::string>>(data);
37+
}
3338

34-
[[nodiscard]] const std::string& vstring() const { return std::get<std::string>(data); }
39+
[[nodiscard]] const std::optional<std::string>& vstring() const
40+
{
41+
return std::get<std::optional<std::string>>(data);
42+
}
3543

36-
void vstring(const std::string& v) { data = v; }
44+
void vstring(const std::optional<std::string>& v) { data = v; }
3745

3846
[[nodiscard]] Namespace& vnamespace() { return std::get<Namespace>(data); }
3947

@@ -81,6 +89,8 @@ namespace ASASM
8189
bool operator==(const Value&) const noexcept = default;
8290

8391
private:
84-
std::variant<std::monostate, int64_t, uint64_t, double, std::string, Namespace> data;
92+
std::variant<std::monostate, int64_t, uint64_t, double, std::optional<std::string>,
93+
Namespace>
94+
data;
8595
};
8696
}

Native/BytecodeEditor/include/Assembler.hpp

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -147,27 +147,27 @@ class Assembler
147147

148148
if (word == "mixin")
149149
{
150-
pushFile(std::make_shared<SourceFile>("#mixin", readString()));
150+
pushFile(std::make_shared<SourceFile>("#mixin", readRealString()));
151151
}
152152
else if (word == "call")
153153
{
154154
auto rsLambda = [this] { return readString(); };
155-
pushFile(std::make_shared<SourceFile>(
156-
"#call", readString(), readList<'(', ')', false>([this] { return readString(); })));
155+
pushFile(std::make_shared<SourceFile>("#call", readRealString(),
156+
readList<'(', ')', false>([this] { return readRealString(); })));
157157
}
158158
else if (word == "include")
159159
{
160-
std::string s = readString();
160+
std::string s = readRealString();
161161
pushFile(std::make_shared<SourceFile>(s, strings.at(s)));
162162
}
163163
else if (word == "get")
164164
{
165-
std::string s = readString();
165+
std::string s = readRealString();
166166
pushFile(std::make_shared<SourceFile>(s, toStringLiteral(strings.at(s))));
167167
}
168168
else if (word == "set")
169169
{
170-
vars[readWord()] = readString();
170+
vars[readWord()] = readRealString();
171171
}
172172
else if (word == "unset")
173173
{
@@ -206,7 +206,7 @@ class Assembler
206206
bool asStringLiteral = false;
207207
if (peekChar() == '"')
208208
{
209-
name = readString();
209+
name = readRealString();
210210
asStringLiteral = true;
211211
}
212212
else
@@ -404,9 +404,9 @@ class Assembler
404404
fail();
405405
}
406406
}
407-
else if constexpr (std::is_same_v<std::string, comp>)
407+
else if constexpr (std::is_same_v<std::optional<std::string>, comp>)
408408
{
409-
if (!obj.empty())
409+
if (obj)
410410
{
411411
fail();
412412
}
@@ -647,7 +647,17 @@ class Assembler
647647
return strtod(w.c_str(), nullptr);
648648
}
649649

650-
std::string readString()
650+
std::string readRealString()
651+
{
652+
auto ret = readString();
653+
if (!ret)
654+
{
655+
throw StringException("Null string found where real string expected");
656+
}
657+
return *ret;
658+
}
659+
660+
std::optional<std::string> readString()
651661
{
652662
skipWhitespace();
653663
char c = readSymbol();
@@ -656,7 +666,7 @@ class Assembler
656666
std::string word = readWord();
657667
if (c == 'n' && word == "ull")
658668
{
659-
return {};
669+
return std::nullopt;
660670
}
661671
else
662672
{
@@ -714,12 +724,12 @@ class Assembler
714724

715725
ABCType kind = toABCType(word);
716726
expectSymbol('(');
717-
std::string name = readString();
718-
int id = 0;
727+
std::optional<std::string> name = readString();
728+
int id = 0;
719729
if (peekChar() == ',')
720730
{
721731
skipChar();
722-
std::string s = readString();
732+
std::string s = readRealString();
723733
auto found = std::find(namespaceLabels.begin(), namespaceLabels.end(), s);
724734
if (found != namespaceLabels.end())
725735
{
@@ -976,7 +986,7 @@ class Assembler
976986
{
977987
ASASM::Metadata ret;
978988
ret.name = readString();
979-
std::vector<std::string> items;
989+
std::vector<std::optional<std::string>> items;
980990
while (true)
981991
{
982992
std::string word = readWord();
@@ -1025,7 +1035,7 @@ class Assembler
10251035
}
10261036
else if (word == "refid")
10271037
{
1028-
addUnique<addUniqueMethod>(methodsByID, readString(), ret);
1038+
addUnique<addUniqueMethod>(methodsByID, readRealString(), ret);
10291039
}
10301040
else if (word == "param")
10311041
{
@@ -1118,7 +1128,7 @@ class Assembler
11181128
std::string word = readWord();
11191129
if (word == "refid")
11201130
{
1121-
addUnique<addUniqueClass>(classesByID, readString(), ret);
1131+
addUnique<addUniqueClass>(classesByID, readRealString(), ret);
11221132
}
11231133
else if (word == "instance")
11241134
{
@@ -1341,12 +1351,12 @@ class Assembler
13411351
case OPCodeArgumentType::Class:
13421352
instruction.arguments[i].classv({});
13431353
localClassFixups.emplace_back(
1344-
currentFile->position(), ret.size(), i, readString(), 0);
1354+
currentFile->position(), ret.size(), i, readRealString(), 0);
13451355
break;
13461356
case OPCodeArgumentType::Method:
13471357
instruction.arguments[i].methodv({});
13481358
localMethodFixups.emplace_back(
1349-
currentFile->position(), ret.size(), i, readString(), 0);
1359+
currentFile->position(), ret.size(), i, readRealString(), 0);
13501360
break;
13511361

13521362
case OPCodeArgumentType::JumpTarget:
@@ -1401,7 +1411,7 @@ class Assembler
14011411
{
14021412
ret[f.ii].arguments[f.ai].jumpTarget(parseLabel(f.name, labels));
14031413
}
1404-
catch (std::exception& e)
1414+
catch (std::exception&)
14051415
{
14061416
setFile(f.where.load());
14071417
throw;
@@ -1414,7 +1424,7 @@ class Assembler
14141424
{
14151425
ret[f.ii].arguments[f.ai].switchTargets()[f.si] = parseLabel(f.name, labels);
14161426
}
1417-
catch (std::exception& e)
1427+
catch (std::exception&)
14181428
{
14191429
setFile(f.where.load());
14201430
throw;
@@ -1443,7 +1453,7 @@ class Assembler
14431453
{
14441454
return parseLabel(word, labels);
14451455
}
1446-
catch (std::exception& e)
1456+
catch (std::exception&)
14471457
{
14481458
backpedal(word.size());
14491459
throw;

0 commit comments

Comments
 (0)