Home | History | Annotate | Download | only in xml
      1 
      2 /*
      3  * Copyright 2006 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #include <jsapi.h>
     11 
     12 #include "SkJS.h"
     13 #include "SkString.h"
     14 
     15 #ifdef _WIN32_WCE
     16 extern "C" {
     17     void abort() {
     18         SkASSERT(0);
     19     }
     20 
     21     unsigned int _control87(unsigned int _new, unsigned int mask ) {
     22         SkASSERT(0);
     23         return 0;
     24     }
     25 
     26     time_t mktime(struct tm *timeptr ) {
     27         SkASSERT(0);
     28         return 0;
     29     }
     30 
     31 //  int errno;
     32 
     33     char *strdup(const char *) {
     34         SkASSERT(0);
     35         return 0;
     36     }
     37 
     38     char *strerror(int errnum) {
     39         SkASSERT(0);
     40         return 0;
     41     }
     42 
     43     int isatty(void* fd) {
     44         SkASSERT(0);
     45         return 0;
     46     }
     47 
     48     int putenv(const char *envstring) {
     49         SkASSERT(0);
     50         return 0;
     51     }
     52 
     53     char *getenv(const char *varname) {
     54         SkASSERT(0);
     55         return 0;
     56     }
     57 
     58     void GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime) {
     59         SkASSERT(0);
     60     }
     61 
     62     struct tm * localtime(const time_t *timer) {
     63         SkASSERT(0);
     64         return 0;
     65     }
     66 
     67     size_t strftime(char *strDest, size_t maxsize, const char *format,
     68         const struct tm *timeptr ) {
     69         SkASSERT(0);
     70         return 0;
     71     }
     72 
     73 }
     74 #endif
     75 
     76 static JSBool
     77 global_enumerate(JSContext *cx, JSObject *obj)
     78 {
     79 #ifdef LAZY_STANDARD_CLASSES
     80     return JS_EnumerateStandardClasses(cx, obj);
     81 #else
     82     return JS_TRUE;
     83 #endif
     84 }
     85 
     86 static JSBool
     87 global_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp)
     88 {
     89 #ifdef LAZY_STANDARD_CLASSES
     90     if ((flags & JSRESOLVE_ASSIGNING) == 0) {
     91         JSBool resolved;
     92 
     93         if (!JS_ResolveStandardClass(cx, obj, id, &resolved))
     94             return JS_FALSE;
     95         if (resolved) {
     96             *objp = obj;
     97             return JS_TRUE;
     98         }
     99     }
    100 #endif
    101 
    102 #if defined(SHELL_HACK) && defined(DEBUG) && defined(XP_UNIX)
    103     if ((flags & (JSRESOLVE_QUALIFIED | JSRESOLVE_ASSIGNING)) == 0) {
    104         /*
    105          * Do this expensive hack only for unoptimized Unix builds, which are
    106          * not used for benchmarking.
    107          */
    108         char *path, *comp, *full;
    109         const char *name;
    110         JSBool ok, found;
    111         JSFunction *fun;
    112 
    113         if (!JSVAL_IS_STRING(id))
    114             return JS_TRUE;
    115         path = getenv("PATH");
    116         if (!path)
    117             return JS_TRUE;
    118         path = JS_strdup(cx, path);
    119         if (!path)
    120             return JS_FALSE;
    121         name = JS_GetStringBytes(JSVAL_TO_STRING(id));
    122         ok = JS_TRUE;
    123         for (comp = strtok(path, ":"); comp; comp = strtok(NULL, ":")) {
    124             if (*comp != '\0') {
    125                 full = JS_smprintf("%s/%s", comp, name);
    126                 if (!full) {
    127                     JS_ReportOutOfMemory(cx);
    128                     ok = JS_FALSE;
    129                     break;
    130                 }
    131             } else {
    132                 full = (char *)name;
    133             }
    134             found = (access(full, X_OK) == 0);
    135             if (*comp != '\0')
    136                 free(full);
    137             if (found) {
    138                 fun = JS_DefineFunction(cx, obj, name, Exec, 0, JSPROP_ENUMERATE);
    139                 ok = (fun != NULL);
    140                 if (ok)
    141                     *objp = obj;
    142                 break;
    143             }
    144         }
    145         JS_free(cx, path);
    146         return ok;
    147     }
    148 #else
    149     return JS_TRUE;
    150 #endif
    151 }
    152 
    153 JSClass global_class = {
    154     "global", JSCLASS_NEW_RESOLVE,
    155     JS_PropertyStub,  JS_PropertyStub,
    156     JS_PropertyStub,  JS_PropertyStub,
    157     global_enumerate, (JSResolveOp) global_resolve,
    158     JS_ConvertStub,   JS_FinalizeStub
    159 };
    160 
    161 SkJS::SkJS(void* hwnd) : SkOSWindow(hwnd) {
    162     if ((fRuntime = JS_NewRuntime(0x100000)) == NULL) {
    163         SkASSERT(0);
    164         return;
    165     }
    166     if ((fContext = JS_NewContext(fRuntime, 0x1000)) == NULL) {
    167         SkASSERT(0);
    168         return;
    169     }
    170     ;
    171     if ((fGlobal = JS_NewObject(fContext, &global_class, NULL, NULL)) == NULL) {
    172         SkASSERT(0);
    173         return;
    174     }
    175     if (JS_InitStandardClasses(fContext, fGlobal) == NULL) {
    176         SkASSERT(0);
    177         return;
    178     }
    179     setConfig(SkBitmap::kARGB32_Config);
    180     updateSize();
    181     setVisibleP(true);
    182     InitializeDisplayables(getBitmap(), fContext, fGlobal, NULL);
    183 }
    184 
    185 SkJS::~SkJS() {
    186     DisposeDisplayables();
    187     JS_DestroyContext(fContext);
    188     JS_DestroyRuntime(fRuntime);
    189     JS_ShutDown();
    190 }
    191 
    192 SkBool SkJS::EvaluateScript(const char* script, jsval* rVal) {
    193     return JS_EvaluateScript(fContext, fGlobal, script, strlen(script),
    194         "memory" /* no file name */, 0 /* no line number */, rVal);
    195 }
    196 
    197 SkBool SkJS::ValueToString(jsval value, SkString* string) {
    198      JSString* str = JS_ValueToString(fContext, value);
    199      if (str == NULL)
    200          return false;
    201      string->set(JS_GetStringBytes(str));
    202      return true;
    203 }
    204 
    205 #ifdef SK_DEBUG
    206 void SkJS::Test(void* hwnd) {
    207     SkJS js(hwnd);
    208     jsval val;
    209     SkBool success = js.EvaluateScript("22/7", &val);
    210     SkASSERT(success);
    211     SkString string;
    212     success = js.ValueToString(val, &string);
    213     SkASSERT(success);
    214     SkASSERT(strcmp(string.c_str(), "3.142857142857143") == 0);
    215     success = js.EvaluateScript(
    216         "var rect = new rectangle();"
    217         "rect.left = 4;"
    218         "rect.top = 10;"
    219         "rect.right = 20;"
    220         "rect.bottom = 30;"
    221         "rect.width = rect.height + 20;"
    222         "rect.draw();"
    223         , &val);
    224     SkASSERT(success);
    225     success = js.ValueToString(val, &string);
    226     SkASSERT(success);
    227 }
    228 #endifASSERT(success);
    229