|
18 | 18 |
|
19 | 19 | #include "common/luajs.h" |
20 | 20 |
|
21 | | -gchar* |
22 | | -tostring(JSContextRef context, JSValueRef value, gchar **error) |
23 | | -{ |
24 | | - JSStringRef str = JSValueToStringCopy(context, value, NULL); |
25 | | - if (!str) { |
26 | | - if (error) |
27 | | - *error = g_strdup("string conversion failed"); |
28 | | - return NULL; |
29 | | - } |
30 | | - size_t size = JSStringGetMaximumUTF8CStringSize(str); |
31 | | - gchar *ret = g_malloc(sizeof(gchar)*size); |
32 | | - JSStringGetUTF8CString(str, ret, size); |
33 | | - JSStringRelease(str); |
34 | | - return ret; |
35 | | -} |
36 | | - |
37 | | -gint |
38 | | -luaJS_pushstring(lua_State *L, JSContextRef context, JSValueRef value, gchar **error) |
39 | | -{ |
40 | | - gchar *str = tostring(context, value, error); |
41 | | - if (str) { |
42 | | - lua_pushstring(L, str); |
43 | | - g_free(str); |
44 | | - return 1; |
45 | | - } |
46 | | - return 0; |
47 | | -} |
48 | | - |
49 | | -gint |
50 | | -luaJS_pushobject(lua_State *L, JSContextRef context, JSObjectRef obj, gchar **error) |
51 | | -{ |
52 | | - gint top = lua_gettop(L); |
53 | | - |
54 | | - JSPropertyNameArrayRef keys = JSObjectCopyPropertyNames(context, obj); |
55 | | - size_t count = JSPropertyNameArrayGetCount(keys); |
56 | | - JSValueRef exception = NULL; |
57 | | - |
58 | | - lua_newtable(L); |
59 | | - |
60 | | - for (size_t i = 0; i < count; i++) { |
61 | | - /* push table key onto stack */ |
62 | | - JSStringRef key = JSPropertyNameArrayGetNameAtIndex(keys, i); |
63 | | - size_t slen = JSStringGetMaximumUTF8CStringSize(key); |
64 | | - gchar cstr[slen]; |
65 | | - JSStringGetUTF8CString(key, cstr, slen); |
66 | | - |
67 | | - gchar *eptr = NULL; |
68 | | - int n = strtol(cstr, &eptr, 10); |
69 | | - if (!*eptr) /* end at '\0' ? == it's a number! */ |
70 | | - lua_pushinteger(L, ++n); /* 0-index array to 1-index array */ |
71 | | - else |
72 | | - lua_pushstring(L, cstr); |
73 | | - |
74 | | - /* push table value into stack */ |
75 | | - JSValueRef val = JSObjectGetProperty(context, obj, key, &exception); |
76 | | - if (exception) { |
77 | | - lua_settop(L, top); |
78 | | - if (error) { |
79 | | - gchar *err = tostring(context, exception, NULL); |
80 | | - *error = g_strdup_printf("JSObjectGetProperty call failed (%s)", |
81 | | - err ? err : "unknown reason"); |
82 | | - g_free(err); |
83 | | - } |
84 | | - JSPropertyNameArrayRelease(keys); |
85 | | - return 0; |
86 | | - } |
87 | | - luaJS_pushvalue(L, context, val, error); |
88 | | - if (error && *error) { |
89 | | - lua_settop(L, top); |
90 | | - JSPropertyNameArrayRelease(keys); |
91 | | - return 0; |
92 | | - } |
93 | | - lua_rawset(L, -3); |
94 | | - } |
95 | | - JSPropertyNameArrayRelease(keys); |
96 | | - return 1; |
97 | | -} |
98 | | - |
99 | | -/* Push JavaScript value onto Lua stack */ |
100 | | -gint |
101 | | -luaJS_pushvalue(lua_State *L, JSContextRef context, JSValueRef value, gchar **error) |
102 | | -{ |
103 | | - switch (JSValueGetType(context, value)) { |
104 | | - case kJSTypeBoolean: |
105 | | - lua_pushboolean(L, JSValueToBoolean(context, value)); |
106 | | - return 1; |
107 | | - |
108 | | - case kJSTypeNumber: |
109 | | - lua_pushnumber(L, JSValueToNumber(context, value, NULL)); |
110 | | - return 1; |
111 | | - |
112 | | - case kJSTypeString: |
113 | | - return luaJS_pushstring(L, context, value, error); |
114 | | - |
115 | | - case kJSTypeObject: |
116 | | - return luaJS_pushobject(L, context, (JSObjectRef)value, error); |
117 | | - |
118 | | - case kJSTypeUndefined: |
119 | | - case kJSTypeNull: |
120 | | - lua_pushnil(L); |
121 | | - return 1; |
122 | | - |
123 | | - default: |
124 | | - break; |
125 | | - } |
126 | | - if (error) |
127 | | - *error = g_strdup("Unable to convert value into equivalent Lua type"); |
128 | | - return 0; |
129 | | -} |
130 | | - |
131 | | -JSValueRef |
132 | | -luaJS_fromtable(lua_State *L, JSContextRef context, gint idx, gchar **error) |
133 | | -{ |
134 | | - gint top = lua_gettop(L); |
135 | | - |
136 | | - /* convert relative index into abs */ |
137 | | - if (idx < 0) |
138 | | - idx = top + idx + 1; |
139 | | - |
140 | | - JSValueRef exception = NULL; |
141 | | - JSObjectRef obj; |
142 | | - |
143 | | - size_t len = lua_objlen(L, idx); |
144 | | - if (len) { |
145 | | - obj = JSObjectMakeArray(context, 0, NULL, &exception); |
146 | | - if (exception) { |
147 | | - if (error) { |
148 | | - gchar *err = tostring(context, exception, NULL); |
149 | | - *error = g_strdup_printf("JSObjectMakeArray call failed (%s)", |
150 | | - err ? err : "unknown reason"); |
151 | | - g_free(err); |
152 | | - } |
153 | | - return NULL; |
154 | | - } |
155 | | - |
156 | | - lua_pushnil(L); |
157 | | - for (guint i = 0; lua_next(L, idx); i++) { |
158 | | - JSValueRef val = luaJS_tovalue(L, context, -1, error); |
159 | | - if (error && *error) { |
160 | | - lua_settop(L, top); |
161 | | - return NULL; |
162 | | - } |
163 | | - lua_pop(L, 1); |
164 | | - JSObjectSetPropertyAtIndex(context, obj, i, val, &exception); |
165 | | - } |
166 | | - } else { |
167 | | - obj = JSObjectMake(context, NULL, NULL); |
168 | | - lua_pushnil(L); |
169 | | - while (lua_next(L, idx)) { |
170 | | - /* We only care about string attributes in the table */ |
171 | | - if (lua_type(L, -2) == LUA_TSTRING) { |
172 | | - JSValueRef val = luaJS_tovalue(L, context, -1, error); |
173 | | - if (error && *error) { |
174 | | - lua_settop(L, top); |
175 | | - return NULL; |
176 | | - } |
177 | | - JSStringRef key = JSStringCreateWithUTF8CString(lua_tostring(L, -2)); |
178 | | - JSObjectSetProperty(context, obj, key, val, |
179 | | - kJSPropertyAttributeNone, &exception); |
180 | | - JSStringRelease(key); |
181 | | - if (exception) { |
182 | | - if (error) { |
183 | | - gchar *err = tostring(context, exception, NULL); |
184 | | - *error = g_strdup_printf("JSObjectSetProperty call failed (%s)", |
185 | | - err ? err : "unknown reason"); |
186 | | - g_free(err); |
187 | | - } |
188 | | - return NULL; |
189 | | - } |
190 | | - } |
191 | | - lua_pop(L, 1); |
192 | | - } |
193 | | - } |
194 | | - return obj; |
195 | | -} |
196 | | - |
197 | | -/* Make JavaScript value from Lua value */ |
198 | | -JSValueRef |
199 | | -luaJS_tovalue(lua_State *L, JSContextRef context, gint idx, gchar **error) |
200 | | -{ |
201 | | - JSStringRef str; |
202 | | - JSValueRef ret; |
203 | | - |
204 | | - switch (lua_type(L, idx)) { |
205 | | - case LUA_TBOOLEAN: |
206 | | - return JSValueMakeBoolean(context, lua_toboolean(L, idx)); |
207 | | - |
208 | | - case LUA_TNUMBER: |
209 | | - return JSValueMakeNumber(context, lua_tonumber(L, idx)); |
210 | | - |
211 | | - case LUA_TNIL: |
212 | | - return JSValueMakeNull(context); |
213 | | - |
214 | | - case LUA_TNONE: |
215 | | - return JSValueMakeUndefined(context); |
216 | | - |
217 | | - case LUA_TSTRING: |
218 | | - str = JSStringCreateWithUTF8CString(lua_tostring(L, idx)); |
219 | | - ret = JSValueMakeString(context, str); |
220 | | - JSStringRelease(str); |
221 | | - return ret; |
222 | | - |
223 | | - case LUA_TTABLE: |
224 | | - return luaJS_fromtable(L, context, idx, error); |
225 | | - |
226 | | - default: |
227 | | - break; |
228 | | - } |
229 | | - |
230 | | - if (error) |
231 | | - *error = g_strdup_printf("unhandled Lua->JS type conversion (type %s)", |
232 | | - lua_typename(L, lua_type(L, idx))); |
233 | | - return JSValueMakeUndefined(context); |
234 | | -} |
235 | | - |
236 | 21 | /* |
237 | 22 | * Converts Lua value referenced by idx to the corresponding JavaScript type. |
238 | 23 | * Returns NULL on failure. |
@@ -296,16 +81,6 @@ JSCValue *luajs_tovalue(lua_State *L, int idx, JSCContext *ctx) |
296 | 81 | return NULL; |
297 | 82 | } |
298 | 83 |
|
299 | | -/* create JavaScript exception object from string */ |
300 | | -JSValueRef |
301 | | -luaJS_make_exception(JSContextRef context, const gchar *error) |
302 | | -{ |
303 | | - JSStringRef estr = JSStringCreateWithUTF8CString(error); |
304 | | - JSValueRef exception = JSValueMakeString(context, estr); |
305 | | - JSStringRelease(estr); |
306 | | - return JSValueToObject(context, exception, NULL); |
307 | | -} |
308 | | - |
309 | 84 | /* |
310 | 85 | * Converts JS value to the corresponding Lua type and pushes the result onto |
311 | 86 | * the Lua stack. Returns the number of pushed values, 0 thus signals error. |
|
0 commit comments