|  | 
 | /* | 
 |  * Copyright 2006 The Android Open Source Project | 
 |  * | 
 |  * Use of this source code is governed by a BSD-style license that can be | 
 |  * found in the LICENSE file. | 
 |  */ | 
 |  | 
 |  | 
 | #include <jsapi.h> | 
 |  | 
 | #include "SkJS.h" | 
 | #include "SkString.h" | 
 |  | 
 | #ifdef _WIN32_WCE | 
 | extern "C" { | 
 |     void abort() { | 
 |         SkASSERT(0); | 
 |     } | 
 |  | 
 |     unsigned int _control87(unsigned int _new, unsigned int mask ) { | 
 |         SkASSERT(0); | 
 |         return 0; | 
 |     } | 
 |  | 
 |     time_t mktime(struct tm *timeptr ) { | 
 |         SkASSERT(0); | 
 |         return 0; | 
 |     } | 
 |  | 
 | //  int errno; | 
 |  | 
 |     char *strdup(const char *) { | 
 |         SkASSERT(0); | 
 |         return 0; | 
 |     } | 
 |  | 
 |     char *strerror(int errnum) { | 
 |         SkASSERT(0); | 
 |         return 0; | 
 |     } | 
 |  | 
 |     int isatty(void* fd) { | 
 |         SkASSERT(0); | 
 |         return 0; | 
 |     } | 
 |  | 
 |     int putenv(const char *envstring) { | 
 |         SkASSERT(0); | 
 |         return 0; | 
 |     } | 
 |  | 
 |     char *getenv(const char *varname) { | 
 |         SkASSERT(0); | 
 |         return 0; | 
 |     } | 
 |  | 
 |     void GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime) { | 
 |         SkASSERT(0); | 
 |     } | 
 |  | 
 |     struct tm * localtime(const time_t *timer) { | 
 |         SkASSERT(0); | 
 |         return 0; | 
 |     } | 
 |  | 
 |     size_t strftime(char *strDest, size_t maxsize, const char *format, | 
 |         const struct tm *timeptr ) { | 
 |         SkASSERT(0); | 
 |         return 0; | 
 |     } | 
 |  | 
 | } | 
 | #endif | 
 |  | 
 | static JSBool | 
 | global_enumerate(JSContext *cx, JSObject *obj) | 
 | { | 
 | #ifdef LAZY_STANDARD_CLASSES | 
 |     return JS_EnumerateStandardClasses(cx, obj); | 
 | #else | 
 |     return JS_TRUE; | 
 | #endif | 
 | } | 
 |  | 
 | static JSBool | 
 | global_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp) | 
 | { | 
 | #ifdef LAZY_STANDARD_CLASSES | 
 |     if ((flags & JSRESOLVE_ASSIGNING) == 0) { | 
 |         JSBool resolved; | 
 |  | 
 |         if (!JS_ResolveStandardClass(cx, obj, id, &resolved)) | 
 |             return JS_FALSE; | 
 |         if (resolved) { | 
 |             *objp = obj; | 
 |             return JS_TRUE; | 
 |         } | 
 |     } | 
 | #endif | 
 |  | 
 | #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 | 
 | } | 
 |  | 
 | JSClass global_class = { | 
 |     "global", JSCLASS_NEW_RESOLVE, | 
 |     JS_PropertyStub,  JS_PropertyStub, | 
 |     JS_PropertyStub,  JS_PropertyStub, | 
 |     global_enumerate, (JSResolveOp) global_resolve, | 
 |     JS_ConvertStub,   JS_FinalizeStub | 
 | }; | 
 |  | 
 | SkJS::SkJS(void* hwnd) : SkOSWindow(hwnd) { | 
 |     if ((fRuntime = JS_NewRuntime(0x100000)) == NULL) { | 
 |         SkASSERT(0); | 
 |         return; | 
 |     } | 
 |     if ((fContext = JS_NewContext(fRuntime, 0x1000)) == NULL) { | 
 |         SkASSERT(0); | 
 |         return; | 
 |     } | 
 |     ; | 
 |     if ((fGlobal = JS_NewObject(fContext, &global_class, NULL, NULL)) == NULL) { | 
 |         SkASSERT(0); | 
 |         return; | 
 |     } | 
 |     if (JS_InitStandardClasses(fContext, fGlobal) == NULL) { | 
 |         SkASSERT(0); | 
 |         return; | 
 |     } | 
 |     setConfig(SkBitmap::kARGB32_Config); | 
 |     updateSize(); | 
 |     setVisibleP(true); | 
 |     InitializeDisplayables(getBitmap(), fContext, fGlobal, NULL); | 
 | } | 
 |  | 
 | SkJS::~SkJS() { | 
 |     DisposeDisplayables(); | 
 |     JS_DestroyContext(fContext); | 
 |     JS_DestroyRuntime(fRuntime); | 
 |     JS_ShutDown(); | 
 | } | 
 |  | 
 | SkBool SkJS::EvaluateScript(const char* script, jsval* rVal) { | 
 |     return JS_EvaluateScript(fContext, fGlobal, script, strlen(script), | 
 |         "memory" /* no file name */, 0 /* no line number */, rVal); | 
 | } | 
 |  | 
 | SkBool SkJS::ValueToString(jsval value, SkString* string) { | 
 |      JSString* str = JS_ValueToString(fContext, value); | 
 |      if (str == NULL) | 
 |          return false; | 
 |      string->set(JS_GetStringBytes(str)); | 
 |      return true; | 
 | } | 
 |  | 
 | #ifdef SK_DEBUG | 
 | void SkJS::Test(void* hwnd) { | 
 |     SkJS js(hwnd); | 
 |     jsval val; | 
 |     SkBool success = js.EvaluateScript("22/7", &val); | 
 |     SkASSERT(success); | 
 |     SkString string; | 
 |     success = js.ValueToString(val, &string); | 
 |     SkASSERT(success); | 
 |     SkASSERT(strcmp(string.c_str(), "3.142857142857143") == 0); | 
 |     success = js.EvaluateScript( | 
 |         "var rect = new rectangle();" | 
 |         "rect.left = 4;" | 
 |         "rect.top = 10;" | 
 |         "rect.right = 20;" | 
 |         "rect.bottom = 30;" | 
 |         "rect.width = rect.height + 20;" | 
 |         "rect.draw();" | 
 |         , &val); | 
 |     SkASSERT(success); | 
 |     success = js.ValueToString(val, &string); | 
 |     SkASSERT(success); | 
 | } | 
 | #endifASSERT(success); | 
 |  |