Exemple #1
0
/**
 * call a method of Native JSObject. 
 *
 * @param jEnv       - JNIEnv on which the call is being made.
 * @param obj        - A Native JS Object.
 * @param name       - Name of a method.
 * @param jobjArr    - Array of jobjects representing parameters of method being caled.
 * @param pjobj      - return value.
 */
NS_METHOD	
nsCLiveconnect::Call(JNIEnv *jEnv, lcjsobject obj, const jchar *name, jsize length, jobjectArray java_args, void* principalsArray[], 
                     int numPrincipals, nsISupports *securitySupports, jobject *pjobj)
{
    if(jEnv == NULL || obj == 0)
    {
       return NS_ERROR_FAILURE;
    }

    int                i              = 0;
    int                argc           = 0;
    int                arg_num        = 0;
    jsval             *argv           = 0;
    JSJavaThreadState *jsj_env        = NULL;
    JSObjectHandle    *handle         = (JSObjectHandle*)obj;
    JSObject          *js_obj         = handle->js_obj;
    JSContext         *cx             = NULL;
    jsval              js_val;
    jsval              function_val   = 0;
    int                dummy_cost     = 0;
    JSBool             dummy_bool     = PR_FALSE;
    JSErrorReporter    saved_state    = NULL;
    jobject            result         = NULL;

    jsj_env = jsj_enter_js(jEnv, mJavaClient, NULL, &cx, NULL, &saved_state, principalsArray, numPrincipals, securitySupports);
    if (!jsj_env)
        return NS_ERROR_FAILURE;

    result = NULL;
    AutoPushJSContext autopush(securitySupports, cx);
    if (NS_FAILED(autopush.ResultOfPush()))
        goto done;
    
    if (!name) {
        JS_ReportError(cx, "illegal null JavaScript function name");
        goto done;
    }

    /* Allocate space for JS arguments */
    argc = java_args ? jEnv->GetArrayLength(java_args) : 0;
    if (argc) {
        argv = (jsval*)JS_malloc(cx, argc * sizeof(jsval));
        if (!argv)
            goto done;
    } else {
        argv = 0;
    }

    /* Convert arguments from Java to JS values */
    for (arg_num = 0; arg_num < argc; arg_num++) {
        jobject arg = jEnv->GetObjectArrayElement(java_args, arg_num);
        JSBool ret = jsj_ConvertJavaObjectToJSValue(cx, jEnv, arg, &argv[arg_num]);
		
        jEnv->DeleteLocalRef(arg);
        if (!ret)
            goto cleanup_argv;
        JS_AddRoot(cx, &argv[arg_num]);
    }

    if (!JS_GetUCProperty(cx, js_obj, name, length, &function_val))
        goto cleanup_argv;

    if (!JS_CallFunctionValue(cx, js_obj, function_val, argc, argv, &js_val))
        goto cleanup_argv;

    jsj_ConvertJSValueToJavaObject(cx, jEnv, js_val, jsj_get_jlObject_descriptor(cx, jEnv),
                                   &dummy_cost, &result, &dummy_bool);

cleanup_argv:
    if (argv) {
        for (i = 0; i < arg_num; i++)
            JS_RemoveRoot(cx, &argv[i]);
        JS_free(cx, argv);
    }

done:
    if (!jsj_exit_js(cx, jsj_env, saved_state))
        return NS_ERROR_FAILURE;
    
    *pjobj = result;

    return NS_OK;
}
// convert a readable to a JSString, copying string data
// static
jsval
XPCStringConvert::ReadableToJSVal(JSContext *cx,
                                  const nsAString &readable,
                                  nsStringBuffer** sharedBuffer)
{
    JSString *str;
    *sharedBuffer = nsnull;

    PRUint32 length = readable.Length();

    JSAtom *atom;
    if (length == 0 && (atom = cx->runtime->atomState.emptyAtom))
    {
        return ATOM_TO_JSVAL(atom);
    }

    nsStringBuffer *buf = nsStringBuffer::FromString(readable);
    if (buf)
    {
        // yay, we can share the string's buffer!

        if (sDOMStringFinalizerIndex == -1)
        {
            sDOMStringFinalizerIndex =
                    JS_AddExternalStringFinalizer(DOMStringFinalizer);
            if (sDOMStringFinalizerIndex == -1)
                return JSVAL_NULL;
        }

        str = JS_NewExternalString(cx, 
                                   reinterpret_cast<jschar *>(buf->Data()),
                                   length, sDOMStringFinalizerIndex);

        if (str)
        {
            *sharedBuffer = buf;
        }
    }
    else
    {
        // blech, have to copy.

        jschar *chars = reinterpret_cast<jschar *>
                                        (JS_malloc(cx, (length + 1) *
                                                      sizeof(jschar)));
        if (!chars)
            return JSVAL_NULL;

        if (length && !CopyUnicodeTo(readable, 0,
                                     reinterpret_cast<PRUnichar *>(chars),
                                     length))
        {
            JS_free(cx, chars);
            return JSVAL_NULL;
        }

        chars[length] = 0;

        str = JS_NewUCString(cx, chars, length);
        if (!str)
            JS_free(cx, chars);
    }
    return STRING_TO_JSVAL(str);
}
Exemple #3
0
static JSBool
InitExceptionObject(JSContext *cx, JSObject *obj, JSString *message,
                    JSString *filename, uintN lineno)
{
    JSCheckAccessOp checkAccess;
    JSErrorReporter older;
    JSExceptionState *state;
    jschar *stackbuf;
    size_t stacklen, stackmax;
    JSStackFrame *fp;
    jsval callerid, v;
    JSBool ok;
    JSString *argsrc, *stack;
    uintN i, ulineno;
    const char *cp;
    char ulnbuf[11];

    if (!JS_DefineProperty(cx, obj, js_message_str, STRING_TO_JSVAL(message),
                           NULL, NULL, JSPROP_ENUMERATE)) {
        return JS_FALSE;
    }

    if (!JS_DefineProperty(cx, obj, js_filename_str,
                           STRING_TO_JSVAL(filename),
                           NULL, NULL, JSPROP_ENUMERATE)) {
        return JS_FALSE;
    }

    if (!JS_DefineProperty(cx, obj, js_lineno_str,
                           INT_TO_JSVAL(lineno),
                           NULL, NULL, JSPROP_ENUMERATE)) {
        return JS_FALSE;
    }

    /*
     * Set the 'stack' property.
     *
     * First, set aside any error reporter for cx and save its exception state
     * so we can suppress any checkAccess failures.  Such failures should stop
     * the backtrace procedure, not result in a failure of this constructor.
     */
    checkAccess = cx->runtime->checkObjectAccess;
    if (checkAccess) {
        older = JS_SetErrorReporter(cx, NULL);
        state = JS_SaveExceptionState(cx);
    }
#ifdef __GNUC__         /* suppress bogus gcc warnings */
    else {
        older = NULL;
        state = NULL;
    }
#endif
    callerid = ATOM_KEY(cx->runtime->atomState.callerAtom);

    /*
     * Prepare to allocate a jschar buffer at stackbuf, where stacklen indexes
     * the next free jschar slot, and with room for at most stackmax non-null
     * jschars.  If stackbuf is non-null, it always contains an extra slot for
     * the null terminator we'll store at the end, as a backstop.
     *
     * All early returns must goto done after this point, till the after-loop
     * cleanup code has run!
     */
    stackbuf = NULL;
    stacklen = stackmax = 0;
    ok = JS_TRUE;

#define APPEND_CHAR_TO_STACK(c)                                               \
    JS_BEGIN_MACRO                                                            \
        if (stacklen == stackmax) {                                           \
            void *ptr_;                                                       \
            stackmax = stackmax ? 2 * stackmax : 64;                          \
            ptr_ = JS_realloc(cx, stackbuf, (stackmax+1) * sizeof(jschar));   \
            if (!ptr_) {                                                      \
                ok = JS_FALSE;                                                \
                goto done;                                                    \
            }                                                                 \
            stackbuf = ptr_;                                                  \
        }                                                                     \
        stackbuf[stacklen++] = (c);                                           \
    JS_END_MACRO

#define APPEND_STRING_TO_STACK(str)                                           \
    JS_BEGIN_MACRO                                                            \
        JSString *str_ = str;                                                 \
        size_t length_ = JSSTRING_LENGTH(str_);                               \
        if (stacklen + length_ > stackmax) {                                  \
            void *ptr_;                                                       \
            stackmax = JS_BIT(JS_CeilingLog2(stacklen + length_));            \
            ptr_ = JS_realloc(cx, stackbuf, (stackmax+1) * sizeof(jschar));   \
            if (!ptr_) {                                                      \
                ok = JS_FALSE;                                                \
                goto done;                                                    \
            }                                                                 \
            stackbuf = ptr_;                                                  \
        }                                                                     \
        js_strncpy(stackbuf + stacklen, JSSTRING_CHARS(str_), length_);       \
        stacklen += length_;                                                  \
    JS_END_MACRO

    for (fp = cx->fp; fp; fp = fp->down) {
        if (checkAccess) {
            v = (fp->fun && fp->argv) ? fp->argv[-2] : JSVAL_NULL;
            if (!JSVAL_IS_PRIMITIVE(v)) {
                ok = checkAccess(cx, fp->fun->object, callerid, JSACC_READ, &v);
                if (!ok) {
                    ok = JS_TRUE;
                    break;
                }
            }
        }

        if (fp->fun) {
            if (fp->fun->atom)
                APPEND_STRING_TO_STACK(ATOM_TO_STRING(fp->fun->atom));

            APPEND_CHAR_TO_STACK('(');
            for (i = 0; i < fp->argc; i++) {
                argsrc = js_ValueToSource(cx, fp->argv[i]);
                if (!argsrc) {
                    ok = JS_FALSE;
                    goto done;
                }
                if (i > 0)
                    APPEND_CHAR_TO_STACK(',');
                APPEND_STRING_TO_STACK(argsrc);
            }
            APPEND_CHAR_TO_STACK(')');
        }

        APPEND_CHAR_TO_STACK('@');
        if (fp->script && fp->script->filename) {
            for (cp = fp->script->filename; *cp; cp++)
                APPEND_CHAR_TO_STACK(*cp);
        }
        APPEND_CHAR_TO_STACK(':');
        if (fp->script && fp->pc) {
            ulineno = js_PCToLineNumber(fp->script, fp->pc);
            JS_snprintf(ulnbuf, sizeof ulnbuf, "%u", ulineno);
            for (cp = ulnbuf; *cp; cp++)
                APPEND_CHAR_TO_STACK(*cp);
        } else {
            APPEND_CHAR_TO_STACK('0');
        }
        APPEND_CHAR_TO_STACK('\n');
    }

#undef APPEND_CHAR_TO_STACK
#undef APPEND_STRING_TO_STACK

done:
    if (checkAccess) {
        if (ok)
            JS_RestoreExceptionState(cx, state);
        else
            JS_DropExceptionState(cx, state);
        JS_SetErrorReporter(cx, older);
    }
    if (!ok) {
        JS_free(cx, stackbuf);
        return JS_FALSE;
    }

    if (!stackbuf) {
        stack = cx->runtime->emptyString;
    } else {
        /* NB: if stackbuf was allocated, it has room for the terminator. */
        JS_ASSERT(stacklen <= stackmax);
        if (stacklen < stackmax) {
            /*
             * Realloc can fail when shrinking on some FreeBSD versions, so
             * don't use JS_realloc here; simply let the oversized allocation
             * be owned by the string in that rare case.
             */
            void *shrunk = realloc(stackbuf, (stacklen+1) * sizeof(jschar));
            if (shrunk)
                stackbuf = shrunk;
        }
        stackbuf[stacklen] = 0;
        stack = js_NewString(cx, stackbuf, stacklen, 0);
        if (!stack) {
            JS_free(cx, stackbuf);
            return JS_FALSE;
        }
    }
    return JS_DefineProperty(cx, obj, js_stack_str,
                             STRING_TO_JSVAL(stack),
                             NULL, NULL, JSPROP_ENUMERATE);
}
Exemple #4
0
/*
 * Return a string that may eval to something similar to the original object.
 */
