+(define-builtin new () "{}")
+
+(define-raw-builtin oget* (object key &rest keys)
+ (js!selfcall
+ "var tmp = (" (ls-compile object) ")[xstring(" (ls-compile key) ")];" *newline*
+ (mapconcat (lambda (key)
+ (code "if (tmp === undefined) return " (ls-compile nil) ";" *newline*
+ "tmp = tmp[xstring(" (ls-compile key) ")];" *newline*))
+ keys)
+ "return tmp === undefined? " (ls-compile nil) " : tmp;" *newline*))
+
+(define-raw-builtin oset* (value object key &rest keys)
+ (let ((keys (cons key keys)))
+ (js!selfcall
+ "var obj = " (ls-compile object) ";" *newline*
+ (mapconcat (lambda (key)
+ (code "obj = obj[xstring(" (ls-compile key) ")];"
+ "if (obj === undefined) throw 'Impossible to set Javascript property.';" *newline*))
+ (butlast keys))
+ "var tmp = obj[xstring(" (ls-compile (car (last keys))) ")] = " (ls-compile value) ";" *newline*
+ "return tmp === undefined? " (ls-compile nil) " : tmp;" *newline*)))
+
+(define-raw-builtin oget (object key &rest keys)
+ (code "js_to_lisp(" (ls-compile `(oget* ,object ,key ,@keys)) ")"))
+
+(define-raw-builtin oset (value object key &rest keys)
+ (ls-compile `(oset* (lisp-to-js ,value) ,object ,key ,@keys)))
+
+(define-builtin objectp (x)
+ (js!bool (code "(typeof (" x ") === 'object')")))
+
+(define-builtin lisp-to-js (x) (code "lisp_to_js(" x ")"))
+(define-builtin js-to-lisp (x) (code "js_to_lisp(" x ")"))
+
+
+(define-builtin in (key object)
+ (js!bool (code "(xstring(" key ") in (" object "))")))
+
+(define-builtin map-for-in (function object)
+ (js!selfcall
+ "var f = " function ";" *newline*
+ "var g = (typeof f === 'function' ? f : f.fvalue);" *newline*
+ "var o = " object ";" *newline*
+ "for (var key in o){" *newline*
+ (indent "g(" (if *multiple-value-p* "values" "pv") ", 1, o[key]);" *newline*)
+ "}"
+ " return " (ls-compile nil) ";" *newline*))
+