Mercurial > pymonkey
annotate pymonkey.c @ 8:6647870380cc
Added support for undefined.
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Sun, 28 Jun 2009 13:32:46 -0700 |
parents | 0d0ce6415b66 |
children | 032cfc448079 |
rev | line source |
---|---|
0 | 1 #include "jsapi.h" |
2 #include <Python/Python.h> | |
3 | |
8
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
4 #define Py_RETURN_UNDEFINED { Py_INCREF(PYM_undefined); \ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
5 return PYM_undefined; } |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
6 |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
7 typedef struct { |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
8 PyObject_HEAD |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
9 } PYM_undefinedObject; |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
10 |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
11 // TODO: We should make this behave as much like JavaScript's |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
12 // "undefined" value as possible; e.g., its string value should |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
13 // be "undefined", the singleton should be falsy, etc. |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
14 static PyTypeObject PYM_undefinedType = { |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
15 PyObject_HEAD_INIT(NULL) |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
16 0, /*ob_size*/ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
17 "pymonkey.undefined", /*tp_name*/ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
18 sizeof(PYM_undefinedObject), /*tp_basicsize*/ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
19 0, /*tp_itemsize*/ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
20 0, /*tp_dealloc*/ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
21 0, /*tp_print*/ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
22 0, /*tp_getattr*/ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
23 0, /*tp_setattr*/ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
24 0, /*tp_compare*/ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
25 0, /*tp_repr*/ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
26 0, /*tp_as_number*/ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
27 0, /*tp_as_sequence*/ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
28 0, /*tp_as_mapping*/ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
29 0, /*tp_hash */ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
30 0, /*tp_call*/ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
31 0, /*tp_str*/ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
32 0, /*tp_getattro*/ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
33 0, /*tp_setattro*/ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
34 0, /*tp_as_buffer*/ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
35 Py_TPFLAGS_DEFAULT, /*tp_flags*/ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
36 /* tp_doc */ |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
37 "Pythonic equivalent of JavaScript's 'undefined' value", |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
38 }; |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
39 |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
40 static PyObject *PYM_undefined = (PyObject *) &PYM_undefinedType; |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
41 |
2
2f6bdc9f7245
pymonkey.evaluate() now returns a python-ized version of the JS return value, though it only supports integers at the moment.
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
42 static JSClass PYM_jsGlobalClass = { |
0 | 43 "PymonkeyGlobal", JSCLASS_GLOBAL_FLAGS, |
44 JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, | |
45 JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, | |
46 JSCLASS_NO_OPTIONAL_MEMBERS | |
47 }; | |
48 | |
49 static PyObject *PYM_error; | |
50 | |
51 static PyObject * | |
2
2f6bdc9f7245
pymonkey.evaluate() now returns a python-ized version of the JS return value, though it only supports integers at the moment.
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
52 PYM_jsvalToPyObject(jsval value) { |
2f6bdc9f7245
pymonkey.evaluate() now returns a python-ized version of the JS return value, though it only supports integers at the moment.
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
53 if (JSVAL_IS_INT(value)) |
2f6bdc9f7245
pymonkey.evaluate() now returns a python-ized version of the JS return value, though it only supports integers at the moment.
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
54 return PyInt_FromLong(JSVAL_TO_INT(value)); |
2f6bdc9f7245
pymonkey.evaluate() now returns a python-ized version of the JS return value, though it only supports integers at the moment.
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
55 |
3
d6a0819ca6ca
Added return value support for doubles.
Atul Varma <varmaa@toolness.com>
parents:
2
diff
changeset
|
56 if (JSVAL_IS_DOUBLE(value)) { |
d6a0819ca6ca
Added return value support for doubles.
Atul Varma <varmaa@toolness.com>
parents:
2
diff
changeset
|
57 jsdouble *doubleRef = JSVAL_TO_DOUBLE(value); |
d6a0819ca6ca
Added return value support for doubles.
Atul Varma <varmaa@toolness.com>
parents:
2
diff
changeset
|
58 return PyFloat_FromDouble(*doubleRef); |
d6a0819ca6ca
Added return value support for doubles.
Atul Varma <varmaa@toolness.com>
parents:
2
diff
changeset
|
59 } |
d6a0819ca6ca
Added return value support for doubles.
Atul Varma <varmaa@toolness.com>
parents:
2
diff
changeset
|
60 |
5 | 61 if (value == JSVAL_FALSE) |
62 Py_RETURN_FALSE; | |
63 | |
64 if (value == JSVAL_TRUE) | |
65 Py_RETURN_TRUE; | |
66 | |
6 | 67 if (JSVAL_IS_NULL(value)) |
68 Py_RETURN_NONE; | |
2
2f6bdc9f7245
pymonkey.evaluate() now returns a python-ized version of the JS return value, though it only supports integers at the moment.
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
69 |
8
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
70 if (JSVAL_IS_VOID(value)) |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
71 Py_RETURN_UNDEFINED; |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
72 |
7
0d0ce6415b66
Added support for unicode strings.
Atul Varma <varmaa@toolness.com>
parents:
6
diff
changeset
|
73 if (JSVAL_IS_STRING(value) && JS_CStringsAreUTF8()) { |
0d0ce6415b66
Added support for unicode strings.
Atul Varma <varmaa@toolness.com>
parents:
6
diff
changeset
|
74 // TODO: What to do if C strings aren't UTF-8? The jschar * |
0d0ce6415b66
Added support for unicode strings.
Atul Varma <varmaa@toolness.com>
parents:
6
diff
changeset
|
75 // type isn't actually UTF-16, it's just "UTF-16-ish", so |
0d0ce6415b66
Added support for unicode strings.
Atul Varma <varmaa@toolness.com>
parents:
6
diff
changeset
|
76 // there doesn't seem to be any other lossless way of |
0d0ce6415b66
Added support for unicode strings.
Atul Varma <varmaa@toolness.com>
parents:
6
diff
changeset
|
77 // transferring the string other than perhaps by transmitting |
0d0ce6415b66
Added support for unicode strings.
Atul Varma <varmaa@toolness.com>
parents:
6
diff
changeset
|
78 // its JSON representation. |
0d0ce6415b66
Added support for unicode strings.
Atul Varma <varmaa@toolness.com>
parents:
6
diff
changeset
|
79 |
0d0ce6415b66
Added support for unicode strings.
Atul Varma <varmaa@toolness.com>
parents:
6
diff
changeset
|
80 JSString *str = JSVAL_TO_STRING(value); |
0d0ce6415b66
Added support for unicode strings.
Atul Varma <varmaa@toolness.com>
parents:
6
diff
changeset
|
81 const char *bytes = JS_GetStringBytes(str); |
0d0ce6415b66
Added support for unicode strings.
Atul Varma <varmaa@toolness.com>
parents:
6
diff
changeset
|
82 const char *errors; |
0d0ce6415b66
Added support for unicode strings.
Atul Varma <varmaa@toolness.com>
parents:
6
diff
changeset
|
83 return PyUnicode_DecodeUTF8(bytes, strlen(bytes), errors); |
0d0ce6415b66
Added support for unicode strings.
Atul Varma <varmaa@toolness.com>
parents:
6
diff
changeset
|
84 } |
0d0ce6415b66
Added support for unicode strings.
Atul Varma <varmaa@toolness.com>
parents:
6
diff
changeset
|
85 |
4
2711b636f8e6
Added support for NULL return values.
Atul Varma <varmaa@toolness.com>
parents:
3
diff
changeset
|
86 // TODO: Support more types. |
2711b636f8e6
Added support for NULL return values.
Atul Varma <varmaa@toolness.com>
parents:
3
diff
changeset
|
87 PyErr_SetString(PyExc_NotImplementedError, |
2711b636f8e6
Added support for NULL return values.
Atul Varma <varmaa@toolness.com>
parents:
3
diff
changeset
|
88 "Data type conversion not implemented."); |
2
2f6bdc9f7245
pymonkey.evaluate() now returns a python-ized version of the JS return value, though it only supports integers at the moment.
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
89 } |
2f6bdc9f7245
pymonkey.evaluate() now returns a python-ized version of the JS return value, though it only supports integers at the moment.
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
90 |
2f6bdc9f7245
pymonkey.evaluate() now returns a python-ized version of the JS return value, though it only supports integers at the moment.
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
91 static PyObject * |
0 | 92 PYM_evaluate(PyObject *self, PyObject *args) |
93 { | |
94 const char *source; | |
95 int sourceLen; | |
96 const char *filename; | |
97 int lineNo; | |
98 | |
99 if (!PyArg_ParseTuple(args, "s#si", &source, &sourceLen, | |
100 &filename, &lineNo)) | |
101 return NULL; | |
102 | |
7
0d0ce6415b66
Added support for unicode strings.
Atul Varma <varmaa@toolness.com>
parents:
6
diff
changeset
|
103 if (!JS_CStringsAreUTF8()) |
0d0ce6415b66
Added support for unicode strings.
Atul Varma <varmaa@toolness.com>
parents:
6
diff
changeset
|
104 JS_SetCStringsAreUTF8(); |
0d0ce6415b66
Added support for unicode strings.
Atul Varma <varmaa@toolness.com>
parents:
6
diff
changeset
|
105 |
0 | 106 JSRuntime *rt = JS_NewRuntime(8L * 1024L * 1024L); |
107 if (rt == NULL) { | |
108 PyErr_SetString(PYM_error, "JS_NewRuntime() failed"); | |
109 return NULL; | |
110 } | |
111 | |
112 JSContext *cx = JS_NewContext(rt, 8192); | |
113 if (cx == NULL) { | |
114 PyErr_SetString(PYM_error, "JS_NewContext() failed"); | |
115 JS_DestroyRuntime(rt); | |
116 } | |
117 | |
118 JS_SetOptions(cx, JSOPTION_VAROBJFIX); | |
119 JS_SetVersion(cx, JSVERSION_LATEST); | |
120 | |
121 JS_BeginRequest(cx); | |
122 | |
2
2f6bdc9f7245
pymonkey.evaluate() now returns a python-ized version of the JS return value, though it only supports integers at the moment.
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
123 JSObject *global = JS_NewObject(cx, &PYM_jsGlobalClass, NULL, NULL); |
0 | 124 if (global == NULL) { |
125 PyErr_SetString(PYM_error, "JS_NewObject() failed"); | |
126 JS_EndRequest(cx); | |
127 JS_DestroyContext(cx); | |
128 JS_DestroyRuntime(rt); | |
129 return NULL; | |
130 } | |
131 | |
132 if (!JS_InitStandardClasses(cx, global)) { | |
133 PyErr_SetString(PYM_error, "JS_InitStandardClasses() failed"); | |
134 JS_EndRequest(cx); | |
135 JS_DestroyContext(cx); | |
136 JS_DestroyRuntime(rt); | |
137 return NULL; | |
138 } | |
139 | |
140 jsval rval; | |
141 if (!JS_EvaluateScript(cx, global, source, sourceLen, filename, | |
142 lineNo, &rval)) { | |
143 // TODO: Actually get the error that was raised. | |
144 PyErr_SetString(PYM_error, "Script failed"); | |
145 JS_EndRequest(cx); | |
146 JS_DestroyContext(cx); | |
147 JS_DestroyRuntime(rt); | |
148 return NULL; | |
149 } | |
150 | |
3
d6a0819ca6ca
Added return value support for doubles.
Atul Varma <varmaa@toolness.com>
parents:
2
diff
changeset
|
151 PyObject *pyRval = PYM_jsvalToPyObject(rval); |
d6a0819ca6ca
Added return value support for doubles.
Atul Varma <varmaa@toolness.com>
parents:
2
diff
changeset
|
152 |
0 | 153 JS_EndRequest(cx); |
154 JS_DestroyContext(cx); | |
155 JS_DestroyRuntime(rt); | |
156 | |
3
d6a0819ca6ca
Added return value support for doubles.
Atul Varma <varmaa@toolness.com>
parents:
2
diff
changeset
|
157 return pyRval; |
0 | 158 } |
159 | |
160 static PyMethodDef PYM_methods[] = { | |
161 {"evaluate", PYM_evaluate, METH_VARARGS, | |
162 "Evaluate the given JavaScript code, using the given filename " | |
163 "and line number information."}, | |
164 {NULL, NULL, 0, NULL} | |
165 }; | |
166 | |
167 PyMODINIT_FUNC | |
168 initpymonkey(void) | |
169 { | |
170 PyObject *module; | |
171 | |
172 module = Py_InitModule("pymonkey", PYM_methods); | |
173 if (module == NULL) | |
174 return; | |
175 | |
8
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
176 if (PyType_Ready(&PYM_undefinedType) < 0) |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
177 return; |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
178 |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
179 Py_INCREF(PYM_undefined); |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
180 PyModule_AddObject(module, "undefined", PYM_undefined); |
6647870380cc
Added support for undefined.
Atul Varma <varmaa@toolness.com>
parents:
7
diff
changeset
|
181 |
0 | 182 PYM_error = PyErr_NewException("pymonkey.error", NULL, NULL); |
183 Py_INCREF(PYM_error); | |
184 PyModule_AddObject(module, "error", PYM_error); | |
185 } |