Cannot create a handle without a HandleScope

2,414 views
Skip to first unread message

Scott Sibley

unread,
Oct 10, 2009, 12:38:11 PM10/10/09
to v8-u...@googlegroups.com
I'm likely to bug the living daylights out of you guys while I piece my program together. I hope you all don't mind.

I'm sure the answer to this is real simple. Below is my code. I'll leave comments to explain my problem some, then I'll continue below.

// Evaluator.h
#include <v8.h>

class Evaluator {
    v8::Handle<v8::ObjectTemplate> global;
    v8::Handle<v8::Context> context;
    public:
    Evaluator();
    ~Evaluator();
    v8::Handle <v8::Script> Compile(const char *str);
    void AddFunction(const char *name, v8::Handle<v8::FunctionTemplate> func);
};

// Evaluator.cpp
#include <v8.h>
#include "Evaluator.h"
#include "PluginUptime.h"
#include <iostream>

Evaluator::Evaluator() {
    v8::HandleScope handle_scope;
    global = v8::ObjectTemplate::New();
    plugin_uptime_init(this); // plugin_uptime_init calls Evaluator::Compile to add the uptime function to javascript
    context = v8::Context::New(NULL, global);
    v8::Context::Scope context_scope(context);
}

Evaluator::~Evaluator() {
    v8::V8::Dispose();
    plugin_uptime_deinit();
}

v8::Handle<v8::Script> Evaluator::Compile(const char *str) {
    context->Enter();
    v8::HandleScope handle_scope;
    return v8::Script::Compile(v8::String::New(str), v8::String::New("(evaluator)"));
}

void Evaluator::AddFunction(const char *name, v8::Handle<v8::FunctionTemplate> func) {
    std::cout << "Adding function " << name << std::endl;
    v8::HandleScope handle_scope;
    global->Set(name, func); // This is where I get the error mentioned in the email title. I added the above handle_scope but it still gives the error.
}

Any clues? I'm going by the shell example mainly. I'm pretty sure I followed the steps similarly, but they're spread across function/method calls, while the example sets up the functions all in the same C++ scope with initializing the "global" handle. That's the only thing I can figure is the problem.

Here's the exact error I get:

#
# Fatal error in v8::HandleScope::CreateHandle()
# Cannot create a handle without a HandleScope
#

Scott Sibley

unread,
Oct 10, 2009, 1:13:26 PM10/10/09
to v8-u...@googlegroups.com
Scratch that. I figured it out. The problem wasn't even in this code I showed. I forgot to add a handle scope where I entered the test code.

Stephan Beal

unread,
Oct 10, 2009, 1:38:29 PM10/10/09
to v8-u...@googlegroups.com
On Sat, Oct 10, 2009 at 6:38 PM, Scott Sibley <sisi...@gmail.com> wrote:
Evaluator::~Evaluator() {
    v8::V8::Dispose();
    plugin_uptime_deinit();

This just feels wrong. Dispose eliminates all v8 resources, but plugin_uptime_deinit() is likely to use Handle<>, and manipulation of handles is not legal once v8 is dead.
 
void Evaluator::AddFunction(const char *name, v8::Handle<v8::FunctionTemplate> func) {
    std::cout << "Adding function " << name << std::endl;
    v8::HandleScope handle_scope;
    global->Set(name, func); // This is where I get the error mentioned in the email title. I added the above handle_scope but it still gives the error.
}

IMO you shouldn't need a handle scope here.

Any clues? I'm going by the shell example mainly. I'm pretty sure I followed the steps similarly, but they're spread across function/method calls, while the example sets up the functions all in the same C++ scope with initializing the "global" handle. That's the only thing I can figure is the problem.

Here's the exact error I get:

#
# Fatal error in v8::HandleScope::CreateHandle()
# Cannot create a handle without a HandleScope
#

Can you post the whole code, so we can see the order of operations? i remember having to fiddle a lot with the example shell to get the ordering of all operations correct in my own app. v8 can be very choosy about ordering for certain operations, and i suspect this is a simple order-of -setup problem.

Are you getting the error for your first Evaluator object or on subsequent objects? If it's the latter case, it's no surprise because you've destroyed v8 ~Evaluator(). Dispose() does not, as a general rule, need to be called by client apps.

--
----- stephan beal
http://wanderinghorse.net/home/stephan/

Scott Sibley

unread,
Oct 10, 2009, 1:44:07 PM10/10/09
to v8-u...@googlegroups.com

Thanks for the reply. I figured the problem out. Below's where the problem was (I didn't include this code before); I've noted in a comment which line I added to fix the problem.

int main() {
    Generic test;
    v8::HandleScope handle_scope; // Added this line.
    v8::Handle<v8::Script> compiled = test.Compile("uptime('%d days %H:%M:%S')");
    v8::Handle<v8::Value> result = compiled->Run();
    v8::String::Utf8Value str(result);
    const char *cstr = ToCString(str);
    cout << cstr << endl;
    return 0;
Reply all
Reply to author
Forward
0 new messages