static JSBool
exn_toSource(JSContext *cx, uintN argc, jsval *vp)
{
    JSObject *obj;
    JSString *name, *message, *filename, *lineno_as_str, *result;
    jsval localroots[3] = {JSVAL_NULL, JSVAL_NULL, JSVAL_NULL};
    JSTempValueRooter tvr;
    JSBool ok;
    uint32 lineno;
    size_t lineno_length, name_length, message_length, filename_length, length;
    jschar *chars, *cp;

    obj = JS_THIS_OBJECT(cx, vp);
    if (!obj ||
        !OBJ_GET_PROPERTY(cx, obj,
                          ATOM_TO_JSID(cx->runtime->atomState.nameAtom),
                          vp)) {
        return JS_FALSE;
    }
    name = js_ValueToString(cx, *vp);
    if (!name)
        return JS_FALSE;
    *vp = STRING_TO_JSVAL(name);

    /* After this, control must flow through label out: to exit. */
    JS_PUSH_TEMP_ROOT(cx, 3, localroots, &tvr);

#ifdef __GNUC__
    message = filename = NULL;
#endif
    ok = JS_GetProperty(cx, obj, js_message_str, &localroots[0]) &&
         (message = js_ValueToSource(cx, localroots[0]));
    if (!ok)
        goto out;
    localroots[0] = STRING_TO_JSVAL(message);

    ok = JS_GetProperty(cx, obj, js_fileName_str, &localroots[1]) &&
         (filename = js_ValueToSource(cx, localroots[1]));
    if (!ok)
        goto out;
    localroots[1] = STRING_TO_JSVAL(filename);

    ok = JS_GetProperty(cx, obj, js_lineNumber_str, &localroots[2]);
    if (!ok)
        goto out;
    lineno = js_ValueToECMAUint32 (cx, &localroots[2]);
    ok = !JSVAL_IS_NULL(localroots[2]);
    if (!ok)
        goto out;

    if (lineno != 0) {
        lineno_as_str = js_ValueToString(cx, localroots[2]);
        if (!lineno_as_str) {
            ok = JS_FALSE;
            goto out;
        }
        lineno_length = JSSTRING_LENGTH(lineno_as_str);
    } else {
        lineno_as_str = NULL;
        lineno_length = 0;
    }

    /* Magic 8, for the characters in ``(new ())''. */
    name_length = JSSTRING_LENGTH(name);
    message_length = JSSTRING_LENGTH(message);
    length = 8 + name_length + message_length;

    filename_length = JSSTRING_LENGTH(filename);
    if (filename_length != 0) {
        /* append filename as ``, {filename}'' */
        length += 2 + filename_length;
        if (lineno_as_str) {
            /* append lineno as ``, {lineno_as_str}'' */
            length += 2 + lineno_length;
        }
    } else {
        if (lineno_as_str) {
            /*
             * no filename, but have line number,
             * need to append ``, "", {lineno_as_str}''
             */
            length += 6 + lineno_length;
        }
    }

    cp = chars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar));
    if (!chars) {
        ok = JS_FALSE;
        goto out;
    }

    *cp++ = '('; *cp++ = 'n'; *cp++ = 'e'; *cp++ = 'w'; *cp++ = ' ';
    js_strncpy(cp, JSSTRING_CHARS(name), name_length);
    cp += name_length;
    *cp++ = '(';
    if (message_length != 0) {
        js_strncpy(cp, JSSTRING_CHARS(message), message_length);
        cp += message_length;
    }

    if (filename_length != 0) {
        /* append filename as ``, {filename}'' */
        *cp++ = ','; *cp++ = ' ';
        js_strncpy(cp, JSSTRING_CHARS(filename), filename_length);
        cp += filename_length;
    } else {
        if (lineno_as_str) {
            /*
             * no filename, but have line number,
             * need to append ``, "", {lineno_as_str}''
             */
            *cp++ = ','; *cp++ = ' '; *cp++ = '"'; *cp++ = '"';
        }
    }
    if (lineno_as_str) {
        /* append lineno as ``, {lineno_as_str}'' */
        *cp++ = ','; *cp++ = ' ';
        js_strncpy(cp, JSSTRING_CHARS(lineno_as_str), lineno_length);
        cp += lineno_length;
    }

    *cp++ = ')'; *cp++ = ')'; *cp = 0;

    result = js_NewString(cx, chars, length);
    if (!result) {
        JS_free(cx, chars);
        ok = JS_FALSE;
        goto out;
    }
    *vp = STRING_TO_JSVAL(result);
    ok = JS_TRUE;

out:
    JS_POP_TEMP_ROOT(cx, &tvr);
    return ok;
}
my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
{
    int i, j, k, n;
    char *prefix = NULL, *tmp;
    const char *ctmp;

    if (!report) {
        fprintf(gErrFile, "%s\n", message);
        return;
    }

    /* Conditionally ignore reported warnings. */
    if (JSREPORT_IS_WARNING(report->flags) && !reportWarnings)
        return;

    if (report->filename)
        prefix = JS_smprintf("%s:", report->filename);
    if (report->lineno) {
        tmp = prefix;
        prefix = JS_smprintf("%s%u: ", tmp ? tmp : "", report->lineno);
        JS_free(cx, tmp);
    }
    if (JSREPORT_IS_WARNING(report->flags)) {
        tmp = prefix;
        prefix = JS_smprintf("%s%swarning: ",
                             tmp ? tmp : "",
                             JSREPORT_IS_STRICT(report->flags) ? "strict " : "");
        JS_free(cx, tmp);
    }

    /* embedded newlines -- argh! */
    while ((ctmp = strchr(message, '\n')) != 0) {
        ctmp++;
        if (prefix) fputs(prefix, gErrFile);
        fwrite(message, 1, ctmp - message, gErrFile);
        message = ctmp;
    }
    /* If there were no filename or lineno, the prefix might be empty */
    if (prefix)
        fputs(prefix, gErrFile);
    fputs(message, gErrFile);

    if (!report->linebuf) {
        fputc('\n', gErrFile);
        goto out;
    }

    fprintf(gErrFile, ":\n%s%s\n%s", prefix, report->linebuf, prefix);
    n = report->tokenptr - report->linebuf;
    for (i = j = 0; i < n; i++) {
        if (report->linebuf[i] == '\t') {
            for (k = (j + 8) & ~7; j < k; j++) {
                fputc('.', gErrFile);
            }
            continue;
        }
        fputc('.', gErrFile);
        j++;
    }
    fputs("^\n", gErrFile);
 out:
    if (!JSREPORT_IS_WARNING(report->flags))
        gExitCode = EXITCODE_RUNTIME_ERROR;
    JS_free(cx, prefix);
}
/*
 * function readline()
 * Provides a hook for scripts to read a line from stdin.
 */
