-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
not an issue. just some suggestions #8
Comments
Thanks for suggestion and links! It'll greatly help me build everything up Mostly my goals for this library is to build somehwat of a nogc runtime and if I can borrow more efficient code I will (with right authorship notices ofc) |
Actually biggest problem is typeinfo |
I never attempted to implement it or need it actually. |
İf you inherit all extern c++ classes from a extern c++ CppObject, you may achieve something similar maybe |
Hmm |
not a neat option: linking with a cpp runtime |
I think I'll pass on that one |
Oh, while you're here Edit: |
I am not good at naming stuff either. I should reflect your intention. maybe "stld". not sure though. |
If to reflect intension then it'd be something like |
i think this is doable: https://github.com/dlang/dmd/blob/master/druntime/src/object.d#L587 create a nogc port of TypeInfo class as extern(C++) class TypeInfo https://github.com/dlang/dmd/blob/master/druntime/src/object.d#L587 you will also need porting extern(C++) class TypeInfo_Class : TypeInfo https://github.com/dlang/dmd/blob/master/druntime/src/object.d#L1575 then all extern(C++) classes must have the required member methods via a template mixin or deriving them from a CPPObject class having the required methods. (this is how D classes actually work, all of them is implicitly derived from an Object class) Then create a function: toString method must yield: modulename.ClassName // traits does the trick name field is important to compare two instances or two types, see here: https://github.com/dlang/dmd/blob/master/druntime/src/object.d#L848 opEquals, getHash, equals, compare, name, etc. You are doing this because you want to provide runtime type information for the situations: pseoudo code: import core.stdc.stdio; extern (C++) class Base {} extern(C)
return 0; |
This might work |
Is what I was going to say, but turns out I had to compile library with -betterC flag |
Are you really sure to go for betterC? Even c++ has a runtime. You don't have to go betterC for nogc nothrow code. I would invest nogc code over betterC. İ believe it is not a reasonable approach to expect full functioning OO features without a runtime. C and betterC is already there for the particular needs. What I and many needs in d is a standard library without gc. Please read this article https://www.auburnsounds.com/blog/2016-11-10_Running-D-without-its-runtime.html Not all runtime use GC. I made DCV nogc nothrow. And i am happy with it. https://github.com/libmir/dcv. |
Please also note that reference counted class objects will not be possible untill Walter Bright implements some compiler internals. Then you can forget shared pointers like in c++ for class objects |
I'm just accounting for it
Yea, nogc all the way
That's what I'm doing plus wierd typeinfo thing I did today and will not touch soon
Ooh, I'll note that
Not sure what you're talking about I'm just doing things I can to maybe get some easier time in future, also like, if it's -betterC compatible then it's nogc compatible you know |
To be completely honest I turn on -betterC flag to completely shut up GC It's extremely leaky and Valgrind constantly complains about those leaks which distracts me from preventing my own leaks Yea... Edit: Edit2: |
Ok, spent a lot of time, but now I can do this: interface IInterface {}
class Parent: CppObject {}
class Child: Parent, IInterface {
mixin RTTI!Parent;
mixin RTTI!IInterface;
}
_typeid!Parent.isBaseOf!Child; // true
_typeid!CppObject.isBaseOf!Child; // true
_typeid!IInterface.isBaseOf!Child; // true
_typeid!CppObject.isBaseOf!IInterface; // false
_typeid!CppObject == _typeid!Parent; // false
Child c;
_typeid(c).name; // gonna give fully qualified name of type And so on, something pointer, something name The THING is that it's so complicated and it can't give even a fraction of information of D's TypeInfo |
Ok, turns out I'm way overthinking it |
I will try your typeinfo. I am mostly offline now because of holiday. İt is not so easy but maybe i run my little evalex library with your classes https://github.com/aferust/evalex |
Honestly if to not delve into brokenD then you can just do this: import clib.memory;
class DClass {}
void main() @nogc {
DClass d = _new!DClass();
TypeInfo t = typeid(d);
_free(d);
} And it WILL work I've tested it! https://github.com/al1-ce/clib/blob/master/test/nogc/test_nogc.d |
I found a little moment to test typeinfo and i get two serious linker errors on Windows with ldc. One is related to d array copy. I have a workaround for it i will make a PR for it. Other is about virtual table. vrtbl stuff. |
Can you send those errors here? |
for the first one, we need this. This is a known bug ldc-developers/ldc#2425 version(LDC) extern(C) void _d_array_slice_copy(void* dst, size_t dstlen, void* src, size_t srclen, size_t elemsz){ the second one: clib.lib(clib.typeinfo.obj) : error LNK2001: unresolved external symbol _D14TypeInfo_Class6__vtblZ |
It should't use any. Maybe you're trying to use betterC version in non-betterC or vise-versa? |
İn the test code,'s dub.json i have dflag betterC |
No idea then. Gonna try building in LDC, but can't say about windows since I'm on linux |
Wait a minute Is dependancy clib:betterc or just clib? Its important distinction |
i also corrected to use subpackage. still I had to make some changes to clear some compiler errors. in memory.d void _free(T)(ref T t) @nogc nothrow {
// If there's ~this we wanna call it
static if (__traits(hasMember, T, "__xdtor")){
assumeNothrowNoGC(
(T x)
{
return x.__xdtor(); // without this compiler complains about __xdtor is not nogc
})(t);
}
import core.memory : pureFree;
pureFree(cast(void*) t);
// And if T is nullable then make it null
static if (__traits(compiles, { t = null; })) t = null;
}
import std.traits;
auto assumeNothrowNoGC(T) (T t) if (isFunctionPointer!T || isDelegate!T)
{
enum attrs = functionAttributes!T
| FunctionAttribute.nogc
| FunctionAttribute.nothrow_;
return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t;
}
/// Unmanaged allocator (a wrapper over malloc)
extern(C++) class Mallocator(T): CppObject, IAllocator!T if (isValidAlloccatorType!T()) { // typo cppObject ?
mixin RTTI!(IAllocator!T); // need T here.
.....
And i had to remove alignment parameter from all occurences of allocate, reallocate etc.
my dub.json:
{
"name": "test",
"dependencies": {
"clib:betterc": {"path": "clib-master"}
},
"dflags": ["-betterC"]
} test code is your test_betterc.d |
Alignment parameter kinda has to be there since it'd be required for more advanced allocators Xdtor should be nogc nothrow if ~this is nogc nothrow, gotta be ldc error |
and this: char[200] __cpp_class_inheritance_generator(T)() {
} |
Yea that one I already discovered and fixed |
Ran this abomination:
LDC does complain about _d_array_slice_copy, your code for that function fixed it all and there's no problem on my machine after that. I'm gonna roll out a new version of lib when I'm done with lists and maps |
I finally understand why there's no nogc implementation for at least some basic STL Making it is like throwing myself at wall
|
Please always remember d classes use reference semantics, and extern(C++) classes too. You should use structs for the containers to make life easier. Nogc exceptions exist. Another way allocate your exception with _new and deallocate it in your catch block. dplug library should have something like that. there are module literals FILE and LINE maybe they help locating exception. https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1008.md Please also note that in nogc code you can even run GC code with debug label, of course only for debug builds debug throw new Exception( ... |
Containers are structs, that's the problem and I personally refuse to make them classes because imo if something is like a basic type or container it should be struct and if it's more complex then it's class LINE and FILE give you only immediate line and file 0 struct vector {
1 fail() {
2 msg("fail");
3 }
4 }
5
6 vector v; v.fail();
7
8 void msg(string F = __FILE_, int L = __LINE__) (string msg) {
9 writeln(F, " ", L, " ", msg);
10 } Will print To fix that I'd have to pass line and file everywhere which is bloat Nogc exceptions I don't remember what was about them but there was something Might've been betterc Might drop betterc actually Gonna do testing, so much testing. Hmm, maybe for solving segfaulting self-destruct I could do something like rust's borrow checker with |
I have invented RefCounting! Putting it here as a reminder import std.stdio;
import core.stdc.stdlib;
void main(string[ ] args) {
test!int a = {42};
test!char b = {'b'};
test!bool c = {false};
munk(a);
func(a);
nunk(a);
junk();
punk(255);
punk(100);
test!string d = sunk();
munk(b);
func(c);
writeln("eof");
}
test!int ti;
test!string sunk() {
test!string t = {"nope"};
t = test!string("here here here");
return t;
}
void junk() {
test!string t = {"test"};
func(t);
}
void punk(int k) {
test!int t = {k};
ti = t;
}
void munk(T)(test!T t) {
func(t);
}
void nunk(T)(test!T t) {
ti = t;
}
void func(T)(test!T t){}
struct test(T) {
T t;
size_t* ctr = null;
this(ref scope test!T o) {
if (o.ctr is null) {
o.ctr = cast(size_t*) malloc(size_t.sizeof);
if (o.ctr is null) writeln("malloc failed");
o.ctr[0] = 1;
}
ctr = o.ctr;
t = o.t;
ctr[0] = ctr[0] + 1;
}
~this() {
writeln("dtor for ", t);
if (ctr is null) return;
ctr[0] = ctr[0] - 1;
writeln("ctr - ", ctr[0], " of ", t);
if (ctr[0] == 0) {
writeln("delete ", t);
free(cast(void*) ctr);
}
}
} The trick is that counter is a pointer, which keeps it synced across instances And surprisingly it all works kinda flawlessly. Gonna have to test it in real environment though Gone will be ages of constant ref, scope and segfaults Well, if that works and if issue with exceptions will be just betterc (for which i will abandon betterc) then it's way better, yes Edit: |
Will you implement all from scratch? Or you can speed up using existing libraries
I suggest you to borrow code around
more for nogc
https://github.com/AuburnSounds/Dplug/blob/master/core/dplug/core/nogc.d
https://github.com/AuburnSounds/Dplug/blob/master/core/dplug/core/thread.d
http://mir-algorithm.libmir.org/ mir libraries provide betterc or nogc alternatives for std.algorithm
The text was updated successfully, but these errors were encountered: