1 module javascriptcore.Context; 2 3 private import glib.ConstructionException; 4 private import glib.Str; 5 private import gobject.ObjectG; 6 private import javascriptcore.Class; 7 private import javascriptcore.Exception; 8 private import javascriptcore.Value; 9 private import javascriptcore.VirtualMachine; 10 private import javascriptcore.c.functions; 11 public import javascriptcore.c.types; 12 13 14 /** 15 * JSCContext represents a JavaScript execution context, where all operations 16 * take place and where the values will be associated. 17 * 18 * When a new context is created, a global object is allocated and the built-in JavaScript 19 * objects (Object, Function, String, Array) are populated. You can execute JavaScript in 20 * the context by using jsc_context_evaluate() or jsc_context_evaluate_with_source_uri(). 21 * It's also possible to register custom objects in the context with jsc_context_register_class(). 22 */ 23 public class Context : ObjectG 24 { 25 /** the main Gtk struct */ 26 protected JSCContext* jSCContext; 27 28 /** Get the main Gtk struct */ 29 public JSCContext* getContextStruct(bool transferOwnership = false) 30 { 31 if (transferOwnership) 32 ownedRef = false; 33 return jSCContext; 34 } 35 36 /** the main Gtk struct as a void* */ 37 protected override void* getStruct() 38 { 39 return cast(void*)jSCContext; 40 } 41 42 /** 43 * Sets our main struct and passes it to the parent class. 44 */ 45 public this (JSCContext* jSCContext, bool ownedRef = false) 46 { 47 this.jSCContext = jSCContext; 48 super(cast(GObject*)jSCContext, ownedRef); 49 } 50 51 52 /** */ 53 public static GType getType() 54 { 55 return jsc_context_get_type(); 56 } 57 58 /** 59 * Create a new #JSCContext. The context is created in a new #JSCVirtualMachine. 60 * Use jsc_context_new_with_virtual_machine() to create a new #JSCContext in an 61 * existing #JSCVirtualMachine. 62 * 63 * Returns: the newly created #JSCContext. 64 * 65 * Throws: ConstructionException GTK+ fails to create the object. 66 */ 67 public this() 68 { 69 auto __p = jsc_context_new(); 70 71 if(__p is null) 72 { 73 throw new ConstructionException("null returned by new"); 74 } 75 76 this(cast(JSCContext*) __p, true); 77 } 78 79 /** 80 * Create a new #JSCContext in @virtual_machine. 81 * 82 * Params: 83 * vm = a #JSCVirtualMachine 84 * 85 * Returns: the newly created #JSCContext. 86 * 87 * Throws: ConstructionException GTK+ fails to create the object. 88 */ 89 public this(VirtualMachine vm) 90 { 91 auto __p = jsc_context_new_with_virtual_machine((vm is null) ? null : vm.getVirtualMachineStruct()); 92 93 if(__p is null) 94 { 95 throw new ConstructionException("null returned by new_with_virtual_machine"); 96 } 97 98 this(cast(JSCContext*) __p, true); 99 } 100 101 /** 102 * Get the #JSCContext that is currently executing a function. This should only be 103 * called within a function or method callback, otherwise %NULL will be returned. 104 * 105 * Returns: the #JSCContext that is currently executing. 106 */ 107 public static Context getCurrent() 108 { 109 auto __p = jsc_context_get_current(); 110 111 if(__p is null) 112 { 113 return null; 114 } 115 116 return ObjectG.getDObject!(Context)(cast(JSCContext*) __p); 117 } 118 119 /** 120 * Check the given @code in @context for syntax errors. The @line_number is the starting line number in @uri; 121 * the value is one-based so the first line is 1. @uri and @line_number are only used to fill the @exception. 122 * In case of errors @exception will be set to a new #JSCException with the details. You can pass %NULL to 123 * @exception to ignore the error details. 124 * 125 * Params: 126 * code = a JavaScript script to check 127 * length = length of @code, or -1 if @code is a nul-terminated string 128 * mode = a #JSCCheckSyntaxMode 129 * uri = the source URI 130 * lineNumber = the starting line number 131 * exception = return location for a #JSCException, or %NULL to ignore 132 * 133 * Returns: a #JSCCheckSyntaxResult 134 */ 135 public JSCCheckSyntaxResult checkSyntax(string code, ptrdiff_t length, JSCCheckSyntaxMode mode, string uri, uint lineNumber, out JException exception) 136 { 137 JSCException* outexception = null; 138 139 auto __p = jsc_context_check_syntax(jSCContext, Str.toStringz(code), length, mode, Str.toStringz(uri), lineNumber, &outexception); 140 141 exception = ObjectG.getDObject!(JException)(outexception); 142 143 return __p; 144 } 145 146 /** 147 * Clear the uncaught exception in @context if any. 148 */ 149 public void clearException() 150 { 151 jsc_context_clear_exception(jSCContext); 152 } 153 154 /** 155 * Evaluate @code in @context. 156 * 157 * Params: 158 * code = a JavaScript script to evaluate 159 * length = length of @code, or -1 if @code is a nul-terminated string 160 * 161 * Returns: a #JSCValue representing the last value generated by the script. 162 */ 163 public Value evaluate(string code, ptrdiff_t length) 164 { 165 auto __p = jsc_context_evaluate(jSCContext, Str.toStringz(code), length); 166 167 if(__p is null) 168 { 169 return null; 170 } 171 172 return ObjectG.getDObject!(Value)(cast(JSCValue*) __p, true); 173 } 174 175 /** 176 * Evaluate @code and create an new object where symbols defined in @code will be added as properties, 177 * instead of being added to @context global object. The new object is returned as @object parameter. 178 * Similar to how jsc_value_new_object() works, if @object_instance is not %NULL @object_class must be provided too. 179 * The @line_number is the starting line number in @uri; the value is one-based so the first line is 1. 180 * @uri and @line_number will be shown in exceptions and they don't affect the behavior of the script. 181 * 182 * Params: 183 * code = a JavaScript script to evaluate 184 * length = length of @code, or -1 if @code is a nul-terminated string 185 * objectInstance = an object instance 186 * objectClass = a #JSCClass or %NULL to use the default 187 * uri = the source URI 188 * lineNumber = the starting line number 189 * object = return location for a #JSCValue. 190 * 191 * Returns: a #JSCValue representing the last value generated by the script. 192 */ 193 public Value evaluateInObject(string code, ptrdiff_t length, void* objectInstance, Class objectClass, string uri, uint lineNumber, out Value object) 194 { 195 JSCValue* outobject = null; 196 197 auto __p = jsc_context_evaluate_in_object(jSCContext, Str.toStringz(code), length, objectInstance, (objectClass is null) ? null : objectClass.getClassStruct(), Str.toStringz(uri), lineNumber, &outobject); 198 199 object = ObjectG.getDObject!(Value)(outobject); 200 201 if(__p is null) 202 { 203 return null; 204 } 205 206 return ObjectG.getDObject!(Value)(cast(JSCValue*) __p, true); 207 } 208 209 /** 210 * Evaluate @code in @context using @uri as the source URI. The @line_number is the starting line number 211 * in @uri; the value is one-based so the first line is 1. @uri and @line_number will be shown in exceptions and 212 * they don't affect the behavior of the script. 213 * 214 * Params: 215 * code = a JavaScript script to evaluate 216 * length = length of @code, or -1 if @code is a nul-terminated string 217 * uri = the source URI 218 * lineNumber = the starting line number 219 * 220 * Returns: a #JSCValue representing the last value generated by the script. 221 */ 222 public Value evaluateWithSourceUri(string code, ptrdiff_t length, string uri, uint lineNumber) 223 { 224 auto __p = jsc_context_evaluate_with_source_uri(jSCContext, Str.toStringz(code), length, Str.toStringz(uri), lineNumber); 225 226 if(__p is null) 227 { 228 return null; 229 } 230 231 return ObjectG.getDObject!(Value)(cast(JSCValue*) __p, true); 232 } 233 234 /** 235 * Get the last unhandled exception thrown in @context by API functions calls. 236 * 237 * Returns: a #JSCException or %NULL if there isn't any 238 * unhandled exception in the #JSCContext. 239 */ 240 public JException getException() 241 { 242 auto __p = jsc_context_get_exception(jSCContext); 243 244 if(__p is null) 245 { 246 return null; 247 } 248 249 return ObjectG.getDObject!(JException)(cast(JSCException*) __p); 250 } 251 252 /** 253 * Get a #JSCValue referencing the @context global object 254 * 255 * Returns: a #JSCValue 256 */ 257 public Value getGlobalObject() 258 { 259 auto __p = jsc_context_get_global_object(jSCContext); 260 261 if(__p is null) 262 { 263 return null; 264 } 265 266 return ObjectG.getDObject!(Value)(cast(JSCValue*) __p, true); 267 } 268 269 /** 270 * Get a property of @context global object with @name. 271 * 272 * Params: 273 * name = the value name 274 * 275 * Returns: a #JSCValue 276 */ 277 public Value getValue(string name) 278 { 279 auto __p = jsc_context_get_value(jSCContext, Str.toStringz(name)); 280 281 if(__p is null) 282 { 283 return null; 284 } 285 286 return ObjectG.getDObject!(Value)(cast(JSCValue*) __p, true); 287 } 288 289 /** 290 * Get the #JSCVirtualMachine where @context was created. 291 * 292 * Returns: the #JSCVirtualMachine where the #JSCContext was created. 293 */ 294 public VirtualMachine getVirtualMachine() 295 { 296 auto __p = jsc_context_get_virtual_machine(jSCContext); 297 298 if(__p is null) 299 { 300 return null; 301 } 302 303 return ObjectG.getDObject!(VirtualMachine)(cast(JSCVirtualMachine*) __p); 304 } 305 306 /** 307 * Remove the last #JSCExceptionHandler previously pushed to @context with 308 * jsc_context_push_exception_handler(). 309 */ 310 public void popExceptionHandler() 311 { 312 jsc_context_pop_exception_handler(jSCContext); 313 } 314 315 /** 316 * Push an exception handler in @context. Whenever a JavaScript exception happens in 317 * the #JSCContext, the given @handler will be called. The default #JSCExceptionHandler 318 * simply calls jsc_context_throw_exception() to throw the exception to the #JSCContext. 319 * If you don't want to catch the exception, but only get notified about it, call 320 * jsc_context_throw_exception() in @handler like the default one does. 321 * The last exception handler pushed is the only one used by the #JSCContext, use 322 * jsc_context_pop_exception_handler() to remove it and set the previous one. When @handler 323 * is removed from the context, @destroy_notify i called with @user_data as parameter. 324 * 325 * Params: 326 * handler = a #JSCExceptionHandler 327 * userData = user data to pass to @handler 328 * destroyNotify = destroy notifier for @user_data 329 */ 330 public void pushExceptionHandler(JSCExceptionHandler handler, void* userData, GDestroyNotify destroyNotify) 331 { 332 jsc_context_push_exception_handler(jSCContext, handler, userData, destroyNotify); 333 } 334 335 /** 336 * Register a custom class in @context using the given @name. If the new class inherits from 337 * another #JSCClass, the parent should be passed as @parent_class, otherwise %NULL should be 338 * used. The optional @vtable parameter allows to provide a custom implementation for handling 339 * the class, for example, to handle external properties not added to the prototype. 340 * When an instance of the #JSCClass is cleared in the context, @destroy_notify is called with 341 * the instance as parameter. 342 * 343 * Params: 344 * name = the class name 345 * parentClass = a #JSCClass or %NULL 346 * vtable = an optional #JSCClassVTable or %NULL 347 * destroyNotify = a destroy notifier for class instances 348 * 349 * Returns: a #JSCClass 350 */ 351 public Class registerClass(string name, Class parentClass, JSCClassVTable* vtable, GDestroyNotify destroyNotify) 352 { 353 auto __p = jsc_context_register_class(jSCContext, Str.toStringz(name), (parentClass is null) ? null : parentClass.getClassStruct(), vtable, destroyNotify); 354 355 if(__p is null) 356 { 357 return null; 358 } 359 360 return ObjectG.getDObject!(Class)(cast(JSCClass*) __p); 361 } 362 363 /** 364 * Set a property of @context global object with @name and @value. 365 * 366 * Params: 367 * name = the value name 368 * value = a #JSCValue 369 */ 370 public void setValue(string name, Value value) 371 { 372 jsc_context_set_value(jSCContext, Str.toStringz(name), (value is null) ? null : value.getValueStruct()); 373 } 374 375 /** 376 * Throw an exception to @context using the given error message. The created #JSCException 377 * can be retrieved with jsc_context_get_exception(). 378 * 379 * Params: 380 * errorMessage = an error message 381 */ 382 public void throwMessage(string errorMessage) 383 { 384 jsc_context_throw(jSCContext, Str.toStringz(errorMessage)); 385 } 386 387 /** 388 * Throw @exception to @context. 389 * 390 * Params: 391 * exception = a #JSCException 392 */ 393 public void throwException(JException exception) 394 { 395 jsc_context_throw_exception(jSCContext, (exception is null) ? null : exception.getExceptionStruct()); 396 } 397 398 /** 399 * Throw an exception to @context using the given error name and message. The created #JSCException 400 * can be retrieved with jsc_context_get_exception(). 401 * 402 * Params: 403 * errorName = the error name 404 * errorMessage = an error message 405 */ 406 public void throwWithName(string errorName, string errorMessage) 407 { 408 jsc_context_throw_with_name(jSCContext, Str.toStringz(errorName), Str.toStringz(errorMessage)); 409 } 410 }