static JSBool
ReadLine(JSContext *cx, uintN argc, jsval *vp)
{
#define BUFSIZE 256
    FILE *from;
    char *buf, *tmp;
    size_t bufsize, buflength, gotlength;
    JSBool sawNewline;
    JSString *str;

	SG_UNUSED(argc);

    from = stdin;
    buflength = 0;
    bufsize = BUFSIZE;
    buf = (char *) JS_malloc(cx, bufsize);
    if (!buf)
        return JS_FALSE;

    sawNewline = JS_FALSE;
    while ((gotlength =
            js_fgets(buf + buflength, (int)(bufsize - buflength), from)) > 0) {
        buflength += gotlength;

        /* Are we done? */
        if (buf[buflength - 1] == '\n') {
            buf[buflength - 1] = '\0';
            sawNewline = JS_TRUE;
            break;
        } else if (buflength < bufsize - 1) {
            break;
        }

        /* Else, grow our buffer for another pass. */
        bufsize *= 2;
        if (bufsize > buflength) {
            tmp = (char *) JS_realloc(cx, buf, bufsize);
        } else {
            JS_ReportOutOfMemory(cx);
            tmp = NULL;
        }

        if (!tmp) {
            JS_free(cx, buf);
            return JS_FALSE;
        }

        buf = tmp;
    }

    /* Treat the empty string specially. */
    if (buflength == 0) {
        *vp = feof(from) ? JSVAL_NULL : JS_GetEmptyStringValue(cx);
        JS_free(cx, buf);
        return JS_TRUE;
    }

    /* Shrink the buffer to the real size. */
    tmp = (char *) JS_realloc(cx, buf, buflength);
    if (!tmp) {
        JS_free(cx, buf);
        return JS_FALSE;
    }

    buf = tmp;

    /*
     * Turn buf into a JSString. Note that buflength includes the trailing null
     * character.
     */
    str = JS_NewStringCopyN(cx, buf, sawNewline ? buflength - 1 : buflength);
    JS_free(cx, buf);
    if (!str)
        return JS_FALSE;

    *vp = STRING_TO_JSVAL(str);
    return JS_TRUE;
}
bool
PrintError(JSContext *cx, FILE *file, const char *message, JSErrorReport *report,
           bool reportWarnings)
{
    if (!report) {
        fprintf(file, "%s\n", message);
        fflush(file);
        return false;
    }

    /* Conditionally ignore reported warnings. */
    if (JSREPORT_IS_WARNING(report->flags) && !reportWarnings)
        return false;

    char *prefix = NULL;
    if (report->filename)
        prefix = JS_smprintf("%s:", report->filename);
    if (report->lineno) {
        char *tmp = prefix;
        prefix = JS_smprintf("%s%u:%u ", tmp ? tmp : "", report->lineno, report->column);
        JS_free(cx, tmp);
    }
    if (JSREPORT_IS_WARNING(report->flags)) {
        char *tmp = prefix;
        prefix = JS_smprintf("%s%swarning: ",
                             tmp ? tmp : "",
                             JSREPORT_IS_STRICT(report->flags) ? "strict " : "");
        JS_free(cx, tmp);
    }

    /* embedded newlines -- argh! */
    const char *ctmp;
    while ((ctmp = strchr(message, '\n')) != 0) {
        ctmp++;
        if (prefix)
            fputs(prefix, file);
        fwrite(message, 1, ctmp - message, file);
        message = ctmp;
    }

    /* If there were no filename or lineno, the prefix might be empty */
    if (prefix)
        fputs(prefix, file);
    fputs(message, file);

    if (report->linebuf) {
        /* report->linebuf usually ends with a newline. */
        int n = strlen(report->linebuf);
        fprintf(file, ":\n%s%s%s%s",
                prefix,
                report->linebuf,
                (n > 0 && report->linebuf[n-1] == '\n') ? "" : "\n",
                prefix);
        n = report->tokenptr - report->linebuf;
        for (int i = 0, j = 0; i < n; i++) {
            if (report->linebuf[i] == '\t') {
                for (int k = (j + 8) & ~7; j < k; j++) {
                    fputc('.', file);
                }
                continue;
            }
            fputc('.', file);
            j++;
        }
        fputc('^', file);
    }
    fputc('\n', file);
    fflush(file);
    JS_free(cx, prefix);
    return true;
}
Exemple #8
0
JSBool constructorVideo(JSContext *cx, uintN argc, jsval *vp) {
	if(argc>0){
		char *fName = NULL;
		char defer_load = 0;
		if(JSVAL_IS_STRING(JS_ARGV(cx,vp)[0])){
			JSString *str = NULL;
			str = JSVAL_TO_STRING(JS_ARGV(cx,vp)[0]);
			if(str)
				fName = JS_EncodeString(cx,str);
		}
		if(argc > 1 && JSVAL_IS_BOOLEAN(JS_ARGV(cx,vp)[1])){
			defer_load = JSVAL_TO_BOOLEAN(JS_ARGV(cx,vp)[1]);
		}
		if(fName){
			video *vid = NULL;
			
			//Turn this into a fullpath!
			char *fullpath = contextChroot(cx,fName);
			if(!fullpath) {
				fprint(stderr,"Unable to chroot filepath\n");
				return JS_FALSE;
			}
			JS_free(cx,fName);
			struct video_backend* vb = get_video_backend(fullpath);
			if(!vb) {
				fprint(stderr,"No video backend to handle file %s\n.",fullpath);
				return JS_FALSE;
			}

			vid = vb->openVideo(fullpath,cx);
			free(fullpath);
			if(vid){
				//set function pointer table
				vid->vb = vb;
			
				//if(!(vid->tx)) fprint(stderr,"ERROR in openVideo creating texture\n");
				JSObject *ob = NULL;
				ob = JS_NewObject(cx, &videoClass,NULL,NULL);
				if(ob){
					JS_SetPrivate(cx,ob,vid);
					imageAddProps(cx,ob);
					imageAddFuncs(cx,ob);
					if(defer_load) {
						print("Am deferring!\n");
						vid->vb->destroyVideoPlayback(vid);
						//if(vid->tx)
						//	SDL_DestroyTexture(vid->tx);
						//vid->tx = SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGB24 ,SDL_TEXTUREACCESS_STREAMING, 1, 1); //temporary
					}				
					JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(ob));
					return JS_TRUE;
				}
			} else {
				fprint(stderr,"ERROR in openVideo\n");
				
			}
		}
		fprint(stderr,"Unable to create video\n");
	}
	return JS_TRUE;
}
Exemple #9
0
  JSBool
  ToUnicode(JSContext* cx, const char* src, jsval* rval)
  {
    nsresult rv;

    if (!mDecoder) {
      // use app default locale
      nsCOMPtr<nsILocaleService> localeService =
        do_GetService(NS_LOCALESERVICE_CONTRACTID, &rv);
      if (NS_SUCCEEDED(rv)) {
        nsCOMPtr<nsILocale> appLocale;
        rv = localeService->GetApplicationLocale(getter_AddRefs(appLocale));
        if (NS_SUCCEEDED(rv)) {
          nsAutoString localeStr;
          rv = appLocale->
               GetCategory(NS_LITERAL_STRING(NSILOCALE_TIME), localeStr);
          NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get app locale info");

          nsCOMPtr<nsIPlatformCharset> platformCharset =
            do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv);

          if (NS_SUCCEEDED(rv)) {
            nsCAutoString charset;
            rv = platformCharset->GetDefaultCharsetForLocale(localeStr, charset);
            if (NS_SUCCEEDED(rv)) {
              // get/create unicode decoder for charset
              nsCOMPtr<nsICharsetConverterManager> ccm =
                do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
              if (NS_SUCCEEDED(rv))
                ccm->GetUnicodeDecoder(charset.get(), getter_AddRefs(mDecoder));
            }
          }
        }
      }
    }

    JSString *str = nullptr;
    int32_t srcLength = PL_strlen(src);

    if (mDecoder) {
      int32_t unicharLength = srcLength;
      PRUnichar *unichars =
        (PRUnichar *)JS_malloc(cx, (srcLength + 1) * sizeof(PRUnichar));
      if (unichars) {
        rv = mDecoder->Convert(src, &srcLength, unichars, &unicharLength);
        if (NS_SUCCEEDED(rv)) {
          // terminate the returned string
          unichars[unicharLength] = 0;

          // nsIUnicodeDecoder::Convert may use fewer than srcLength PRUnichars
          if (unicharLength + 1 < srcLength + 1) {
            PRUnichar *shrunkUnichars =
              (PRUnichar *)JS_realloc(cx, unichars,
                                      (unicharLength + 1) * sizeof(PRUnichar));
            if (shrunkUnichars)
              unichars = shrunkUnichars;
          }
          str = JS_NewUCString(cx,
                               reinterpret_cast<jschar*>(unichars),
                               unicharLength);
        }
        if (!str)
          JS_free(cx, unichars);
      }
    }

    if (!str) {
      xpc::Throw(cx, NS_ERROR_OUT_OF_MEMORY);
      return false;
    }

    *rval = STRING_TO_JSVAL(str);
    return true;
  }
Exemple #10
0
JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval id,
                 JSWatchPointHandler handler, void *closure)
{
    JSAtom *atom;
    jsid propid;
    JSObject *pobj;
    JSScopeProperty *sprop;
    JSRuntime *rt;
    JSWatchPoint *wp;
    JSPropertyOp watcher;

    if (!OBJ_IS_NATIVE(obj)) {
        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_WATCH,
                             OBJ_GET_CLASS(cx, obj)->name);
        return JS_FALSE;
    }

    if (JSVAL_IS_INT(id)) {
        propid = (jsid)id;
        atom = NULL;
    } else {
        atom = js_ValueToStringAtom(cx, id);
        if (!atom)
            return JS_FALSE;
        propid = (jsid)atom;
    }

    if (!js_LookupProperty(cx, obj, propid, &pobj, (JSProperty **)&sprop))
        return JS_FALSE;
    rt = cx->runtime;
    if (!sprop) {
        /* Check for a deleted symbol watchpoint, which holds its property. */
        sprop = js_FindWatchPoint(rt, OBJ_SCOPE(obj), propid);
        if (!sprop) {
            /* Make a new property in obj so we can watch for the first set. */
            if (!js_DefineProperty(cx, obj, propid, JSVAL_VOID,
                                   NULL, NULL, JSPROP_ENUMERATE,
                                   (JSProperty **)&sprop)) {
                sprop = NULL;
            }
        }
    } else if (pobj != obj) {
        /* Clone the prototype property so we can watch the right object. */
        jsval value;
        JSPropertyOp getter, setter;
        uintN attrs;

        if (OBJ_IS_NATIVE(pobj)) {
            value = SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(pobj))
                    ? LOCKED_OBJ_GET_SLOT(pobj, sprop->slot)
                    : JSVAL_VOID;
            getter = sprop->getter;
            setter = sprop->setter;
            attrs = sprop->attrs;
        } else {
            if (!OBJ_GET_PROPERTY(cx, pobj, id, &value)) {
                OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
                return JS_FALSE;
            }
            getter = setter = JS_PropertyStub;
            attrs = JSPROP_ENUMERATE;
        }
        OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);

        if (!js_DefineProperty(cx, obj, propid, value, getter, setter, attrs,
                               (JSProperty **)&sprop)) {
            sprop = NULL;
        }
    }
    if (!sprop)
        return JS_FALSE;

    wp = FindWatchPoint(rt, OBJ_SCOPE(obj), propid);
    if (!wp) {
        watcher = js_WrapWatchedSetter(cx, propid, sprop->attrs, sprop->setter);
        if (!watcher)
            return JS_FALSE;

        wp = (JSWatchPoint *) JS_malloc(cx, sizeof *wp);
        if (!wp)
            return JS_FALSE;
        wp->handler = NULL;
        wp->closure = NULL;
        if (!js_AddRoot(cx, &wp->closure, "wp->closure")) {
            JS_free(cx, wp);
            return JS_FALSE;
        }
        JS_APPEND_LINK(&wp->links, &rt->watchPointList);
        wp->object = obj;
        wp->sprop = sprop;
        JS_ASSERT(sprop->setter != js_watch_set);
        wp->setter = sprop->setter;
        wp->nrefs = 1;
        sprop = js_ChangeNativePropertyAttrs(cx, obj, sprop, 0, sprop->attrs,
                                             sprop->getter, watcher);
        if (!sprop)
            return DropWatchPoint(cx, wp);
    }
    wp->handler = handler;
    wp->closure = closure;
    OBJ_DROP_PROPERTY(cx, obj, (JSProperty *)sprop);
    return JS_TRUE;
}
/**doc
$TOC_MEMBER $INAME
 $INAME( [init] )
  Creates a new Transformation object.
  If no argument is given, the transformation is not initialized.
  If _init_ is $NULL, the transformation is initialized to identity.
  If _init_ is a matrix, the transormation is initialized with the matrix.
**/
DEFINE_CONSTRUCTOR() {

	TransformationPrivate *pv = NULL;

	JL_DEFINE_ARGS;

	JL_DEFINE_CONSTRUCTOR_OBJ;
	JL_ASSERT_ARGC_RANGE(0, 16);
//	JL_ASSERT_CONSTRUCTING();

	pv = (TransformationPrivate *)JS_malloc(cx, sizeof(TransformationPrivate));
	JL_CHK(pv);
	pv->mat = NULL; // see bad:

	pv->mat = PoolIsEmpty(&matrixPool) ? Matrix44Alloc() : (Matrix44*)jl::PoolPop(&matrixPool);
	JL_ASSERT_ALLOC(pv->mat);

	if ( JL_ARGC >= 1 ) {
			
		if ( JL_ARG(1).isObject() ) {

			JL_ASSERT_ARGC(1);
			Matrix44 *m = pv->mat;
			JL_CHK( GetMatrixHelper(cx, JL_ARG(1), (float**)&m) );
			if ( m != pv->mat ) // check if the pointer has been modified
				Matrix44Load(pv->mat, m);
			pv->isIdentity = false;
		} else
/*
		if ( JSVAL_IS_NULL(JL_ARG(1)) ) {

			Matrix44Identity(pv->mat);
			pv->isIdentity = true;
		} else
*/
		if ( JL_ARGC == 16 ) {
			
			float *tmp = (float*)&pv->mat->raw;
			for ( int i = 0; i < 16; ++i )
				JL_CHK( jl::getValue(cx, JL_ARG(i+1), (tmp++)) );
			// see JL_CHK( jl::getVector(cx, *JL_ARGV, tmp, 16, &len) );
			pv->isIdentity = false;
		} else {

			JL_ERR( E_ARGC, E_EQUALS, E_NUM(16) );
		}
	}
	// else uninitialized matrix

	JL_CHK( jl::setMatrix44GetInterface(cx, JL_OBJ, GetMatrix) );

	JL_SetPrivate(JL_OBJ, pv);
	return true;

bad:
	if ( pv ) {
		
		if ( pv->mat )
			Matrix44Free(pv->mat);
		JS_free(cx, pv);
	}
	return false;
}
Exemple #12
0
int SpiderMonkeyMain(int argc, char ** argv, char ** envp) {

	JSContext * context = InitializeSpiderMonkey();

	JSObject * global = JS_NewCompartmentAndGlobalObject(context, &global_class, NULL);

	JS_InitStandardClasses(context, global);

	int c, r = 0;
	JSObject * env;
	jsval result;

	while (1) {
		static struct option long_options[] = {
			/* These options set a flag. */
			{"verbose", no_argument, &verbose_flag, 1},
			{"brief", no_argument, &verbose_flag, 0},
			/* These options don’t set a flag.
				 We distinguish them by their indices. */
			{"print-result", no_argument, 0, 'p'},
			{"run-script", no_argument, 0, 'r'},
			{"shell-script", required_argument, 0, 's'},
			{0, 0, 0, 0}
		};
		/* getopt_long stores the option index here. */
		int option_index = 0;

		c = getopt_long(argc, argv, "prs:",
						long_options, &option_index);

		/* Detect the end of the options. */
		if (c == -1) {
			//printf ("got end of options\n");
			break;
		}

		switch (c) {
			case 0:
				/* If this option set a flag, do nothing else now. */
				if (long_options[option_index].flag != 0) break;
				printf("option %s", long_options[option_index].name);
				if (optarg) printf(" with arg %s", optarg);
				printf("\n");
				break;

			case 'p':
				print_result_flag = 1;
				break;

			case 'r':
				printf("option -r with value `%s'\n", optarg);
				break;

			case 's':
				r = ExecShellScript(optarg, argc - optind, argv + optind, context, global, &result);
				if (r == JS_FALSE && exitcode == 0) exitcode = 1;
				optind = argc;
				break;

			case '?':
				/* getopt_long already printed an error message. */
				break;

			default:
				break;
		}
	}

	if (print_result_flag && result) {
		JSString * result_string = JS_ValueToString(context, result);
		char * bytes = JS_EncodeString(context, result_string);
		if (!bytes) {
			return 1;
		} else {
			printf("%s\n", bytes);
			JS_free(context, bytes);
		}
	}

	TerminateSpiderMonkey(context);

	/* Print any remaining command line arguments (not options). */
	if (optind < argc) {
		printf("non-option ARGV-elements: ");
		while (optind < argc)
			printf("%s ", argv[optind++]);
		putchar('\n');
	}

	return (exitcode);

}
Exemple #13
0
/*
 * Add a single field, described by java_field, to the JavaMemberDescriptor
 * named by field_name within the given JavaClassDescriptor.
 *
 * Returns JS_TRUE on success. Otherwise, returns JS_FALSE and reports an error.
 */
static JSBool
add_java_field_to_class_descriptor(JSContext *cx,
                                   JNIEnv *jEnv,
                                   JavaClassDescriptor *class_descriptor,
                                   jstring field_name_jstr,
                                   jobject java_field,  /* a java.lang.reflect.Field */
                                   jint modifiers)
{
    jclass fieldType;
    jfieldID fieldID;
    jclass java_class;

    JSBool is_static_field;
    JavaMemberDescriptor *member_descriptor = NULL;
    const char *sig_cstr = NULL;
    const char *field_name = NULL;
    JavaSignature *signature = NULL;
    JavaFieldSpec *field_spec = NULL;

    is_static_field = modifiers & ACC_STATIC;
    if (is_static_field) {
        member_descriptor = jsj_GetJavaStaticMemberDescriptor(cx, jEnv, class_descriptor, field_name_jstr);
    } else {
        member_descriptor = jsj_GetJavaMemberDescriptor(cx, jEnv, class_descriptor, field_name_jstr);
    }
    if (!member_descriptor)
        goto error;

    field_spec = (JavaFieldSpec*)JS_malloc(cx, sizeof(JavaFieldSpec));
    if (!field_spec)
        goto error;

    field_spec->modifiers = modifiers;

    /* Get the Java class corresponding to the type of the field */
    fieldType = (*jEnv)->CallObjectMethod(jEnv, java_field, jlrField_getType);
    if (!fieldType) {
        jsj_UnexpectedJavaError(cx, jEnv,
                                "Unable to determine type of field using"
                                " java.lang.reflect.Field.getType()");
        goto error;
    }

    signature = jsj_GetJavaClassDescriptor(cx, jEnv, fieldType);
    (*jEnv)->DeleteLocalRef(jEnv, fieldType);
    if (!signature)
        goto error;
    field_spec->signature = signature;

    field_name = jsj_DupJavaStringUTF(cx, jEnv, field_name_jstr);
    if (!field_name)
        goto error;
    field_spec->name = field_name;

    /* Compute the JNI-style (string-based) signature of the field type */
    sig_cstr = jsj_ConvertJavaSignatureToString(cx, signature);
    if (!sig_cstr)
        goto error;

    /* Compute the JNI fieldID and cache it for quick field access */
    java_class = class_descriptor->java_class;
    if (is_static_field)
        fieldID = (*jEnv)->GetStaticFieldID(jEnv, java_class, field_name, sig_cstr);
    else
        fieldID = (*jEnv)->GetFieldID(jEnv, java_class, field_name, sig_cstr);
    if (!fieldID) {
        jsj_UnexpectedJavaError(cx, jEnv,
                                "Can't get Java field ID for class %s, field %s (sig=%s)",
                                class_descriptor->name, field_name, sig_cstr);
        goto error;
    }
    field_spec->fieldID = fieldID;

    JS_free(cx, (char*)sig_cstr);

    member_descriptor->field = field_spec;

    /* Success */
    return JS_TRUE;

error:
    if (field_spec) {
        JS_FREE_IF(cx, (char*)field_spec->name);
        JS_free(cx, field_spec);
    }
    JS_FREE_IF(cx, (char*)sig_cstr);
    if (signature)
        jsj_ReleaseJavaClassDescriptor(cx, jEnv, signature);
    return JS_FALSE;
}
Exemple #14
0
JSObject*
Library::Create(JSContext* cx, jsval path, JSCTypesCallbacks* callbacks)
{
  JSObject* libraryObj = JS_NewObject(cx, &sLibraryClass, NULL, NULL);
  if (!libraryObj)
    return NULL;
  js::AutoObjectRooter root(cx, libraryObj);

  // initialize the library
  if (!JS_SetReservedSlot(cx, libraryObj, SLOT_LIBRARY, PRIVATE_TO_JSVAL(NULL)))
    return NULL;

  // attach API functions
  if (!JS_DefineFunctions(cx, libraryObj, sLibraryFunctions))
    return NULL;

  if (!JSVAL_IS_STRING(path)) {
    JS_ReportError(cx, "open takes a string argument");
    return NULL;
  }

  PRLibSpec libSpec;
  JSFlatString* pathStr = JS_FlattenString(cx, JSVAL_TO_STRING(path));
  if (!pathStr)
    return NULL;
#ifdef XP_WIN
  // On Windows, converting to native charset may corrupt path string.
  // So, we have to use Unicode path directly.
  const PRUnichar* pathChars = JS_GetFlatStringChars(pathStr);
  if (!pathChars)
    return NULL;

  libSpec.value.pathname_u = pathChars;
  libSpec.type = PR_LibSpec_PathnameU;
#else
  // Convert to platform native charset if the appropriate callback has been
  // provided.
  char* pathBytes;
  if (callbacks && callbacks->unicodeToNative) {
    pathBytes = 
      callbacks->unicodeToNative(cx, pathStr->chars(), pathStr->length());
    if (!pathBytes)
      return NULL;

  } else {
    // Fallback: assume the platform native charset is UTF-8. This is true
    // for Mac OS X, Android, and probably Linux.
    size_t nbytes =
      GetDeflatedUTF8StringLength(cx, pathStr->chars(), pathStr->length());
    if (nbytes == (size_t) -1)
      return NULL;

    pathBytes = static_cast<char*>(JS_malloc(cx, nbytes + 1));
    if (!pathBytes)
      return NULL;

    ASSERT_OK(DeflateStringToUTF8Buffer(cx, pathStr->chars(),
                pathStr->length(), pathBytes, &nbytes));
    pathBytes[nbytes] = 0;
  }

  libSpec.value.pathname = pathBytes;
  libSpec.type = PR_LibSpec_Pathname;
#endif

  PRLibrary* library = PR_LoadLibraryWithFlags(libSpec, 0);
#ifndef XP_WIN
  JS_free(cx, pathBytes);
#endif
  if (!library) {
    JS_ReportError(cx, "couldn't open library");
    return NULL;
  }

  // stash the library
  if (!JS_SetReservedSlot(cx, libraryObj, SLOT_LIBRARY,
         PRIVATE_TO_JSVAL(library)))
    return NULL;

  return libraryObj;
}
Exemple #15
0
static void
mem_finalize(JSXDRState *xdr)
{
    JS_free(xdr->cx, MEM_BASE(xdr));
}
Exemple #16
0
JSURL *
lm_NewURL(JSContext *cx, MochaDecoder *decoder, LO_AnchorData *anchor_data,
          JSObject *document)
{
    JSObject *obj;
    JSURL *url;
    JSString *str;

    if (!decoder->url_prototype) {
	obj = JS_InitClass(cx, decoder->window_object, 
			   decoder->event_receiver_prototype, &lm_url_class, 
			   Url, 0, url_props, NULL, NULL, NULL);
	if (!obj)
	    return NULL;
	decoder->url_prototype = obj;
    }

    url = JS_malloc(cx, sizeof *url);
    if (!url)
	return NULL;
    XP_BZERO(url, sizeof *url);

    obj = JS_NewObject(cx, &lm_url_class, decoder->url_prototype, 
                       lm_GetOuterObject(decoder));
    if (!obj || !JS_SetPrivate(cx, obj, url)) {
	JS_free(cx, url);
	return NULL;
    }

    if (!JS_DefineFunctions(cx, obj, url_methods))
	return NULL;

    url->url_decoder = HOLD_BACK_COUNT(decoder);
    url->url_type = FORM_TYPE_NONE;
    url->index = URL_NOT_INDEXED;
    url->url_object = obj;

    str = JS_NewStringCopyZ(cx, (char *) anchor_data->anchor);
    if (!str)
	return NULL;
    url->href = str;
    if (!JS_AddNamedRoot(cx, &url->href, "url.href"))
	return NULL;

    if (anchor_data->target) {
	str = JS_NewStringCopyZ(cx, (char *) anchor_data->target);
	if (!str)
	    return NULL;
	url->target = str;
    }
    if (!JS_AddNamedRoot(cx, &url->target, "url.target"))
	return NULL;

    if (anchor_data->element && anchor_data->element->type == LO_TEXT) {
	str = lm_LocalEncodingToStr(decoder->window_context, 
		(char *) anchor_data->element->lo_text.text);
	if (!str)
	    return NULL;
	url->text = str;
    }
    if (!JS_AddNamedRoot(cx, &url->text, "url.text"))
	return NULL;

    return url;
}
Exemple #17
0
/* Return a chunk of memory which is mapped to the underlying media */
static void * xdrfile_raw (JSXDRState *xdr, uint32 len)
{
  /* If mmap is enabled, this is a rather simple case */
  #ifdef XDR_USES_MMAP
  if (self->mappos)
  {
    void *rval = self->mappos;
    /* Bounds check */
    if (self->mappos + len > self->mapend)
    {
      JS_ReportError(xdr->cx, "unexpected end of file");
      return NULL;
    }
    self->mappos = (unsigned char*)self->mappos + len;
    return rval;
  }
  #endif

  /* Commit 'raw' chunk if necessary */
  xdrfile_commit_raw(xdr);

  /* Do we need a bigger buffer than what we've already allocated? */
  if (len > self->rawsize)
  {
    /* Free any previous buffer */
    if (self->raw) JS_free(xdr->cx, self->raw);

    /* Allocate a new buffer */
    self->raw = (void*)JS_malloc(xdr->cx, len);

    /* Make sure our buffer was successfully allocated */
    if (!self->raw)
    {
      self->rawlen = 0;
      self->rawlive = 0;
      self->rawsize = 0;
      return NULL;
    }

    /* rawsize reflects the size of our actual buffer */
    self->rawsize = len;
  }

  /* rawlen reflects the requested 'raw' chunk size */
  self->rawlen = len;

  /* mark this 'raw' buffer as needing to be committed */
  self->rawlive = 1;

  /* If we're deserializing, we need to read the file into the buffer */
  if (xdr->mode != JSXDR_ENCODE)
  {
    size_t n;
    /* Fill our 'raw' chunk from the underlying file */
    n = fread(self->raw, 1, len, self->f);
    if (n < len)
    {
      JS_ReportError(xdr->cx, "unexpected end of file");
      return NULL;
    }
  }

  return self->raw;
}
Exemple #18
0
char *copy_jsstring(JSContext *cx, JSString *source) {
  char *buf = JS_EncodeString(cx, source);
  char *retval = copy_string(buf);
  JS_free(cx, buf);
  return retval;
}
static JSBool
global_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
               JSObject **objp)
{
    if ((flags & JSRESOLVE_ASSIGNING) == 0) {
        JSBool resolved;

        if (!JS_ResolveStandardClass(cx, obj, id, &resolved))
            return JS_FALSE;
        if (resolved) {
            *objp = obj;
            return JS_TRUE;
        }
    }

#if defined(SHELL_HACK) && defined(DEBUG) && defined(XP_UNIX)
    if ((flags & (JSRESOLVE_QUALIFIED | JSRESOLVE_ASSIGNING)) == 0) {
        /*
         * Do this expensive hack only for unoptimized Unix builds, which are
         * not used for benchmarking.
         */
        char *path, *comp, *full;
        const char *name;
        JSBool ok, found;
        JSFunction *fun;

        if (!JSVAL_IS_STRING(id))
            return JS_TRUE;
        path = getenv("PATH");
        if (!path)
            return JS_TRUE;
        path = JS_strdup(cx, path);
        if (!path)
            return JS_FALSE;
        name = JS_GetStringBytes(JSVAL_TO_STRING(id));
        ok = JS_TRUE;
        for (comp = strtok(path, ":"); comp; comp = strtok(NULL, ":")) {
            if (*comp != '\0') {
                full = JS_smprintf("%s/%s", comp, name);
                if (!full) {
                    JS_ReportOutOfMemory(cx);
                    ok = JS_FALSE;
                    break;
                }
            } else {
                full = (char *)name;
            }
            found = (access(full, X_OK) == 0);
            if (*comp != '\0')
                free(full);
            if (found) {
                fun = JS_DefineFunction(cx, obj, name, Exec, 0,
                                        JSPROP_ENUMERATE);
                ok = (fun != NULL);
                if (ok)
                    *objp = obj;
                break;
            }
        }
        JS_free(cx, path);
        return ok;
    }
#else
    return JS_TRUE;
#endif
}
Exemple #20
0
void
js_LeaveLocalRootScopeWithResult(JSContext *cx, jsval rval)
{
    JSLocalRootStack *lrs;
    uint32 mark, m, n;
    JSLocalRootChunk *lrc;

    /* Defend against buggy native callers. */
    lrs = cx->localRootStack;
    JS_ASSERT(lrs && lrs->rootCount != 0);
    if (!lrs || lrs->rootCount == 0)
        return;

    mark = lrs->scopeMark;
    JS_ASSERT(mark != JSLRS_NULL_MARK);
    if (mark == JSLRS_NULL_MARK)
        return;

    /* Free any chunks being popped by this leave operation. */
    m = mark >> JSLRS_CHUNK_SHIFT;
    n = (lrs->rootCount - 1) >> JSLRS_CHUNK_SHIFT;
    while (n > m) {
        lrc = lrs->topChunk;
        JS_ASSERT(lrc != &lrs->firstChunk);
        lrs->topChunk = lrc->down;
        JS_free(cx, lrc);
        --n;
    }

    /*
     * Pop the scope, restoring lrs->scopeMark.  If rval is a GC-thing, push
     * it on the caller's scope, or store it in lastInternalResult if we are
     * leaving the outermost scope.  We don't need to allocate a new lrc
     * because we can overwrite the old mark's slot with rval.
     */
    lrc = lrs->topChunk;
    m = mark & JSLRS_CHUNK_MASK;
    lrs->scopeMark = (uint32) JSVAL_TO_INT(lrc->roots[m]);
    if (JSVAL_IS_GCTHING(rval) && !JSVAL_IS_NULL(rval)) {
        if (mark == 0) {
            cx->weakRoots.lastInternalResult = rval;
        } else {
            /*
             * Increment m to avoid the "else if (m == 0)" case below.  If
             * rval is not a GC-thing, that case would take care of freeing
             * any chunk that contained only the old mark.  Since rval *is*
             * a GC-thing here, we want to reuse that old mark's slot.
             */
            lrc->roots[m++] = rval;
            ++mark;
        }
    }
    lrs->rootCount = (uint32) mark;

    /*
     * Free the stack eagerly, risking malloc churn.  The alternative would
     * require an lrs->entryCount member, maintained by Enter and Leave, and
     * tested by the GC in addition to the cx->localRootStack non-null test.
     *
     * That approach would risk hoarding 264 bytes (net) per context.  Right
     * now it seems better to give fresh (dirty in CPU write-back cache, and
     * the data is no longer needed) memory back to the malloc heap.
     */
    if (mark == 0) {
        cx->localRootStack = NULL;
        JS_free(cx, lrs);
    } else if (m == 0) {
        lrs->topChunk = lrc->down;
        JS_free(cx, lrc);
    }
}
Exemple #21
0
static JSString *
StackTraceToString(JSContext *cx, JSExnPrivate *priv)
{
    jschar *stackbuf;
    size_t stacklen, stackmax;
    JSStackTraceElem *elem, *endElem;
    jsval *values;
    size_t i;
    JSString *str;
    const char *cp;
    char ulnbuf[11];

    /* After this point, failing control flow must goto bad. */
    stackbuf = NULL;
    stacklen = stackmax = 0;

/* Limit the stackbuf length to a reasonable value to avoid overflow checks. */
#define STACK_LENGTH_LIMIT JS_BIT(20)

#define APPEND_CHAR_TO_STACK(c)                                               \
    JS_BEGIN_MACRO                                                            \
        if (stacklen == stackmax) {                                           \
            void *ptr_;                                                       \
            if (stackmax >= STACK_LENGTH_LIMIT)                               \
                goto done;                                                    \
            stackmax = stackmax ? 2 * stackmax : 64;                          \
            ptr_ = JS_realloc(cx, stackbuf, (stackmax+1) * sizeof(jschar));   \
            if (!ptr_)                                                        \
                goto bad;                                                     \
            stackbuf = (jschar *) ptr_;                                       \
        }                                                                     \
        stackbuf[stacklen++] = (c);                                           \
    JS_END_MACRO

#define APPEND_STRING_TO_STACK(str)                                           \
    JS_BEGIN_MACRO                                                            \
        JSString *str_ = str;                                                 \
        jschar *chars_;                                                       \
        size_t length_;                                                       \
                                                                              \
        JSSTRING_CHARS_AND_LENGTH(str_, chars_, length_);                     \
        if (length_ > stackmax - stacklen) {                                  \
            void *ptr_;                                                       \
            if (stackmax >= STACK_LENGTH_LIMIT ||                             \
                length_ >= STACK_LENGTH_LIMIT - stacklen) {                   \
                goto done;                                                    \
            }                                                                 \
            stackmax = JS_BIT(JS_CeilingLog2(stacklen + length_));            \
            ptr_ = JS_realloc(cx, stackbuf, (stackmax+1) * sizeof(jschar));   \
            if (!ptr_)                                                        \
                goto bad;                                                     \
            stackbuf = (jschar *) ptr_;                                       \
        }                                                                     \
        js_strncpy(stackbuf + stacklen, chars_, length_);                     \
        stacklen += length_;                                                  \
    JS_END_MACRO

    values = GetStackTraceValueBuffer(priv);
    elem = priv->stackElems;
    for (endElem = elem + priv->stackDepth; elem != endElem; elem++) {
        if (elem->funName) {
            APPEND_STRING_TO_STACK(elem->funName);
            APPEND_CHAR_TO_STACK('(');
            for (i = 0; i != elem->argc; i++, values++) {
                if (i > 0)
                    APPEND_CHAR_TO_STACK(',');
                str = ValueToShortSource(cx, *values);
                if (!str)
                    goto bad;
                APPEND_STRING_TO_STACK(str);
            }
            APPEND_CHAR_TO_STACK(')');
        }
        APPEND_CHAR_TO_STACK('@');
        if (elem->filename) {
            for (cp = elem->filename; *cp; cp++)
                APPEND_CHAR_TO_STACK(*cp);
        }
        APPEND_CHAR_TO_STACK(':');
        JS_snprintf(ulnbuf, sizeof ulnbuf, "%u", elem->ulineno);
        for (cp = ulnbuf; *cp; cp++)
            APPEND_CHAR_TO_STACK(*cp);
        APPEND_CHAR_TO_STACK('\n');
    }
#undef APPEND_CHAR_TO_STACK
#undef APPEND_STRING_TO_STACK
#undef STACK_LENGTH_LIMIT

  done:
    if (stacklen == 0) {
        JS_ASSERT(!stackbuf);
        return cx->runtime->emptyString;
    }
    if (stacklen < stackmax) {
        /*
         * Realloc can fail when shrinking on some FreeBSD versions, so
         * don't use JS_realloc here; simply let the oversized allocation
         * be owned by the string in that rare case.
         */
        void *shrunk = JS_realloc(cx, stackbuf, (stacklen+1) * sizeof(jschar));
        if (shrunk)
            stackbuf = (jschar *) shrunk;
    }

    stackbuf[stacklen] = 0;
    str = js_NewString(cx, stackbuf, stacklen);
    if (str)
        return str;

  bad:
    if (stackbuf)
        JS_free(cx, stackbuf);
    return NULL;
}
Exemple #22
0
static JSBool
go(JSContext* cx, JSObject* obj, HTTPData* http, char* body, size_t bodylen)
{
    CurlState state;
    char* referer;
    JSString* jsbody;
    JSBool ret = JS_FALSE;
    jsval tmp;
    
    state.cx = cx;
    state.http = http;
    
    state.sendbuf = body;
    state.sendlen = bodylen;
    state.sent = 0;
    state.sent_once = 0;

    state.recvbuf = NULL;
    state.recvlen = 0;
    state.read = 0;

    if(HTTP_HANDLE == NULL) {
        HTTP_HANDLE = curl_easy_init();
        curl_easy_setopt(HTTP_HANDLE, CURLOPT_READFUNCTION, send_body);
        curl_easy_setopt(HTTP_HANDLE, CURLOPT_SEEKFUNCTION,
                                        (curl_seek_callback) seek_body);
        curl_easy_setopt(HTTP_HANDLE, CURLOPT_HEADERFUNCTION, recv_header);
        curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEFUNCTION, recv_body);
        curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOPROGRESS, 1);
        curl_easy_setopt(HTTP_HANDLE, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
        curl_easy_setopt(HTTP_HANDLE, CURLOPT_ERRORBUFFER, ERRBUF);
        curl_easy_setopt(HTTP_HANDLE, CURLOPT_COOKIEFILE, "");
        curl_easy_setopt(HTTP_HANDLE, CURLOPT_USERAGENT,
                                            "CouchHTTP Client - Relax");
    }
    
    if(!HTTP_HANDLE) {
        JS_ReportError(cx, "Failed to initialize cURL handle.");
        goto done;
    }

    if(!JS_GetReservedSlot(cx, obj, 0, &tmp)) {
      JS_ReportError(cx, "Failed to readreserved slot.");
      goto done;
    }

    if(!(referer = enc_string(cx, tmp, NULL))) {
      JS_ReportError(cx, "Failed to encode referer.");
      goto done;
    }
    curl_easy_setopt(HTTP_HANDLE, CURLOPT_REFERER, referer);
    free(referer);

    if(http->method < 0 || http->method > OPTIONS) {
        JS_ReportError(cx, "INTERNAL: Unknown method.");
        goto done;
    }

    curl_easy_setopt(HTTP_HANDLE, CURLOPT_CUSTOMREQUEST, METHODS[http->method]);
    curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 0);
    curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 1);
    curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 0);
    
    if(http->method == HEAD) {
        curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 1);
        curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0);
    } else if(http->method == POST || http->method == PUT) {
        curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 1);
        curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0);
    }
    
    if(body && bodylen) {
        curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, bodylen);        
    } else {
        curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, 0);
    }

    // curl_easy_setopt(HTTP_HANDLE, CURLOPT_VERBOSE, 1);

    curl_easy_setopt(HTTP_HANDLE, CURLOPT_URL, http->url);
    curl_easy_setopt(HTTP_HANDLE, CURLOPT_HTTPHEADER, http->req_headers);
    curl_easy_setopt(HTTP_HANDLE, CURLOPT_READDATA, &state);
    curl_easy_setopt(HTTP_HANDLE, CURLOPT_SEEKDATA, &state);
    curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEHEADER, &state);
    curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEDATA, &state);

    if(curl_easy_perform(HTTP_HANDLE) != 0) {
        JS_ReportError(cx, "Failed to execute HTTP request: %s", ERRBUF);
        goto done;
    }
    
    if(!state.resp_headers) {
        JS_ReportError(cx, "Failed to recieve HTTP headers.");
        goto done;
    }

    tmp = OBJECT_TO_JSVAL(state.resp_headers);
    if(!JS_DefineProperty(
        cx, obj,
        "_headers",
        tmp,
        NULL, NULL,
        JSPROP_READONLY
    )) {
        JS_ReportError(cx, "INTERNAL: Failed to set response headers.");
        goto done;
    }
    
    if(state.recvbuf) {
        state.recvbuf[state.read] = '\0';
        jsbody = dec_string(cx, state.recvbuf, state.read+1);
        if(!jsbody) {
            // If we can't decode the body as UTF-8 we forcefully
            // convert it to a string by just forcing each byte
            // to a jschar.
            jsbody = str_from_binary(cx, state.recvbuf, state.read);
            if(!jsbody) {
                if(!JS_IsExceptionPending(cx)) {
                    JS_ReportError(cx, "INTERNAL: Failed to decode body.");
                }
                goto done;
            }
        }
        tmp = STRING_TO_JSVAL(jsbody);
    } else {
        tmp = JS_GetEmptyStringValue(cx);
    }
    
    if(!JS_DefineProperty(
        cx, obj,
        "responseText",
        tmp,
        NULL, NULL,
        JSPROP_READONLY
    )) {
        JS_ReportError(cx, "INTERNAL: Failed to set responseText.");
        goto done;
    }
    
    ret = JS_TRUE;

