Esempio n. 1
0
VJSArray::VJSArray( JS4D::ContextRef inContext, const std::vector<VJSValue>& inValues, JS4D::ExceptionRef *outException)
: fContext( inContext)
{
	// build an array
	if (inValues.empty())
	{
		#if NEW_WEBKIT
		fObject = JSObjectMakeArray( fContext, 0, NULL, outException);
		#else
		fObject = NULL;
		#endif
	}
	else
	{
		JSValueRef *values = new JSValueRef[inValues.size()];
		if (values != NULL)
		{
			size_t j = 0;
			for( std::vector<VJSValue>::const_iterator i = inValues.begin() ; i != inValues.end() ; ++i)
				values[j++] = i->GetValueRef();
		}
		#if NEW_WEBKIT
		fObject = JSObjectMakeArray( fContext, inValues.size(), values, outException);
		#else
		fObject = NULL;
		#endif
		delete[] values;
	}
}
static JSValueRef
get_users_cb(JSContextRef context,
			 JSObjectRef thisObject,
			 JSStringRef propertyName,
			 JSValueRef *exception) {

	JSObjectRef array;
	const GList *users, *link;
	guint i, n_users = 0;
	JSValueRef *args;

	users = lightdm_user_list_get_users(lightdm_user_list_get_instance());
	n_users = g_list_length((GList *) users);
	args = g_malloc(sizeof(JSValueRef) * ( n_users + 1 ));

	for (i = 0, link = users; link; i++, link = link->next) {
		LightDMUser *user = link->data;
		g_object_ref(user);
		args[i] = JSObjectMake(context, lightdm_user_class, user);
	}

	array = JSObjectMakeArray(context, n_users, args, exception);
	g_free(args);

	if (array == NULL) {
		return JSValueMakeNull(context);
	} else {
		return array;
	}
}
Esempio n. 3
0
JSValueRef function_read_file(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject,
                              size_t argc, const JSValueRef args[], JSValueRef *exception) {
    // TODO: implement fully

    if (argc == 1 && JSValueGetType(ctx, args[0]) == kJSTypeString) {
        char path[100];
        JSStringRef path_str = JSValueToStringCopy(ctx, args[0], NULL);
        assert(JSStringGetLength(path_str) < 100);
        JSStringGetUTF8CString(path_str, path, 100);
        JSStringRelease(path_str);

        // debug_print_value("read_file", ctx, args[0]);

        time_t last_modified = 0;
        char *contents = get_contents(path, &last_modified);
        if (contents != NULL) {
            JSStringRef contents_str = JSStringCreateWithUTF8CString(contents);
            free(contents);

            JSValueRef res[2];
            res[0] = JSValueMakeString(ctx, contents_str);
            res[1] = JSValueMakeNumber(ctx, last_modified);
            return JSObjectMakeArray(ctx, 2, res, NULL);
        }
    }

    return JSValueMakeNull(ctx);
}
Esempio n. 4
0
static JSValueRef firstRectForCharacterRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
    if (!view)
        return JSValueMakeUndefined(context);

    if (argumentCount < 2)
        return JSValueMakeUndefined(context);

    int location = static_cast<int>(JSValueToNumber(context, arguments[0], exception));
    g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context));

    int length = static_cast<int>(JSValueToNumber(context, arguments[1], exception));
    g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context));

    GdkRectangle rect;
    if (!DumpRenderTreeSupportGtk::firstRectForCharacterRange(view, location, length, &rect))
        return JSValueMakeUndefined(context);

    JSValueRef arrayValues[4];
    arrayValues[0] = JSValueMakeNumber(context, rect.x);
    arrayValues[1] = JSValueMakeNumber(context, rect.y);
    arrayValues[2] = JSValueMakeNumber(context, rect.width);
    arrayValues[3] = JSValueMakeNumber(context, rect.height);
    JSObjectRef arrayObject = JSObjectMakeArray(context, 4, arrayValues, exception);
    g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context));

    return arrayObject;
}
Esempio n. 5
0
JSValueRef function_file_input_stream_read(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject,
                                           size_t argc, const JSValueRef args[], JSValueRef *exception) {
    if (argc == 1
        && JSValueGetType(ctx, args[0]) == kJSTypeString) {

        char *descriptor = value_to_c_string(ctx, args[0]);

        size_t buf_size = 4096;
        uint8_t *buf = malloc(buf_size * sizeof(uint8_t));

        size_t read = file_read(descriptor_str_to_int(descriptor), buf_size, buf);

        free(descriptor);

        JSValueRef arguments[read];
        int num_arguments = (int) read;
        for (int i = 0; i < num_arguments; i++) {
            arguments[i] = JSValueMakeNumber(ctx, buf[i]);
        }

        return JSObjectMakeArray(ctx, num_arguments, arguments, NULL);
    }

    return JSValueMakeNull(ctx);
}
static JSValueRef firstRectForCharacterRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    if (argumentCount < 2)
        return JSValueMakeUndefined(context);

    double start = JSValueToNumber(context, arguments[0], exception);
    ASSERT(!*exception);

    double length = JSValueToNumber(context, arguments[1], exception);
    ASSERT(!*exception);

    TextInputController* controller = static_cast<TextInputController*>(JSObjectGetPrivate(thisObject));

    if (controller) {
        vector<int> rect = controller->firstRectForCharacterRange(start, length);
        if (rect.size() == 4) {
            JSValueRef argumentsArrayValues[] = 
            { 
                JSValueMakeNumber(context, rect[0]), 
                JSValueMakeNumber(context, rect[1]), 
                JSValueMakeNumber(context, rect[2]), 
                JSValueMakeNumber(context, rect[3]), 
            };
            JSObjectRef result = JSObjectMakeArray(context, sizeof(argumentsArrayValues) / sizeof(JSValueRef), argumentsArrayValues, exception);
            ASSERT(!*exception);
            return result;
        }
    }

    return JSValueMakeUndefined(context);
}
Esempio n. 7
0
JSValueRef function_load_deps_cljs_files(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject,
		size_t argc, const JSValueRef args[], JSValueRef* exception) {
	int num_files = 0;
	char **deps_cljs_files = NULL;

	if (argc == 0) {
		for (int i = 0; i < num_src_paths; i++) {
			char *type = src_paths[i].type;
			char *location = src_paths[i].path;

			if (strcmp(type, "jar") == 0) {
				char *source = get_contents_zip(location, "deps.cljs", NULL);
				if (source != NULL) {
					num_files += 1;
					deps_cljs_files = realloc(deps_cljs_files, num_files * sizeof(char*));
					deps_cljs_files[num_files - 1] = source;
				}
			}
		}
	}

	JSValueRef files[num_files];
	for (int i = 0; i < num_files; i++) {
		JSStringRef file = JSStringCreateWithUTF8CString(deps_cljs_files[i]);
		files[i] = JSValueMakeString(ctx, file);
		free(deps_cljs_files[i]);
	}
	free(deps_cljs_files);

	return JSObjectMakeArray(ctx, num_files, files, NULL);
}
Esempio n. 8
0
NATIVE(JSObject,jobject,makeArray) (PARAMS, jlong ctx, jlongArray args) {
	JSValueRef exception = NULL;

	int i, sum = 0;
	jsize len = env->GetArrayLength(args);
	jlong *values = env->GetLongArrayElements(args, 0);
	JSValueRef* elements = new JSValueRef[len];
	for (i=0; i<len; i++) {
		elements[i] = (JSValueRef) values[i];
	}
	env->ReleaseLongArrayElements(args, values, 0);

	jclass ret = env->FindClass("org/liquidplayer/webkit/javascriptcore/JNIReturnObject");
	jmethodID cid = env->GetMethodID(ret,"<init>","()V");
	jobject out = env->NewObject(ret, cid);

	jfieldID fid = env->GetFieldID(ret , "reference", "J");
	env->SetLongField( out, fid, (long) JSObjectMakeArray((JSContextRef) ctx, (size_t)len, (len==0)?NULL:elements, &exception));

	fid = env->GetFieldID(ret , "exception", "J");
	env->SetLongField( out, fid, (long) exception);

	delete elements;
	return out;
}
static JSValueRef
get_sessions_cb(JSContextRef context,
				JSObjectRef thisObject,
				JSStringRef propertyName,
				JSValueRef *exception) {

	JSObjectRef array;
	const GList *sessions, *link;
	guint i, n_sessions = 0;
	JSValueRef *args;

	sessions = lightdm_get_sessions();
	n_sessions = g_list_length((GList *) sessions);
	args = g_malloc(sizeof(JSValueRef) * ( n_sessions + 1 ));

	for (i = 0, link = sessions; link; i++, link = link->next) {
		LightDMSession *session = link->data;
		g_object_ref(session);

		args[i] = JSObjectMake(context, lightdm_session_class, session);
	}

	array = JSObjectMakeArray(context, n_sessions, args, exception);
	g_free(args);

	if (array == NULL) {
		return JSValueMakeNull(context);
	} else {
		return array;
	}
}
Esempio n. 10
0
JSValueRef function_get_term_size(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject,
		size_t argc, const JSValueRef args[], JSValueRef* exception) {
	// if (return_term_size)
	struct winsize w;
	ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
	JSValueRef  arguments[2];
	arguments[0] = JSValueMakeNumber(ctx, w.ws_row);
	arguments[1] = JSValueMakeNumber(ctx, w.ws_col);
	return JSObjectMakeArray(ctx, 2, arguments, NULL);
	// return JSValueMakeNull(ctx);
}
static JSValueRef
get_dirlist_cb(JSContextRef context,
			JSObjectRef function,
			JSObjectRef thisObject,
			size_t argumentCount,
			const JSValueRef arguments[],
			JSValueRef *exception) {
	JSObjectRef array;
	guint n_entries = 0;
	JSValueRef *args = NULL;
	GDir *dir;
	gchar *path, *fullpath;
	const gchar *dirent;
	GError *err = NULL;

	if (argumentCount != 1) {
		return mkexception(context, exception, ARGNOTSUPPLIED);
	}

	path = arg_to_string(context, arguments[0], exception);
	if (!path) {
		return JSValueMakeNull(context);
	}

	dir = g_dir_open (path, 0, &err);

	if (err) {
		_mkexception(context, exception, err->message);
		g_error_free(err);
		return JSValueMakeNull(context);
	}

	/*
	 * Create the lis of the directory entries
	 */

	while ((dirent = g_dir_read_name (dir)) != NULL) {
		n_entries++;
		args = g_realloc (args, sizeof (JSValueRef) * (n_entries + 1));
		fullpath = g_build_filename (path, dirent, NULL); /* Give theme developer full pathname */
		args[(n_entries - 1)] = string_or_null (context, fullpath);
		g_free (fullpath);
	}

	g_dir_close (dir);

	array = JSObjectMakeArray (context, n_entries, args, exception);
	g_free (args);
	if (array == NULL) {
		return JSValueMakeNull (context);
	} else {
		return array;
	}
}
Esempio n. 12
0
File: ns_net.c Progetto: vifino/dwb
/**
 * Gets all cookies from the cookie jar.
 *
 * @name allCookies
 * @memberOf net
 * @function
 * @since 1.5
 *
 * @returns {Array[{@link Cookie}]}
 *      An array of {@link Cookie|cookies}
 *
 * */
