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