done:
    if(state.recvbuf) JS_free(cx, state.recvbuf);
    return ret;
}
Exemple #23
0
void
js_DestroyContext(JSContext *cx, JSGCMode gcmode)
{
    JSRuntime *rt;
    JSBool last;
    JSArgumentFormatMap *map;
    JSLocalRootStack *lrs;
    JSLocalRootChunk *lrc;

    rt = cx->runtime;

    /* Remove cx from context list first. */
    JS_LOCK_GC(rt);
    JS_ASSERT(rt->state == JSRTS_UP || rt->state == JSRTS_LAUNCHING);
    JS_REMOVE_LINK(&cx->links);
    last = (rt->contextList.next == &rt->contextList);
    if (last)
        rt->state = JSRTS_LANDING;
    JS_UNLOCK_GC(rt);

    if (last) {
#ifdef JS_THREADSAFE
        /*
         * If cx is not in a request already, begin one now so that we wait
         * for any racing GC started on a not-last context to finish, before
         * we plow ahead and unpin atoms.  Note that even though we begin a
         * request here if necessary, we end all requests on cx below before
         * forcing a final GC.  This lets any not-last context destruction
         * racing in another thread try to force or maybe run the GC, but by
         * that point, rt->state will not be JSRTS_UP, and that GC attempt
         * will return early.
         */
        if (cx->requestDepth == 0)
            JS_BeginRequest(cx);
#endif

        /* Unpin all pinned atoms before final GC. */
        js_UnpinPinnedAtoms(&rt->atomState);

        /* Unlock and clear GC things held by runtime pointers. */
        js_FinishRuntimeNumberState(cx);
        js_FinishRuntimeStringState(cx);

        /* Clear debugging state to remove GC roots. */
        JS_ClearAllTraps(cx);
        JS_ClearAllWatchPoints(cx);
    }

#if JS_HAS_REGEXPS
    /*
     * Remove more GC roots in regExpStatics, then collect garbage.
     * XXX anti-modularity alert: we rely on the call to js_RemoveRoot within
     * XXX this function call to wait for any racing GC to complete, in the
     * XXX case where JS_DestroyContext is called outside of a request on cx
     */
    js_FreeRegExpStatics(cx, &cx->regExpStatics);
#endif

#ifdef JS_THREADSAFE
    /*
     * Destroying a context implicitly calls JS_EndRequest().  Also, we must
     * end our request here in case we are "last" -- in that event, another
     * js_DestroyContext that was not last might be waiting in the GC for our
     * request to end.  We'll let it run below, just before we do the truly
     * final GC and then free atom state.
     *
     * At this point, cx must be inaccessible to other threads.  It's off the
     * rt->contextList, and it should not be reachable via any object private
     * data structure.
     */
    while (cx->requestDepth != 0)
        JS_EndRequest(cx);
#endif

    if (last) {
        /* Always force, so we wait for any racing GC to finish. */
        js_ForceGC(cx, GC_LAST_CONTEXT);

        /* Iterate until no finalizer removes a GC root or lock. */
        while (rt->gcPoke)
            js_GC(cx, GC_LAST_CONTEXT);

        /* Try to free atom state, now that no unrooted scripts survive. */
        if (rt->atomState.liveAtoms == 0)
            js_FreeAtomState(cx, &rt->atomState);

        /* Now after the last GC can we free the script filename table. */
        js_FinishRuntimeScriptState(cx);

        /* Take the runtime down, now that it has no contexts or atoms. */
        JS_LOCK_GC(rt);
        rt->state = JSRTS_DOWN;
        JS_NOTIFY_ALL_CONDVAR(rt->stateChange);
        JS_UNLOCK_GC(rt);
    } else {
        if (gcmode == JS_FORCE_GC)
            js_ForceGC(cx, 0);
        else if (gcmode == JS_MAYBE_GC)
            JS_MaybeGC(cx);
    }

    /* Free the stuff hanging off of cx. */
    JS_FinishArenaPool(&cx->stackPool);
    JS_FinishArenaPool(&cx->tempPool);
    if (cx->lastMessage)
        free(cx->lastMessage);

    /* Remove any argument formatters. */
    map = cx->argumentFormatMap;
    while (map) {
        JSArgumentFormatMap *temp = map;
        map = map->next;
        JS_free(cx, temp);
    }

    /* Destroy the resolve recursion damper. */
    if (cx->resolvingTable) {
        JS_DHashTableDestroy(cx->resolvingTable);
        cx->resolvingTable = NULL;
    }

    lrs = cx->localRootStack;
    if (lrs) {
        while ((lrc = lrs->topChunk) != &lrs->firstChunk) {
            lrs->topChunk = lrc->down;
            JS_free(cx, lrc);
        }
        JS_free(cx, lrs);
    }

    /* Destroy the lint information */
    if (cx->lint) {
        JS_free(cx, cx->lint);
    }

    /* Finally, free cx itself. */
    free(cx);
}
Exemple #24
0
static JSBool vm_isCompilableUnit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
  JSString 	*str;
  jsrefcount 	depth;
  size_t	len, maxLen = 0;
  char		*buf;
  size_t        i;

  /** Coerce all args .toString() and calculate maximal buffer size */
  for (i = 0; i < argc; i++)
  {
    if (!JSVAL_IS_STRING(argv[i]))
    {
      str = JS_ValueToString(cx, argv[i]);
      argv[i] = STRING_TO_JSVAL(str);
    }
    else
      str = JSVAL_TO_STRING(argv[i]);

    len = JS_GetStringLength(JSVAL_TO_STRING(argv[i]));
    if (len > maxLen)
      maxLen = len;
  }

  buf = JS_malloc(cx, maxLen + 1);
  if (!buf)
    return JS_FALSE;

  if (argc > 1)
  {
    for (i = 0; i < (argc - 1); i++)
    {
      str = JS_ValueToString(cx, argv[i]);
      if (!str)
      {
	JS_free(cx, buf);
	return JS_FALSE;
      }

      strcpy(buf, JS_GetStringBytes(str));
      depth = JS_SuspendRequest(cx);
      gpsee_printf(cx, "%s%s", i ? " " : "", buf);
      JS_ResumeRequest(cx, depth);
    }
  }
  else
    i = 0;

  if (argc)
  {
    str = JS_ValueToString(cx, argv[i]);
    if (!str)
    {
      JS_free(cx, buf);
      return JS_FALSE;
    }

    strcpy(buf, JS_GetStringBytes(str));
  }
  else
    *buf = (char)0;

  *rval = JS_BufferIsCompilableUnit(cx, obj, buf, strlen(buf)) == JS_TRUE ? JSVAL_TRUE : JSVAL_FALSE;

  JS_free(cx, buf);
  return JS_TRUE;
}
Exemple #25
0
JSBool openfiledlg(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
	JSObject * filterArray = NULL;
	LPWSTR initialDirectory = NULL;
	LPWSTR dlgTitle = NULL;
	LPWSTR defaultExtension = NULL;
	JSBool save = JS_FALSE;
	
	JS_BeginRequest(cx);
	if(!JS_ConvertArguments(cx, argc, argv, "W W W o/ b", &initialDirectory, &defaultExtension, &dlgTitle, &filterArray, &save))
	{
		JS_ReportError(cx, "Error parsing arguments in OpenFileDialog");
		JS_EndRequest(cx);
		return JS_FALSE;
	}

	jsuint nFilters;
	JS_GetArrayLength(cx, filterArray, &nFilters);
	LPWSTR filterBuffer = (LPWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (50 * nFilters) * sizeof(WCHAR));
	long filterBufferUsed = 0, filterBufferSize = (50 * nFilters);
	for(jsuint i = 0; i < nFilters; i++)
	{
		jsval curFilter;
		JS_GetElement(cx, filterArray, i, &curFilter);
		JSString * curFilterString = JS_ValueToString(cx, curFilter);
		LPWSTR curFilterRaw = (LPWSTR)JS_GetStringChars(curFilterString);
		int delta = wcslen(curFilterRaw);
		if(filterBufferSize - ( 2 + JS_GetStringLength(curFilterString) + filterBufferUsed) <= 0)
		{
			filterBufferSize += 50;
			HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, filterBuffer, filterBufferSize * sizeof(WCHAR));
		}
		wcscpy_s(filterBuffer + filterBufferUsed, filterBufferSize - filterBufferUsed, (LPWSTR)JS_GetStringChars(curFilterString));
		filterBufferUsed += JS_GetStringLength(curFilterString) + 1;
	}
	filterBuffer[filterBufferUsed] = TEXT('\0');


	OPENFILENAME ofn;
	memset(&ofn, 0, sizeof(OPENFILENAME));
	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.lpstrFilter = filterBuffer;
	ofn.nFilterIndex = 0;
	ofn.lpstrFile = (LPWSTR)JS_malloc(cx, 260 * sizeof(WCHAR));
	memset(ofn.lpstrFile, 0, sizeof(WCHAR) * 260);
	ofn.nMaxFile = 260;
	ofn.lpstrFileTitle = (LPWSTR)JS_malloc(cx, 260 * sizeof(WCHAR));
	memset(ofn.lpstrFileTitle, 0, sizeof(WCHAR) * 260);
	ofn.nMaxFileTitle = 260;
	ofn.lpstrInitialDir = initialDirectory;
	ofn.lpstrTitle = dlgTitle;
	ofn.lpstrDefExt = defaultExtension;
	ofn.lpfnHook = OFN_Hook;
	ofn.Flags = OFN_ENABLEHOOK | OFN_EXPLORER;
	jsrefcount rCount = JS_SuspendRequest(cx);
	BOOL ok;
	if(save)
		ok = GetSaveFileName(&ofn);
	else
		ok = GetOpenFileName(&ofn);
	DWORD errorCode = CommDlgExtendedError();
	HeapFree(GetProcessHeap(), 0, filterBuffer);
	JS_ResumeRequest(cx, rCount);
	if(!ok)
	{
		JS_free(cx, ofn.lpstrFile);
		JS_free(cx, ofn.lpstrFileTitle);
		*rval = JSVAL_FALSE;
		return JS_TRUE;
	}

	JSObject * retObj = JS_NewObject(cx, NULL, NULL, obj);
	*rval = OBJECT_TO_JSVAL(retObj);

	jsval filePathVal = STRING_TO_JSVAL(JS_NewUCString(cx, (jschar*)ofn.lpstrFile, wcslen(ofn.lpstrFile)));
	JS_DefineProperty(cx, retObj, "filePath", filePathVal, NULL, NULL, JSPROP_PERMANENT | JSPROP_ENUMERATE);
	jsval fileTitleVal = STRING_TO_JSVAL(JS_NewUCString(cx, (jschar*)ofn.lpstrFileTitle, wcslen(ofn.lpstrFileTitle)));
	JS_DefineProperty(cx, retObj, "fileTitle", fileTitleVal, NULL, NULL, JSPROP_PERMANENT | JSPROP_ENUMERATE);
	JS_EndRequest(cx);
	return JS_TRUE;
}
Exemple #26
0
static JSBool
array_join_sub(JSContext *cx, JSObject *obj, JSString *sep, JSBool literalize,
               jsval *rval, JSBool localeString)
{
    JSBool ok;
    jsval v;
    jsuint length, index;
    jschar *chars, *ochars;
    size_t nchars, growth, seplen, tmplen;
    const jschar *sepstr;
    JSString *str;
    JSHashEntry *he;
    JSObject *obj2;

    ok = js_GetLengthProperty(cx, obj, &length);
    if (!ok)
        return JS_FALSE;

    he = js_EnterSharpObject(cx, obj, NULL, &chars);
    if (!he)
        return JS_FALSE;
    if (literalize) {
        if (IS_SHARP(he)) {
#if JS_HAS_SHARP_VARS
            nchars = js_strlen(chars);
#else
            chars[0] = '[';
            chars[1] = ']';
            chars[2] = 0;
            nchars = 2;
#endif
            goto make_string;
        }

        /*
         * Allocate 1 + 3 + 1 for "[", the worst-case closing ", ]", and the
         * terminating 0.
         */
        growth = (1 + 3 + 1) * sizeof(jschar);
        if (!chars) {
            nchars = 0;
            chars = (jschar *) malloc(growth);
            if (!chars)
                goto done;
        } else {
            MAKE_SHARP(he);
            nchars = js_strlen(chars);
            chars = (jschar *)
                realloc((ochars = chars), nchars * sizeof(jschar) + growth);
            if (!chars) {
                free(ochars);
                goto done;
            }
        }
        chars[nchars++] = '[';
    } else {
        /*
         * Free any sharp variable definition in chars.  Normally, we would
         * MAKE_SHARP(he) so that only the first sharp variable annotation is
         * a definition, and all the rest are references, but in the current
         * case of (!literalize), we don't need chars at all.
         */
        if (chars)
            JS_free(cx, chars);
        chars = NULL;
        nchars = 0;

        /* Return the empty string on a cycle as well as on empty join. */
        if (IS_BUSY(he) || length == 0) {
            js_LeaveSharpObject(cx, NULL);
            *rval = JS_GetEmptyStringValue(cx);
            return ok;
        }

        /* Flag he as BUSY so we can distinguish a cycle from a join-point. */
        MAKE_BUSY(he);
    }
    sepstr = NULL;
    seplen = JSSTRING_LENGTH(sep);

    v = JSVAL_NULL;
    for (index = 0; index < length; index++) {
        ok = JS_GetElement(cx, obj, index, &v);
        if (!ok)
            goto done;

        if (!literalize && (JSVAL_IS_VOID(v) || JSVAL_IS_NULL(v))) {
            str = cx->runtime->emptyString;
        } else {
            if (localeString) {
                if (!js_ValueToObject(cx, v, &obj2) ||
                    !js_TryMethod(cx, obj2,
                                  cx->runtime->atomState.toLocaleStringAtom,
                                  0, NULL, &v)) {
                    str = NULL;
                } else {
                    str = js_ValueToString(cx, v);
                }
            } else {
                str = (literalize ? js_ValueToSource : js_ValueToString)(cx, v);
            }
            if (!str) {
                ok = JS_FALSE;
                goto done;
            }
        }

        /* Allocate 3 + 1 at end for ", ", closing bracket, and zero. */
        growth = (nchars + (sepstr ? seplen : 0) +
                  JSSTRING_LENGTH(str) +
                  3 + 1) * sizeof(jschar);
        if (!chars) {
            chars = (jschar *) malloc(growth);
            if (!chars)
                goto done;
        } else {
            chars = (jschar *) realloc((ochars = chars), growth);
            if (!chars) {
                free(ochars);
                goto done;
            }
        }

        if (sepstr) {
            js_strncpy(&chars[nchars], sepstr, seplen);
            nchars += seplen;
        }
        sepstr = JSSTRING_CHARS(sep);

        tmplen = JSSTRING_LENGTH(str);
        js_strncpy(&chars[nchars], JSSTRING_CHARS(str), tmplen);
        nchars += tmplen;
    }

  done:
    if (literalize) {
        if (chars) {
            if (JSVAL_IS_VOID(v)) {
                chars[nchars++] = ',';
                chars[nchars++] = ' ';
            }
            chars[nchars++] = ']';
        }
    } else {
        CLEAR_BUSY(he);
    }
    js_LeaveSharpObject(cx, NULL);
    if (!ok) {
        if (chars)
            free(chars);
        return ok;
    }

  make_string:
    if (!chars) {
        JS_ReportOutOfMemory(cx);
        return JS_FALSE;
    }
    chars[nchars] = 0;
    str = js_NewString(cx, chars, nchars, 0);
    if (!str) {
        free(chars);
        return JS_FALSE;
    }
    *rval = STRING_TO_JSVAL(str);
    return JS_TRUE;
}
Exemple #27
0
/*
 * Class:     netscape_javascript_JSObject
 * Method:    call
 * Signature: (Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;
 */
