Beispiel #1
0
JSValueRef JSCArrayBuffer::isViewCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObj, size_t argumentCount, const JSValueRef* arguments, JSValueRef* exception) {

	struct JSCArrayBufferPrivate* privData = (struct JSCArrayBufferPrivate*)JSObjectGetPrivate(thisObj);

	if (false) {
	} else if (argumentCount == 1 &&
	           true) {
		void* localValue = JSObjectGetPrivate(JSValueToObject(ctx, arguments[0], exception));

		bool retVal = privData->nativeObj->isView(localValue);

		JSValueRef jscRetVal = JSValueMakeBoolean(ctx, retVal);
		return jscRetVal;
	}

	JSStringRef exceptionString = JSStringCreateWithUTF8CString("Parameter mismatch while calling isView");
	*exception = JSValueMakeString(ctx, exceptionString);
	JSStringRelease(exceptionString);
	return JSValueMakeUndefined(ctx);
}
Beispiel #2
0
void QtBuiltinBundlePage::registerNavigatorQtObject(JSGlobalContextRef context)
{
    static JSStringRef postMessageName = JSStringCreateWithUTF8CString("postMessage");
    static JSStringRef navigatorName = JSStringCreateWithUTF8CString("navigator");
    static JSStringRef qtName = JSStringCreateWithUTF8CString("qt");

    if (m_navigatorQtObject)
        JSValueUnprotect(context, m_navigatorQtObject);
    m_navigatorQtObject = JSObjectMake(context, navigatorQtObjectClass(), this);
    JSValueProtect(context, m_navigatorQtObject);

    JSObjectRef postMessage = JSObjectMakeFunctionWithCallback(context, postMessageName, qt_postMessageCallback);
    JSObjectSetProperty(context, m_navigatorQtObject, postMessageName, postMessage, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly, 0);

    JSValueRef navigatorValue = JSObjectGetProperty(context, JSContextGetGlobalObject(context), navigatorName, 0);
    if (!JSValueIsObject(context, navigatorValue))
        return;
    JSObjectRef navigatorObject = JSValueToObject(context, navigatorValue, 0);
    JSObjectSetProperty(context, navigatorObject, qtName, m_navigatorQtObject, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly, 0);
}
Beispiel #3
0
    KValueRef KKJSMethod::Call(KObjectRef thisObject, const ValueList& args)
    {
        JSValueRef thisObjectValue = KJSUtil::ToJSValue(Value::NewObject(thisObject), this->context);
        if (!JSValueIsObject(this->context, thisObjectValue))
        {
            SharedString ss(thisObject->DisplayString());
            throw ValueException::FromFormat("Could not convert %s to JSObjectRef for KKJSMethod::Call",
                ss->c_str());
        }

        JSObjectRef jsThisObject = JSValueToObject(this->context, thisObjectValue, NULL);
        if (!jsThisObject)
        {
            SharedString ss(thisObject->DisplayString());
            throw ValueException::FromFormat("Could not convert %s to JSObjectRef for KKJSMethod::Call",
                ss->c_str());
        }

        return this->Call(jsThisObject, args);
    }
static void callOnMessage(JSObjectRef object, WKStringRef contents, WKBundlePageRef page)
{
    static JSStringRef onmessageName = JSStringCreateWithUTF8CString("onmessage");

    if (!object)
        return;

    WKBundleFrameRef frame = WKBundlePageGetMainFrame(page);
    JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame);

    JSValueRef onmessageValue = JSObjectGetProperty(context, object, onmessageName, 0);
    if (!JSValueIsObject(context, onmessageValue))
        return;

    JSObjectRef onmessageFunction = JSValueToObject(context, onmessageValue, 0);
    if (!JSObjectIsFunction(context, onmessageFunction))
        return;

    JSObjectRef wrappedMessage = createWrappedMessage(context, contents);
    JSObjectCallAsFunction(context, onmessageFunction, 0, 1, &wrappedMessage, 0);
}
Beispiel #5
0
void QtBuiltinBundlePage::didReceiveMessageToNavigatorQtObject(WKStringRef contents)
{
    static JSStringRef onmessageName = JSStringCreateWithUTF8CString("onmessage");

    if (!m_navigatorQtObject)
        return;

    WKBundleFrameRef frame = WKBundlePageGetMainFrame(m_page);
    JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame);

    JSValueRef onmessageValue = JSObjectGetProperty(context, m_navigatorQtObject, onmessageName, 0);
    if (!JSValueIsObject(context, onmessageValue))
        return;

    JSObjectRef onmessageFunction = JSValueToObject(context, onmessageValue, 0);
    if (!JSObjectIsFunction(context, onmessageFunction))
        return;

    JSObjectRef wrappedMessage = createWrappedMessage(context, contents);
    JSObjectCallAsFunction(context, onmessageFunction, 0, 1, &wrappedMessage, 0);
}
void InspectorController::removeScriptResource(InspectorResource* resource)
{
    ASSERT(m_scriptContext);
    ASSERT(m_scriptObject);
    if (!m_scriptContext || !m_scriptObject)
        return;

    ASSERT(resource);
    ASSERT(resource->scriptObject);
    if (!resource || !resource->scriptObject)
        return;

    JSStringRef removeResourceString = JSStringCreateWithUTF8CString("removeResource");
    JSObjectRef removeResourceFunction = JSValueToObject(m_scriptContext, JSObjectGetProperty(m_scriptContext, m_scriptObject, removeResourceString, 0), 0);
    JSStringRelease(removeResourceString);

    JSValueRef arguments[] = { resource->scriptObject };
    JSObjectCallAsFunction(m_scriptContext, removeResourceFunction, m_scriptObject, 1, arguments, 0);

    resource->setScriptObject(0, 0);
}
Beispiel #7
0
JS4D::ObjectRef JS4D::VFilePathToObjectAsFileOrFolder( ContextRef inContext, const XBOX::VFilePath& inPath, ValueRef *outException)
{
	ObjectRef value;
	if (inPath.IsFolder())
	{
		VFolder *folder = new VFolder( inPath);
		value = VFolderToObject( inContext, folder, outException);
		ReleaseRefCountable( &folder);
	}
	else if (inPath.IsFile())
	{
		VFile *file = new VFile( inPath);
		value = VFileToObject( inContext, file, outException);
		ReleaseRefCountable( &file);
	}
	else
	{
		value = JSValueToObject( inContext, JSValueMakeNull( inContext), outException);	// exception instead ?
	}
	return value;
}
static void registerNavigatorObject(JSObjectRef *object, JSStringRef name,
                                    JSGlobalContextRef context, void* data,
                                    CreateClassRefCallback createClassRefCallback,
                                    JSStringRef postMessageName, JSObjectCallAsFunctionCallback postMessageCallback)
{
    static JSStringRef navigatorName = JSStringCreateWithUTF8CString("navigator");

    if (*object)
        JSValueUnprotect(context, *object);
    *object = JSObjectMake(context, createClassRefCallback(), data);
    JSValueProtect(context, *object);

    JSObjectRef postMessage = JSObjectMakeFunctionWithCallback(context, postMessageName, postMessageCallback);
    JSObjectSetProperty(context, *object, postMessageName, postMessage, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly, 0);

    JSValueRef navigatorValue = JSObjectGetProperty(context, JSContextGetGlobalObject(context), navigatorName, 0);
    if (!JSValueIsObject(context, navigatorValue))
        return;
    JSObjectRef navigatorObject = JSValueToObject(context, navigatorValue, 0);
    JSObjectSetProperty(context, navigatorObject, name, *object, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly, 0);
}
Beispiel #9
0
static JSValueRef assignToHTMLImageElement(JSContextRef context, JSObjectRef function, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    if (!argumentCount)
        return JSValueMakeUndefined(context);

    JSObjectRef objectArg = JSValueToObject(context, arguments[0], exception);
    if (!objectArg)
        return JSValueMakeUndefined(context);

    JSObject* jsObject = ::toJS(objectArg);

    if (!jsObject->inherits(&JSHTMLImageElement::s_info))
        return JSValueMakeUndefined(context);

    QVariant& data = *static_cast<QVariant*>(JSObjectGetPrivate(object));

    // We now know that we have a valid <img> element as the argument, we can attach the image to it.
    RefPtr<StillImage> stillImage = WebCore::StillImage::create(toImage(data));
    HTMLImageElement* imageElement = static_cast<HTMLImageElement*>(static_cast<JSHTMLImageElement*>(jsObject)->impl());
    imageElement->setCachedImage(new CachedImage(stillImage.get()));
    return JSValueMakeUndefined(context);
}
Beispiel #10
0
static JSValueRef JSNode_appendChild(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    UNUSED_PARAM(function);

    /* Example of throwing a type error for invalid values */
    if (!JSValueIsObjectOfClass(context, thisObject, JSNode_class(context))) {
        JSStringRef message = JSStringCreateWithUTF8CString("TypeError: appendChild can only be called on nodes");
        *exception = JSValueMakeString(context, message);
        JSStringRelease(message);
    } else if (argumentCount < 1 || !JSValueIsObjectOfClass(context, arguments[0], JSNode_class(context))) {
        JSStringRef message = JSStringCreateWithUTF8CString("TypeError: first argument to appendChild must be a node");
        *exception = JSValueMakeString(context, message);
        JSStringRelease(message);
    } else {
        Node* node = JSObjectGetPrivate(thisObject);
        Node* child = JSObjectGetPrivate(JSValueToObject(context, arguments[0], NULL));

        Node_appendChild(node, child);
    }

    return JSValueMakeUndefined(context);
}
Beispiel #11
0
bool TestRunner::findString(JSStringRef target, JSValueRef optionsArrayAsValue)
{
    WKFindOptions options = 0;

    auto& injectedBundle = InjectedBundle::singleton();
    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(injectedBundle.page()->page());
    JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
    JSRetainPtr<JSStringRef> lengthPropertyName(Adopt, JSStringCreateWithUTF8CString("length"));
    JSObjectRef optionsArray = JSValueToObject(context, optionsArrayAsValue, 0);
    JSValueRef lengthValue = JSObjectGetProperty(context, optionsArray, lengthPropertyName.get(), 0);
    if (!JSValueIsNumber(context, lengthValue))
        return false;

    size_t length = static_cast<size_t>(JSValueToNumber(context, lengthValue, 0));
    for (size_t i = 0; i < length; ++i) {
        JSValueRef value = JSObjectGetPropertyAtIndex(context, optionsArray, i, 0);
        if (!JSValueIsString(context, value))
            continue;

        JSRetainPtr<JSStringRef> optionName(Adopt, JSValueToStringCopy(context, value, 0));

        if (JSStringIsEqualToUTF8CString(optionName.get(), "CaseInsensitive"))
            options |= kWKFindOptionsCaseInsensitive;
        else if (JSStringIsEqualToUTF8CString(optionName.get(), "AtWordStarts"))
            options |= kWKFindOptionsAtWordStarts;
        else if (JSStringIsEqualToUTF8CString(optionName.get(), "TreatMedialCapitalAsWordStart"))
            options |= kWKFindOptionsTreatMedialCapitalAsWordStart;
        else if (JSStringIsEqualToUTF8CString(optionName.get(), "Backwards"))
            options |= kWKFindOptionsBackwards;
        else if (JSStringIsEqualToUTF8CString(optionName.get(), "WrapAround"))
            options |= kWKFindOptionsWrapAround;
        else if (JSStringIsEqualToUTF8CString(optionName.get(), "StartInSelection")) {
            // FIXME: No kWKFindOptionsStartInSelection.
        }
    }

    return WKBundlePageFindString(injectedBundle.page()->page(), toWK(target).get(), options);
}
static JSValueRef callAfterScrollingCompletes(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    if (argumentCount < 1)
        return JSValueMakeUndefined(context);

    JSObjectRef jsCallbackFunction = JSValueToObject(context, arguments[0], exception);
    if (!jsCallbackFunction)
        return JSValueMakeUndefined(context);

    if (!frame)
        return JSValueMakeUndefined(context);

    JSGlobalContextRef globalContext = frame->globalContext();

    COMPtr<IWebFrame2> frame2;
    if (FAILED(frame->QueryInterface(&frame2)))
        return JSValueMakeUndefined(context);

    WebCore::Frame* coreFrame = core(static_cast<WebFrame*>(frame2.get()));
    WebCoreTestSupport::setTestCallbackAndStartNotificationTimer(*coreFrame, globalContext, jsCallbackFunction);

    return JSValueMakeUndefined(context);
}
Beispiel #13
0
void VJSArray::_Splice( size_t inWhere, size_t inCount, const std::vector<VJSValue> *inValues, JS4D::ExceptionRef *outException) const
{
    JSStringRef jsString = JSStringCreateWithUTF8CString( "splice");
	JSValueRef splice = JSObjectGetProperty( fContext, fObject, jsString, outException);
	JSObjectRef spliceFunction = JSValueToObject( fContext, splice, outException);
    JSStringRelease( jsString);

	JSValueRef *values = new JSValueRef[2 + ((inValues != NULL) ? inValues->size() : 0)];
	if (values != NULL)
	{
		size_t j = 0;
		values[j++] = JSValueMakeNumber( fContext, inWhere);
		values[j++] = JSValueMakeNumber( fContext, inCount);
		if (inValues != NULL)
		{
			for( std::vector<VJSValue>::const_iterator i = inValues->begin() ; i != inValues->end() ; ++i)
				values[j++] = i->GetValueRef();
		}
	
		JS4DObjectCallAsFunction( fContext, spliceFunction, fObject, j, values, outException);
	}
	delete[] values;
}
Beispiel #14
0
static WPARAM buildModifierFlags(JSContextRef context, const JSValueRef modifiers)
{
    JSObjectRef modifiersArray = JSValueToObject(context, modifiers, 0);
    if (!modifiersArray)
        return 0;

    WPARAM flags = 0;
    int modifiersCount = JSValueToNumber(context, JSObjectGetProperty(context, modifiersArray, JSStringCreateWithUTF8CString("length"), 0), 0);
    for (int i = 0; i < modifiersCount; ++i) {
        JSValueRef value = JSObjectGetPropertyAtIndex(context, modifiersArray, i, 0);
        JSStringRef string = JSValueToStringCopy(context, value, 0);
        if (JSStringIsEqualToUTF8CString(string, "ctrlKey")
            || JSStringIsEqualToUTF8CString(string, "addSelectionKey"))
            flags |= MK_CONTROL;
        else if (JSStringIsEqualToUTF8CString(string, "shiftKey")
                 || JSStringIsEqualToUTF8CString(string, "rangeSelectionKey"))
            flags |= MK_SHIFT;
        // No way to specifiy altKey in a MSG.

        JSStringRelease(string);
    }
    return flags;
}
Beispiel #15
0
/**
 * Sends a http-request synchronously
 * @name sendRequestSync
 * @memberOf net
 * @function
 *
 * @param {String} uri          The uri the request will be sent to.
 * @param {String} [method]     The http request method, default GET
 *
 * @returns {Object}
 *      Object that contains the response body, the response headers and the
 *      http status code of the request.
 * */
