januari februari (2) maart (3) april mei (7) juni (1) juli (1) augustus september (5) oktober (1) november (3) december (5)
2016-05-03 19:02 xxm430 [permalink]
- xxmISAPI: fixed issue with open connections not accepting new requests
- revised context object lifetime management (lock-less reference counting)
- demo 7 "Resources": added "If-Modified-Since"
- demo 12 "Long Polling": added example EventSource (text/event-stream)
2016-05-03 19:17 plasm [permalink]
It is also a play thing to try and tame this beast that is assembler. Not any assembler in particular, but just in general what it is to try and make things work with a limited set of registers and instructions and having to shuffle anything that doesn't fit in those to and from memory. If I put more work into this, it could go two ways:
I can evolve the machine code further and try to design a binary encoding for the possible instructions, and have the code turn up in the memory as it is accessed by the normal registers. (It is not now, the
I register now indexes into a separate set of instructions, possibly with overlapping values.)
Otherways I could try and build a compiler that compiles code into this set of machine instructions (perhaps based on this one), finding out along the way what is all the fuss about register allocation and heuristic optimizations...
And ofcourse the both meet and I could try to build a compiler straight into these virtual machine instructions, but I have the luxury of not having to do this. And since it's all about learning and exploring by doing, it'll probably get me stuck faster.
But for now I think I'll let this rest for a little while. See how it looks when I come back to it after a while.
See also https://github.com/stijnsanders/plasm
postgreSQL: date and time manipulation
2016-05-13 00:06 pg1 [permalink]
Babysteps! I've had the chance to dabble a bit in PostgreSQL, and after (years of) T-SQL, and some MySQL/MariaDB and SQLite, it's yet another SQL dialect to get a hang of. First impressions are good. It feels like a mature dialect. Searching the docs usually helps me find swiftly what I'm looking for. (And there's this ofcourse.) Porting an existing project makes you bump into the differences:
'f'instead of 1 and 0)
create procedure, but there's
create or replace function ... returns void
exec, but since it's all functions use
ID int identity(1,1) not null, use
ID serial primary key not nullor hook up a sequence by yourself...
insert into x (...) values (...) returning ID into NewID
I'll probably hit a lot more like these in the time to come, but that you should use
timestamptz) instead of
datetime2) deserves a separate mention. Especially there's no
extract, that's pretty straight-forward, but to replace
dateadd, you do something like it feels it should always have been: plain arithmetic.
PostgreSQL is pretty intelligent about operators (just do
select * from pg_operator, wow!) so just subtract two timestamps to get something of type
interval, something like
x + interval '2 days' result into exactly what you'd expect, and for constructing, apparently casting is pretty smart, for example:
select now()+(X.X||'day')::interval from (values (0),(1),(2),(3),(4)) X(X)
One more: instead of
datediff(dd,x,y)=0 just do this:
x::date=y::date pretty obvious if you think about it. Like I said, PostgreSQL made a pretty good first impression.
Delphi and PostgreSQL
2016-05-13 00:19 LibPQData [permalink]
Searching for an alternative way to use PostgreSQL from Delphi? In the spirit of the other as-light-as-it-gets database connector wrappers, I've converted the header(s) to the LibPQ dll. See the LibPQ and LibPQData units in this repository:
To start an attempt to move to something more like a generic database layer, I've started this DataLank idea, but it needs more work. Actually I don't intend to develop it all the way into a full-fledged data-layer. Specialities of each specific database solution are so diverse and important, that I really don't want to hide them between an opaque abstraction layer. I want a database connector wrapper to be as light as possible, but also to allow access to the underlying technology. The main point for using DataLank, is to have less work changing DB's by using TDataConnection and TQueryResult types, but not no work. Adapting the used SQL to a different dialect will probably involve updating many (or all) calls the database anyway. But I'll post about that later when I put some more time in. (And perhaps write a libmysql.dll wrapper first...)
Microsoft is Coca-Cola.
2016-05-23 10:10 mscc [permalink]
Or, at least, that was what popped into my head when I thought (again) about Microsoft open-sourcing the Windows operating system. Why wouldn't they? Coca-cola gave the super-secret recipe away at some point. It takes a certain stability, and vision, and momentum, to do that, but in my humble opinion both Coca-Cola and Microsoft have that.
Let's see how this could work. It's not because Microsoft would open-source Windows that they should stop selling it. Far from it. You can still buy Coca-cola, right? Have you ever bought cola made from the official Coca-Cola recipe, but concocted by someone else? Would you? Same goes for Windows. If you're in the market for a new computer, and want to run Windows on it, you'll probably go to the source, buy Microsoft, and be sure to get updates (and some free OneDrive space, and an Office365 trial...)
So I really am hopeful. Recently Microsoft has really (really!) opened up quite a bit, and even chose the MIT-license for some things, which was unthinkable just a few years ago. So a logic step would be to go all the way, and release the cash-cows, such as Windows, perhaps SQL Server... Even only perhaps there's a small chance they won't be the cash-cows for much longer... Computer sales is under pressure from smartphones and other hand-held devices. The database landscape is still suffering after-shocks from the NoSQL phenomenon, and from things like PostgreSQL and MariaDB, we roughly know what it takes to run a database anyway. So to ensure cash flowing in in the long run, it's almost a must to open up on old secrets. At least in my humble opinion.
Update: Microsoft is too big! Time to split it up in pieces.
Just another debugging story from the trenches
2016-05-27 23:23 a-debug-story [permalink]
It's all logic, really. Once you get to the bottom of it. But getting there... Phew!
So I was working on something that had a line like this:
function TPostgresConnection.Insert(const TableName: UTF8String;
const Values: array of OleVariant; const PKFieldName: UTF8String=''): int64;
I forgot what went wrong in the beginning (it was somewhere yesterday between midnight and bedtime...) but to check something out, to debug without a debugger so to speak, I wanted to dump a string. Deep within the data-layer you can't really access the things that handle the output to the user, so I just do this:
And then run the application again and reproduce the issue you're tending to. But it doesn't throw this exception, it throws a quite severe access violation instead, strange. Not the error it started with, but none the less something strange going on in the exact same bit of code you're working on. But it was running late and I felt ready to go to sleep, so that is where I left it. It's always nicer to leave a project in working order at the end if the working day, but problems like this typically look different when viewed with a freshly rested set of eyes.
So the next day, let's move the debug exception somewhere higher up in the function body. Actually, all that happens before is handing the values in the
Values array... So instead, I put this in near the top:
for i:=0 to l-1 do sql1:=sql1+','+IntToHex(VarType(Values[i]),4);
Which gives me:
Hmm, so it looks like the list of VarType's of the Values array, but these values are totally bogus! The VarType constants are (at least in older Delphi versions) right there at the top of System.pas (the unit that's always included, even if you don't list in a
uses-clause), $0000 is varEmpty, but $FD18 is impossible since only
varArray = $2000 and
varByRef = $4000 are used of the highest 4 bits... And I'm sure I didn't pass any empties in. What is this?! Time to break out the real debugger then, I guess.
An xxm project pre-compiles files that have HTML and server-side pascal in the same source-files, into a full-fledged set of .pas files and a .dpr file, have that compiled, and then hot-swaps this new DLL in place to handle the next web-requests. So the usual development on an xxm project doesn't involve the Delphi IDE (I actually use atom.io since a while now.) but since the source is right there, you can open it in the plain old Delphi IDE and have the debugger start the DLL using something like xxmHttp.exe (the xxm handler that doesn't auto-recompile like xxmHttpDev.exe, since that would interfere with debugging.)
So, let's see what the debugger makes of this Values array the moment of this debug execption:
Values: (Unassigned, Variant array of Unknown, Unknown type: 21, Variant array of Unknown, Variant array of Unknown, Unassigned, Delphi exception EAccessViolation at $...
Yikes. But good news since with debugger it is doing the exact same thing wrong. That's something you can't take for granted, but that's another story.
So setting a breakpoint at this specific call to Insert, to see if the values get passed in:
Hey! Those are the correct values. But just one press of the F7 key later:
Bam, they're gone. Hmm, switching on the compiler "Use Debug DCUs" setting and retrying this doesn't bring me into any underlying code (sometimes some behind-the-scenes work is done on variants and strings for you), so nothing there...
And then it dawned on me! I know of one thing that can 'eat' your memory like that and it's compiler optimization.
By putting in that 'debug raise', using only an unrelated string, the optimization might conclude it can get away with releasing the memory of that Values array sooner, apparently disregarding the work that's been done on it. (Newer versions of Delphi may handle this differently, but that's another story...) So having a quick try with this:
for i:=0 to l-1 do sql1:=sql1+','+IntToHex(VarType(Values[i]),4);
if l<1000 then
And it works! So that's the weird misbehaving variant array out of the way. Now I feel extra silly not remembering what was originally the thing that I thought went wrong, was I just getting tired? This function is rather new, so I was just trying to debug for the first time, I guess. Still, makes for a nice story about debugging deeper and deeper until hitting the system, then finding out what's causing your trouble, calling on more of your knowledge of that system than usual.
(In case you want to know more about what I was working on in the first place, look here.)
TIL: JVM and CIL both use the stack instead of registers.
2016-05-30 16:03 jvmcilstack [permalink]
Thing I learned today: both JVM and CIL use the stack instead of registers!
Sounds like a bad decision, not only because most other intermediate stuff I've seen uses SSA, but especially it makes the work for JIT-compilers that much harder.
At least, that's my first impression, just from thinking about what a JIT-compiler would have to do: assigning the processor's available registers to what they'll be used for in a section of logic, is a science and an artform all on its own; but if you don't have anything roughly materialized to work with from the beginning, you're bound to eke it out of the given logic and see what it's supposed to do, by following the things that hop on and off the stack... With the lot of guesswork, statistics and heuristics that comes with it.
I guess that's where the recent hype in JIT-compiler innovation comes from. If you get a cleaner conversion to something as if it was written with SSA, you'll probably get better results, but it still feels like a step backward and two steps forward.
And all this because I was comtemplating which back-end to (re)use in case I would have a go at having a play language of my own compile into something executable.
So, sorry guys, but I guess I'm back to looking into LLVM or GCC for a back-end... (unless...)