+(define-builtin new ()
+ '(object))
+
+(define-raw-builtin oget* (object key &rest keys)
+ `(selfcall
+ (progn
+ (var (tmp (property ,(convert object) (call |xstring| ,(convert key)))))
+ ,@(mapcar (lambda (key)
+ `(progn
+ (if (=== tmp undefined) (return ,(convert nil)))
+ (= tmp (property tmp (call |xstring| ,(convert key))))))
+ keys))
+ (return (if (=== tmp undefined) ,(convert nil) tmp))))
+
+(define-raw-builtin oset* (value object key &rest keys)
+ (let ((keys (cons key keys)))
+ `(selfcall
+ (progn
+ (var (obj ,(convert object)))
+ ,@(mapcar (lambda (key)
+ `(progn
+ (= obj (property obj (call |xstring| ,(convert key))))
+ (if (=== object undefined)
+ (throw "Impossible to set object property."))))
+ (butlast keys))
+ (var (tmp
+ (= (property obj (call |xstring| ,(convert (car (last keys)))))
+ ,(convert value))))
+ (return (if (=== tmp undefined)
+ ,(convert nil)
+ tmp))))))
+
+(define-raw-builtin oget (object key &rest keys)
+ `(call |js_to_lisp| ,(convert `(oget* ,object ,key ,@keys))))
+
+(define-raw-builtin oset (value object key &rest keys)
+ (convert `(oset* (lisp-to-js ,value) ,object ,key ,@keys)))
+
+(define-builtin objectp (x)
+ `(bool (=== (typeof ,x) "object")))
+
+(define-builtin lisp-to-js (x) `(call |lisp_to_js| ,x))
+(define-builtin js-to-lisp (x) `(call |js_to_lisp| ,x))
+
+
+(define-builtin in (key object)
+ `(bool (in (call |xstring| ,key) ,object)))
+
+(define-builtin map-for-in (function object)
+ `(selfcall
+ (var (f ,function)
+ (g (if (=== (typeof f) "function") f (get f "fvalue")))
+ (o ,object))
+ (for-in (key o)
+ (call g ,(if *multiple-value-p* '|values| '|pv|) 1 (get o "key")))
+ (return ,(convert nil))))
+