// examples/classes // BEGIN mycpp output #include "gc_heap.h" using gc_heap::Alloc; using gc_heap::kZeroMask; using gc_heap::StackRoots; #include "my_runtime.h" #include "mylib2.h" using gc_heap::NewStr; using gc_heap::NewList; using gc_heap::NewDict; GLOBAL_STR(str0, "TextOutput constructor"); GLOBAL_STR(str1, "Base"); GLOBAL_STR(str2, "Derived"); GLOBAL_STR(str3, "foo\n"); GLOBAL_STR(str4, "bar\n"); GLOBAL_STR(str5, "Wrote %d bytes"); GLOBAL_STR(str6, "foo\n"); GLOBAL_STR(str7, "Ran %d iterations"); GLOBAL_STR(str8, "Wrote %d bytes"); namespace classes { // forward declare class ColorOutput; class TextOutput; class Base; class Derived; } // forward declare namespace classes namespace classes { // declare class ColorOutput : public gc_heap::Obj { public: ColorOutput(mylib::Writer* f); void write(Str* s); mylib::Writer* f; int num_chars; DISALLOW_COPY_AND_ASSIGN(ColorOutput) }; class TextOutput : public ColorOutput { public: TextOutput(mylib::Writer* f); DISALLOW_COPY_AND_ASSIGN(TextOutput) }; class Base : public gc_heap::Obj { public: Base(); virtual Str* method(); int x(); DISALLOW_COPY_AND_ASSIGN(Base) }; class Derived : public Base { public: Derived(); virtual Str* method(); int y(); DISALLOW_COPY_AND_ASSIGN(Derived) }; extern classes::Derived* GLOBAL; Str* f(classes::Base* obj); void run_tests(); void run_benchmarks(); inline Str* fmt0(int a0) { gBuf.reset(); gBuf.write_const("Wrote ", 6); gBuf.format_d(a0); gBuf.write_const(" bytes", 6); return gBuf.getvalue(); } inline Str* fmt1(int a0) { gBuf.reset(); gBuf.write_const("Ran ", 4); gBuf.format_d(a0); gBuf.write_const(" iterations", 11); return gBuf.getvalue(); } inline Str* fmt2(int a0) { gBuf.reset(); gBuf.write_const("Wrote ", 6); gBuf.format_d(a0); gBuf.write_const(" bytes", 6); return gBuf.getvalue(); } } // declare namespace classes namespace classes { // define ColorOutput::ColorOutput(mylib::Writer* f) : gc_heap::Obj(Tag::FixedSize, kZeroMask, sizeof(ColorOutput)) { this->f = f; this->num_chars = 0; } void ColorOutput::write(Str* s) { StackRoots _roots({&s}); this->f->write(s); this->num_chars += len(s); } TextOutput::TextOutput(mylib::Writer* f) : ColorOutput(f) { print(str0); } Base::Base() : gc_heap::Obj(Tag::FixedSize, kZeroMask, sizeof(Base)) { ; // pass } Str* Base::method() { return str1; } int Base::x() { return 42; } Derived::Derived() : Base() { } Str* Derived::method() { return str2; } int Derived::y() { return 43; } Derived gobj0; classes::Derived* GLOBAL = &gobj0; Str* f(classes::Base* obj) { StackRoots _roots({&obj}); return obj->method(); } void run_tests() { mylib::Writer* stdout = nullptr; classes::TextOutput* out = nullptr; classes::Derived* d = nullptr; StackRoots _roots({&stdout, &out, &d}); stdout = mylib::Stdout(); out = Alloc(stdout); out->write(str3); out->write(str4); println_stderr(fmt0(out->num_chars)); d = Alloc(); print(d->method()); print(f(d)); print(GLOBAL->method()); } void run_benchmarks() { int n; int x; int result; mylib::BufWriter* f = nullptr; classes::TextOutput* out = nullptr; int i; StackRoots _roots({&f, &out}); n = 50000; x = 33; result = -1; f = Alloc(); out = Alloc(f); i = 0; while (i < n) { out->write(str6); i += 1; } println_stderr(fmt1(n)); println_stderr(fmt2(out->num_chars)); } } // define namespace classes int main(int argc, char **argv) { // gc_heap::gHeap.Init(512); gc_heap::gHeap.Init(128 << 10); // 128 KiB; doubling in size // gc_heap::gHeap.Init(400 << 20); // 400 MiB to avoid garbage collection if (getenv("BENCHMARK")) { fprintf(stderr, "Benchmarking...\n"); classes::run_benchmarks(); } else { classes::run_tests(); } }