Hi,
  Recently, I'm writing an application which uses JavaScriptCore to execute
javascript code. I just encountered a problem when using JSEvaluateScript
function to evaluate a piece of script. When executing the script, some
callbacks provided by my code will be called, but I found that the context
received by callbacks are different than the context I created and passed to
JSEvaluateScript function.

Attached is a test program.
Below is the output of this program on my system (ubuntu 8.04 64bit with
latest webkit svn):

Create context 0x7faf5d567e88, global object 0x7faf5d530000
InitializeCallback(ctx=0x7faf5d567e88, obj=0x7faf5d532400)
HasPropertyCallback(ctx=0x7faf50c4b048, obj=0x7faf5d532400, prop=prototype)
CallAsConstructorCallback(ctx=0x7faf50c4b0c0, obj=0x7faf5d532400)
InitializeCallback(ctx=0x7faf50c4b0c0, obj=0x7faf5d532440)
SetPropertyCallback(ctx=0x7faf50c4b048, obj=0x7faf5d532440, prop=prop1)
HasPropertyCallback(ctx=0x7faf50c4b048, obj=0x7faf5d532440, prop=prop1)
FinalizeCallback(obj=0x7faf5d532400)
FinalizeCallback(obj=0x7faf5d532440)

You can see that, the callback functions received several different context
pointers comparing to the one created at first beginning.

Is it an intend behavior or a bug of webkit? And how can I avoid or
workaround this problem?

Thanks a lot.

James Su
#include <cstdio>
#include <string>
#include <JavaScriptCore/JavaScript.h>

static std::string ConvertJSString(JSStringRef js_str) {
  size_t bufsize = JSStringGetMaximumUTF8CStringSize(js_str);
  char *buf = new char[bufsize];
  buf[JSStringGetUTF8CString(js_str, buf, bufsize)] = 0;
  std::string result(buf);
  delete buf;
  return result;
}

static void InitializeCallback(JSContextRef ctx, JSObjectRef object) {
  printf("InitializeCallback(ctx=%p, obj=%p)\n", ctx, object);
}

static void FinalizeCallback(JSObjectRef object) {
  printf("FinalizeCallback(obj=%p)\n", object);
}

static bool HasPropertyCallback(JSContextRef ctx,
                                JSObjectRef object,
                                JSStringRef property_name) {
  printf("HasPropertyCallback(ctx=%p, obj=%p, prop=%s)\n",
         ctx, object, ConvertJSString(property_name).c_str());
  return false;
}

static JSValueRef GetPropertyCallback(JSContextRef ctx,
                                      JSObjectRef object,
                                      JSStringRef property_name,
                                      JSValueRef* exception) {
  printf("GetPropertyCallback(ctx=%p, obj=%p, prop=%s)\n",
         ctx, object, ConvertJSString(property_name).c_str());
  return NULL;
}

static bool SetPropertyCallback(JSContextRef ctx,
                                JSObjectRef object,
                                JSStringRef property_name,
                                JSValueRef value,
                                JSValueRef* exception) {
  printf("SetPropertyCallback(ctx=%p, obj=%p, prop=%s)\n",
         ctx, object, ConvertJSString(property_name).c_str());
  return false;
}

// Only for custom registered classes.
static JSObjectRef CallAsConstructorCallback(JSContextRef ctx,
                                             JSObjectRef constructor,
                                             size_t argument_count,
                                             const JSValueRef arguments[],
                                             JSValueRef* exception) {
  printf("CallAsConstructorCallback(ctx=%p, obj=%p)\n", ctx, constructor);
  JSClassRef class_ref =
      static_cast<JSClassRef>(JSObjectGetPrivate(constructor));
  return JSObjectMake(ctx, class_ref, NULL);
}

static const JSClassDefinition
kClassDefinition = {
  0,                            // version, shall be 0
  kJSClassAttributeNone,        // attributes
  "Hello",                      // className, utf-8 encoded
  NULL,                         // parentClass
  NULL,                         // staticValues
  NULL,                         // staticFunctions
  InitializeCallback,
  FinalizeCallback,
  HasPropertyCallback,
  GetPropertyCallback,
  SetPropertyCallback,
  NULL,                         // deleteProperty
  NULL,
  NULL,
  CallAsConstructorCallback,
  NULL,                         // hasInstance,
  NULL,                         // convertToType
};

static const char kTestScript[] =
"var v1 = new Hello;\n"
"v1.prop1 = 123;\n"
"var v2 = v1.prop1;\n";

int main() {
  JSGlobalContextRef context = JSGlobalContextCreate(NULL);
  JSObjectRef global_object = JSContextGetGlobalObject(context);
  printf("Create context %p, global object %p\n", context, global_object);
  JSClassRef hello_class = JSClassCreate(&kClassDefinition);
  JSObjectRef class_object =
      JSObjectMake(context, hello_class, NULL);
  JSObjectSetPrivate(class_object, hello_class);

  JSStringRef class_name = JSStringCreateWithUTF8CString("Hello");
  JSObjectSetProperty(context, global_object, class_name, class_object, 0, NULL);
  JSStringRelease(class_name);

  JSStringRef test_script =
      JSStringCreateWithUTF8CString(kTestScript);
  JSEvaluateScript(context, test_script, NULL, NULL, 0, NULL);
  JSStringRelease(test_script);

  JSGlobalContextRelease(context);
  JSClassRelease(hello_class);
}
_______________________________________________
webkit-dev mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev

Reply via email to