]> err.no Git - sope/blob - skyrix-sope/NGJavaScript/NGJavaScriptLanguage.m
added svn:keywords and svn:ignore where appropriate. removed CVS artifacts.
[sope] / skyrix-sope / NGJavaScript / NGJavaScriptLanguage.m
1 /*
2   Copyright (C) 2000-2003 SKYRIX Software AG
3
4   This file is part of OGo
5
6   OGo is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with OGo; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21 // $Id$
22
23 #include <NGScripting/NGScriptLanguage.h>
24
25 @interface NGJavaScriptLanguage : NGScriptLanguage
26 {
27   id rootctx;
28
29
30 @end
31
32 #include "NGJavaScriptObjectMappingContext.h"
33 #include "NGJavaScriptContext.h"
34 #include "NGJavaScriptShadow.h"
35 #include "NGJavaScriptRuntime.h"
36 #include "NSObject+JS.h"
37 #include "common.h"
38
39 @implementation NGJavaScriptLanguage
40
41 - (id)initWithLanguage:(NSString *)_language {
42   if ((self = [super initWithLanguage:_language])) {
43     NSLog(@"%@", [NGJavaScriptRuntime javaScriptImplementationVersion]);
44     
45     self->rootctx = [[NGJavaScriptObjectMappingContext alloc] init];
46     [[self->rootctx jsContext] loadStandardClasses];
47     [self->rootctx pushContext];
48   }
49   return self;
50 }
51 - (void)dealloc {
52   [self->rootctx popContext];
53   [self->rootctx release];
54   [super dealloc];
55 }
56
57 - (NSString *)language {
58   return @"javascript";
59 }
60
61 - (id)evaluateScript:(NSString *)_script onObject:(id)_object 
62   source:(NSString *)_source line:(unsigned)_line
63 {
64   NGJavaScriptObjectMappingContext *mctx;
65   JSBool      res;
66   jsval       lastValue;
67   void        *jso;
68   void        *cx;
69   NSException *e;
70   const char *srcname = NULL;
71   
72   mctx = [NGJavaScriptObjectMappingContext activeObjectMappingContext];
73   NSAssert(mctx, @"no javascript mapping context is active !");
74   
75   jso = [mctx handleForObject:_object];
76   NSAssert(jso, @"missing JS object ..");
77   
78   cx = [[mctx jsContext] handle];
79   
80   if ([_source hasPrefix:@"file://"])
81     _source = [_source substringFromIndex:7];
82   // TODO: use buffer
83   srcname = [_source cString];
84   
85 #if 0
86   NSLog(@"%s:%i eval script on objc=0x%08X js=0x%08X cx=0x%08X", 
87         [_source cString], _line,
88         _object, jso, cx);
89 #endif
90   
91   res = JS_EvaluateScript(cx, jso,
92                           [_script cString],
93                           [_script cStringLength],
94                           srcname, /* source file */
95                           _line,   /* line number */
96                           &lastValue);
97   
98   if (res == JS_TRUE)
99     return [mctx objectForJSValue:&lastValue];
100   
101   if ([(e = [[mctx jsContext] lastError]) retain]) {
102     
103     [[mctx jsContext] clearLastError];
104     [[mctx jsContext] collectGarbage];
105     //[[mctx jsContext] collectGarbage];
106     //[[mctx jsContext] collectGarbage];
107     
108     [e raise];
109   }
110   
111   {
112     NSDictionary *ui;
113     
114     ui = [NSDictionary dictionaryWithObjectsAndKeys:
115                          _script,             @"script",
116                          _object,             @"objectHandler",
117                          [NGJavaScriptContext jsContextForHandle:cx],
118                            @"jscontext",
119                          nil];
120     
121     e = [[NSException alloc] initWithName:@"JavaScriptEvalException"
122                              reason:@"couldn't evaluate script"
123                              userInfo:ui];
124     [e raise];
125   }
126   return nil;
127 }
128
129 /* functions */
130
131 - (id)callFunction:(NSString *)_func onObject:(id)_object {
132   NGJavaScriptObjectMappingContext *mctx;
133   JSBool ret;
134   void   *jso;
135   jsval  result;
136   
137   mctx = [NGJavaScriptObjectMappingContext activeObjectMappingContext];
138   NSAssert(mctx, @"no javascript mapping context is active !");
139   
140   jso = [mctx handleForObject:_object];
141   NSAssert(jso, @"missing JS object ..");
142   
143   ret = JS_CallFunctionName([[mctx jsContext] handle],
144                             jso,
145                             [_func cString],
146                             0 /* argc */, NULL /* argv */,
147                             &result);
148   if (ret == JS_TRUE)
149     return [mctx objectForJSValue:&result];
150   
151   NSLog(@"%s: couldn't run function %@", __PRETTY_FUNCTION__, _func);
152   return nil;
153 }
154
155 - (id)callFunction:(NSString *)_func
156   withArgument:(id)_arg0
157   onObject:(id)_object 
158 {
159   NGJavaScriptObjectMappingContext *mctx;
160   JSBool ret;
161   void   *jso;
162   jsval  result;
163   jsval  argv[1];
164   
165   mctx = [NGJavaScriptObjectMappingContext activeObjectMappingContext];
166   NSAssert(mctx, @"no javascript mapping context is active !");
167   
168   jso = [mctx handleForObject:_object];
169   NSAssert(jso, @"missing JS object ..");
170   
171   if (![mctx jsValue:&(argv[0]) forObject:_arg0]) {
172     NSLog(@"%s: couldn't get value for first function argument ..",
173           __PRETTY_FUNCTION__);
174     return nil;
175   }
176   
177   ret = JS_CallFunctionName([[mctx jsContext] handle],
178                             jso,
179                             [_func cString],
180                             1, argv,
181                             &result);
182   if (ret == JS_TRUE)
183     return [mctx objectForJSValue:&result];
184   
185   NSLog(@"%s: couldn't run function %@", __PRETTY_FUNCTION__, _func);
186   return nil;
187 }
188 - (id)callFunction:(NSString *)_func
189   withArgument:(id)_arg0
190   withArgument:(id)_arg1
191   onObject:(id)_object 
192 {
193   NGJavaScriptObjectMappingContext *mctx;
194   JSBool ret;
195   void   *jso;
196   jsval  result;
197   jsval  argv[2];
198   
199   mctx = [NGJavaScriptObjectMappingContext activeObjectMappingContext];
200   NSAssert(mctx, @"no javascript mapping context is active !");
201   
202   jso = [mctx handleForObject:_object];
203   NSAssert(jso, @"missing JS object ..");
204   
205   if (![mctx jsValue:&(argv[0]) forObject:_arg0]) {
206     NSLog(@"%s: couldn't get value for first function argument ..",
207           __PRETTY_FUNCTION__);
208     return nil;
209   }
210   
211   if (![mctx jsValue:&(argv[1]) forObject:_arg1]) {
212     NSLog(@"%s: couldn't get value for second function argument ..",
213           __PRETTY_FUNCTION__);
214     return nil;
215   }
216   
217   ret = JS_CallFunctionName([[mctx jsContext] handle],
218                             jso,
219                             [_func cString],
220                             2, argv,
221                             &result);
222   if (ret == JS_TRUE)
223     return [mctx objectForJSValue:&result];
224   
225   NSLog(@"%s: couldn't run function %@", __PRETTY_FUNCTION__, _func);
226   return nil;
227 }
228
229 /* reflection */
230
231 - (BOOL)object:(id)_object hasFunctionNamed:(NSString *)_name {
232   return [_object hasFunctionNamed:_name];
233 }
234
235 /* shadow objects */
236
237 - (id)createShadowForMaster:(id)_master {
238   NGJavaScriptShadow *shadow;
239   
240   if (_master == nil)
241     /* no shadow without a master ... */
242     return nil;
243   
244   if ((shadow = [[NGJavaScriptShadow alloc] init]) == nil) {
245     NSLog(@"%s: could not create shadow for master %@", 
246           __PRETTY_FUNCTION__, _master);
247     return nil;
248   }
249   
250   [shadow setMasterObject:_master];
251   
252   return shadow; /* returns a retained object */
253 }
254
255 /* mapping ctx */
256
257 - (NGObjectMappingContext *)createMappingContext {
258   NGJavaScriptObjectMappingContext *ctx;
259   
260   ctx = [[NGJavaScriptObjectMappingContext alloc] init];
261   [[ctx jsContext] loadStandardClasses];
262   return ctx;
263 }
264
265 @end /* NGJavaScriptLanguage */