michael@0: michael@0: /* michael@0: * Copyright 2006 The Android Open Source Project michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: michael@0: #include michael@0: michael@0: #include "SkJS.h" michael@0: #include "SkString.h" michael@0: michael@0: #ifdef _WIN32_WCE michael@0: extern "C" { michael@0: void abort() { michael@0: SkASSERT(0); michael@0: } michael@0: michael@0: unsigned int _control87(unsigned int _new, unsigned int mask ) { michael@0: SkASSERT(0); michael@0: return 0; michael@0: } michael@0: michael@0: time_t mktime(struct tm *timeptr ) { michael@0: SkASSERT(0); michael@0: return 0; michael@0: } michael@0: michael@0: // int errno; michael@0: michael@0: char *strdup(const char *) { michael@0: SkASSERT(0); michael@0: return 0; michael@0: } michael@0: michael@0: char *strerror(int errnum) { michael@0: SkASSERT(0); michael@0: return 0; michael@0: } michael@0: michael@0: int isatty(void* fd) { michael@0: SkASSERT(0); michael@0: return 0; michael@0: } michael@0: michael@0: int putenv(const char *envstring) { michael@0: SkASSERT(0); michael@0: return 0; michael@0: } michael@0: michael@0: char *getenv(const char *varname) { michael@0: SkASSERT(0); michael@0: return 0; michael@0: } michael@0: michael@0: void GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime) { michael@0: SkASSERT(0); michael@0: } michael@0: michael@0: struct tm * localtime(const time_t *timer) { michael@0: SkASSERT(0); michael@0: return 0; michael@0: } michael@0: michael@0: size_t strftime(char *strDest, size_t maxsize, const char *format, michael@0: const struct tm *timeptr ) { michael@0: SkASSERT(0); michael@0: return 0; michael@0: } michael@0: michael@0: } michael@0: #endif michael@0: michael@0: static JSBool michael@0: global_enumerate(JSContext *cx, JSObject *obj) michael@0: { michael@0: #ifdef LAZY_STANDARD_CLASSES michael@0: return JS_EnumerateStandardClasses(cx, obj); michael@0: #else michael@0: return JS_TRUE; michael@0: #endif michael@0: } michael@0: michael@0: static JSBool michael@0: global_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp) michael@0: { michael@0: #ifdef LAZY_STANDARD_CLASSES michael@0: if ((flags & JSRESOLVE_ASSIGNING) == 0) { michael@0: JSBool resolved; michael@0: michael@0: if (!JS_ResolveStandardClass(cx, obj, id, &resolved)) michael@0: return JS_FALSE; michael@0: if (resolved) { michael@0: *objp = obj; michael@0: return JS_TRUE; michael@0: } michael@0: } michael@0: #endif michael@0: michael@0: #if defined(SHELL_HACK) && defined(DEBUG) && defined(XP_UNIX) michael@0: if ((flags & (JSRESOLVE_QUALIFIED | JSRESOLVE_ASSIGNING)) == 0) { michael@0: /* michael@0: * Do this expensive hack only for unoptimized Unix builds, which are michael@0: * not used for benchmarking. michael@0: */ michael@0: char *path, *comp, *full; michael@0: const char *name; michael@0: JSBool ok, found; michael@0: JSFunction *fun; michael@0: michael@0: if (!JSVAL_IS_STRING(id)) michael@0: return JS_TRUE; michael@0: path = getenv("PATH"); michael@0: if (!path) michael@0: return JS_TRUE; michael@0: path = JS_strdup(cx, path); michael@0: if (!path) michael@0: return JS_FALSE; michael@0: name = JS_GetStringBytes(JSVAL_TO_STRING(id)); michael@0: ok = JS_TRUE; michael@0: for (comp = strtok(path, ":"); comp; comp = strtok(NULL, ":")) { michael@0: if (*comp != '\0') { michael@0: full = JS_smprintf("%s/%s", comp, name); michael@0: if (!full) { michael@0: JS_ReportOutOfMemory(cx); michael@0: ok = JS_FALSE; michael@0: break; michael@0: } michael@0: } else { michael@0: full = (char *)name; michael@0: } michael@0: found = (access(full, X_OK) == 0); michael@0: if (*comp != '\0') michael@0: free(full); michael@0: if (found) { michael@0: fun = JS_DefineFunction(cx, obj, name, Exec, 0, JSPROP_ENUMERATE); michael@0: ok = (fun != NULL); michael@0: if (ok) michael@0: *objp = obj; michael@0: break; michael@0: } michael@0: } michael@0: JS_free(cx, path); michael@0: return ok; michael@0: } michael@0: #else michael@0: return JS_TRUE; michael@0: #endif michael@0: } michael@0: michael@0: JSClass global_class = { michael@0: "global", JSCLASS_NEW_RESOLVE, michael@0: JS_PropertyStub, JS_PropertyStub, michael@0: JS_PropertyStub, JS_PropertyStub, michael@0: global_enumerate, (JSResolveOp) global_resolve, michael@0: JS_ConvertStub, JS_FinalizeStub michael@0: }; michael@0: michael@0: SkJS::SkJS(void* hwnd) : SkOSWindow(hwnd) { michael@0: if ((fRuntime = JS_NewRuntime(0x100000)) == NULL) { michael@0: SkASSERT(0); michael@0: return; michael@0: } michael@0: if ((fContext = JS_NewContext(fRuntime, 0x1000)) == NULL) { michael@0: SkASSERT(0); michael@0: return; michael@0: } michael@0: ; michael@0: if ((fGlobal = JS_NewObject(fContext, &global_class, NULL, NULL)) == NULL) { michael@0: SkASSERT(0); michael@0: return; michael@0: } michael@0: if (JS_InitStandardClasses(fContext, fGlobal) == NULL) { michael@0: SkASSERT(0); michael@0: return; michael@0: } michael@0: setConfig(SkBitmap::kARGB32_Config); michael@0: updateSize(); michael@0: setVisibleP(true); michael@0: InitializeDisplayables(getBitmap(), fContext, fGlobal, NULL); michael@0: } michael@0: michael@0: SkJS::~SkJS() { michael@0: DisposeDisplayables(); michael@0: JS_DestroyContext(fContext); michael@0: JS_DestroyRuntime(fRuntime); michael@0: JS_ShutDown(); michael@0: } michael@0: michael@0: SkBool SkJS::EvaluateScript(const char* script, jsval* rVal) { michael@0: return JS_EvaluateScript(fContext, fGlobal, script, strlen(script), michael@0: "memory" /* no file name */, 0 /* no line number */, rVal); michael@0: } michael@0: michael@0: SkBool SkJS::ValueToString(jsval value, SkString* string) { michael@0: JSString* str = JS_ValueToString(fContext, value); michael@0: if (str == NULL) michael@0: return false; michael@0: string->set(JS_GetStringBytes(str)); michael@0: return true; michael@0: } michael@0: michael@0: #ifdef SK_DEBUG michael@0: void SkJS::Test(void* hwnd) { michael@0: SkJS js(hwnd); michael@0: jsval val; michael@0: SkBool success = js.EvaluateScript("22/7", &val); michael@0: SkASSERT(success); michael@0: SkString string; michael@0: success = js.ValueToString(val, &string); michael@0: SkASSERT(success); michael@0: SkASSERT(strcmp(string.c_str(), "3.142857142857143") == 0); michael@0: success = js.EvaluateScript( michael@0: "var rect = new rectangle();" michael@0: "rect.left = 4;" michael@0: "rect.top = 10;" michael@0: "rect.right = 20;" michael@0: "rect.bottom = 30;" michael@0: "rect.width = rect.height + 20;" michael@0: "rect.draw();" michael@0: , &val); michael@0: SkASSERT(success); michael@0: success = js.ValueToString(val, &string); michael@0: SkASSERT(success); michael@0: } michael@0: #endifASSERT(success);