docs: public static Scriptable toObject(Context cx, Scriptable scope, Object val)
      {
          if (val == null) {
              throw typeError0("msg.null.to.object");
          }
          if (Undefined.isUndefined(val)) {
              throw typeError0("msg.undef.to.object");
          }
  
          if (isSymbol(val)) {
              NativeSymbol result = new NativeSymbol((NativeSymbol)val);
              setBuiltinProtoAndParent(result, scope, TopLevel.Builtins.Symbol);
              return result;
          }
          if (val instanceof Scriptable) {
              return (Scriptable) val;
          }
          if (val instanceof CharSequence) {
              // FIXME we want to avoid toString() here, especially for concat()
              NativeString result = new NativeString((CharSequence)val);
              setBuiltinProtoAndParent(result, scope, TopLevel.Builtins.String);
              return result;
          }
          if (val instanceof Number) {
              NativeNumber result = new NativeNumber(((Number)val).doubleValue());
              setBuiltinProtoAndParent(result, scope, TopLevel.Builtins.Number);
              return result;
          }
          if (val instanceof Boolean) {
              NativeBoolean result = new NativeBoolean(((Boolean)val).booleanValue());
              setBuiltinProtoAndParent(result, scope, TopLevel.Builtins.Boolean);
              return result;
          }
  
          // Extension: Wrap as a LiveConnect object.
          Object wrapped = cx.getWrapFactory().wrap(cx, scope, val, null);
          if (wrapped instanceof Scriptable)
              return (Scriptable) wrapped;
          throw errorWithClassName("msg.invalid.type", val);
      }