Convert the JSON code to use D slices instead of pointers#8555
Convert the JSON code to use D slices instead of pointers#8555JinShil merged 7 commits intodlang:masterfrom
Conversation
|
Thanks for your pull request and interest in making D better, @Geod24! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. Bugzilla referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub fetch digger
dub run digger -- build "master + dmd#8555" |
7934d97 to
310aa16
Compare
src/dmd/json.d
Outdated
| if (type) | ||
| { | ||
| property(name, type.toChars()); | ||
| property(name, RootObject.toString(type)); |
There was a problem hiding this comment.
Not too thrilled about this. It should be type.toString(). Yes, the C++ code cannot call it, but all you need to do is put a dummy function declaration there on the C++ side so the vtbl[] entries line up.
| return buf.extractString(); | ||
| } | ||
|
|
||
| extern (D) const(char)[] toString() const |
There was a problem hiding this comment.
As I mentioned before, toString() is used pervasively in dmd, and as long as it does what the other toString()'s do, adding a Ddoc for it is redundant.
There was a problem hiding this comment.
While I agree that a comment is not really necessary here, you have to add some ddoc comment to make the function appear in the documentation at all. Not sure if that is a good thing as you have to litter the code with empty comments this way. Is there an option to put all (public) symbols into the documentation?
There was a problem hiding this comment.
For the record I added a (trivial) DDOC comment just for this reason (documentation)
| return null; | ||
| } | ||
|
|
||
| extern (D) const(char)[] stcToString(ref StorageClass stc) |
| return trustToString(trust).ptr; | ||
| } | ||
|
|
||
| extern (D) string trustToString(TRUST trust) |
| return protectionToString(kind).ptr; | ||
| } | ||
|
|
||
| extern (D) string protectionToString(Prot.Kind kind) |
src/dmd/json.d
Outdated
| if (auto filename = toDString(loc.filename)) | ||
| { | ||
| if (!this.filename || strcmp(filename, this.filename)) | ||
| if (!this.filename.length || filename != this.filename) |
There was a problem hiding this comment.
I'm guessing you're trying keep the new to code be as close as possible to the old code but this first expression (!this.filename.length) isn't needed anymore?
|
Updated according to feedback |
src/dmd/dmodule.d
Outdated
| return buf.extractString(); | ||
| } | ||
|
|
||
| /// Provide an human readable representation |
src/dmd/hdrgen.d
Outdated
|
|
||
| /** | ||
| * Returns: | ||
| * an human readable representation of `stc` |
src/dmd/hdrgen.d
Outdated
|
|
||
| /** | ||
| * Returns: | ||
| * an human readable representation of `trust`, |
src/dmd/hdrgen.d
Outdated
|
|
||
| /** | ||
| * Returns: | ||
| * an human readable representation of `kind` |
| } | ||
|
|
||
| void stringPart(const(char)* s) | ||
| extern(D) void stringPart(const(char)[] s) |
There was a problem hiding this comment.
Wouldn't all non-visit members of this visitor be private? Ergo you can just add extern(D): at the top of this body rather than adding it for each individual function.
Think about it for future refactor.
There was a problem hiding this comment.
True that. At the moment I'm putting extern(D) right and left (got more slice-ification coming), but I also had weird bugs (compiler SEGV) being triggered in the past some I decided to go for verbose and simple. But when enough is converted, we surely can do that.
| } while (value); | ||
| return buf[i .. $]; | ||
| } | ||
|
|
There was a problem hiding this comment.
Seems like a leftover from a previous attempt here.
There was a problem hiding this comment.
It is, but also its own commit
|
Fixed |
src/dmd/json.d
Outdated
| static extern(D) const(char)[] toDString (const(char)* s) | ||
| { | ||
| return s ? s[0 .. strlen(s)] : null; | ||
| } |
There was a problem hiding this comment.
Why not put this as a global function into utils or similar? It's used at other places too and doesn't really fit in ToJsonVisitor
There was a problem hiding this comment.
Didn't expect it to be so widely used :(
Also I'm wary that dmd.utils will be imported everywhere soon.
But let's give it a shot...
src/dmd/hdrgen.d
Outdated
| extern (D) const(char)[] stcToString(ref StorageClass stc) | ||
| { | ||
| auto p = stcToChars(stc); | ||
| return p[0 .. strlen(p)]; |
There was a problem hiding this comment.
Could use toDString from below.
src/dmd/dmodule.d
Outdated
| extern (D) const(char)[] toString() const | ||
| { | ||
| auto p = this.toChars(); | ||
| return p[0 .. strlen(p)]; |
There was a problem hiding this comment.
Could use toDString from below.
src/dmd/json.d
Outdated
| property("kind", s.kind()); | ||
| property("comment", s.comment); | ||
| property("kind", toDString(s.kind())); | ||
| property("comment", toDString(s.comment)); |
There was a problem hiding this comment.
Nit: another advantage of making toDString a global function is that you can do the more natural: s.comment.toDString()
| { | ||
| import core.stdc.string : strlen; | ||
| auto p = this.toChars(); | ||
| return p[0 .. strlen(p)]; |
There was a problem hiding this comment.
Could use toDString from above.
There was a problem hiding this comment.
Here I choose not to, as we want rootobject to depends on as little as possible.
|
Addressed @wilzbach 's comments |
|
Since this has gotten a bit more reviews, and one might be wondering where I am going, I added a bit more diff than originally intended:
As for the end goal is, it's to be able to do this gradually. |
src/tests/cxxfrontend.c
Outdated
| semantic3(m, NULL); | ||
|
|
||
| // Basic test for D slice passing | ||
| DArray<const char> sl = m->toString(); |
There was a problem hiding this comment.
Does this work on Windows? I’ve been told D arrays are returned in registers while structs of this size are not on Windows.
There was a problem hiding this comment.
I should've known it was too good to be true.
I'll wait for the auto-tester to tell me what's the situation with Windows, but it fails on 32 bits.
So I guess I will take that test out for now :'(
There was a problem hiding this comment.
Hum, the C++ frontend tests only run on POSIX anyway...
| } | ||
|
|
||
| /// Slices a `\0`-terminated C-string, excluding the terminator | ||
| const(char)[] toDString (const(char)* s) pure nothrow @nogc |
There was a problem hiding this comment.
toString is to provide a string representation, this is to convert a const(char)* to a const(char)[].
7cc187a to
b5641b3
Compare
What's the deal with that warning ?? |
Yeah that's the newly added Dscanner static code analysis check and the idea is that the checks slowly allow to modernize DMD / enforce some automatic code checking.
tl;dr: in this case, add your module to this list: Line 118 in 48726c8 |
|
@wilzbach : Thanks, glad to see there's a way out of it! |
| virtual const char *toChars(); | ||
| /// This function is `extern(D)` and should not be called from C++, | ||
| /// as the ABI does not match on some platforms | ||
| virtual DArray<const char> toString(); |
There was a problem hiding this comment.
Is it possible to implement this on the C++ and have the implementation assert?
If we want to use DArray from dmd.root it cannot reside in globals.h, so it is moved to a standalone header.
At the moment it is simply doing an `strlen` on the result of `toChars`, but as more code uses it, we can start to move away from that. Another reason to do it this way is because code can rely on the string being null terminated, so this way `x.toString().ptr` is still a drop-in replacement of `x.toChars()`.
strlen must die, right ?
The conversion is pretty straightforward, but required in order to convert globals. Since globals are still C-style string, a local toDString is used. It can later be removed as globals are converted to D slices.
|
Rebased on master, let's see. |
wilzbach
left a comment
There was a problem hiding this comment.
Yeah same here. One small step forward (:
|
Anything else ? Got a few changes depending on this PR (to be precise, on |
|
I think this is just pending/blocked on Ian's change request. @ibuclaw are you okay with moving forward here? |
Since we want to get rid of strlen, I tried to convert a simple global to a D slice and was blocked by the JSON module. So here is the module conversion to D.
Some simple things were added (e.g.
RootObject.toStringwhich juststrlenontoChars), but I avoided changing the AST as much as possible, so things likekind()andLoc.filenamecan be done in another PR.