static JSValueRef
net_send_request_sync(JSContextRef ctx, JSObjectRef f, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exc)
{
    char *method = NULL, *uri = NULL;
    SoupMessage *msg;
    guint status;
    JSValueRef val;
    JSObjectRef o;
    JSStringRef js_key;
    JSValueRef js_value;

    if (argc < 1)
        return NIL;

    uri = js_value_to_char(ctx, argv[0], -1, exc);
    if (uri == NULL)
        return NIL;

    if (argc > 1)
        method = js_value_to_char(ctx, argv[1], -1, exc);

    msg = soup_message_new(method == NULL ? "GET" : method, uri);
    if (argc > 2)
        set_request(ctx, msg, argv[2], exc);

    status = soup_session_send_message(webkit_get_default_session(), msg);
    val = get_message_data(msg);

    js_key = JSStringCreateWithUTF8CString("status");
    js_value = JSValueMakeNumber(ctx, status);

    o = JSValueToObject(ctx, val, exc);
    JSObjectSetProperty(ctx, o, js_key, js_value, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly, exc);

    JSStringRelease(js_key);
    return o;
}
Beispiel #16
0
static JSValueRef setValueAndClosePopupCallback(JSContextRef context,
        JSObjectRef, JSObjectRef, size_t argumentCount,
        const JSValueRef arguments[], JSValueRef*)
{
    JSValueRef jsRetVal = JSValueMakeUndefined(context);
    if (argumentCount <= 0)
        return jsRetVal;

    JSStringRef string = JSValueToStringCopy(context, arguments[0], 0);
    size_t sizeUTF8 = JSStringGetMaximumUTF8CStringSize(string);
    Vector<char> strArgs(sizeUTF8 + 1);
    strArgs[sizeUTF8] = 0;
    JSStringGetUTF8CString(string, strArgs.data(), sizeUTF8);
    JSStringRelease(string);
    JSObjectRef popUpObject = JSValueToObject(context,
            arguments[argumentCount - 1], 0);
    PagePopupBlackBerry::SharedClientPointer* client = reinterpret_cast<PagePopupBlackBerry::SharedClientPointer*>(JSObjectGetPrivate(popUpObject));

    // Check the weak pointer as the owner page may have destroyed the popup.
    if (client->get())
        client->get()->setValueAndClosePopup(0, strArgs.data());

    return jsRetVal;
}
Beispiel #17
0
static JSValueRef evaluateScriptWithJSC(
    JSGlobalContextRef ctx,
    JSStringRef script,
    JSStringRef sourceURL) {
  JSValueRef exn;
  auto result = JSEvaluateScript(ctx, script, nullptr, sourceURL, 0, &exn);
  if (result == nullptr) {
    JSValueProtect(ctx, exn);
    std::string exceptionText = Value(ctx, exn).toString().str();
    FBLOGE("Got JS Exception: %s", exceptionText.c_str());
    auto line = Value(ctx, JSObjectGetProperty(ctx,
      JSValueToObject(ctx, exn, nullptr),
      JSStringCreateWithUTF8CString("line"), nullptr
    ));
    std::ostringstream lineInfo;
    if (line != nullptr && line.isNumber()) {
      lineInfo << " (line " << line.asInteger() << " in the generated bundle)";
    } else {
      lineInfo << " (no line info)";
    }
    throwNewJavaException("com/facebook/react/bridge/JSExecutionException", (exceptionText + lineInfo.str()).c_str());
  }
  return result;
}
Beispiel #18
0
JSValueRef function_http_request(JSContextRef ctx, JSObjectRef function, JSObjectRef this_object,
		size_t argc, const JSValueRef args[], JSValueRef* exception) {
	if (argc == 1 && JSValueGetType(ctx, args[0]) == kJSTypeObject) {
		JSObjectRef opts = JSValueToObject(ctx, args[0], NULL);
		JSValueRef url_ref = JSObjectGetProperty(ctx, opts, JSStringCreateWithUTF8CString("url"), NULL);
		char *url = value_to_c_string(ctx, url_ref);
		JSValueRef timeout_ref = JSObjectGetProperty(ctx, opts, JSStringCreateWithUTF8CString("timeout"), NULL);
		time_t timeout = 0;
		if (JSValueIsNumber(ctx, timeout_ref)) {
			timeout = (time_t) JSValueToNumber(ctx, timeout_ref, NULL);
		}
		JSValueRef method_ref = JSObjectGetProperty(ctx, opts, JSStringCreateWithUTF8CString("method"), NULL);
		char *method = value_to_c_string(ctx, method_ref);
		JSValueRef body_ref = JSObjectGetProperty(ctx, opts, JSStringCreateWithUTF8CString("body"), NULL);

		JSObjectRef headers_obj = JSValueToObject(ctx, JSObjectGetProperty(ctx, opts, JSStringCreateWithUTF8CString("headers"), NULL), NULL);

		CURL *handle = curl_easy_init();
		assert(handle != NULL);

		curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, method);
		curl_easy_setopt(handle, CURLOPT_URL, url);

		struct curl_slist *headers = NULL;
		if (!JSValueIsNull(ctx, headers_obj)) {
			JSPropertyNameArrayRef properties = JSObjectCopyPropertyNames(ctx, headers_obj);
			size_t n = JSPropertyNameArrayGetCount(properties);
			for (int i = 0; i < n; i++) {
				JSStringRef key_str = JSPropertyNameArrayGetNameAtIndex(properties, i);
				JSValueRef val_ref = JSObjectGetProperty(ctx, headers_obj, key_str, NULL);

				size_t len = JSStringGetLength(key_str) + 1;
				char *key = malloc(len * sizeof(char));
				JSStringGetUTF8CString(key_str, key, len);
				JSStringRef val_as_str = to_string(ctx, val_ref);
				char *val = value_to_c_string(ctx, JSValueMakeString(ctx, val_as_str));
				JSStringRelease(val_as_str);

				size_t len_key = strlen(key);
				size_t len_val = strlen(val);
				char *header = malloc((len_key + len_val + 2 + 1) * sizeof(char));
				sprintf(header, "%s: %s", key, val);
				curl_slist_append(headers, header);
				free(header);

				free(key);
				free(val);
			}

			curl_easy_setopt(handle, CURLOPT_HEADER, headers);
		}

		// curl_easy_setopt(handle, CURLOPT_HEADER, 1L);
		curl_easy_setopt(handle, CURLOPT_TIMEOUT, timeout);

		struct read_string_state input_state;
		if (!JSValueIsUndefined(ctx, body_ref)) {
			char *body = value_to_c_string(ctx, body_ref);
			input_state.input = body;
			input_state.offset = 0;
			input_state.length = strlen(body);
			curl_easy_setopt(handle, CURLOPT_READDATA, &input_state);
			curl_easy_setopt(handle, CURLOPT_READFUNCTION, read_string_callback);
		}

		JSObjectRef response_headers = JSObjectMake(ctx, NULL, NULL);
		struct header_state header_state;
		header_state.ctx = ctx;
		header_state.headers = response_headers;
		curl_easy_setopt(handle, CURLOPT_HEADERDATA, &header_state);
		curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, header_to_object_callback);

		struct write_state body_state;
		body_state.offset = 0;
		body_state.length = 0;
		body_state.data = NULL;
		curl_easy_setopt(handle, CURLOPT_WRITEDATA, &body_state);
		curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_string_callback);

		JSObjectRef result = JSObjectMake(ctx, NULL, NULL);

		int res = curl_easy_perform(handle);
		if (res != 0) {
			JSStringRef error_str = JSStringCreateWithUTF8CString(curl_easy_strerror(res));
			JSObjectSetProperty(ctx, result, JSStringCreateWithUTF8CString("error"), JSValueMakeString(ctx, error_str), kJSPropertyAttributeReadOnly, NULL);
		}

		int status = 0;
		curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &status);

		// printf("%d bytes, %x\n", body_state.offset, body_state.data);
		if (body_state.data != NULL) {
			JSStringRef body_str = JSStringCreateWithUTF8CString(body_state.data);
			JSObjectSetProperty(ctx, result, JSStringCreateWithUTF8CString("body"), JSValueMakeString(ctx, body_str), kJSPropertyAttributeReadOnly, NULL);
			free(body_state.data);
		}

		JSObjectSetProperty(ctx, result, JSStringCreateWithUTF8CString("status"), JSValueMakeNumber(ctx, status), kJSPropertyAttributeReadOnly, NULL);
		JSObjectSetProperty(ctx, result, JSStringCreateWithUTF8CString("headers"), response_headers, kJSPropertyAttributeReadOnly, NULL);

		curl_slist_free_all(headers);
		curl_easy_cleanup(handle);

		return result;
	}

	return JSValueMakeNull(ctx);
}
Beispiel #19
0
static JSObjectRef
ns_new(JSContextRef context,
       const char   *ns_name)
{
    Ns *priv = NULL;
    JSObjectRef ret = NULL;
    JSObjectRef global = NULL;
    gboolean found = FALSE;
    JSObjectRef proto = NULL;
    JSValueRef exception = NULL;

    // XXX: NOT THREAD SAFE?
    if (!gwkjs_ns_class_ref) {
        gwkjs_ns_class_ref = JSClassCreate(&gwkjs_ns_class);
        JSClassRetain(gwkjs_ns_class_ref);
    }

    global = gwkjs_get_import_global(context);
    if (!(found = gwkjs_object_has_property(context,
                                            global,
                                            gwkjs_ns_class.className))) {
        proto = JSObjectMake(context,
                             gwkjs_ns_class_ref,
                             NULL);

        gwkjs_object_set_property(context, global,
                                  gwkjs_ns_class.className,
                                  proto,
                                  GWKJS_PROTO_PROP_FLAGS,
                                  &exception);

        if (exception)
           g_error("Can't init class %s", gwkjs_ns_class.className);

        gwkjs_debug(GWKJS_DEBUG_IMPORTER, "Initialized class %s prototype %p",
                    gwkjs_ns_class.className, proto);
    } else {
        JSValueRef proto_val = gwkjs_object_get_property(context,
                                                         global,
                                                         gwkjs_ns_class.className,
                                                         &exception);

        if (exception || proto_val == NULL || !JSValueIsObject(context, proto_val))
            g_error("Can't get protoType for class %s", gwkjs_ns_class.className);

        proto = JSValueToObject(context, proto_val, NULL);
    }
    g_assert(proto != NULL);

    ret = JSObjectMake(context, gwkjs_ns_class_ref, NULL);

    if (ret == NULL)
        return ret;

    JSObjectSetPrototype(context, ret, proto);

    priv = g_slice_new0(Ns);
    GWKJS_INC_COUNTER(ns);
    
    g_assert(priv_from_js(ret) == NULL);
    JSObjectSetPrivate(ret, priv);

    gwkjs_debug_lifecycle(GWKJS_DEBUG_GNAMESPACE, "ns constructor, obj %p priv %p", ret, priv);

    priv = priv_from_js(ret);
    priv->modules = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);

    priv->gi_namespace = g_strdup(ns_name);
    return ret;
}
Beispiel #20
0
VJSObject VJSPropertyIterator::GetPropertyAsObject( JS4D::ExceptionRef *outException) const
{
	JS4D::ValueRef value = _GetProperty(  outException);
	return VJSObject( fObject.GetContextRef(), ((value != NULL) && JSValueIsObject( fObject.GetContextRef(), value)) ? JSValueToObject( fObject.GetContextRef(), value, outException) : NULL);
}
Beispiel #21
0
bool VJSValue::IsFunction() const
{
	JSObjectRef obj = ( (fValue != NULL) && JSValueIsObject( fContext, fValue) ) ? JSValueToObject( fContext, fValue, NULL) : NULL;
	return (obj != NULL) ? JSObjectIsFunction( fContext, obj) : false;
}
Beispiel #22
0
void VJSValue::GetObject( VJSObject& outObject, JS4D::ExceptionRef *outException) const
{
	outObject.SetObjectRef( ((fValue != NULL) && JSValueIsObject( fContext, fValue)) ? JSValueToObject( fContext, fValue, outException) : NULL);
}
Beispiel #23
0
static const gchar*
webview_eval_js(WebKitWebFrame *frame, const gchar *script, const gchar *file)
{
    JSGlobalContextRef context;
    JSObjectRef globalobject;
    JSStringRef js_file;
    JSStringRef js_script;
    JSValueRef js_result;
    JSValueRef js_exc = NULL;
    JSStringRef js_result_string;
    GString *result = g_string_new(NULL);
    size_t js_result_size;

    context = webkit_web_frame_get_global_context(frame);
    globalobject = JSContextGetGlobalObject(context);

    /* evaluate the script and get return value*/
    js_script = JSStringCreateWithUTF8CString(script);
    js_file = JSStringCreateWithUTF8CString(file);
    js_result = JSEvaluateScript(context, js_script, globalobject, js_file, 0, &js_exc);
    if (js_result && !JSValueIsUndefined(context, js_result)) {
        js_result_string = JSValueToStringCopy(context, js_result, NULL);
        js_result_size = JSStringGetMaximumUTF8CStringSize(js_result_string);

        if (js_result_size) {
            gchar js_result_utf8[js_result_size];
            JSStringGetUTF8CString(js_result_string, js_result_utf8, js_result_size);
            g_string_assign(result, js_result_utf8);
        }

        JSStringRelease(js_result_string);
    }
    else if (js_exc) {
        size_t size;
        JSStringRef prop, val;
        JSObjectRef exc = JSValueToObject(context, js_exc, NULL);

        g_printf("Exception occured while executing script:\n");

        /* Print file */
        prop = JSStringCreateWithUTF8CString("sourceURL");
        val = JSValueToStringCopy(context, JSObjectGetProperty(context, exc, prop, NULL), NULL);
        size = JSStringGetMaximumUTF8CStringSize(val);
        if(size) {
            gchar cstr[size];
            JSStringGetUTF8CString(val, cstr, size);
            g_printf("At %s", cstr);
        }
        JSStringRelease(prop);
        JSStringRelease(val);

        /* Print line */
        prop = JSStringCreateWithUTF8CString("line");
        val = JSValueToStringCopy(context, JSObjectGetProperty(context, exc, prop, NULL), NULL);
        size = JSStringGetMaximumUTF8CStringSize(val);
        if(size) {
            gchar cstr[size];
            JSStringGetUTF8CString(val, cstr, size);
            g_printf(":%s: ", cstr);
        }
        JSStringRelease(prop);
        JSStringRelease(val);

        /* Print message */
        val = JSValueToStringCopy(context, exc, NULL);
        size = JSStringGetMaximumUTF8CStringSize(val);
        if(size) {
            gchar cstr[size];
            JSStringGetUTF8CString(val, cstr, size);
            g_printf("%s\n", cstr);
        }
        JSStringRelease(val);
    }

    /* cleanup */
    JSStringRelease(js_script);
    JSStringRelease(js_file);

    return g_string_free(result, FALSE);
}
Beispiel #24
0
static JSValueRef beginDragWithFilesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    if (argumentCount < 1)
        return JSValueMakeUndefined(context);

    JSObjectRef filesArray = JSValueToObject(context, arguments[0], 0);

    if (!filesArray)
        return JSValueMakeUndefined(context);

    JSStringRef lengthProperty = JSStringCreateWithUTF8CString("length");
    Vector<UChar> files;
    int filesCount = JSValueToNumber(context, JSObjectGetProperty(context, filesArray, lengthProperty, 0), 0);
    for (int i = 0; i < filesCount; ++i) {
        JSValueRef value = JSObjectGetPropertyAtIndex(context, filesArray, i, 0);
        JSStringRef file = JSValueToStringCopy(context, value, 0);
        files.append(JSStringGetCharactersPtr(file), JSStringGetLength(file));
        files.append(0);
        JSStringRelease(file);
    }

    if (files.isEmpty())
        return JSValueMakeUndefined(context);

    // We should append "0" in the end of |files| so that |DragQueryFileW| retrieved the number of files correctly from Ole Clipboard.
    files.append(0);

    STGMEDIUM hDropMedium = {0};
    hDropMedium.tymed = TYMED_HGLOBAL;
    SIZE_T dropFilesSize = sizeof(DROPFILES) + (sizeof(WCHAR) * files.size());
    hDropMedium.hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, dropFilesSize);
    DROPFILES* dropFiles = reinterpret_cast<DROPFILES*>(GlobalLock(hDropMedium.hGlobal));
    memset(dropFiles, 0, sizeof(DROPFILES));
    dropFiles->pFiles = sizeof(DROPFILES);
    dropFiles->fWide = TRUE;

    UChar* data = reinterpret_cast<UChar*>(reinterpret_cast<BYTE*>(dropFiles) + sizeof(DROPFILES));
    for (size_t i = 0; i < files.size(); ++i)
        data[i] = files[i];
    GlobalUnlock(hDropMedium.hGlobal); 

    STGMEDIUM hFileNameMedium = {0};
    hFileNameMedium.tymed = TYMED_HGLOBAL;
    SIZE_T hFileNameSize = sizeof(WCHAR) * files.size();
    hFileNameMedium.hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, hFileNameSize);
    WCHAR* hFileName = static_cast<WCHAR*>(GlobalLock(hFileNameMedium.hGlobal));
    for (size_t i = 0; i < files.size(); i++)
        hFileName[i] = files[i];
    GlobalUnlock(hFileNameMedium.hGlobal);

    if (draggingInfo) {
        delete draggingInfo;
        draggingInfo = 0;
    }

    COMPtr<DRTDataObject> dataObeject;
    COMPtr<IDropSource> source;
    if (FAILED(DRTDataObject::createInstance(&dataObeject)))
        dataObeject = 0;

    if (FAILED(DRTDropSource::createInstance(&source)))
        source = 0;

    if (dataObeject && source) {
        draggingInfo = new DraggingInfo(dataObeject.get(), source.get());
        draggingInfo->setPerformedDropEffect(DROPEFFECT_COPY);
    }

    if (draggingInfo) {
        draggingInfo->dataObject()->SetData(cfHDropFormat(), &hDropMedium, FALSE);
        draggingInfo->dataObject()->SetData(cfFileNameWFormat(), &hFileNameMedium, FALSE);
        draggingInfo->dataObject()->SetData(cfUrlWFormat(), &hFileNameMedium, FALSE);
        OleSetClipboard(draggingInfo->dataObject());
        down = true;
    }

    JSStringRelease(lengthProperty);
    return JSValueMakeUndefined(context);
}
Beispiel #25
0
JSValueRef JSCInt16Array::setCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObj, size_t argumentCount, const JSValueRef* arguments, JSValueRef* exception) {

	struct JSCInt16ArrayPrivate* privData = (struct JSCInt16ArrayPrivate*)JSObjectGetPrivate(thisObj);

	if (false) {
	} else if (argumentCount == 2 &&
	           JSValueIsObject(ctx, arguments[0]) && JSValueIsObjectOfClass(ctx, arguments[0], JSCInt16Array::getTmpl()) &&
	           JSValueIsNumber(ctx, arguments[1])) {
		uscxml::Int16Array* localArray = ((struct JSCInt16Array::JSCInt16ArrayPrivate*)JSObjectGetPrivate(JSValueToObject(ctx, arguments[0], exception)))->nativeObj;
		unsigned long localOffset = (unsigned long)JSValueToNumber(ctx, arguments[1], exception);

		privData->nativeObj->set(localArray, localOffset);

		JSValueRef jscRetVal = JSValueMakeUndefined(ctx);
		return jscRetVal;
	} else if (argumentCount == 2 &&
	           JSValueIsNumber(ctx, arguments[0]) &&
	           JSValueIsNumber(ctx, arguments[1])) {
		unsigned long localIndex = (unsigned long)JSValueToNumber(ctx, arguments[0], exception);
		short localValue = (short)JSValueToNumber(ctx, arguments[1], exception);

		privData->nativeObj->set(localIndex, localValue);

		JSValueRef jscRetVal = JSValueMakeUndefined(ctx);
		return jscRetVal;
	} else if (argumentCount == 2 &&
	           JSValueIsObject(ctx, arguments[0]) &&
	           JSValueIsNumber(ctx, arguments[1])) {

		std::vector<short> localArray;

		JSValueRef localArrayItem;
		unsigned int localArrayIndex = 0;
		while((localArrayItem = JSObjectGetPropertyAtIndex(ctx, JSValueToObject(ctx, arguments[0], exception), localArrayIndex, exception))) {
			if (JSValueIsUndefined(ctx, localArrayItem))
				break;
			if (JSValueIsNumber(ctx,localArrayItem))
				localArray.push_back(JSValueToNumber(ctx, localArrayItem, exception));
			localArrayIndex++;
		}
		unsigned long localOffset = (unsigned long)JSValueToNumber(ctx, arguments[1], exception);

		privData->nativeObj->set(localArray, localOffset);

		JSValueRef jscRetVal = JSValueMakeUndefined(ctx);
		return jscRetVal;
	} else if (argumentCount == 1 &&
	           JSValueIsObject(ctx, arguments[0]) && JSValueIsObjectOfClass(ctx, arguments[0], JSCInt16Array::getTmpl())) {
		uscxml::Int16Array* localArray = ((struct JSCInt16Array::JSCInt16ArrayPrivate*)JSObjectGetPrivate(JSValueToObject(ctx, arguments[0], exception)))->nativeObj;

		privData->nativeObj->set(localArray);

		JSValueRef jscRetVal = JSValueMakeUndefined(ctx);
		return jscRetVal;
	} else if (argumentCount == 1 &&
	           JSValueIsObject(ctx, arguments[0])) {

		std::vector<short> localArray;

		JSValueRef localArrayItem;
		unsigned int localArrayIndex = 0;
		while((localArrayItem = JSObjectGetPropertyAtIndex(ctx, JSValueToObject(ctx, arguments[0], exception), localArrayIndex, exception))) {
			if (JSValueIsUndefined(ctx, localArrayItem))
				break;
			if (JSValueIsNumber(ctx,localArrayItem))
				localArray.push_back(JSValueToNumber(ctx, localArrayItem, exception));
			localArrayIndex++;
		}

		privData->nativeObj->set(localArray);

		JSValueRef jscRetVal = JSValueMakeUndefined(ctx);
		return jscRetVal;
	}

	JSStringRef exceptionString = JSStringCreateWithUTF8CString("Parameter mismatch while calling set");
	*exception = JSValueMakeString(ctx, exceptionString);
	JSStringRelease(exceptionString);
	return JSValueMakeUndefined(ctx);
}
Beispiel #26
0
JSObjectRef JSCInt16Array::jsConstructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) {
	uscxml::Int16Array* localInstance = NULL;

	if (false) {
	} else if (argumentCount == 3 &&
	           JSValueIsObject(ctx, arguments[0]) && JSValueIsObjectOfClass(ctx, arguments[0], JSCArrayBuffer::getTmpl()) &&
	           JSValueIsNumber(ctx, arguments[1]) &&
	           JSValueIsNumber(ctx, arguments[2])) {

		uscxml::ArrayBuffer* localBuffer = ((struct JSCArrayBuffer::JSCArrayBufferPrivate*)JSObjectGetPrivate(JSValueToObject(ctx, arguments[0], exception)))->nativeObj;
		unsigned long localByteOffset = (unsigned long)JSValueToNumber(ctx, arguments[1], exception);
		unsigned long localLength = (unsigned long)JSValueToNumber(ctx, arguments[2], exception);
		localInstance = new uscxml::Int16Array(localBuffer, localByteOffset, localLength);

	} else if (argumentCount == 2 &&
	           JSValueIsObject(ctx, arguments[0]) && JSValueIsObjectOfClass(ctx, arguments[0], JSCArrayBuffer::getTmpl()) &&
	           JSValueIsNumber(ctx, arguments[1])) {

		uscxml::ArrayBuffer* localBuffer = ((struct JSCArrayBuffer::JSCArrayBufferPrivate*)JSObjectGetPrivate(JSValueToObject(ctx, arguments[0], exception)))->nativeObj;
		unsigned long localByteOffset = (unsigned long)JSValueToNumber(ctx, arguments[1], exception);
		localInstance = new uscxml::Int16Array(localBuffer, localByteOffset);

	} else if (argumentCount == 1 &&
	           JSValueIsObject(ctx, arguments[0]) && JSValueIsObjectOfClass(ctx, arguments[0], JSCInt16Array::getTmpl())) {

		uscxml::Int16Array* localArray = ((struct JSCInt16Array::JSCInt16ArrayPrivate*)JSObjectGetPrivate(JSValueToObject(ctx, arguments[0], exception)))->nativeObj;
		localInstance = new uscxml::Int16Array(localArray);

	} else if (argumentCount == 1 &&
	           JSValueIsObject(ctx, arguments[0]) && JSValueIsObjectOfClass(ctx, arguments[0], JSCArrayBuffer::getTmpl())) {

		uscxml::ArrayBuffer* localBuffer = ((struct JSCArrayBuffer::JSCArrayBufferPrivate*)JSObjectGetPrivate(JSValueToObject(ctx, arguments[0], exception)))->nativeObj;
		localInstance = new uscxml::Int16Array(localBuffer);

	} else if (argumentCount == 1 &&
	           JSValueIsNumber(ctx, arguments[0])) {

		unsigned long localLength = (unsigned long)JSValueToNumber(ctx, arguments[0], exception);
		localInstance = new uscxml::Int16Array(localLength);

	} else if (argumentCount == 1 &&
	           JSValueIsObject(ctx, arguments[0])) {


		std::vector<short> localArray;

		JSValueRef localArrayItem;
		unsigned int localArrayIndex = 0;
		while((localArrayItem = JSObjectGetPropertyAtIndex(ctx, JSValueToObject(ctx, arguments[0], exception), localArrayIndex, exception))) {
			if (JSValueIsUndefined(ctx, localArrayItem))
				break;
			if (JSValueIsNumber(ctx,localArrayItem))
				localArray.push_back(JSValueToNumber(ctx, localArrayItem, exception));
			localArrayIndex++;
		}
		localInstance = new uscxml::Int16Array(localArray);

	}
	if (!localInstance) {
		JSStringRef exceptionString = JSStringCreateWithUTF8CString("Parameter mismatch while calling constructor for Int16Array");
		*exception = JSValueMakeString(ctx, exceptionString);
		JSStringRelease(exceptionString);
		return (JSObjectRef)JSValueMakeNull(ctx);
	}

	JSClassRef retClass = JSCInt16Array::getTmpl();

	struct JSCInt16Array::JSCInt16ArrayPrivate* retPrivData = new JSCInt16Array::JSCInt16ArrayPrivate();
	retPrivData->nativeObj = localInstance;

	JSObjectRef retObj = JSObjectMake(ctx, retClass, retPrivData);
	return retObj;
}
Beispiel #27
0
static JSValueRef keyDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    if (argumentCount < 1)
        return JSValueMakeUndefined(context);

    static const JSStringRef lengthProperty = JSStringCreateWithUTF8CString("length");

    COMPtr<IWebFramePrivate> framePrivate;
    if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
        framePrivate->layout();
    
    JSStringRef character = JSValueToStringCopy(context, arguments[0], exception);
    ASSERT(!*exception);
    int virtualKeyCode;
    int charCode = 0;
    int keyData = 1;
    bool needsShiftKeyModifier = false;
    if (JSStringIsEqualToUTF8CString(character, "leftArrow")) {
        virtualKeyCode = VK_LEFT;
        keyData += KF_EXTENDED << 16; // In this case, extended means "not keypad".
    } else if (JSStringIsEqualToUTF8CString(character, "rightArrow")) {
        virtualKeyCode = VK_RIGHT;
        keyData += KF_EXTENDED << 16;
    } else if (JSStringIsEqualToUTF8CString(character, "upArrow")) {
        virtualKeyCode = VK_UP;
        keyData += KF_EXTENDED << 16;
    } else if (JSStringIsEqualToUTF8CString(character, "downArrow")) {
        virtualKeyCode = VK_DOWN;
        keyData += KF_EXTENDED << 16;
    } else if (JSStringIsEqualToUTF8CString(character, "pageUp"))
        virtualKeyCode = VK_PRIOR;
    else if (JSStringIsEqualToUTF8CString(character, "pageDown"))
        virtualKeyCode = VK_NEXT;
    else if (JSStringIsEqualToUTF8CString(character, "home"))
        virtualKeyCode = VK_HOME;
    else if (JSStringIsEqualToUTF8CString(character, "end"))
        virtualKeyCode = VK_END;
    else if (JSStringIsEqualToUTF8CString(character, "insert"))
        virtualKeyCode = VK_INSERT;
    else if (JSStringIsEqualToUTF8CString(character, "delete"))
        virtualKeyCode = VK_DELETE;
    else if (JSStringIsEqualToUTF8CString(character, "printScreen"))
        virtualKeyCode = VK_SNAPSHOT;
    else if (JSStringIsEqualToUTF8CString(character, "menu"))
        virtualKeyCode = VK_APPS;
    else if (JSStringIsEqualToUTF8CString(character, "leftControl")) {
        virtualKeyCode = VK_CONTROL;
        keyData += makeKeyDataForScanCode(VK_LCONTROL);
    } else if (JSStringIsEqualToUTF8CString(character, "leftShift")) {
        virtualKeyCode = VK_SHIFT;
        keyData += makeKeyDataForScanCode(VK_LSHIFT);
    } else if (JSStringIsEqualToUTF8CString(character, "leftAlt")) {
        virtualKeyCode = VK_MENU;
        keyData += makeKeyDataForScanCode(VK_LMENU);
    } else if (JSStringIsEqualToUTF8CString(character, "rightControl")) {
        virtualKeyCode = VK_CONTROL;
        keyData += makeKeyDataForScanCode(VK_RCONTROL);
    } else if (JSStringIsEqualToUTF8CString(character, "rightShift")) {
        virtualKeyCode = VK_SHIFT;
        keyData += makeKeyDataForScanCode(VK_RSHIFT);
    } else if (JSStringIsEqualToUTF8CString(character, "rightAlt")) {
        virtualKeyCode = VK_MENU;
        keyData += makeKeyDataForScanCode(VK_RMENU);
    } else {
        charCode = JSStringGetCharactersPtr(character)[0];
        virtualKeyCode = LOBYTE(VkKeyScan(charCode));
        if (WTF::isASCIIUpper(charCode))
            needsShiftKeyModifier = true;
    }
    JSStringRelease(character);

    BYTE keyState[256];
    if (argumentCount > 1 || needsShiftKeyModifier) {
        ::GetKeyboardState(keyState);

        BYTE newKeyState[256];
        memcpy(newKeyState, keyState, sizeof(keyState));

        if (needsShiftKeyModifier)
            newKeyState[VK_SHIFT] = 0x80;

        if (argumentCount > 1) {
            JSObjectRef modifiersArray = JSValueToObject(context, arguments[1], 0);
            if (modifiersArray) {
                int modifiersCount = JSValueToNumber(context, JSObjectGetProperty(context, modifiersArray, lengthProperty, 0), 0);
                for (int i = 0; i < modifiersCount; ++i) {
                    JSValueRef value = JSObjectGetPropertyAtIndex(context, modifiersArray, i, 0);
                    JSStringRef string = JSValueToStringCopy(context, value, 0);
                    if (JSStringIsEqualToUTF8CString(string, "ctrlKey") || JSStringIsEqualToUTF8CString(string, "addSelectionKey"))
                        newKeyState[VK_CONTROL] = 0x80;
                    else if (JSStringIsEqualToUTF8CString(string, "shiftKey") || JSStringIsEqualToUTF8CString(string, "rangeSelectionKey"))
                        newKeyState[VK_SHIFT] = 0x80;
                    else if (JSStringIsEqualToUTF8CString(string, "altKey"))
                        newKeyState[VK_MENU] = 0x80;

                    JSStringRelease(string);
                }
            }
        }

        ::SetKeyboardState(newKeyState);
    }

    MSG msg = makeMsg(webViewWindow, (::GetKeyState(VK_MENU) & 0x8000) ? WM_SYSKEYDOWN : WM_KEYDOWN, virtualKeyCode, keyData);
    if (virtualKeyCode != 255)
        dispatchMessage(&msg);
    else {
        // For characters that do not exist in the active keyboard layout,
        // ::Translate will not work, so we post an WM_CHAR event ourselves.
        ::PostMessage(webViewWindow, WM_CHAR, charCode, 0);
    }

    // Tests expect that all messages are processed by the time keyDown() returns.
    if (::PeekMessage(&msg, webViewWindow, WM_CHAR, WM_CHAR, PM_REMOVE) || ::PeekMessage(&msg, webViewWindow, WM_SYSCHAR, WM_SYSCHAR, PM_REMOVE))
        ::DispatchMessage(&msg);

    MSG msgUp = makeMsg(webViewWindow, (::GetKeyState(VK_MENU) & 0x8000) ? WM_SYSKEYUP : WM_KEYUP, virtualKeyCode, keyData);
    ::DispatchMessage(&msgUp);

    if (argumentCount > 1 || needsShiftKeyModifier)
        ::SetKeyboardState(keyState);

    return JSValueMakeUndefined(context);
}
pdf_jsimp_obj *pdf_jsimp_array_item(pdf_jsimp *imp, pdf_jsimp_obj *obj, int i)
{
	return wrap_val(imp, JSObjectGetPropertyAtIndex(imp->jscore_ctx, JSValueToObject(imp->jscore_ctx, obj->ref, NULL), i, NULL));
}
Beispiel #29
0
static JSValueRef keyDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    if (argumentCount < 1)
        return JSValueMakeUndefined(context);

    static const JSStringRef lengthProperty = JSStringCreateWithUTF8CString("length");

    webkit_web_frame_layout(mainFrame);

    // handle modifier keys.
    int state = 0;
    if (argumentCount > 1) {
        JSObjectRef modifiersArray = JSValueToObject(context, arguments[1], exception);
        if (modifiersArray) {
            for (int i = 0; i < JSValueToNumber(context, JSObjectGetProperty(context, modifiersArray, lengthProperty, 0), 0); ++i) {
                JSValueRef value = JSObjectGetPropertyAtIndex(context, modifiersArray, i, 0);
                JSStringRef string = JSValueToStringCopy(context, value, 0);
                if (JSStringIsEqualToUTF8CString(string, "ctrlKey"))
                    state |= GDK_CONTROL_MASK;
                else if (JSStringIsEqualToUTF8CString(string, "shiftKey"))
                    state |= GDK_SHIFT_MASK;
                else if (JSStringIsEqualToUTF8CString(string, "altKey"))
                    state |= GDK_MOD1_MASK;

                JSStringRelease(string);
            }
        }
    }

    // handle location argument.
    int location = DOM_KEY_LOCATION_STANDARD;
    if (argumentCount > 2)
        location = (int)JSValueToNumber(context, arguments[2], exception);

    JSStringRef character = JSValueToStringCopy(context, arguments[0], exception);
    g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context));
    int gdkKeySym = GDK_VoidSymbol;
    if (location == DOM_KEY_LOCATION_NUMPAD) {
        if (JSStringIsEqualToUTF8CString(character, "leftArrow"))
            gdkKeySym = GDK_KP_Left;
        else if (JSStringIsEqualToUTF8CString(character, "rightArrow"))
            gdkKeySym = GDK_KP_Right;
        else if (JSStringIsEqualToUTF8CString(character, "upArrow"))
            gdkKeySym = GDK_KP_Up;
        else if (JSStringIsEqualToUTF8CString(character, "downArrow"))
            gdkKeySym = GDK_KP_Down;
        else if (JSStringIsEqualToUTF8CString(character, "pageUp"))
            gdkKeySym = GDK_KP_Page_Up;
        else if (JSStringIsEqualToUTF8CString(character, "pageDown"))
            gdkKeySym = GDK_KP_Page_Down;
        else if (JSStringIsEqualToUTF8CString(character, "home"))
            gdkKeySym = GDK_KP_Home;
        else if (JSStringIsEqualToUTF8CString(character, "end"))
            gdkKeySym = GDK_KP_End;
        else
            // Assume we only get arrow/pgUp/pgDn/home/end keys with
            // location=NUMPAD for now.
            g_assert_not_reached();
    } else {
        if (JSStringIsEqualToUTF8CString(character, "leftArrow"))
            gdkKeySym = GDK_Left;
        else if (JSStringIsEqualToUTF8CString(character, "rightArrow"))
            gdkKeySym = GDK_Right;
        else if (JSStringIsEqualToUTF8CString(character, "upArrow"))
            gdkKeySym = GDK_Up;
        else if (JSStringIsEqualToUTF8CString(character, "downArrow"))
            gdkKeySym = GDK_Down;
        else if (JSStringIsEqualToUTF8CString(character, "pageUp"))
            gdkKeySym = GDK_Page_Up;
        else if (JSStringIsEqualToUTF8CString(character, "pageDown"))
            gdkKeySym = GDK_Page_Down;
        else if (JSStringIsEqualToUTF8CString(character, "home"))
            gdkKeySym = GDK_Home;
        else if (JSStringIsEqualToUTF8CString(character, "end"))
            gdkKeySym = GDK_End;
        else if (JSStringIsEqualToUTF8CString(character, "delete"))
            gdkKeySym = GDK_BackSpace;
        else if (JSStringIsEqualToUTF8CString(character, "F1"))
            gdkKeySym = GDK_F1;
        else if (JSStringIsEqualToUTF8CString(character, "F2"))
            gdkKeySym = GDK_F2;
        else if (JSStringIsEqualToUTF8CString(character, "F3"))
            gdkKeySym = GDK_F3;
        else if (JSStringIsEqualToUTF8CString(character, "F4"))
            gdkKeySym = GDK_F4;
        else if (JSStringIsEqualToUTF8CString(character, "F5"))
            gdkKeySym = GDK_F5;
        else if (JSStringIsEqualToUTF8CString(character, "F6"))
            gdkKeySym = GDK_F6;
        else if (JSStringIsEqualToUTF8CString(character, "F7"))
            gdkKeySym = GDK_F7;
        else if (JSStringIsEqualToUTF8CString(character, "F8"))
            gdkKeySym = GDK_F8;
        else if (JSStringIsEqualToUTF8CString(character, "F9"))
            gdkKeySym = GDK_F9;
        else if (JSStringIsEqualToUTF8CString(character, "F10"))
            gdkKeySym = GDK_F10;
        else if (JSStringIsEqualToUTF8CString(character, "F11"))
            gdkKeySym = GDK_F11;
        else if (JSStringIsEqualToUTF8CString(character, "F12"))
            gdkKeySym = GDK_F12;
        else {
            int charCode = JSStringGetCharactersPtr(character)[0];
            if (charCode == '\n' || charCode == '\r')
                gdkKeySym = GDK_Return;
            else if (charCode == '\t')
                gdkKeySym = GDK_Tab;
            else if (charCode == '\x8')
                gdkKeySym = GDK_BackSpace;
            else {
                gdkKeySym = gdk_unicode_to_keyval(charCode);
                if (WTF::isASCIIUpper(charCode))
                    state |= GDK_SHIFT_MASK;
            }
        }
    }
    JSStringRelease(character);

    WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
    if (!view)
        return JSValueMakeUndefined(context);

    // create and send the event
    GdkEvent event;
    memset(&event, 0, sizeof(event));
    event.key.keyval = gdkKeySym;
    event.key.state = state;
    event.key.window = GTK_WIDGET(view)->window;

    // When synthesizing an event, an invalid hardware_keycode value
    // can cause it to be badly processed by Gtk+.
    GdkKeymapKey* keys;
    gint n_keys;
    if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), gdkKeySym, &keys, &n_keys)) {
        event.key.hardware_keycode = keys[0].keycode;
        g_free(keys);
    }

    gboolean return_val;
    event.key.type = GDK_KEY_PRESS;

    g_signal_emit_by_name(view, "key-press-event", &event.key, &return_val);

    event.key.type = GDK_KEY_RELEASE;
    g_signal_emit_by_name(view, "key-release-event", &event.key, &return_val);

    return JSValueMakeUndefined(context);
}
Beispiel #30
0
int main(int argc, char* argv[])
{
    const char *scriptPath = "testapi.js";
    if (argc > 1) {
        scriptPath = argv[1];
    }
    
    // Test garbage collection with a fresh context
    context = JSGlobalContextCreateInGroup(NULL, NULL);
    TestInitializeFinalize = true;
    testInitializeFinalize();
    JSGlobalContextRelease(context);
    TestInitializeFinalize = false;

    ASSERT(Base_didFinalize);

    JSClassDefinition globalObjectClassDefinition = kJSClassDefinitionEmpty;
    globalObjectClassDefinition.initialize = globalObject_initialize;
    globalObjectClassDefinition.staticValues = globalObject_staticValues;
    globalObjectClassDefinition.staticFunctions = globalObject_staticFunctions;
    globalObjectClassDefinition.attributes = kJSClassAttributeNoAutomaticPrototype;
    JSClassRef globalObjectClass = JSClassCreate(&globalObjectClassDefinition);
    context = JSGlobalContextCreateInGroup(NULL, globalObjectClass);

    JSGlobalContextRetain(context);
    JSGlobalContextRelease(context);

    JSObjectRef globalObject = JSContextGetGlobalObject(context);
    ASSERT(JSValueIsObject(context, globalObject));
    
    JSValueRef jsUndefined = JSValueMakeUndefined(context);
    JSValueRef jsNull = JSValueMakeNull(context);
    JSValueRef jsTrue = JSValueMakeBoolean(context, true);
    JSValueRef jsFalse = JSValueMakeBoolean(context, false);
    JSValueRef jsZero = JSValueMakeNumber(context, 0);
    JSValueRef jsOne = JSValueMakeNumber(context, 1);
    JSValueRef jsOneThird = JSValueMakeNumber(context, 1.0 / 3.0);
    JSObjectRef jsObjectNoProto = JSObjectMake(context, NULL, NULL);
    JSObjectSetPrototype(context, jsObjectNoProto, JSValueMakeNull(context));

    // FIXME: test funny utf8 characters
    JSStringRef jsEmptyIString = JSStringCreateWithUTF8CString("");
    JSValueRef jsEmptyString = JSValueMakeString(context, jsEmptyIString);
    
    JSStringRef jsOneIString = JSStringCreateWithUTF8CString("1");
    JSValueRef jsOneString = JSValueMakeString(context, jsOneIString);

    UniChar singleUniChar = 65; // Capital A
    CFMutableStringRef cfString = 
        CFStringCreateMutableWithExternalCharactersNoCopy(kCFAllocatorDefault,
                                                          &singleUniChar,
                                                          1,
                                                          1,
                                                          kCFAllocatorNull);

    JSStringRef jsCFIString = JSStringCreateWithCFString(cfString);
    JSValueRef jsCFString = JSValueMakeString(context, jsCFIString);
    
    CFStringRef cfEmptyString = CFStringCreateWithCString(kCFAllocatorDefault, "", kCFStringEncodingUTF8);
    
    JSStringRef jsCFEmptyIString = JSStringCreateWithCFString(cfEmptyString);
    JSValueRef jsCFEmptyString = JSValueMakeString(context, jsCFEmptyIString);

    CFIndex cfStringLength = CFStringGetLength(cfString);
    UniChar* buffer = (UniChar*)malloc(cfStringLength * sizeof(UniChar));
    CFStringGetCharacters(cfString, 
                          CFRangeMake(0, cfStringLength), 
                          buffer);
    JSStringRef jsCFIStringWithCharacters = JSStringCreateWithCharacters((JSChar*)buffer, cfStringLength);
    JSValueRef jsCFStringWithCharacters = JSValueMakeString(context, jsCFIStringWithCharacters);
    
    JSStringRef jsCFEmptyIStringWithCharacters = JSStringCreateWithCharacters((JSChar*)buffer, CFStringGetLength(cfEmptyString));
    free(buffer);
    JSValueRef jsCFEmptyStringWithCharacters = JSValueMakeString(context, jsCFEmptyIStringWithCharacters);

    ASSERT(JSValueGetType(context, jsUndefined) == kJSTypeUndefined);
    ASSERT(JSValueGetType(context, jsNull) == kJSTypeNull);
    ASSERT(JSValueGetType(context, jsTrue) == kJSTypeBoolean);
    ASSERT(JSValueGetType(context, jsFalse) == kJSTypeBoolean);
    ASSERT(JSValueGetType(context, jsZero) == kJSTypeNumber);
    ASSERT(JSValueGetType(context, jsOne) == kJSTypeNumber);
    ASSERT(JSValueGetType(context, jsOneThird) == kJSTypeNumber);
    ASSERT(JSValueGetType(context, jsEmptyString) == kJSTypeString);
    ASSERT(JSValueGetType(context, jsOneString) == kJSTypeString);
    ASSERT(JSValueGetType(context, jsCFString) == kJSTypeString);
    ASSERT(JSValueGetType(context, jsCFStringWithCharacters) == kJSTypeString);
    ASSERT(JSValueGetType(context, jsCFEmptyString) == kJSTypeString);
    ASSERT(JSValueGetType(context, jsCFEmptyStringWithCharacters) == kJSTypeString);

    JSObjectRef myObject = JSObjectMake(context, MyObject_class(context), NULL);
    JSStringRef myObjectIString = JSStringCreateWithUTF8CString("MyObject");
    JSObjectSetProperty(context, globalObject, myObjectIString, myObject, kJSPropertyAttributeNone, NULL);
    JSStringRelease(myObjectIString);
    
    JSValueRef exception;

    // Conversions that throw exceptions
    exception = NULL;
    ASSERT(NULL == JSValueToObject(context, jsNull, &exception));
    ASSERT(exception);
    
    exception = NULL;
    // FIXME <rdar://4668451> - On i386 the isnan(double) macro tries to map to the isnan(float) function,
    // causing a build break with -Wshorten-64-to-32 enabled.  The issue is known by the appropriate team.
    // After that's resolved, we can remove these casts
    ASSERT(isnan((float)JSValueToNumber(context, jsObjectNoProto, &exception)));
    ASSERT(exception);

    exception = NULL;
    ASSERT(!JSValueToStringCopy(context, jsObjectNoProto, &exception));
    ASSERT(exception);
    
    ASSERT(JSValueToBoolean(context, myObject));
    
    exception = NULL;
    ASSERT(!JSValueIsEqual(context, jsObjectNoProto, JSValueMakeNumber(context, 1), &exception));
    ASSERT(exception);
    
    exception = NULL;
    JSObjectGetPropertyAtIndex(context, myObject, 0, &exception);
    ASSERT(1 == JSValueToNumber(context, exception, NULL));

    assertEqualsAsBoolean(jsUndefined, false);
    assertEqualsAsBoolean(jsNull, false);
    assertEqualsAsBoolean(jsTrue, true);
    assertEqualsAsBoolean(jsFalse, false);
    assertEqualsAsBoolean(jsZero, false);
    assertEqualsAsBoolean(jsOne, true);
    assertEqualsAsBoolean(jsOneThird, true);
    assertEqualsAsBoolean(jsEmptyString, false);
    assertEqualsAsBoolean(jsOneString, true);
    assertEqualsAsBoolean(jsCFString, true);
    assertEqualsAsBoolean(jsCFStringWithCharacters, true);
    assertEqualsAsBoolean(jsCFEmptyString, false);
    assertEqualsAsBoolean(jsCFEmptyStringWithCharacters, false);
    
    assertEqualsAsNumber(jsUndefined, nan(""));
    assertEqualsAsNumber(jsNull, 0);
    assertEqualsAsNumber(jsTrue, 1);
    assertEqualsAsNumber(jsFalse, 0);
    assertEqualsAsNumber(jsZero, 0);
    assertEqualsAsNumber(jsOne, 1);
    assertEqualsAsNumber(jsOneThird, 1.0 / 3.0);
    assertEqualsAsNumber(jsEmptyString, 0);
    assertEqualsAsNumber(jsOneString, 1);
    assertEqualsAsNumber(jsCFString, nan(""));
    assertEqualsAsNumber(jsCFStringWithCharacters, nan(""));
    assertEqualsAsNumber(jsCFEmptyString, 0);
    assertEqualsAsNumber(jsCFEmptyStringWithCharacters, 0);
    ASSERT(sizeof(JSChar) == sizeof(UniChar));
    
    assertEqualsAsCharactersPtr(jsUndefined, "undefined");
    assertEqualsAsCharactersPtr(jsNull, "null");
    assertEqualsAsCharactersPtr(jsTrue, "true");
    assertEqualsAsCharactersPtr(jsFalse, "false");
    assertEqualsAsCharactersPtr(jsZero, "0");
    assertEqualsAsCharactersPtr(jsOne, "1");
    assertEqualsAsCharactersPtr(jsOneThird, "0.3333333333333333");
    assertEqualsAsCharactersPtr(jsEmptyString, "");
    assertEqualsAsCharactersPtr(jsOneString, "1");
    assertEqualsAsCharactersPtr(jsCFString, "A");
    assertEqualsAsCharactersPtr(jsCFStringWithCharacters, "A");
    assertEqualsAsCharactersPtr(jsCFEmptyString, "");
    assertEqualsAsCharactersPtr(jsCFEmptyStringWithCharacters, "");
    
    assertEqualsAsUTF8String(jsUndefined, "undefined");
    assertEqualsAsUTF8String(jsNull, "null");
    assertEqualsAsUTF8String(jsTrue, "true");
    assertEqualsAsUTF8String(jsFalse, "false");
    assertEqualsAsUTF8String(jsZero, "0");
    assertEqualsAsUTF8String(jsOne, "1");
    assertEqualsAsUTF8String(jsOneThird, "0.3333333333333333");
    assertEqualsAsUTF8String(jsEmptyString, "");
    assertEqualsAsUTF8String(jsOneString, "1");
    assertEqualsAsUTF8String(jsCFString, "A");
    assertEqualsAsUTF8String(jsCFStringWithCharacters, "A");
    assertEqualsAsUTF8String(jsCFEmptyString, "");
    assertEqualsAsUTF8String(jsCFEmptyStringWithCharacters, "");
    
    ASSERT(JSValueIsStrictEqual(context, jsTrue, jsTrue));
    ASSERT(!JSValueIsStrictEqual(context, jsOne, jsOneString));

    ASSERT(JSValueIsEqual(context, jsOne, jsOneString, NULL));
    ASSERT(!JSValueIsEqual(context, jsTrue, jsFalse, NULL));
    
    CFStringRef cfJSString = JSStringCopyCFString(kCFAllocatorDefault, jsCFIString);
    CFStringRef cfJSEmptyString = JSStringCopyCFString(kCFAllocatorDefault, jsCFEmptyIString);
    ASSERT(CFEqual(cfJSString, cfString));
    ASSERT(CFEqual(cfJSEmptyString, cfEmptyString));
    CFRelease(cfJSString);
    CFRelease(cfJSEmptyString);

    CFRelease(cfString);
    CFRelease(cfEmptyString);
    
    jsGlobalValue = JSObjectMake(context, NULL, NULL);
    JSValueProtect(context, jsGlobalValue);
    JSGarbageCollect(context);
    ASSERT(JSValueIsObject(context, jsGlobalValue));
    JSValueUnprotect(context, jsGlobalValue);

    JSStringRef goodSyntax = JSStringCreateWithUTF8CString("x = 1;");
    JSStringRef badSyntax = JSStringCreateWithUTF8CString("x := 1;");
    ASSERT(JSCheckScriptSyntax(context, goodSyntax, NULL, 0, NULL));
    ASSERT(!JSCheckScriptSyntax(context, badSyntax, NULL, 0, NULL));

    JSValueRef result;
    JSValueRef v;
    JSObjectRef o;
    JSStringRef string;

    result = JSEvaluateScript(context, goodSyntax, NULL, NULL, 1, NULL);
    ASSERT(result);
    ASSERT(JSValueIsEqual(context, result, jsOne, NULL));

    exception = NULL;
    result = JSEvaluateScript(context, badSyntax, NULL, NULL, 1, &exception);
    ASSERT(!result);
    ASSERT(JSValueIsObject(context, exception));
    
    JSStringRef array = JSStringCreateWithUTF8CString("Array");
    JSObjectRef arrayConstructor = JSValueToObject(context, JSObjectGetProperty(context, globalObject, array, NULL), NULL);
    JSStringRelease(array);
    result = JSObjectCallAsConstructor(context, arrayConstructor, 0, NULL, NULL);
    ASSERT(result);
    ASSERT(JSValueIsObject(context, result));
    ASSERT(JSValueIsInstanceOfConstructor(context, result, arrayConstructor, NULL));
    ASSERT(!JSValueIsInstanceOfConstructor(context, JSValueMakeNull(context), arrayConstructor, NULL));

    o = JSValueToObject(context, result, NULL);
    exception = NULL;
    ASSERT(JSValueIsUndefined(context, JSObjectGetPropertyAtIndex(context, o, 0, &exception)));
    ASSERT(!exception);
    
    JSObjectSetPropertyAtIndex(context, o, 0, JSValueMakeNumber(context, 1), &exception);
    ASSERT(!exception);
    
    exception = NULL;
    ASSERT(1 == JSValueToNumber(context, JSObjectGetPropertyAtIndex(context, o, 0, &exception), &exception));
    ASSERT(!exception);

    JSStringRef functionBody;
    JSObjectRef function;
    
    exception = NULL;
    functionBody = JSStringCreateWithUTF8CString("rreturn Array;");
    JSStringRef line = JSStringCreateWithUTF8CString("line");
    ASSERT(!JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, &exception));
    ASSERT(JSValueIsObject(context, exception));
    v = JSObjectGetProperty(context, JSValueToObject(context, exception, NULL), line, NULL);
    assertEqualsAsNumber(v, 1);
    JSStringRelease(functionBody);
    JSStringRelease(line);

    exception = NULL;
    functionBody = JSStringCreateWithUTF8CString("return Array;");
    function = JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, &exception);
    JSStringRelease(functionBody);
    ASSERT(!exception);
    ASSERT(JSObjectIsFunction(context, function));
    v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, NULL);
    ASSERT(v);
    ASSERT(JSValueIsEqual(context, v, arrayConstructor, NULL));
    
    exception = NULL;
    function = JSObjectMakeFunction(context, NULL, 0, NULL, jsEmptyIString, NULL, 0, &exception);
    ASSERT(!exception);
    v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, &exception);
    ASSERT(v && !exception);
    ASSERT(JSValueIsUndefined(context, v));
    
    exception = NULL;
    v = NULL;
    JSStringRef foo = JSStringCreateWithUTF8CString("foo");
    JSStringRef argumentNames[] = { foo };
    functionBody = JSStringCreateWithUTF8CString("return foo;");
    function = JSObjectMakeFunction(context, foo, 1, argumentNames, functionBody, NULL, 1, &exception);
    ASSERT(function && !exception);
    JSValueRef arguments[] = { JSValueMakeNumber(context, 2) };
    v = JSObjectCallAsFunction(context, function, NULL, 1, arguments, &exception);
    JSStringRelease(foo);
    JSStringRelease(functionBody);
    
    string = JSValueToStringCopy(context, function, NULL);
    assertEqualsAsUTF8String(JSValueMakeString(context, string), "function foo(foo) {return foo;}");
    JSStringRelease(string);

    JSStringRef print = JSStringCreateWithUTF8CString("print");
    JSObjectRef printFunction = JSObjectMakeFunctionWithCallback(context, print, print_callAsFunction);
    JSObjectSetProperty(context, globalObject, print, printFunction, kJSPropertyAttributeNone, NULL); 
    JSStringRelease(print);
    
    ASSERT(!JSObjectSetPrivate(printFunction, (void*)1));
    ASSERT(!JSObjectGetPrivate(printFunction));

    JSStringRef myConstructorIString = JSStringCreateWithUTF8CString("MyConstructor");
    JSObjectRef myConstructor = JSObjectMakeConstructor(context, NULL, myConstructor_callAsConstructor);
    JSObjectSetProperty(context, globalObject, myConstructorIString, myConstructor, kJSPropertyAttributeNone, NULL);
    JSStringRelease(myConstructorIString);
    
    ASSERT(!JSObjectSetPrivate(myConstructor, (void*)1));
    ASSERT(!JSObjectGetPrivate(myConstructor));
    
    string = JSStringCreateWithUTF8CString("Derived");
    JSObjectRef derivedConstructor = JSObjectMakeConstructor(context, Derived_class(context), NULL);
    JSObjectSetProperty(context, globalObject, string, derivedConstructor, kJSPropertyAttributeNone, NULL);
    JSStringRelease(string);
    
    o = JSObjectMake(context, NULL, NULL);
    JSObjectSetProperty(context, o, jsOneIString, JSValueMakeNumber(context, 1), kJSPropertyAttributeNone, NULL);
    JSObjectSetProperty(context, o, jsCFIString,  JSValueMakeNumber(context, 1), kJSPropertyAttributeDontEnum, NULL);
    JSPropertyNameArrayRef nameArray = JSObjectCopyPropertyNames(context, o);
    size_t expectedCount = JSPropertyNameArrayGetCount(nameArray);
    size_t count;
    for (count = 0; count < expectedCount; ++count)
        JSPropertyNameArrayGetNameAtIndex(nameArray, count);
    JSPropertyNameArrayRelease(nameArray);
    ASSERT(count == 1); // jsCFString should not be enumerated

    JSClassDefinition nullDefinition = kJSClassDefinitionEmpty;
    nullDefinition.attributes = kJSClassAttributeNoAutomaticPrototype;
    JSClassRef nullClass = JSClassCreate(&nullDefinition);
    JSClassRelease(nullClass);
    
    nullDefinition = kJSClassDefinitionEmpty;
    nullClass = JSClassCreate(&nullDefinition);
    JSClassRelease(nullClass);

    functionBody = JSStringCreateWithUTF8CString("return this;");
    function = JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, NULL);
    JSStringRelease(functionBody);
    v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, NULL);
    ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
    v = JSObjectCallAsFunction(context, function, o, 0, NULL, NULL);
    ASSERT(JSValueIsEqual(context, v, o, NULL));

    functionBody = JSStringCreateWithUTF8CString("return eval(\"this\");");
    function = JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, NULL);
    JSStringRelease(functionBody);
    v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, NULL);
    ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
    v = JSObjectCallAsFunction(context, function, o, 0, NULL, NULL);
    ASSERT(JSValueIsEqual(context, v, o, NULL));

    JSStringRef script = JSStringCreateWithUTF8CString("this;");
    v = JSEvaluateScript(context, script, NULL, NULL, 1, NULL);
    ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
    v = JSEvaluateScript(context, script, o, NULL, 1, NULL);
    ASSERT(JSValueIsEqual(context, v, o, NULL));
    JSStringRelease(script);

    script = JSStringCreateWithUTF8CString("eval(this);");
    v = JSEvaluateScript(context, script, NULL, NULL, 1, NULL);
    ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
    v = JSEvaluateScript(context, script, o, NULL, 1, NULL);
    ASSERT(JSValueIsEqual(context, v, o, NULL));
    JSStringRelease(script);

    char* scriptUTF8 = createStringWithContentsOfFile(scriptPath);
    if (!scriptUTF8)
        printf("FAIL: Test script could not be loaded.\n");
    else {
        script = JSStringCreateWithUTF8CString(scriptUTF8);
        result = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
        if (JSValueIsUndefined(context, result))
            printf("PASS: Test script executed successfully.\n");
        else {
            printf("FAIL: Test script returned unexpected value:\n");
            JSStringRef exceptionIString = JSValueToStringCopy(context, exception, NULL);
            CFStringRef exceptionCF = JSStringCopyCFString(kCFAllocatorDefault, exceptionIString);
            CFShow(exceptionCF);
            CFRelease(exceptionCF);
            JSStringRelease(exceptionIString);
        }
        JSStringRelease(script);
        free(scriptUTF8);
    }

    // Clear out local variables pointing at JSObjectRefs to allow their values to be collected
    function = NULL;
    v = NULL;
    o = NULL;
    globalObject = NULL;

    JSStringRelease(jsEmptyIString);
    JSStringRelease(jsOneIString);
    JSStringRelease(jsCFIString);
    JSStringRelease(jsCFEmptyIString);
    JSStringRelease(jsCFIStringWithCharacters);
    JSStringRelease(jsCFEmptyIStringWithCharacters);
    JSStringRelease(goodSyntax);
    JSStringRelease(badSyntax);

    JSGlobalContextRelease(context);
    JSClassRelease(globalObjectClass);

    printf("PASS: Program exited normally.\n");
    return 0;
}