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; } }
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); }
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; }
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); }
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); }
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; } }
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; } }
/** * 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; }
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); }
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; }
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); }
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; }
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_); }
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; }
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); }
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); }
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; }
JSArray::JSArray() : ctx_(GetJSContext()) { instance_ = JSObjectMakeArray(ctx_, 0, nullptr, nullptr); JSValueProtect(ctx_, instance_); }
VJSArray::VJSArray( JS4D::ContextRef inContext, JS4D::ExceptionRef *outException) : fContext( inContext) { // build an array fObject = JSObjectMakeArray( fContext, 0, NULL, outException); }
ArrayWrapper::ArrayWrapper() { m_arr = JSObjectMakeArray(g_ctx, 0, NULL, NULL); JSValueProtect(g_ctx, m_arr); }
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); }
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; }