JNIEXPORT jobject JNICALL
Java_netscape_javascript_JSObject_call(JNIEnv *jEnv, jobject java_wrapper_obj,
                                       jstring function_name_jstr, jobjectArray java_args)
{
    int i, argc, arg_num;
    jsval *argv;
    JSContext *cx = NULL;
    JSObject *js_obj;
    jsval js_val, function_val;
    int dummy_cost;
    JSBool dummy_bool;
    const jchar *function_name_ucs2;
    jsize function_name_len;
    JSErrorReporter saved_reporter;
    jboolean is_copy;
    jobject result;
    JSJavaThreadState *jsj_env;
    
    jsj_env = jsj_enter_js(jEnv, NULL, java_wrapper_obj, &cx, &js_obj, &saved_reporter, NULL, 0, NULL);
    if (!jsj_env)
        return NULL;
    
    function_name_ucs2 = NULL;
    result = NULL;
    if (!function_name_jstr) {
        JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
                                                    JSJMSG_NULL_FUNCTION_NAME);
        goto done;
    }

    /* Get the function name to eval as raw Unicode characters */
    function_name_ucs2 = (*jEnv)->GetStringChars(jEnv, function_name_jstr, &is_copy);
    if (!function_name_ucs2) {
        JS_ASSERT(0);
        goto done;
    }
    function_name_len = (*jEnv)->GetStringLength(jEnv, function_name_jstr);
    
    /* Allocate space for JS arguments */
    if (java_args) {
        argc = (*jEnv)->GetArrayLength(jEnv, java_args);
        argv = (jsval*)JS_malloc(cx, argc * sizeof(jsval));
    } else {
        argc = 0;
        argv = 0;
    }

    /* Convert arguments from Java to JS values */
    for (arg_num = 0; arg_num < argc; arg_num++) {
        jobject arg = (*jEnv)->GetObjectArrayElement(jEnv, java_args, arg_num);

        if (!jsj_ConvertJavaObjectToJSValue(cx, jEnv, arg, &argv[arg_num]))
            goto cleanup_argv;
        JS_AddNamedRoot(cx, &argv[arg_num], "&argv[arg_num]");
    }

    if (!JS_GetUCProperty(cx, js_obj, function_name_ucs2, function_name_len,
                          &function_val))
        goto cleanup_argv;

    if (!JS_CallFunctionValue(cx, js_obj, function_val, argc, argv, &js_val))
        goto cleanup_argv;

    jsj_ConvertJSValueToJavaObject(cx, jEnv, js_val, jsj_get_jlObject_descriptor(cx, jEnv),
                                   &dummy_cost, &result, &dummy_bool);