static JSValueRef
net_all_cookies(JSContextRef ctx, JSObjectRef f, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exc)
{
    JSValueRef ret = NULL;
    GSList *cookies = dwb_soup_get_all_cookies();
    if (cookies != NULL)
    {
        guint l = g_slist_length(cookies), i=0;
        JSValueRef *args = g_malloc(l * sizeof (JSValueRef));
        for (GSList *l = cookies; l; l=l->next, i++)
        {
            args[i] = scripts_make_cookie(l->data);
        }
        ret = JSObjectMakeArray(ctx, i, args, exc);
        g_free(args);
        g_slist_free(cookies);
    }
    else
        ret = JSObjectMakeArray(ctx, 0, NULL, exc);
    return ret;
}
Esempio n. 13
0
static inline JSValueRef stringArrayToJS(JSContextRef context, WKArrayRef strings)
{
    const size_t count = WKArrayGetSize(strings);

    OwnArrayPtr<JSValueRef> jsStringsArray = adoptArrayPtr(new JSValueRef[count]);
    for (size_t i = 0; i < count; ++i) {
        WKStringRef stringRef = static_cast<WKStringRef>(WKArrayGetItemAtIndex(strings, i));
        JSRetainPtr<JSStringRef> stringJS = toJS(stringRef);
        jsStringsArray[i] = JSValueMakeString(context, stringJS.get());
    }

    return JSObjectMakeArray(context, count, jsStringsArray.get(), 0);
}
Esempio n. 14
0
static inline JSValueRef stringArrayToJS(JSContextRef context, WKArrayRef strings)
{
    const size_t count = WKArrayGetSize(strings);

    JSValueRef arrayResult = JSObjectMakeArray(context, 0, 0, 0);
    JSObjectRef arrayObj = JSValueToObject(context, arrayResult, 0);
    for (size_t i = 0; i < count; ++i) {
        WKStringRef stringRef = static_cast<WKStringRef>(WKArrayGetItemAtIndex(strings, i));
        JSRetainPtr<JSStringRef> stringJS = toJS(stringRef);
        JSObjectSetPropertyAtIndex(context, arrayObj, i, JSValueMakeString(context, stringJS.get()), 0);
    }

    return arrayResult;
}
Esempio n. 15
0
JSValueRef Value::fromDynamicInner(JSContextRef ctx, const folly::dynamic& obj) {
  switch (obj.type()) {
    // For premitive types (and strings), just create and return an equivalent JSValue
    case folly::dynamic::Type::NULLT:
      return JSValueMakeNull(ctx);

    case folly::dynamic::Type::BOOL:
      return JSValueMakeBoolean(ctx, obj.getBool());

    case folly::dynamic::Type::DOUBLE:
      return JSValueMakeNumber(ctx, obj.getDouble());

    case folly::dynamic::Type::INT64:
      return JSValueMakeNumber(ctx, obj.asDouble());

    case folly::dynamic::Type::STRING:
      return JSValueMakeString(ctx, String(obj.getString().c_str()));

    case folly::dynamic::Type::ARRAY: {
      // Collect JSValue for every element in the array
      JSValueRef vals[obj.size()];
      for (size_t i = 0; i < obj.size(); ++i) {
        vals[i] = fromDynamicInner(ctx, obj[i]);
      }
      // Create a JSArray with the values
      JSValueRef arr = JSObjectMakeArray(ctx, obj.size(), vals, nullptr);
      return arr;
    }

    case folly::dynamic::Type::OBJECT: {
      // Create an empty object
      JSObjectRef jsObj = JSObjectMake(ctx, nullptr, nullptr);
      // Create a JSValue for each of the object's children and set them in the object
      for (auto it = obj.items().begin(); it != obj.items().end(); ++it) {
        JSObjectSetProperty(
          ctx,
          jsObj,
          String(it->first.asString().c_str()),
          fromDynamicInner(ctx, it->second),
          kJSPropertyAttributeNone,
          nullptr);
      }
      return jsObj;
    }
    default:
      // Assert not reached
      LOG(FATAL) << "Trying to convert a folly object of unsupported type.";
      return JSValueMakeNull(ctx);
  }
}
static JSValueRef markedRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    TextInputController* controller = static_cast<TextInputController*>(JSObjectGetPrivate(thisObject));
    if (controller) {
        vector<int> range = controller->markedRange();
        if (range.size() == 2) {
            JSValueRef argumentsArrayValues[] = { JSValueMakeNumber(context, range[0]), JSValueMakeNumber(context, range[1]) };
            JSObjectRef result = JSObjectMakeArray(context, sizeof(argumentsArrayValues) / sizeof(JSValueRef), argumentsArrayValues, exception);
            ASSERT(!*exception);
            return result;
        }
    }

    return JSValueMakeUndefined(context);
}
Esempio n. 17
0
JSValueRef function_list_files(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject,
                               size_t argc, const JSValueRef args[], JSValueRef *exception) {
    if (argc == 1
        && JSValueGetType(ctx, args[0]) == kJSTypeString) {

        char *path = value_to_c_string(ctx, args[0]);

        size_t capacity = 32;
        size_t count = 0;
        JSValueRef *paths = malloc(capacity * sizeof(paths));

        DIR *d;
        struct dirent *dir;
        d = opendir(path);

        size_t path_len = strlen(path);
        if (path_len && path[path_len - 1] == '/') {
            path[--path_len] = 0;
        }

        if (d) {
            while ((dir = readdir(d)) != NULL) {
                if (strcmp(dir->d_name, ".") && strcmp(dir->d_name, "..")) {

                    char *buf = malloc((path_len + strlen(dir->d_name) + 2));
                    sprintf(buf, "%s/%s", path, dir->d_name);
                    paths[count++] = c_string_to_value(ctx, buf);
                    free(buf);

                    if (count == capacity) {
                        capacity *= 2;
                        paths = realloc(paths, capacity * sizeof(paths));
                    }
                }
            }

            closedir(d);
        }

        free(path);

        JSValueRef rv = JSObjectMakeArray(ctx, count, paths, NULL);
        free(paths);

        return rv;
    }
    return JSValueMakeNull(ctx);
}
JNIEXPORT jintLong JNICALL WebKit_win32_NATIVE(JSObjectMakeArray)
	(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jintLongArray arg2, jintLongArray arg3)
{
	jintLong *lparg2=NULL;
	jintLong *lparg3=NULL;
	jintLong rc = 0;
	WebKit_win32_NATIVE_ENTER(env, that, JSObjectMakeArray_FUNC);
	if (arg2) if ((lparg2 = env->GetIntLongArrayElements(arg2, NULL)) == NULL) goto fail;
	if (arg3) if ((lparg3 = env->GetIntLongArrayElements(arg3, NULL)) == NULL) goto fail;
	rc = (jintLong)JSObjectMakeArray((JSContextRef)arg0, (size_t)arg1, (const struct OpaqueJSValue * const*)lparg2, (JSValueRef*)lparg3);
fail:
	if (arg3 && lparg3) env->ReleaseIntLongArrayElements(arg3, lparg3, 0);
	if (arg2 && lparg2) env->ReleaseIntLongArrayElements(arg2, lparg2, 0);
	WebKit_win32_NATIVE_EXIT(env, that, JSObjectMakeArray_FUNC);
	return rc;
}
Esempio n. 19
0
JSArray::JSArray(const std::initializer_list<JSValue>& values) : ctx_(GetJSContext()) {
  size_t argCount = values.size();
  JSValueRef* args = nullptr;
  if (argCount) {
    args = new JSValueRef[argCount];
    size_t i = 0;
    for (auto arg : values)
      args[i++] = arg;
  }

  instance_ = JSObjectMakeArray(ctx_, argCount, args, nullptr);

  if (args)
    delete[] args;

  JSValueProtect(ctx_, instance_);
}
Esempio n. 20
0
static JSValueRef selectedRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
    if (!view)
        return JSValueMakeUndefined(context);

    int start, end;
    if (!DumpRenderTreeSupportGtk::selectedRange(view, &start, &end))
        return JSValueMakeUndefined(context);

    JSValueRef arrayValues[2];
    arrayValues[0] = JSValueMakeNumber(context, start);
    arrayValues[1] = JSValueMakeNumber(context, end);
    JSObjectRef arrayObject = JSObjectMakeArray(context, 2, arrayValues, exception);
    g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context));

    return arrayObject;
}
Esempio n. 21
0
JSValueRef function_file_reader_read(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject,
                                     size_t argc, const JSValueRef args[], JSValueRef *exception) {
    if (argc == 1
        && JSValueGetType(ctx, args[0]) == kJSTypeString) {

        char *descriptor = value_to_c_string(ctx, args[0]);

        JSStringRef result = ufile_read(descriptor_str_to_int(descriptor));

        free(descriptor);

        JSValueRef arguments[2];
        if (result != NULL) {
            arguments[0] = JSValueMakeString(ctx, result);
            JSStringRelease(result);
        } else {
            arguments[0] = JSValueMakeNull(ctx);
        }
        arguments[1] = JSValueMakeNull(ctx);
        return JSObjectMakeArray(ctx, 2, arguments, NULL);
    }

    return JSValueMakeNull(ctx);
}
Esempio n. 22
0
JSValueRef dbus_to_js(JSContextRef ctx, GVariant *dbus)
{
    JSValueRef jsvalue = NULL;
    GVariantClass type = g_variant_classify(dbus);
    switch (type) {
        case G_VARIANT_CLASS_STRING:
        case G_VARIANT_CLASS_OBJECT_PATH:
        case G_VARIANT_CLASS_SIGNATURE:
            {
                JSStringRef js_string = JSStringCreateWithUTF8CString(g_variant_get_string(dbus, NULL));
                jsvalue = JSValueMakeString(ctx, js_string);
                JSStringRelease(js_string);
                return jsvalue;
            }
        case G_VARIANT_CLASS_BYTE:
            return JSValueMakeNumber(ctx, g_variant_get_byte(dbus));
        case G_VARIANT_CLASS_DOUBLE:
            return JSValueMakeNumber(ctx, g_variant_get_double(dbus));
        case G_VARIANT_CLASS_INT16:
            return JSValueMakeNumber(ctx, g_variant_get_int16(dbus));
        case G_VARIANT_CLASS_UINT16:
            return JSValueMakeNumber(ctx, g_variant_get_uint16(dbus));
        case G_VARIANT_CLASS_INT32:
            return JSValueMakeNumber(ctx, g_variant_get_int32(dbus));
        case G_VARIANT_CLASS_UINT32:
            return JSValueMakeNumber(ctx, g_variant_get_uint32(dbus));
        case G_VARIANT_CLASS_INT64:
            return JSValueMakeNumber(ctx, g_variant_get_int64(dbus));
        case G_VARIANT_CLASS_UINT64:
            return JSValueMakeNumber(ctx, g_variant_get_uint64(dbus));
        case G_VARIANT_CLASS_BOOLEAN:
            return JSValueMakeBoolean(ctx, g_variant_get_boolean(dbus));
        case G_VARIANT_CLASS_HANDLE:
            g_warning("didn't support FD type");
            return JSValueMakeNumber(ctx, g_variant_get_uint32(dbus));
        case G_VARIANT_CLASS_VARIANT:
            {
                GVariant* v = g_variant_get_variant(dbus);
                jsvalue = dbus_to_js(ctx, v);
                g_variant_unref(v);
                return jsvalue;
            }

        case G_VARIANT_CLASS_DICT_ENTRY:
            /*g_assert_not_reached();*/
            break;

        case G_VARIANT_CLASS_ARRAY:
            {
                if (g_variant_type_is_dict_entry(g_variant_type_element(g_variant_get_type(dbus)))) {
                    jsvalue = JSObjectMake(ctx, NULL, NULL);
                    for (size_t i=0; i<g_variant_n_children(dbus); i++) {
                        GVariant *dic = g_variant_get_child_value(dbus, i);
                        GVariant *key= g_variant_get_child_value (dic, 0);
                        GVariant *value = g_variant_get_child_value (dic, 1);

                        JSValueRef js_key = dbus_to_js(ctx, key);
                        JSValueRef js_value = dbus_to_js(ctx, value);

                        JSStringRef key_str = JSValueToStringCopy(ctx, js_key, NULL);
                        JSObjectSetProperty(ctx, (JSObjectRef)jsvalue, key_str, js_value, 0, NULL);
                        JSStringRelease(key_str);

                        g_variant_unref(key);
                        g_variant_unref(value);
                        g_variant_unref(dic);
                    }
                    return jsvalue;
                } else {
                    int n = g_variant_n_children(dbus);
                    JSValueRef *args = g_new(JSValueRef, n);
                    for (int i=0; i < n; i++) {
                        GVariant* v = g_variant_get_child_value(dbus, i);
                        args[i] = dbus_to_js(ctx, v);
                        g_variant_unref(v);
                    }
                    jsvalue = JSObjectMakeArray(ctx, n, args, NULL);
                    g_free(args);
                    return jsvalue;
                }
            }
        case G_VARIANT_CLASS_TUPLE:
            {
                int n = g_variant_n_children(dbus);
                jsvalue = JSObjectMakeArray(ctx, 0, NULL, NULL);
                for (int i=0; i < n; i++) {
                    GVariant* v = g_variant_get_child_value(dbus, i);
                    JSObjectSetPropertyAtIndex(ctx, (JSObjectRef)jsvalue, i, dbus_to_js(ctx, v), NULL);
                    g_variant_unref(v);
                }
                return jsvalue;
            }
        case G_VARIANT_CLASS_MAYBE:
            g_assert_not_reached();
    }
    g_warning("didn't support signature type:%c", type);
    return JSValueMakeUndefined(ctx);
}
Esempio n. 23
0
int main(int argc, char **argv) {
	struct option long_options[] = {
		{"help", no_argument, NULL, 'h'},
		{"legal", no_argument, NULL, 'l'},
		{"verbose", no_argument, NULL, 'v'},
		{"quiet", no_argument, NULL, 'q'},
		{"repl", no_argument, NULL, 'r'},
		{"static-fns", no_argument, NULL, 's'},
		{"elide-asserts", no_argument, NULL, 'a'},
		{"cache", required_argument, NULL, 'k'},
		{"eval", required_argument, NULL, 'e'},
		{"theme", required_argument, NULL, 't'},
		{"classpath", required_argument, NULL, 'c'},
		{"auto-cache", no_argument, NULL, 'K'},
		{"init", required_argument, NULL, 'i'},
		{"main", required_argument, NULL, 'm'},

		// development options
		{"javascript", no_argument, NULL, 'j'},
		{"out", required_argument, NULL, 'o'},

		{0, 0, 0, 0}
	};
	int opt, option_index;
	while ((opt = getopt_long(argc, argv, "h?lvrsak:je:t:c:o:Ki:qm:", long_options, &option_index)) != -1) {
		switch (opt) {
		case 'h':
			usage(argv[0]);
			exit(0);
		case 'l':
			legal();
			return 0;
		case 'v':
			verbose = true;
			break;
		case 'q':
			quiet = true;
			break;
		case 'r':
			repl = true;
			break;
		case 's':
			static_fns = true;
			break;
		case 'a':
			elide_asserts = true;
			break;
		case 'k':
			cache_path = argv[optind - 1];
			break;
		case 'K':
			cache_path = ".planck_cache";
			{
				char *path_copy = strdup(cache_path);
				char *dir = dirname(path_copy);
				if (mkdir_p(dir) < 0) {
					fprintf(stderr, "Could not create %s: %s\n", cache_path, strerror(errno));
				}
				free(path_copy);
			}
			break;
		case 'j':
			javascript = true;
			break;
		case 'e':
			num_scripts += 1;
			scripts = realloc(scripts, num_scripts * sizeof(struct script));
			scripts[num_scripts - 1].type = "text";
			scripts[num_scripts - 1].expression = true;
			scripts[num_scripts - 1].source = argv[optind - 1];
			break;
		case 'i':
			num_scripts += 1;
			scripts = realloc(scripts, num_scripts * sizeof(struct script));
			scripts[num_scripts - 1].type = "path";
			scripts[num_scripts - 1].expression = false;
			scripts[num_scripts - 1].source = argv[optind - 1];
			break;
		case 'm':
			main_ns_name = argv[optind - 1];
		case 't':
			theme = argv[optind - 1];
			break;
		case 'c':
			{
				char *classpath = argv[optind - 1];
				char *source = strtok(classpath, ":");
				while (source != NULL) {
					char *type = "src";
					if (str_has_suffix(source, ".jar") == 0) {
						type = "jar";
					}

					num_src_paths += 1;
					src_paths = realloc(src_paths, num_src_paths * sizeof(struct src_path));
					src_paths[num_src_paths - 1].type = type;
					src_paths[num_src_paths - 1].path = strdup(source);

					source = strtok(NULL, ":");
				}

				break;
			}
		case 'o':
			out_path = argv[optind - 1];
			break;
		case '?':
			usage(argv[0]);
			exit(1);
		default:
			printf("unhandled argument: %c\n", opt);
		}
	}

	int num_rest_args = 0;
	char **rest_args = NULL;
	if (optind < argc) {
		num_rest_args = argc - optind;
		rest_args = malloc((argc - optind) * sizeof(char*));
		int i = 0;
		while (optind < argc) {
			rest_args[i++] = argv[optind++];
		}
	}

	if (num_scripts == 0 && main_ns_name == NULL && num_rest_args == 0) {
		repl = true;
	}

	if (main_ns_name != NULL && repl) {
		printf("Only one main-opt can be specified.");
	}

	JSGlobalContextRef ctx = JSGlobalContextCreate(NULL);

	JSStringRef nameRef = JSStringCreateWithUTF8CString("planck");
	JSGlobalContextSetName(ctx, nameRef);

	evaluate_script(ctx, "var global = this;", "<init>");

	register_global_function(ctx, "AMBLY_IMPORT_SCRIPT", function_import_script);
	bootstrap(ctx, out_path);

	register_global_function(ctx, "PLANCK_CONSOLE_LOG", function_console_log);
	register_global_function(ctx, "PLANCK_CONSOLE_ERROR", function_console_error);

	evaluate_script(ctx, "var console = {};"\
			"console.log = PLANCK_CONSOLE_LOG;"\
			"console.error = PLANCK_CONSOLE_ERROR;", "<init>");

	evaluate_script(ctx, "var PLANCK_VERSION = \"" PLANCK_VERSION "\";", "<init>");

	// require app namespaces
	evaluate_script(ctx, "goog.require('planck.repl');", "<init>");

	// without this things won't work
	evaluate_script(ctx, "var window = global;", "<init>");

	register_global_function(ctx, "PLANCK_READ_FILE", function_read_file);
	register_global_function(ctx, "PLANCK_LOAD", function_load);
	register_global_function(ctx, "PLANCK_LOAD_DEPS_CLJS_FILES", function_load_deps_cljs_files);
	register_global_function(ctx, "PLANCK_CACHE", function_cache);

	register_global_function(ctx, "PLANCK_EVAL", function_eval);

	register_global_function(ctx, "PLANCK_GET_TERM_SIZE", function_get_term_size);
	register_global_function(ctx, "PLANCK_PRINT_FN", function_print_fn);
	register_global_function(ctx, "PLANCK_PRINT_ERR_FN", function_print_err_fn);

	register_global_function(ctx, "PLANCK_SET_EXIT_VALUE", function_set_exit_value);

	is_tty = isatty(STDIN_FILENO) == 1;
	register_global_function(ctx, "PLANCK_RAW_READ_STDIN", function_raw_read_stdin);
	register_global_function(ctx, "PLANCK_RAW_WRITE_STDOUT", function_raw_write_stdout);
	register_global_function(ctx, "PLANCK_RAW_FLUSH_STDOUT", function_raw_flush_stdout);
	register_global_function(ctx, "PLANCK_RAW_WRITE_STDERR", function_raw_write_stderr);
	register_global_function(ctx, "PLANCK_RAW_FLUSH_STDERR", function_raw_flush_stderr);

	{
		JSValueRef arguments[num_rest_args];
		for (int i = 0; i < num_rest_args; i++) {
			arguments[i] = c_string_to_value(ctx, rest_args[i]);
		}
		JSValueRef args_ref = JSObjectMakeArray(ctx, num_rest_args, arguments, NULL);

		JSValueRef global_obj = JSContextGetGlobalObject(ctx);
		JSStringRef prop = JSStringCreateWithUTF8CString("PLANCK_INITIAL_COMMAND_LINE_ARGS");
		JSObjectSetProperty(ctx, JSValueToObject(ctx, global_obj, NULL), prop, args_ref, kJSPropertyAttributeNone, NULL);
		JSStringRelease(prop);
	}

	evaluate_script(ctx, "cljs.core.set_print_fn_BANG_.call(null,PLANCK_PRINT_FN);", "<init>");
	evaluate_script(ctx, "cljs.core.set_print_err_fn_BANG_.call(null,PLANCK_PRINT_ERR_FN);", "<init>");

	char *elide_script = str_concat("cljs.core._STAR_assert_STAR_ = ", elide_asserts ? "false" : "true");
	evaluate_script(ctx, elide_script, "<init>");
	free(elide_script);

	{
		JSValueRef arguments[4];
		arguments[0] = JSValueMakeBoolean(ctx, repl);
		arguments[1] = JSValueMakeBoolean(ctx, verbose);
		JSValueRef cache_path_ref = NULL;
		if (cache_path != NULL) {
			JSStringRef cache_path_str = JSStringCreateWithUTF8CString(cache_path);
			cache_path_ref = JSValueMakeString(ctx, cache_path_str);
		}
		arguments[2] = cache_path_ref;
		arguments[3] = JSValueMakeBoolean(ctx, static_fns);
		JSValueRef ex = NULL;
		JSObjectCallAsFunction(ctx, get_function(ctx, "planck.repl", "init"), JSContextGetGlobalObject(ctx), 4, arguments, &ex);
		debug_print_value("planck.repl/init", ctx, ex);
	}

	if (repl) {
		evaluate_source(ctx, "text", "(require '[planck.repl :refer-macros [apropos dir find-doc doc source pst]])", true, false, "cljs.user", "dumb");
	}

	evaluate_script(ctx, "goog.provide('cljs.user');", "<init>");
	evaluate_script(ctx, "goog.require('cljs.core');", "<init>");

	evaluate_script(ctx, "cljs.core._STAR_assert_STAR_ = true;", "<init>");

	// Process init arguments

	for (int i = 0; i < num_scripts; i++) {
		// TODO: exit if not successfull
		evaluate_source(ctx, scripts[i].type, scripts[i].source, scripts[i].expression, false, NULL, theme);
	}

	// Process main arguments

	if (main_ns_name != NULL) {
		run_main_in_ns(ctx, main_ns_name, num_rest_args, rest_args);
	} else if (!repl && num_rest_args > 0) {
		char *path = rest_args[0];

		struct script script;
		if (strcmp(path, "-") == 0) {
			char *source = read_all(stdin);
			script.type = "text";
			script.source = source;
			script.expression = false;
		} else {
			script.type = "path";
			script.source = path;
			script.expression = false;
		}

		evaluate_source(ctx, script.type, script.source, script.expression, false, NULL, theme);
	} else if (repl) {
		if (!quiet) {
			banner();
		}

		char *home = getenv("HOME");
		char *history_path = NULL;
		if (home != NULL) {
			char history_name[] = ".planck_history";
			int len = strlen(home) + strlen(history_name) + 2;
			history_path = malloc(len * sizeof(char));
			snprintf(history_path, len, "%s/%s", home, history_name);

			linenoiseHistoryLoad(history_path);
		}

		char *prompt = javascript ? " > " : " => ";

		char *line;
		while ((line = linenoise(prompt)) != NULL) {
			if (javascript) {
				JSValueRef res = evaluate_script(ctx, line, "<stdin>");
				print_value("", ctx, res);
			} else {
				evaluate_source(ctx, "text", line, true, true, "cljs.user", theme);
			}
			linenoiseHistoryAdd(line);
			if (history_path != NULL) {
				linenoiseHistorySave(history_path);
			}
			free(line);
		}
	}

	return exit_value;
}
Esempio n. 24
0
JSArray::JSArray() : ctx_(GetJSContext()) {
  instance_ = JSObjectMakeArray(ctx_, 0, nullptr, nullptr);
  JSValueProtect(ctx_, instance_);
}
Esempio n. 25
0
VJSArray::VJSArray( JS4D::ContextRef inContext, JS4D::ExceptionRef *outException)
: fContext( inContext)
{
	// build an array
	fObject = JSObjectMakeArray( fContext, 0, NULL, outException);
}
Esempio n. 26
0
ArrayWrapper::ArrayWrapper()
{
    m_arr = JSObjectMakeArray(g_ctx, 0, NULL, NULL);
    JSValueProtect(g_ctx, m_arr);
}
Esempio n. 27
0
JSValueRef function_load(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject,
                         size_t argc, const JSValueRef args[], JSValueRef *exception) {
    // TODO: implement fully

    if (argc == 1 && JSValueGetType(ctx, args[0]) == kJSTypeString) {
        char path[PATH_MAX];
        JSStringRef path_str = JSValueToStringCopy(ctx, args[0], NULL);
        assert(JSStringGetLength(path_str) < PATH_MAX);
        JSStringGetUTF8CString(path_str, path, PATH_MAX);
        JSStringRelease(path_str);

        // debug_print_value("load", ctx, args[0]);

        time_t last_modified = 0;
        char *contents = NULL;
        char *loaded_path = strdup(path);

        bool developing = (config.num_src_paths == 1 &&
                           strcmp(config.src_paths[0].type, "src") == 0 &&
                           str_has_suffix(config.src_paths[0].path, "/planck-cljs/src/") == 0);

        if (!developing) {
            contents = bundle_get_contents(path);
            last_modified = 0;
        }

        // load from classpath
        if (contents == NULL) {
            for (int i = 0; i < config.num_src_paths; i++) {
                if (config.src_paths[i].blacklisted) {
                    continue;
                }

                char *type = config.src_paths[i].type;
                char *location = config.src_paths[i].path;

                if (strcmp(type, "src") == 0) {
                    char *full_path = str_concat(location, path);
                    contents = get_contents(full_path, &last_modified);
                    if (contents != NULL) {
                        free(loaded_path);
                        loaded_path = strdup(full_path);
                    }
                    free(full_path);
                } else if (strcmp(type, "jar") == 0) {
                    struct stat file_stat;
                    if (stat(location, &file_stat) == 0) {
                        contents = get_contents_zip(location, path, &last_modified);
                    } else {
                        cljs_perror(location);
                        config.src_paths[i].blacklisted = true;
                    }
                }

                if (contents != NULL) {
                    break;
                }
            }
        }

        // load from out/
        if (contents == NULL) {
            if (config.out_path != NULL) {
                char *full_path = str_concat(config.out_path, path);
                contents = get_contents(full_path, &last_modified);
                free(full_path);
            }
        }

        if (developing && contents == NULL) {
            contents = bundle_get_contents(path);
            last_modified = 0;
        }

        if (contents != NULL) {
            JSStringRef contents_str = JSStringCreateWithUTF8CString(contents);
            free(contents);
            JSStringRef loaded_path_str = JSStringCreateWithUTF8CString(loaded_path);
            free(loaded_path);

            JSValueRef res[3];
            res[0] = JSValueMakeString(ctx, contents_str);
            res[1] = JSValueMakeNumber(ctx, last_modified);
            res[2] = JSValueMakeString(ctx, loaded_path_str);
            return JSObjectMakeArray(ctx, 3, res, NULL);
        }
    }

    return JSValueMakeNull(ctx);
}
Esempio n. 28
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);
    
    JSReportExtraMemoryCost(context, 0);
    JSReportExtraMemoryCost(context, 1);
    JSReportExtraMemoryCost(context, 1024);

    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);
    
    JSObjectRef EvilExceptionObject = JSObjectMake(context, EvilExceptionObject_class(context), NULL);
    JSStringRef EvilExceptionObjectIString = JSStringCreateWithUTF8CString("EvilExceptionObject");
    JSObjectSetProperty(context, globalObject, EvilExceptionObjectIString, EvilExceptionObject, kJSPropertyAttributeNone, NULL);
    JSStringRelease(EvilExceptionObjectIString);
    
    JSObjectRef EmptyObject = JSObjectMake(context, EmptyObject_class(context), NULL);
    JSStringRef EmptyObjectIString = JSStringCreateWithUTF8CString("EmptyObject");
    JSObjectSetProperty(context, globalObject, EmptyObjectIString, EmptyObject, kJSPropertyAttributeNone, NULL);
    JSStringRelease(EmptyObjectIString);
    
    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;\n}");
    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

    JSValueRef argumentsArrayValues[] = { JSValueMakeNumber(context, 10), JSValueMakeNumber(context, 20) };
    o = JSObjectMakeArray(context, sizeof(argumentsArrayValues) / sizeof(JSValueRef), argumentsArrayValues, NULL);
    string = JSStringCreateWithUTF8CString("length");
    v = JSObjectGetProperty(context, o, string, NULL);
    assertEqualsAsNumber(v, 2);
    v = JSObjectGetPropertyAtIndex(context, o, 0, NULL);
    assertEqualsAsNumber(v, 10);
    v = JSObjectGetPropertyAtIndex(context, o, 1, NULL);
    assertEqualsAsNumber(v, 20);

    o = JSObjectMakeArray(context, 0, NULL, NULL);
    v = JSObjectGetProperty(context, o, string, NULL);
    assertEqualsAsNumber(v, 0);
    JSStringRelease(string);

    JSValueRef argumentsDateValues[] = { JSValueMakeNumber(context, 0) };
    o = JSObjectMakeDate(context, 1, argumentsDateValues, NULL);
    if (timeZoneIsPST())
        assertEqualsAsUTF8String(o, "Wed Dec 31 1969 16:00:00 GMT-0800 (PST)");

    string = JSStringCreateWithUTF8CString("an error message");
    JSValueRef argumentsErrorValues[] = { JSValueMakeString(context, string) };
    o = JSObjectMakeError(context, 1, argumentsErrorValues, NULL);
    assertEqualsAsUTF8String(o, "Error: an error message");
    JSStringRelease(string);

    string = JSStringCreateWithUTF8CString("foo");
    JSStringRef string2 = JSStringCreateWithUTF8CString("gi");
    JSValueRef argumentsRegExpValues[] = { JSValueMakeString(context, string), JSValueMakeString(context, string2) };
    o = JSObjectMakeRegExp(context, 2, argumentsRegExpValues, NULL);
    assertEqualsAsUTF8String(o, "/foo/gi");
    JSStringRelease(string);
    JSStringRelease(string2);

    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);

    // Verify that creating a constructor for a class with no static functions does not trigger
    // an assert inside putDirect or lead to a crash during GC. <https://bugs.webkit.org/show_bug.cgi?id=25785>
    nullDefinition = kJSClassDefinitionEmpty;
    nullClass = JSClassCreate(&nullDefinition);
    myConstructor = JSObjectMakeConstructor(context, nullClass, 0);
    JSClassRelease(nullClass);

    char* scriptUTF8 = createStringWithContentsOfFile(scriptPath);
    if (!scriptUTF8) {
        printf("FAIL: Test script could not be loaded.\n");
        failed = 1;
    } 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);
            failed = 1;
        }
        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;
    myConstructor = NULL;

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

    JSGlobalContextRelease(context);
    JSClassRelease(globalObjectClass);

    // Test for an infinite prototype chain that used to be created. This test
    // passes if the call to JSObjectHasProperty() does not hang.

    JSClassDefinition prototypeLoopClassDefinition = kJSClassDefinitionEmpty;
    prototypeLoopClassDefinition.staticFunctions = globalObject_staticFunctions;
    JSClassRef prototypeLoopClass = JSClassCreate(&prototypeLoopClassDefinition);
    JSGlobalContextRef prototypeLoopContext = JSGlobalContextCreateInGroup(NULL, prototypeLoopClass);

    JSStringRef nameProperty = JSStringCreateWithUTF8CString("name");
    JSObjectHasProperty(prototypeLoopContext, JSContextGetGlobalObject(prototypeLoopContext), nameProperty);

    JSGlobalContextRelease(prototypeLoopContext);
    JSClassRelease(prototypeLoopClass);

    printf("PASS: Infinite prototype chain does not occur.\n");

    if (failed) {
        printf("FAIL: Some tests failed.\n");
        return 1;
    }

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