/* * 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);