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