cleanup_argv:
    if (argv) {
        for (i = 0; i < arg_num; i++)
            JS_RemoveRoot(cx, &argv[i]);
        JS_free(cx, argv);
    }

done:
    if (function_name_ucs2)
        (*jEnv)->ReleaseStringChars(jEnv, function_name_jstr, function_name_ucs2);
    if (!jsj_exit_js(cx, jsj_env, saved_reporter))
        return NULL;
    
    return result;
}
Exemple #28
0
/* XXXmccabe do the sort helper functions need to take int?  (Or can we claim
 * that 2^32 * 32 is too large to worry about?)  Something dumps when I change
 * to unsigned int; is qsort using -1 as a fencepost?
 */
static JSBool
array_sort(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
    jsval fval;
    CompareArgs ca;
    jsuint len, newlen, i;
    jsval *vec;
    jsid id;
    size_t nbytes;

    /*
     * Optimize the default compare function case if all of obj's elements
     * have values of type string.
     */
    JSBool all_strings;

    if (argc > 0) {
        if (JSVAL_IS_PRIMITIVE(argv[0])) {
            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                                 JSMSG_BAD_SORT_ARG);
            return JS_FALSE;
        }
        fval = argv[0];
        all_strings = JS_FALSE; /* non-default compare function */
    } else {
        fval = JSVAL_NULL;
        all_strings = JS_TRUE;  /* check for all string values */
    }

    if (!js_GetLengthProperty(cx, obj, &len))
        return JS_FALSE;
    if (len == 0) {
        *rval = OBJECT_TO_JSVAL(obj);
        return JS_TRUE;
    }

    /*
     * Test for size_t overflow, which could lead to indexing beyond the end
     * of the malloc'd vector.
     */
    nbytes = len * sizeof(jsval);
    if (nbytes != (double) len * sizeof(jsval)) {
        JS_ReportOutOfMemory(cx);
        return JS_FALSE;
    }
    vec = (jsval *) JS_malloc(cx, nbytes);
    if (!vec)
        return JS_FALSE;

