On Tue, Jul 9, 2013 at 12:24 PM, Elijah Insua <tmp...@gmail.com> wrote:
> Can you explain what the magic "slot" numbers are used for? > They are basically local handles. Each JS value that's created during the scope of a function gets a unique slot value (some negative integer). If you want a value to live past the current function, you need to either js_ref it or js_return/js_throw it or store it as a property on some object that's going to outlive the current function. The shim wrapping this code can loop through all the created slots and manage memory accordingly. Also slot of "0" references "this" and positive slots are passed in arguments. > > > On Tue, Jul 9, 2013 at 10:08 AM, Tim Caswell <t...@creationix.com> wrote: > >> >> >> >> On Tue, Jul 9, 2013 at 4:16 AM, Floby <florent.j...@gmail.com> wrote: >> >>> Tim's examples are pretty nice. >>> The only things missing for all my use cases are storing pointers in JS >>> objects so I can get them back when I need it. >>> >>> something like >>> >>> js_set_pointer(C, myObject, pointer); >>> myType *pointer = js_get_pointer(C, myObject); >>> >> >> Ok, now the proposed API has a more complete feature set including an >> example of how to embed C structs inside JS objects. >> https://gist.github.com/creationix/5954513#file-point-c (Also I ran all >> the code through gcc and clang with -pendantic to make sure my header is >> valid code) >> >> #include "js_api.h" >> #include <stdlib.h> // malloc, free >> >> >> // Suppose I want to create a point type that's backed by a real C struct >> for points. >> >> typedef struct { >> >> double x; >> double y; >> >> } my_point; >> >> void cleanup_point(void* point, const char* type) { >> >> free(point); >> } >> >> bool create_point(js_context* C) { >> >> my_point* point = (my_point*)malloc(sizeof(my_point)); >> >> point->x = js_to_double(C, 1); >> >> point->y = js_to_double(C, 2); >> >> int proto = js_named_read_ref(C, "my_point_proto"); >> >> return js_return_external_pointer_with_proto(C, point, "my_point", proto, >> cleanup_point); >> >> } >> >> bool add_method(js_context* C) { >> >> my_point* point = (my_point*)js_to_pointer(C, 0, "my_point"); >> >> if (!point) { >> return js_throw_type_error(C, "Expected this to be 'my_point' instance"); >> >> } >> return js_return_double(C, point->x * point->y); >> >> } >> >> bool export_point(js_context* C) { >> >> int proto = js_create_object(C); >> >> js_set_function(C, proto, "add", add_method); >> >> js_named_ref(C, proto, "my_point_proto"); >> >> return js_return_function(C, create_point); >> >> } >> >> >> >> >> >> >> >>> >>> >>> On Monday, 8 July 2013 20:35:36 UTC+2, Timothy J Fontaine wrote: >>>> >>>> [cross post from http://atxconsulting.com/** >>>> 2013/07/06/rewrite-it-anyway/<http://atxconsulting.com/2013/07/06/rewrite-it-anyway/> >>>> ] >>>> >>>> Node v1.0 is approaching, and v0.12 is imminent (as far as that goes >>>> for FOSS >>>> projects). As we work towards getting v0.12 out the door, there have >>>> been a lot >>>> of changes happening for node's primary dependency v8. Ben is working >>>> on moving >>>> us to the 3.20 branch, follow his progress >>>> [here](https://github.com/**joyent/node/pull/5804<https://github.com/joyent/node/pull/5804> >>>> ). >>>> >>>> As you can tell this is a signficant change to the API, which requires >>>> a touch >>>> of virtually every file in our `src/`, this has been a huge headache >>>> for him, >>>> and will ultimately cause a huge headache for developers of binary >>>> addons. >>>> >>>> You're going to have to `#ifdef` around significant portions of the API >>>> to keep >>>> your module working across different version of node, this is going to >>>> cause >>>> endless amounts of pain and issues for node and developers who have for >>>> the >>>> most part been accepting of the churn in our underspecified addon API. >>>> >>>> This one is going to hurt. >>>> >>>> A lot. >>>> >>>> ## TL;DR -- A modest proposal >>>> >>>> Since you're going to have to rewrite your module anyway, it's time for >>>> node to >>>> specify and export the API we are going to "bless" for addons. That is, >>>> just >>>> what API we are going to support and make sure continues to work from >>>> minor and >>>> major releases, as well as a deprecation policy. >>>> >>>> More specifically I think we should be exporting a separate (and not >>>> equal) >>>> wrapper around (at the very least) javascript object creation, get/set, >>>> function >>>> calling. >>>> >>>> Additionally we should package and distribute (if possible in npm) a >>>> transitional library/headers which module authors can target today >>>> which will >>>> allow their module to compile and work from v0.8 through v1.0 >>>> >>>> ## The Platform Problem >>>> >>>> We currently allow platforms/distributors to build against shared >>>> (their own) >>>> versions of many of our dependencies, including but not limited to: >>>> >>>> * v8 >>>> - Holy crap, we're about as tightly coupled to the version of v8 we >>>> ship as >>>> chromium itself is. >>>> * libuv >>>> - If we weren't strictly coupled to v8, we certainly are for libuv, >>>> there >>>> would be no (useful) node, without libuv. >>>> * openssl >>>> - This is a must for linux distributions, who like to break DSA keys >>>> and then >>>> make every dependency vulnerable as a result (sorry Debian, I keed I >>>> keed). >>>> - This actually allows distributors who know specific things about >>>> their >>>> platform to enable/disable the features that allow it to run best. >>>> * zlib >>>> - Meh, this isn't such a big deal, it doesn't really change all that >>>> often. >>>> * http_parser >>>> - Really? People ship this as a separate library? >>>> >>>> This functionality was added to appease platform builders, the likes of >>>> Debian, >>>> Fedora, and even SmartOS. However, doing so has complicated and muddled >>>> the >>>> scenario of building and linking binary addons. >>>> >>>> Currently node-gyp downloads the sourceball, extracts the headers from >>>> it, >>>> and makes some assumptions from `process.config` about how to build >>>> your addon. >>>> In practice this has been working reasonably well. >>>> >>>> However, I'm very concerned about this as a long term strategy. It's >>>> possible >>>> for someone to have tweaked or twisted the node (or one of its >>>> dependencies) >>>> builds, which could lead to some unintended consequences. In the "best" >>>> case, >>>> you'll get a compiler error from a changed API or clashing symbol. In >>>> the worst >>>> case they have modified the ABI which will manifest itself in >>>> unexpected and >>>> often subtle ways. >>>> >>>> Not to mention that we have no good answer on how to build and link >>>> addon >>>> modules against the proper version of a shared dependency (what if the >>>> system >>>> has multiple openssl's, what if they compiled against it in one place, >>>> but now >>>> run against it in another). >>>> >>>> And last but not least, how do modules consume symbols from our >>>> dependencies >>>> that node itself doesn't consume. Consider a specific crypto routine >>>> from >>>> openssl that you want to provide as an addon module because node doesn't >>>> currently have an interface for it. >>>> >>>> ## Enemies without, and enemies within >>>> >>>> As if it weren't bad enough that platforms may ship against a version >>>> of v8 >>>> that we haven't blessed, we (and addon developers) have to fight >>>> against the >>>> beast that is the v8 API churn. >>>> >>>> I don't really fault Google and the chromium or v8 team for how they are >>>> handling this, more often then not we just end up with ugly compile time >>>> deprecation warnings, letting us know the world is about to break. >>>> >>>> However, there have been times -- like right now -- where node can't >>>> paper over >>>> the drastic change in the v8 API for module developers. And as a result >>>> we >>>> begrudgingly pass the API change to module authors. >>>> >>>> To paraphrase, don't forget that execrement will inevitably lose its >>>> battle >>>> with gravity. >>>> >>>> So what are we going to do? >>>> >>>> ## Meat and Potatoes >>>> >>>> This is where I don't particularly have everything fleshed out, and I'm >>>> sure I >>>> will take a considerable amount of heat from people on API decisions >>>> that >>>> haven't been made. >>>> >>>> I want to export the following interfaces: >>>> >>>> * `node/js.h` >>>> - Object creation and manipulation. >>>> - Function calling and Error throwing. >>>> * `node/platform.h` >>>> - IO and event loop abstraction. >>>> * `node/ssl.h` >>>> * `node/zlib.h` >>>> * `node/http.h` >>>> >>>> While I am not particularly attached to the names of these headers, each >>>> represent an interface that I think module authors would opt to target. >>>> I only >>>> feel strongly that we export `js` and `platform` as soon as possible as >>>> they are the primary interactions for every module. >>>> >>>> ### Basic Principles >>>> >>>> There are only a few principles: >>>> >>>> * Avoid (like the plague) any scenario where we expose an ABI to >>>> module authors. >>>> - Where possible use opaque handles and getter/setter functions. >>>> * The exported API should be a reliable interface which authors can >>>> depend on >>>> working across releases. >>>> * While a dependency may change its API, we have committed to our >>>> external API >>>> and need to provide a transitional interface in accordance with our >>>> deprecation >>>> policy. >>>> * The API should never expose an implementation detail to module >>>> authors (A >>>> spidermonkey backed node one day?). >>>> >>>> ### Platform >>>> >>>> The `platform` interface is the easiest to discuss, but the pattern >>>> would >>>> follow for `ssl`, `zlib`, and `http`. >>>> >>>> This would just rexport the existing `uv` API, however with a C-style >>>> namespace >>>> of `node_`. Any struct passing should be avoided, and libuv would need >>>> to be >>>> updated to reflect that. >>>> >>>> ### JS >>>> >>>> I expect the `js` interface to be the most contentious, and also >>>> fraught with >>>> peril. >>>> >>>> The interface for addon authors should be C, I don't want to forsake >>>> the C++ >>>> folk, but I think the binding for that should be based on our C >>>> interface. >>>> >>>> I was going to describe my ideal interface, and frame it in context of >>>> my ruby >>>> and python experience. However, after a brief investigation, the JSAPI >>>> for >>>> spidermonkey exports almost exactly the API I had in mind. So read >>>> about that >>>> [here](https://developer.**mozilla.org/en-US/docs/** >>>> SpiderMonkey/JSAPI_User_Guide<https://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_User_Guide> >>>> )**. >>>> >>>> Would it make sense, and would it be worth the effort, for node to >>>> export a >>>> JSAPI compatible interface? >>>> >>>> Would it make more sense to export a JSAPI influenced API currently >>>> targetted >>>> at v8 which could be trivially extended to also support spidermonkey? >>>> >>>> UPDATE 2013-07-08: >>>> >>>> > It's interesting and worthy to have a conversation about being able to >>>> > provide a backend neutral object model, though our current coupling >>>> to v8 and >>>> > its usage in existing addons may not make it possible to entirely >>>> hide away >>>> > the eccentricities of the v8 API. But what we can provide is an >>>> interface >>>> > that is viable to target against from release to release regardless >>>> of how >>>> > the public v8 API changes. >>>> >>>> ## Prior Art >>>> >>>> A lot of these ideas came from a discussion I had with >>>> [Joshua Clulow](http://blog.sysmgr.**org/ <http://blog.sysmgr.org/>) >>>> while en route to >>>> [NodeConf](http://nodeconf.com**). >>>> >>>> Part of that conversation was about [v8+](https://github.com/** >>>> wesolows/v8plus <https://github.com/wesolows/v8plus>) >>>> which was written by a particularly talented coworker, who had a rather >>>> nasty >>>> experience writing for the existing C++ API (such as it is). >>>> >>>> There's some overlap in how it works and how I envisioned the new API. >>>> However, >>>> I'm not sure I'm particularly fond of automatically converting objects >>>> into >>>> nvlists, though that does solve some of the release and retain issues. >>>> >>>> In general I would advocate opaque handles and getter and setter >>>> functions, >>>> with a helper API which could do that wholesale conversion for you. >>>> >>>> Really though this matters less in a world where addon authors are >>>> following >>>> some defined "Best Practices". >>>> >>>> * Only pass and return "primitives" to/from the javascript/C boundary >>>> - Primitives would be things like: `String`, `Number`, `Buffer`. >>>> * Only perform objection manipulation in javascript where the JIT can >>>> work >>>> its magic >>>> >>>> ## Dessert >>>> >>>> Work on this needs to begin as soon as possible. We should be able to >>>> distribute it in npm, and authors should be able to target it by >>>> including a >>>> few headers in their source and adding a dependency stanza in their >>>> `binding.gyp`, and by doing so their module will work from v0.8 through >>>> v1.0 >>>> >>>> I mean, you're going to have to rewrite it anyway. >>>> >>> -- >>> -- >>> Job Board: http://jobs.nodejs.org/ >>> Posting guidelines: >>> https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines >>> You received this message because you are subscribed to the Google >>> Groups "nodejs" group. >>> To post to this group, send email to nodejs@googlegroups.com >>> To unsubscribe from this group, send email to >>> nodejs+unsubscr...@googlegroups.com >>> For more options, visit this group at >>> http://groups.google.com/group/nodejs?hl=en?hl=en >>> >>> --- >>> You received this message because you are subscribed to the Google >>> Groups "nodejs" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to nodejs+unsubscr...@googlegroups.com. >>> For more options, visit https://groups.google.com/groups/opt_out. >>> >>> >>> >> >> -- >> -- >> Job Board: http://jobs.nodejs.org/ >> Posting guidelines: >> https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines >> You received this message because you are subscribed to the Google >> Groups "nodejs" group. >> To post to this group, send email to nodejs@googlegroups.com >> To unsubscribe from this group, send email to >> nodejs+unsubscr...@googlegroups.com >> For more options, visit this group at >> http://groups.google.com/group/nodejs?hl=en?hl=en >> >> --- >> You received this message because you are subscribed to the Google Groups >> "nodejs" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to nodejs+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/groups/opt_out. >> >> >> > > -- > -- > Job Board: http://jobs.nodejs.org/ > Posting guidelines: > https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines > You received this message because you are subscribed to the Google > Groups "nodejs" group. > To post to this group, send email to nodejs@googlegroups.com > To unsubscribe from this group, send email to > nodejs+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/nodejs?hl=en?hl=en > > --- > You received this message because you are subscribed to the Google Groups > "nodejs" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to nodejs+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/groups/opt_out. > > > -- -- Job Board: http://jobs.nodejs.org/ Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines You received this message because you are subscribed to the Google Groups "nodejs" group. To post to this group, send email to nodejs@googlegroups.com To unsubscribe from this group, send email to nodejs+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/nodejs?hl=en?hl=en --- You received this message because you are subscribed to the Google Groups "nodejs" group. To unsubscribe from this group and stop receiving emails from it, send an email to nodejs+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.