luiscubal
|
|
Posted on: June 28, 2010, 04:11:53 pm |
|
|
Joined: Jun 2009
Posts: 452
|
Google's V8 embedding API for C++ rocks. Honestly, it'll be really competitive with Lua, although I don't have benchmarks to compare them in terms of speed. The garbage collection API is a bit strange. I'm not yet fully sure what's the difference between a common Handle<T> and a Local<T> handle. It also took me a bit to get used to the concept of ObjectTemplate, how to handle functions-as-constructors and I still haven't figured out how to change the prototype of primitive types(such as adding methods to strings). Also, I like the use of static New methods instead of ordinary C++ constructors. It solves a number of garbage collector issues. In just two days, I went from zero to having a working CommonJS Modules 1.0(slighly modified) implementation in V8(with the help of zlib). If anyone is considering embedding scripts in your projects(games or otherwise), V8 is definitively worth considering. At least on Linux, it's really easy to setup(#include "v8.h" with -lv8). I'm guessing Windows and Mac OS X users shouldn't have too much trouble either. V8 also has the reputation of being ultra-fast. If anyone is interested, the following pages should help: http://code.google.com/apis/v8/get_started.htmlhttp://code.google.com/apis/v8/embed.htmlhttp://bespin.cz/~ondras/html/namespacev8.htmlhttp://v8.googlecode.com/svn/trunk/samples/The API is very easy to use and is actually making me consider some modifications to a language VM I'm currently designing.
|
|
|
Logged
|
|
|
|
|
Josh @ Dreamland
|
|
Reply #2 Posted on: June 28, 2010, 11:36:15 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
What retep said. But I was met with great opposition, as usual. In fact, the thread is still under the Suggestions and Proposals subforum.
You are wrong in one aspect, though; compiling it for Windows is a miserable fucking bitch and a half. I've never pulled it off.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
|
Josh @ Dreamland
|
|
Reply #4 Posted on: June 29, 2010, 11:19:32 am |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
That's exactly what I said I'd do. And nope, not that lucky.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
|
Josh @ Dreamland
|
|
Reply #6 Posted on: June 29, 2010, 01:20:07 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
...No? With() already offered such a headache, and the new instance system blows that headache right out of the water. The accessors would just be conscious of the with() scope (which, at its lowest element, is the event scope).
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
|
|
Josh @ Dreamland
|
|
Reply #9 Posted on: June 29, 2010, 02:17:54 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
I don't simply propose things without thinking them through. I considered everything mentioned here and then some months ago, bouncing ideas off of Luda. It's been necessary since square one that a hash table be kept for each instance if all aspects of GML were to be supported. I statically compile everything I can, yes. R3 in fact did nothing with hash tables; R4 doesn't yet, either. But consider this code: random(10).flarg = 90; What happens if flarg doesn't exist in the randomly chosen instance? This worked in R3; in R3, a dummy object by the same type was returned. In GM, however, the variable is added to the huge hash map Mark keeps. To simulate GM, a hash table would be used by flarg's accessor. (In R3, the accessor was this bulky thing that copied everything, because the instance system practically relied on it). Note, of course, that accessors can have nasty implications, and so are only used for instance.varname lookups. The other alternative is to scope all variables accessed that way into the parent object, but that wastes some memory in instances not using the variable, too.
The trick is that compiled code knows what variables it's accessing. Only the code-generated accessors would ever work with the hash table. V8 Would call those same accessors (which would be generated indiscriminately for the occasion); not interface with the hash table directly, which would indeed turn the entire operation into a huge mess.
What does turn the operation into a huge mess is having ENIGMA generate a wrapper to the entire C library for the interpreter. I'm surprised that wasn't your first point of attack, it's clearly the most intricate. I'll indicate, though; it is well within my capability using some neat var hacks. V8 requires all called functions take its own interesting argument array type. The array can be iterated for pass to C functions. Casting is the trick; ENIGMA doesn't keep track of argument types. So the solution is indeed an interesting one: Give ENIGMA's own variant a constructor for V8's varargs type. This would be done, via code generation, for all available functions. This is the C++ pseudo code:
ofstream wto("interpreter.cpp"); for (fit fname = functions.begin(); it != functions.end(); it++) { wto << "static Handle<Value> V8_WRAP_" << fname->first << "(const Arguments& argument) {" << endl; wto << " return (variant)" << fname->first << "("; for (int anum = 0; anum < it->second->argcount; it++) wto << "variant(argument[" << it << "]),"; wto << ");" << endl << "}" << endl; }
Because variant is programmed with macros, magic, and awesome, all that would be required is a cast for each argument to variant and then a cast from the result to variant. Variant::variant(v8::Argument) would handle conversion to a sane value. The magic with which variant is laced will handle conversion to the correct type for each parameter. Variant's magic constructors would then get a workable type out of the return value of the C function. Then variant::operator Handle<Value>() would take care of the cast back to something V8 can use.
|
|
« Last Edit: June 29, 2010, 02:27:15 pm by Josh @ Dreamland »
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
|
|
Josh @ Dreamland
|
|
Reply #12 Posted on: June 29, 2010, 04:23:21 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
Nay, one's almost entirely code-generated. I have to maintain an extra wrapper function for V8 to use as an accessor.
Luis: Static is for the entire function. No point in burdening the linker.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
|
|
|