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