diff options
Diffstat (limited to 'src/xml/SkJS.cpp')
-rw-r--r-- | src/xml/SkJS.cpp | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/src/xml/SkJS.cpp b/src/xml/SkJS.cpp new file mode 100644 index 0000000..03ccba6 --- /dev/null +++ b/src/xml/SkJS.cpp @@ -0,0 +1,237 @@ +/* libs/graphics/xml/SkJS.cpp +** +** Copyright 2006, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#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); + |