#if JS_HAS_SPARSE_ARRAYS
    newlen = 0;
#else
    newlen = len;
#endif

    for (i = 0; i < len; i++) {
        ca.status = IndexToId(cx, i, &id);
        if (!ca.status)
            goto out;
#if JS_HAS_SPARSE_ARRAYS
        {
            JSObject *obj2;
            JSProperty *prop;
            ca.status = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop);
            if (!ca.status)
                goto out;
            if (!prop) {
                vec[i] = JSVAL_VOID;
                continue;
            }
            OBJ_DROP_PROPERTY(cx, obj2, prop);
            newlen++;
        }
#endif
        ca.status = OBJ_GET_PROPERTY(cx, obj, id, &vec[i]);
        if (!ca.status)
            goto out;

        /* We know JSVAL_IS_STRING yields 0 or 1, so avoid a branch via &=. */
        all_strings &= JSVAL_IS_STRING(vec[i]); 
    }

    ca.context = cx;
    ca.fval = fval;
    ca.status = JS_TRUE;
    if (!js_HeapSort(vec, (size_t) len, sizeof(jsval),
                     all_strings ? sort_compare_strings : sort_compare,
                     &ca)) {
        JS_ReportOutOfMemory(cx);
        ca.status = JS_FALSE;
    }

    if (ca.status) {
        ca.status = InitArrayElements(cx, obj, newlen, vec);
        if (ca.status)
            *rval = OBJECT_TO_JSVAL(obj);
#if JS_HAS_SPARSE_ARRAYS
        /* set length of newly-created array object to old length. */
        if (ca.status && newlen < len) {
            ca.status = js_SetLengthProperty(cx, obj, len);

            /* Delete any leftover properties greater than newlen. */
            while (ca.status && newlen < len) {
                jsval junk;

                ca.status = !IndexToId(cx, newlen, &id) ||
                    !OBJ_DELETE_PROPERTY(cx, obj, id, &junk);
                newlen++;
            }
        }
#endif
    }

out:
    if (vec)
        JS_free(cx, vec);
    return ca.status;
}
Exemple #29
0
/*
 * Return a string that may eval to something similar to the original object.
 */
static JSBool
exn_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
    jsval v;
    JSString *name, *message, *filename, *lineno_as_str, *result;
    int32 lineno;
    size_t lineno_length, name_length, message_length, filename_length, length;
    jschar *chars, *cp;

    if (!OBJ_GET_PROPERTY(cx, obj, (jsid)cx->runtime->atomState.nameAtom, &v))
        return JS_FALSE;
    name = js_ValueToString(cx, v);
    if (!name)
        return JS_FALSE;

    if (!JS_GetProperty(cx, obj, js_message_str, &v) ||
        !(message = js_ValueToSource(cx, v))) {
        return JS_FALSE;
    }

    if (!JS_GetProperty(cx, obj, js_filename_str, &v) ||
        !(filename = js_ValueToSource(cx, v))) {
        return JS_FALSE;
    }

    if (!JS_GetProperty(cx, obj, js_lineno_str, &v) ||
        !js_ValueToInt32 (cx, v, &lineno)) {
        return JS_FALSE;
    }

    if (lineno != 0) {
        if (!(lineno_as_str = js_ValueToString(cx, v))) {
            return JS_FALSE;
        }
        lineno_length = JSSTRING_LENGTH(lineno_as_str);
    } else {
        lineno_as_str = NULL;
        lineno_length = 0;
    }

    /* Magic 8, for the characters in ``(new ())''. */
    name_length = JSSTRING_LENGTH(name);
    message_length = JSSTRING_LENGTH(message);
    length = 8 + name_length + message_length;

    filename_length = JSSTRING_LENGTH(filename);
    if (filename_length != 0) {
        /* append filename as ``, {filename}'' */
        length += 2 + filename_length;
        if (lineno_as_str) {
            /* append lineno as ``, {lineno_as_str}'' */
            length += 2 + lineno_length;
        }
    } else {
        if (lineno_as_str) {
            /*
             * no filename, but have line number,
             * need to append ``, "", {lineno_as_str}''
             */
            length += 6 + lineno_length;
        }
    }

    cp = chars = (jschar*) JS_malloc(cx, (length + 1) * sizeof(jschar));
    if (!chars)
        return JS_FALSE;

    *cp++ = '('; *cp++ = 'n'; *cp++ = 'e'; *cp++ = 'w'; *cp++ = ' ';
    js_strncpy(cp, JSSTRING_CHARS(name), name_length);
    cp += name_length;
    *cp++ = '(';
    if (message_length != 0) {
        js_strncpy(cp, JSSTRING_CHARS(message), message_length);
        cp += message_length;
    }

    if (filename_length != 0) {
        /* append filename as ``, {filename}'' */
        *cp++ = ','; *cp++ = ' ';
        js_strncpy(cp, JSSTRING_CHARS(filename), filename_length);
        cp += filename_length;
    } else {
        if (lineno_as_str) {
            /*
             * no filename, but have line number,
             * need to append ``, "", {lineno_as_str}''
             */
            *cp++ = ','; *cp++ = ' '; *cp++ = '"'; *cp++ = '"';
        }
    }
    if (lineno_as_str) {
        /* append lineno as ``, {lineno_as_str}'' */
        *cp++ = ','; *cp++ = ' ';
        js_strncpy(cp, JSSTRING_CHARS(lineno_as_str), lineno_length);
        cp += lineno_length;
    }

    *cp++ = ')'; *cp++ = ')'; *cp = 0;

    result = js_NewString(cx, chars, length, 0);
    if (!result) {
        JS_free(cx, chars);
        return JS_FALSE;
    }
    *rval = STRING_TO_JSVAL(result);
    return JS_TRUE;
}
Exemple #30
0
JSObject*
Library::Create(JSContext* cx, Value path_, const JSCTypesCallbacks* callbacks)
{
    RootedValue path(cx, path_);
    RootedObject libraryObj(cx, JS_NewObject(cx, &sLibraryClass));
    if (!libraryObj)
        return nullptr;

    // initialize the library
    JS_SetReservedSlot(libraryObj, SLOT_LIBRARY, PrivateValue(nullptr));

    // attach API functions
    if (!JS_DefineFunctions(cx, libraryObj, sLibraryFunctions))
        return nullptr;

    if (!path.isString()) {
        JS_ReportError(cx, "open takes a string argument");
        return nullptr;
    }

    PRLibSpec libSpec;
    RootedFlatString pathStr(cx, JS_FlattenString(cx, path.toString()));
    if (!pathStr)
        return nullptr;
    AutoStableStringChars pathStrChars(cx);
    if (!pathStrChars.initTwoByte(cx, pathStr))
        return nullptr;
#ifdef XP_WIN
    // On Windows, converting to native charset may corrupt path string.
    // So, we have to use Unicode path directly.
    char16ptr_t pathChars = pathStrChars.twoByteChars();
    libSpec.value.pathname_u = pathChars;
    libSpec.type = PR_LibSpec_PathnameU;
#else
    // Convert to platform native charset if the appropriate callback has been
    // provided.
    char* pathBytes;
    if (callbacks && callbacks->unicodeToNative) {
        pathBytes =
            callbacks->unicodeToNative(cx, pathStrChars.twoByteChars(), pathStr->length());
        if (!pathBytes)
            return nullptr;

    } else {
        // Fallback: assume the platform native charset is UTF-8. This is true
        // for Mac OS X, Android, and probably Linux.
        size_t nbytes =
            GetDeflatedUTF8StringLength(cx, pathStrChars.twoByteChars(), pathStr->length());
        if (nbytes == (size_t) -1)
            return nullptr;

        pathBytes = static_cast<char*>(JS_malloc(cx, nbytes + 1));
        if (!pathBytes)
            return nullptr;

        ASSERT_OK(DeflateStringToUTF8Buffer(cx, pathStrChars.twoByteChars(),
                                            pathStr->length(), pathBytes, &nbytes));
        pathBytes[nbytes] = 0;
    }

    libSpec.value.pathname = pathBytes;
    libSpec.type = PR_LibSpec_Pathname;
#endif

    PRLibrary* library = PR_LoadLibraryWithFlags(libSpec, 0);

    if (!library) {
        char* error = (char*) JS_malloc(cx, PR_GetErrorTextLength() + 1);
        if (error)
            PR_GetErrorText(error);

#ifdef XP_WIN
        JS_ReportError(cx, "couldn't open library %hs: %s", pathChars, error);
#else
        JS_ReportError(cx, "couldn't open library %s: %s", pathBytes, error);
        JS_free(cx, pathBytes);
#endif
        JS_free(cx, error);
        return nullptr;
    }

#ifndef XP_WIN
    JS_free(cx, pathBytes);
#endif

    // stash the library
    JS_SetReservedSlot(libraryObj, SLOT_LIBRARY, PrivateValue(library));

    return libraryObj;
}