On Fri, Oct 3, 2008 at 9:42 AM, Christian Plesner Hansen
<[EMAIL PROTECTED]> wrote:
> Hi Evan
> Early on in the project we actually had both a C and a C++ api but the
> C api was dropped during a rewrite. I don't think we'd want to add a
> new C api to v8. We don't have a use for it ourselves and so it would
> inevitably be less well tested and maintained than the C++ api -- as
> indeed was the case with our old C api.
Thanks for the response. That makes sense to me.
> Your approach seems reasonable but there are many ways to map the C++
> abstractions we use to C, and finding the right approach will probably
> take some experimentation. Our old C api didn't have a handle
> abstraction, for instance. Instead of a Handle<Object> you would use
> a V8Object*, and there was no distinction between the operations that
> acted on the handle and on the object itself. Representing the
> distinction between handles and the objects contained in handles is
> difficult in C if you also want to use the type system to track which
> type of object is stored in handles.
Since my target is binding to other languages, my plan is to make the
C level relatively stupid and then restore the type information in the
language bindings. I also had a few different tries at getting
something that would work.
> As for the v8.h changes, having #ifdef
> <option_specific_to_another_library> is something we want to avoid,
> but in this case for instance the ability to create handle scopes that
> are not stack-allocated might be useful in other contexts so we might
> consider adding that in some form. As long as it's functionality that
> is generally useful and not tied to a particular library we'll
> consider adding it.
Ok, that was the most important part of the patch.
(I wrote a longer response here but I'm reconsidering now.) It seems
that HandleScope could be considered just a shortcut for managing
handle lifetimes. Maybe I could just avoid using them from C code?
For example, are these the same:
1)
{
v8::HandleScope hs;
v8::Local<v8::String> str = v8::String::New("test");
} // str is freed here
2)
v8::Persistent<v8::String> str = v8::String::New("test");
str.Dispose(); // str is freed here
It seems the latter involves a call to GlobalizeReference -- is that
expensive? If it is, is there a lighter-weight alternative other than
HandleScope?
Another option would be making some static function on HandleScope
that is an alias for calling new, with an uglier name to discourage
people from using it. E.g.
class HandleScope {
// [... as before ...]
// Returns a new HandleScope. This is not necessary from C++ code,
// as HandleScopes should be allocated on the stack, and is only available
// to work with languages other than C++.
static HandleScope* NewHeapAllocated();
static DeleteHeapAllocated(HandleScope*);
}
A final option is that maybe it just makes sense to allow
heap-allocated HandleScopes.
You understand all this much better than me -- what do you think?
PS: here's a snippet of some Haskell code that uses my bindings, with
some helper functions elided. It uses type classes to simulate
subtyping (e.g. "global" is an ObjectTemplate but you're allowed to
pass it to templateSet). Dunno if there are any Haskell fans on the
v8 team...
main = do
args <- getArgs
let code = case args of
[code] -> code
[] -> "'this is a sample ' + 'string of code'"
V8.withHandleScope $ do
print_cb <- V8.functionTemplateNew printCallback
global <- V8.objectTemplateNew
V8.templateSet global "print" print_cb
V8.withContext global $ do
V8.withTryCatch $ \trycatch -> do
script <- V8.scriptCompile code
case script of
Nothing -> printError trycatch "compile error"
Just script -> do
result <- V8.scriptRun script
case result of
Nothing -> printError trycatch "run error"
Just result -> do
putStr " => "
printValue result
putStrLn ""
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---