Skip to content

Commit c869192

Browse files
authored
feat(core): Support Bool in Any/AnyView (#7)
This PR introduces `bool` support across the stack, including: - Boolean values in `Any`/`AnyView` - `Ref<bool>` and `Optional<bool>` - Boolean fields and `Optional<bool>` fields in C/Python dataclasses - Proper JSON parsing for boolean values - Serialization/deserialization with boolean values - Structural equal/hash with boolean values - Boolean literals in Printer AST
1 parent a7b3452 commit c869192

36 files changed

+1181
-354
lines changed

cpp/c_api_tests.cc

Lines changed: 160 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <cstring>
12
#include <mlc/core/all.h>
23

34
namespace mlc {
@@ -7,6 +8,7 @@ namespace {
78

89
MLC_REGISTER_FUNC("mlc.testing.cxx_none").set_body([]() -> void { return; });
910
MLC_REGISTER_FUNC("mlc.testing.cxx_null").set_body([]() -> void * { return nullptr; });
11+
MLC_REGISTER_FUNC("mlc.testing.cxx_bool").set_body([](bool x) -> bool { return x; });
1012
MLC_REGISTER_FUNC("mlc.testing.cxx_int").set_body([](int x) -> int { return x; });
1113
MLC_REGISTER_FUNC("mlc.testing.cxx_float").set_body([](double x) -> double { return x; });
1214
MLC_REGISTER_FUNC("mlc.testing.cxx_ptr").set_body([](void *x) -> void * { return x; });
@@ -17,6 +19,7 @@ MLC_REGISTER_FUNC("mlc.testing.cxx_raw_str").set_body([](const char *x) { return
1719
/**************** Reflection ****************/
1820

1921
struct TestingCClassObj : public Object {
22+
bool bool_;
2023
int8_t i8;
2124
int16_t i16;
2225
int32_t i32;
@@ -40,6 +43,7 @@ struct TestingCClassObj : public Object {
4043
Dict<Any, Str> dict_any_str;
4144
Dict<Str, List<int>> dict_str_list_int;
4245

46+
Optional<bool> opt_bool;
4347
Optional<int64_t> opt_i64;
4448
Optional<double> opt_f64;
4549
Optional<void *> opt_raw_ptr;
@@ -57,22 +61,22 @@ struct TestingCClassObj : public Object {
5761
Optional<Dict<Any, Str>> opt_dict_any_str;
5862
Optional<Dict<Str, List<int>>> opt_dict_str_list_int;
5963

60-
explicit TestingCClassObj(int8_t i8, int16_t i16, int32_t i32, int64_t i64, float f32, double f64, void *raw_ptr,
61-
DLDataType dtype, DLDevice device, Any any, Func func, UList ulist, UDict udict, Str str_,
62-
Str str_readonly, List<Any> list_any, List<List<int>> list_list_int,
64+
explicit TestingCClassObj(bool bool_, int8_t i8, int16_t i16, int32_t i32, int64_t i64, float f32, double f64,
65+
void *raw_ptr, DLDataType dtype, DLDevice device, Any any, Func func, UList ulist,
66+
UDict udict, Str str_, Str str_readonly, List<Any> list_any, List<List<int>> list_list_int,
6367
Dict<Any, Any> dict_any_any, Dict<Str, Any> dict_str_any, Dict<Any, Str> dict_any_str,
64-
Dict<Str, List<int>> dict_str_list_int, Optional<int64_t> opt_i64, Optional<double> opt_f64,
65-
Optional<void *> opt_raw_ptr, Optional<DLDataType> opt_dtype, Optional<DLDevice> opt_device,
66-
Optional<Func> opt_func, Optional<UList> opt_ulist, Optional<UDict> opt_udict,
67-
Optional<Str> opt_str, Optional<List<Any>> opt_list_any,
68+
Dict<Str, List<int>> dict_str_list_int, Optional<bool> opt_bool, Optional<int64_t> opt_i64,
69+
Optional<double> opt_f64, Optional<void *> opt_raw_ptr, Optional<DLDataType> opt_dtype,
70+
Optional<DLDevice> opt_device, Optional<Func> opt_func, Optional<UList> opt_ulist,
71+
Optional<UDict> opt_udict, Optional<Str> opt_str, Optional<List<Any>> opt_list_any,
6872
Optional<List<List<int>>> opt_list_list_int, Optional<Dict<Any, Any>> opt_dict_any_any,
6973
Optional<Dict<Str, Any>> opt_dict_str_any, Optional<Dict<Any, Str>> opt_dict_any_str,
7074
Optional<Dict<Str, List<int>>> opt_dict_str_list_int)
71-
: i8(i8), i16(i16), i32(i32), i64(i64), f32(f32), f64(f64), raw_ptr(raw_ptr), dtype(dtype), device(device),
72-
any(any), func(func), ulist(ulist), udict(udict), str_(str_), str_readonly(str_readonly), list_any(list_any),
73-
list_list_int(list_list_int), dict_any_any(dict_any_any), dict_str_any(dict_str_any),
74-
dict_any_str(dict_any_str), dict_str_list_int(dict_str_list_int), opt_i64(opt_i64), opt_f64(opt_f64),
75-
opt_raw_ptr(opt_raw_ptr), opt_dtype(opt_dtype), opt_device(opt_device), opt_func(opt_func),
75+
: bool_(bool_), i8(i8), i16(i16), i32(i32), i64(i64), f32(f32), f64(f64), raw_ptr(raw_ptr), dtype(dtype),
76+
device(device), any(any), func(func), ulist(ulist), udict(udict), str_(str_), str_readonly(str_readonly),
77+
list_any(list_any), list_list_int(list_list_int), dict_any_any(dict_any_any), dict_str_any(dict_str_any),
78+
dict_any_str(dict_any_str), dict_str_list_int(dict_str_list_int), opt_bool(opt_bool), opt_i64(opt_i64),
79+
opt_f64(opt_f64), opt_raw_ptr(opt_raw_ptr), opt_dtype(opt_dtype), opt_device(opt_device), opt_func(opt_func),
7680
opt_ulist(opt_ulist), opt_udict(opt_udict), opt_str(opt_str), opt_list_any(opt_list_any),
7781
opt_list_list_int(opt_list_list_int), opt_dict_any_any(opt_dict_any_any), opt_dict_str_any(opt_dict_str_any),
7882
opt_dict_any_str(opt_dict_any_str), opt_dict_str_list_int(opt_dict_str_list_int) {}
@@ -84,6 +88,7 @@ struct TestingCClassObj : public Object {
8488

8589
struct TestingCClass : public ObjectRef {
8690
MLC_DEF_OBJ_REF(MLC_EXPORTS, TestingCClass, TestingCClassObj, ObjectRef)
91+
.Field("bool_", &TestingCClassObj::bool_)
8792
.Field("i8", &TestingCClassObj::i8)
8893
.Field("i16", &TestingCClassObj::i16)
8994
.Field("i32", &TestingCClassObj::i32)
@@ -105,6 +110,7 @@ struct TestingCClass : public ObjectRef {
105110
.Field("dict_str_any", &TestingCClassObj::dict_str_any)
106111
.Field("dict_any_str", &TestingCClassObj::dict_any_str)
107112
.Field("dict_str_list_int", &TestingCClassObj::dict_str_list_int)
113+
.Field("opt_bool", &TestingCClassObj::opt_bool)
108114
.Field("opt_i64", &TestingCClassObj::opt_i64)
109115
.Field("opt_f64", &TestingCClassObj::opt_f64)
110116
.Field("opt_raw_ptr", &TestingCClassObj::opt_raw_ptr)
@@ -121,13 +127,13 @@ struct TestingCClass : public ObjectRef {
121127
.Field("opt_dict_any_str", &TestingCClassObj::opt_dict_any_str)
122128
.Field("opt_dict_str_list_int", &TestingCClassObj::opt_dict_str_list_int)
123129
.MemFn("i64_plus_one", &TestingCClassObj::i64_plus_one)
124-
.StaticFn("__init__",
125-
InitOf<TestingCClassObj, int8_t, int16_t, int32_t, int64_t, float, double, void *, DLDataType, DLDevice,
126-
Any, Func, UList, UDict, Str, Str, List<Any>, List<List<int>>, Dict<Any, Any>, Dict<Str, Any>,
127-
Dict<Any, Str>, Dict<Str, List<int>>, Optional<int64_t>, Optional<double>, Optional<void *>,
128-
Optional<DLDataType>, Optional<DLDevice>, Optional<Func>, Optional<UList>, Optional<UDict>,
129-
Optional<Str>, Optional<List<Any>>, Optional<List<List<int>>>, Optional<Dict<Any, Any>>,
130-
Optional<Dict<Str, Any>>, Optional<Dict<Any, Str>>, Optional<Dict<Str, List<int>>>>);
130+
.StaticFn("__init__", InitOf<TestingCClassObj, bool, int8_t, int16_t, int32_t, int64_t, float, double, void *,
131+
DLDataType, DLDevice, Any, Func, UList, UDict, Str, Str, List<Any>, List<List<int>>,
132+
Dict<Any, Any>, Dict<Str, Any>, Dict<Any, Str>, Dict<Str, List<int>>, Optional<bool>,
133+
Optional<int64_t>, Optional<double>, Optional<void *>, Optional<DLDataType>,
134+
Optional<DLDevice>, Optional<Func>, Optional<UList>, Optional<UDict>, Optional<Str>,
135+
Optional<List<Any>>, Optional<List<List<int>>>, Optional<Dict<Any, Any>>,
136+
Optional<Dict<Str, Any>>, Optional<Dict<Any, Str>>, Optional<Dict<Str, List<int>>>>);
131137
};
132138

133139
/**************** Traceback ****************/
@@ -191,5 +197,140 @@ MLC_REGISTER_FUNC("mlc.testing.nested_type_checking_list").set_body([](Str name)
191197
MLC_UNREACHABLE();
192198
});
193199

200+
/**************** Visitor ****************/
201+
202+
MLC_REGISTER_FUNC("mlc.testing.VisitFields").set_body([](ObjectRef root) {
203+
struct Visitor {
204+
void operator()(MLCTypeField *f, const Any *any) { Push("Any", f->name, *any); }
205+
void operator()(MLCTypeField *f, ObjectRef *obj) { Push("ObjectRef", f->name, *obj); }
206+
void operator()(MLCTypeField *f, Optional<ObjectRef> *opt) { Push("Optional<ObjectRef>", f->name, *opt); }
207+
void operator()(MLCTypeField *f, Optional<bool> *opt) { Push("Optional<bool>", f->name, *opt); }
208+
void operator()(MLCTypeField *f, Optional<int64_t> *opt) { Push("Optional<int64_t>", f->name, *opt); }
209+
void operator()(MLCTypeField *f, Optional<double> *opt) { Push("Optional<double>", f->name, *opt); }
210+
void operator()(MLCTypeField *f, Optional<DLDevice> *opt) { Push("Optional<DLDevice>", f->name, *opt); }
211+
void operator()(MLCTypeField *f, Optional<DLDataType> *opt) { Push("Optional<DLDataType>", f->name, *opt); }
212+
void operator()(MLCTypeField *f, bool *v) { Push("bool", f->name, *v); }
213+
void operator()(MLCTypeField *f, int8_t *v) { Push("int8_t", f->name, *v); }
214+
void operator()(MLCTypeField *f, int16_t *v) { Push("int16_t", f->name, *v); }
215+
void operator()(MLCTypeField *f, int32_t *v) { Push("int32_t", f->name, *v); }
216+
void operator()(MLCTypeField *f, int64_t *v) { Push("int64_t", f->name, *v); }
217+
void operator()(MLCTypeField *f, float *v) { Push("float", f->name, *v); }
218+
void operator()(MLCTypeField *f, double *v) { Push("double", f->name, *v); }
219+
void operator()(MLCTypeField *f, DLDataType *v) { Push("DLDataType", f->name, *v); }
220+
void operator()(MLCTypeField *f, DLDevice *v) { Push("DLDevice", f->name, *v); }
221+
void operator()(MLCTypeField *f, Optional<void *> *v) { Push("Optional<void *>", f->name, *v); }
222+
void operator()(MLCTypeField *f, void **v) { Push("void *", f->name, *v); }
223+
void operator()(MLCTypeField *f, const char **v) { Push("const char *", f->name, *v); }
224+
225+
void Push(const char *ty, const char *name, Any value) {
226+
types->push_back(ty);
227+
names->push_back(name);
228+
values->push_back(value);
229+
}
230+
List<Str> *types;
231+
List<Str> *names;
232+
UList *values;
233+
};
234+
List<Str> types;
235+
List<Str> names;
236+
UList values;
237+
MLCTypeInfo *info = ::mlc::Lib::GetTypeInfo(root.GetTypeIndex());
238+
::mlc::core::VisitFields(root.get(), info, Visitor{&types, &names, &values});
239+
return UList{types, names, values};
240+
});
241+
242+
struct FieldFoundException : public ::std::exception {};
243+
244+
struct FieldGetter {
245+
void operator()(MLCTypeField *f, const Any *any) { Check(f->name, any); }
246+
void operator()(MLCTypeField *f, ObjectRef *obj) { Check(f->name, obj); }
247+
void operator()(MLCTypeField *f, Optional<ObjectRef> *opt) { Check(f->name, opt); }
248+
void operator()(MLCTypeField *f, Optional<bool> *opt) { Check(f->name, opt); }
249+
void operator()(MLCTypeField *f, Optional<int64_t> *opt) { Check(f->name, opt); }
250+
void operator()(MLCTypeField *f, Optional<double> *opt) { Check(f->name, opt); }
251+
void operator()(MLCTypeField *f, Optional<DLDevice> *opt) { Check(f->name, opt); }
252+
void operator()(MLCTypeField *f, Optional<DLDataType> *opt) { Check(f->name, opt); }
253+
void operator()(MLCTypeField *f, bool *v) { Check(f->name, v); }
254+
void operator()(MLCTypeField *f, int8_t *v) { Check(f->name, v); }
255+
void operator()(MLCTypeField *f, int16_t *v) { Check(f->name, v); }
256+
void operator()(MLCTypeField *f, int32_t *v) { Check(f->name, v); }
257+
void operator()(MLCTypeField *f, int64_t *v) { Check(f->name, v); }
258+
void operator()(MLCTypeField *f, float *v) { Check(f->name, v); }
259+
void operator()(MLCTypeField *f, double *v) { Check(f->name, v); }
260+
void operator()(MLCTypeField *f, DLDataType *v) { Check(f->name, v); }
261+
void operator()(MLCTypeField *f, DLDevice *v) { Check(f->name, v); }
262+
void operator()(MLCTypeField *f, Optional<void *> *v) { Check(f->name, v); }
263+
void operator()(MLCTypeField *f, void **v) { Check(f->name, v); }
264+
void operator()(MLCTypeField *f, const char **v) { Check(f->name, v); }
265+
266+
template <typename T> void Check(const char *name, T *v) {
267+
if (std::strcmp(name, target_name) == 0) {
268+
*ret = Any(*v);
269+
throw FieldFoundException();
270+
}
271+
}
272+
const char *target_name;
273+
Any *ret;
274+
};
275+
276+
struct FieldSetter {
277+
void operator()(MLCTypeField *f, Any *any) { Check(f->name, any); }
278+
void operator()(MLCTypeField *f, ObjectRef *obj) { Check(f->name, obj); }
279+
void operator()(MLCTypeField *f, Optional<ObjectRef> *opt) { Check(f->name, opt); }
280+
void operator()(MLCTypeField *f, Optional<bool> *opt) { Check(f->name, opt); }
281+
void operator()(MLCTypeField *f, Optional<int64_t> *opt) { Check(f->name, opt); }
282+
void operator()(MLCTypeField *f, Optional<double> *opt) { Check(f->name, opt); }
283+
void operator()(MLCTypeField *f, Optional<DLDevice> *opt) { Check(f->name, opt); }
284+
void operator()(MLCTypeField *f, Optional<DLDataType> *opt) { Check(f->name, opt); }
285+
void operator()(MLCTypeField *f, bool *v) { Check(f->name, v); }
286+
void operator()(MLCTypeField *f, int8_t *v) { Check(f->name, v); }
287+
void operator()(MLCTypeField *f, int16_t *v) { Check(f->name, v); }
288+
void operator()(MLCTypeField *f, int32_t *v) { Check(f->name, v); }
289+
void operator()(MLCTypeField *f, int64_t *v) { Check(f->name, v); }
290+
void operator()(MLCTypeField *f, float *v) { Check(f->name, v); }
291+
void operator()(MLCTypeField *f, double *v) { Check(f->name, v); }
292+
void operator()(MLCTypeField *f, DLDataType *v) { Check(f->name, v); }
293+
void operator()(MLCTypeField *f, DLDevice *v) { Check(f->name, v); }
294+
void operator()(MLCTypeField *f, Optional<void *> *v) { Check(f->name, v); }
295+
void operator()(MLCTypeField *f, void **v) { Check(f->name, v); }
296+
void operator()(MLCTypeField *f, const char **v) { Check(f->name, v); }
297+
298+
template <typename T> void Check(const char *name, T *v) {
299+
if (std::strcmp(name, target_name) == 0) {
300+
if constexpr (std::is_same_v<T, Any>) {
301+
*v = src;
302+
} else {
303+
*v = src.operator T();
304+
}
305+
throw FieldFoundException();
306+
}
307+
}
308+
const char *target_name;
309+
Any src;
310+
};
311+
312+
MLC_REGISTER_FUNC("mlc.testing.FieldGet").set_body([](ObjectRef root, const char *target_name) {
313+
Any ret;
314+
MLCTypeInfo *info = ::mlc::Lib::GetTypeInfo(root.GetTypeIndex());
315+
try {
316+
::mlc::core::VisitFields(root.get(), info, FieldGetter{target_name, &ret});
317+
} catch (FieldFoundException &) {
318+
return ret;
319+
}
320+
MLC_THROW(ValueError) << "Field not found: " << target_name;
321+
MLC_UNREACHABLE();
322+
});
323+
324+
MLC_REGISTER_FUNC("mlc.testing.FieldSet").set_body([](ObjectRef root, const char *target_name, Any src) {
325+
MLCTypeInfo *info = ::mlc::Lib::GetTypeInfo(root.GetTypeIndex());
326+
try {
327+
::mlc::core::VisitFields(root.get(), info, FieldSetter{target_name, src});
328+
} catch (FieldFoundException &) {
329+
return;
330+
}
331+
MLC_THROW(ValueError) << "Field not found: " << target_name;
332+
MLC_UNREACHABLE();
333+
});
334+
194335
} // namespace
195336
} // namespace mlc

cpp/json.cc

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
#include <sstream>
55

66
namespace mlc {
7-
namespace core {
87
namespace {
98

9+
using mlc::core::TopoVisit;
10+
using mlc::core::VisitFields;
11+
1012
mlc::Str Serialize(Any any);
1113
Any Deserialize(const char *json_str, int64_t json_str_len);
1214
Any JSONLoads(const char *json_str, int64_t json_str_len);
@@ -35,11 +37,13 @@ inline mlc::Str Serialize(Any any) {
3537
// clang-format off
3638
MLC_INLINE void operator()(MLCTypeField *, ObjectRef *obj) { if (Object *v = obj->get()) EmitObject(v); else EmitNil(); }
3739
MLC_INLINE void operator()(MLCTypeField *, Optional<ObjectRef> *opt) { if (Object *v = opt->get()) EmitObject(v); else EmitNil(); }
40+
MLC_INLINE void operator()(MLCTypeField *, Optional<bool> *opt) { if (const bool *v = opt->get()) EmitBool(*v); else EmitNil(); }
3841
MLC_INLINE void operator()(MLCTypeField *, Optional<int64_t> *opt) { if (const int64_t *v = opt->get()) EmitInt(*v); else EmitNil(); }
3942
MLC_INLINE void operator()(MLCTypeField *, Optional<double> *opt) { if (const double *v = opt->get()) EmitFloat(*v); else EmitNil(); }
4043
MLC_INLINE void operator()(MLCTypeField *, Optional<DLDevice> *opt) { if (const DLDevice *v = opt->get()) EmitDevice(*v); else EmitNil(); }
4144
MLC_INLINE void operator()(MLCTypeField *, Optional<DLDataType> *opt) { if (const DLDataType *v = opt->get()) EmitDType(*v); else EmitNil(); }
4245
// clang-format on
46+
MLC_INLINE void operator()(MLCTypeField *, bool *v) { EmitBool(*v); }
4347
MLC_INLINE void operator()(MLCTypeField *, int8_t *v) { EmitInt(static_cast<int64_t>(*v)); }
4448
MLC_INLINE void operator()(MLCTypeField *, int16_t *v) { EmitInt(static_cast<int64_t>(*v)); }
4549
MLC_INLINE void operator()(MLCTypeField *, int32_t *v) { EmitInt(static_cast<int64_t>(*v)); }
@@ -56,6 +60,7 @@ inline mlc::Str Serialize(Any any) {
5660
MLC_THROW(TypeError) << "Unserializable type: const char *";
5761
}
5862
inline void EmitNil() { (*os) << ", null"; }
63+
inline void EmitBool(bool v) { (*os) << ", " << (v ? "true" : "false"); }
5964
inline void EmitFloat(double v) { (*os) << ", " << std::fixed << std::setprecision(19) << v; }
6065
inline void EmitInt(int64_t v) {
6166
int32_t type_int = (*get_json_type_index)(TypeTraits<int64_t>::type_str);
@@ -73,6 +78,8 @@ inline mlc::Str Serialize(Any any) {
7378
int32_t type_index = any->type_index;
7479
if (type_index == kMLCNone) {
7580
EmitNil();
81+
} else if (type_index == kMLCBool) {
82+
EmitBool(any->operator bool());
7683
} else if (type_index == kMLCInt) {
7784
EmitInt(any->operator int64_t());
7885
} else if (type_index == kMLCFloat) {
@@ -144,6 +151,9 @@ inline mlc::Str Serialize(Any any) {
144151
TopoVisit(any.operator Object *(), nullptr, on_visit);
145152
} else if (any.type_index == kMLCNone) {
146153
os << "null";
154+
} else if (any.type_index == kMLCBool) {
155+
bool v = any.operator bool();
156+
os << (v ? "true" : "false");
147157
} else if (any.type_index == kMLCInt) {
148158
int32_t type_int = get_json_type_index(TypeTraits<int64_t>::type_str);
149159
int64_t v = any;
@@ -211,7 +221,8 @@ inline Any Deserialize(const char *json_str, int64_t json_str_len) {
211221
}
212222
} else if (arg.type_index == kMLCList) {
213223
list[j] = invoke_init(arg.operator UList());
214-
} else if (arg.type_index == kMLCStr || arg.type_index == kMLCFloat || arg.type_index == kMLCNone) {
224+
} else if (arg.type_index == kMLCStr || arg.type_index == kMLCBool || arg.type_index == kMLCFloat ||
225+
arg.type_index == kMLCNone) {
215226
// Do nothing
216227
} else {
217228
MLC_THROW(ValueError) << "Unexpected value: " << arg;
@@ -223,6 +234,7 @@ inline Any Deserialize(const char *json_str, int64_t json_str_len) {
223234
values[i] = values[k];
224235
} else if (obj.type_index == kMLCStr) {
225236
// Do nothing
237+
// TODO: how about kMLCBool, kMLCFloat, kMLCNone?
226238
} else {
227239
MLC_THROW(ValueError) << "Unexpected value: " << obj;
228240
}
@@ -277,10 +289,10 @@ inline Any JSONLoads(const char *json_str, int64_t json_str_len) {
277289
Any ParseBoolean() {
278290
if (PeekChar() == 't') {
279291
ExpectString("true", 4);
280-
return Any(1);
292+
return Any(true);
281293
} else {
282294
ExpectString("false", 5);
283-
return Any(0);
295+
return Any(false);
284296
}
285297
}
286298

@@ -479,23 +491,27 @@ inline Any JSONLoads(const char *json_str, int64_t json_str_len) {
479491
}
480492
return JSONParser{0, json_str_len, json_str}.Parse();
481493
}
494+
} // namespace
495+
} // namespace mlc
482496

483-
MLC_REGISTER_FUNC("mlc.core.JSONLoads").set_body([](AnyView json_str) {
497+
namespace mlc {
498+
499+
Any JSONLoads(AnyView json_str) {
484500
if (json_str.type_index == kMLCRawStr) {
485-
return ::mlc::core::JSONLoads(json_str.operator const char *());
501+
return JSONLoads(json_str.operator const char *());
486502
} else {
487-
::mlc::Str str = json_str;
488-
return ::mlc::core::JSONLoads(str);
503+
return JSONLoads(json_str.operator Str());
489504
}
490-
});
491-
MLC_REGISTER_FUNC("mlc.core.JSONSerialize").set_body(::mlc::core::Serialize);
492-
MLC_REGISTER_FUNC("mlc.core.JSONDeserialize").set_body([](AnyView json_str) {
505+
}
506+
507+
Any JSONDeserialize(AnyView json_str) {
493508
if (json_str.type_index == kMLCRawStr) {
494-
return ::mlc::core::Deserialize(json_str.operator const char *());
509+
return Deserialize(json_str.operator const char *());
495510
} else {
496-
return ::mlc::core::Deserialize(json_str.operator ::mlc::Str());
511+
return Deserialize(json_str.operator ::mlc::Str());
497512
}
498-
});
499-
} // namespace
500-
} // namespace core
513+
}
514+
515+
Str JSONSerialize(AnyView source) { return Serialize(source); }
516+
501517
} // namespace mlc

0 commit comments

Comments
 (0)