001/* 002 * This file is part of OCaml-Java runtime. 003 * Copyright (C) 2007-2013 Xavier Clerc. 004 * 005 * OCaml-Java runtime is free software; you can redistribute it and/or modify 006 * it under the terms of the GNU Lesser General Public License as published by 007 * the Free Software Foundation; either version 3 of the License, or 008 * (at your option) any later version. 009 * 010 * OCaml-Java runtime is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.ocamljava.runtime.wrappers; 020 021import java.lang.invoke.MethodHandle; 022import java.lang.invoke.MethodHandles; 023import java.lang.invoke.MethodType; 024 025import org.ocamljava.runtime.values.Value; 026 027/** 028 * The {@code OCamlFunction6} class represent an OCaml function taking six 029 * parameter. 030 * 031 * @author <a href="mailto:xclerc@ocamljava.org">Xavier Clerc</a> 032 * @version 2.0 033 * @since 2.0 034 */ 035public abstract class OCamlFunction6<T0 extends OCamlValue, 036 T1 extends OCamlValue, 037 T2 extends OCamlValue, 038 T3 extends OCamlValue, 039 T4 extends OCamlValue, 040 T5 extends OCamlValue, 041 TR extends OCamlValue> extends OCamlValue { 042 043 /** Wrapper for first parameter. */ 044 protected final Wrapper<T0> wrapper0; 045 046 /** Wrapper for second parameter. */ 047 protected final Wrapper<T1> wrapper1; 048 049 /** Wrapper for third parameter. */ 050 protected final Wrapper<T2> wrapper2; 051 052 /** Wrapper for fourth parameter. */ 053 protected final Wrapper<T3> wrapper3; 054 055 /** Wrapper for fifth parameter. */ 056 protected final Wrapper<T4> wrapper4; 057 058 /** Wrapper for sixth parameter. */ 059 protected final Wrapper<T5> wrapper5; 060 061 /** Wrapper for return value. */ 062 protected final Wrapper<TR> wrapperr; 063 064 /** Method handle for function actually called from the OCaml runtime. */ 065 private static final MethodHandle METHOD_HANDLE; 066 067 static { 068 MethodHandle mh; 069 try { 070 final MethodHandles.Lookup lookup = MethodHandles.lookup(); 071 final MethodType mt = MethodType.methodType(Value.class, 072 Value.class, 073 Value.class, 074 Value.class, 075 Value.class, 076 Value.class, 077 Value.class); 078 mh = lookup.findVirtual(OCamlFunction6Caller.class, "called", mt); 079 } catch (final NoSuchMethodException | IllegalAccessException e) { 080 assert false : "OCamlFunction6: unable to get method handle"; 081 mh = null; 082 } // end try/catch 083 METHOD_HANDLE = mh; 084 } // end static block 085 086 /** 087 * Constructs a new instance. <br/> 088 * To be used by Java implementations. 089 * @param w0 wrapper for first parameter - should not be {@code null} 090 * @param w1 wrapper for second parameter - should not be {@code null} 091 * @param w2 wrapper for third parameter - should not be {@code null} 092 * @param w3 wrapper for fourth parameter - should not be {@code null} 093 * @param w4 wrapper for fifth parameter - should not be {@code null} 094 * @param w5 wrapper for sixth parameter - should not be {@code null} 095 * @param wr wrapper for result - should not be {@code null} 096 */ 097 public OCamlFunction6(final Wrapper<T0> w0, 098 final Wrapper<T1> w1, 099 final Wrapper<T2> w2, 100 final Wrapper<T3> w3, 101 final Wrapper<T4> w4, 102 final Wrapper<T5> w5, 103 final Wrapper<TR> wr) { 104 super(Value.UNIT); 105 assert w0 != null : "null w0"; 106 assert w1 != null : "null w1"; 107 assert w2 != null : "null w2"; 108 assert w3 != null : "null w3"; 109 assert w4 != null : "null w4"; 110 assert w5 != null : "null w5"; 111 assert wr != null : "null wr"; 112 this.wrapper0 = w0; 113 this.wrapper1 = w1; 114 this.wrapper2 = w2; 115 this.wrapper3 = w3; 116 this.wrapper4 = w4; 117 this.wrapper5 = w5; 118 this.wrapperr = wr; 119 } // end constructor(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<TR>) 120 121 /** 122 * Constructs a new instance. <br/> 123 * To be used by Java implementations. 124 */ 125 @SuppressWarnings("unchecked") 126 public OCamlFunction6() { 127 this((Wrapper<T0>) OCamlValue.WRAPPER, 128 (Wrapper<T1>) OCamlValue.WRAPPER, 129 (Wrapper<T2>) OCamlValue.WRAPPER, 130 (Wrapper<T3>) OCamlValue.WRAPPER, 131 (Wrapper<T4>) OCamlValue.WRAPPER, 132 (Wrapper<T5>) OCamlValue.WRAPPER, 133 (Wrapper<TR>) OCamlValue.WRAPPER); 134 } // end empty constructor 135 136 /** 137 * Constructs a new instance from a value. <br/> 138 * To be used by OCaml implementations. 139 * @param w0 wrapper for first parameter - should not be {@code null} 140 * @param w1 wrapper for second parameter - should not be {@code null} 141 * @param w2 wrapper for third parameter - should not be {@code null} 142 * @param w3 wrapper for fourth parameter - should not be {@code null} 143 * @param w4 wrapper for fifth parameter - should not be {@code null} 144 * @param w5 wrapper for fifth parameter - should not be {@code null} 145 * @param wr wrapper for result - should not be {@code null} 146 */ 147 OCamlFunction6(final Value v, 148 final Wrapper<T0> w0, 149 final Wrapper<T1> w1, 150 final Wrapper<T2> w2, 151 final Wrapper<T3> w3, 152 final Wrapper<T4> w4, 153 final Wrapper<T5> w5, 154 final Wrapper<TR> wr) { 155 super(v); 156 assert w0 != null : "null w0"; 157 assert w1 != null : "null w1"; 158 assert w2 != null : "null w2"; 159 assert w3 != null : "null w3"; 160 assert w4 != null : "null w4"; 161 assert w5 != null : "null w5"; 162 assert wr != null : "null wr"; 163 this.wrapper0 = w0; 164 this.wrapper1 = w1; 165 this.wrapper2 = w2; 166 this.wrapper3 = w3; 167 this.wrapper4 = w4; 168 this.wrapper5 = w5; 169 this.wrapperr = wr; 170 } // end constructor(Value, Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<TR>) 171 172 /** 173 * {@inheritDoc} 174 */ 175 @Override 176 public final Wrapper<? extends OCamlFunction6<T0, T1, T2, T3, T4, T5, TR>> getWrapper() { 177 return OCamlFunction6.wrapper(this.wrapper0, 178 this.wrapper1, 179 this.wrapper2, 180 this.wrapper3, 181 this.wrapper4, 182 this.wrapper5, 183 this.wrapperr); 184 } // end method 'getWrapper()' 185 186 /** 187 * {@inheritDoc} 188 */ 189 @Override 190 public Wrapper<? extends OCamlValue> getWrapper(final int idx) { 191 switch (idx) { 192 case 0: return this.wrapper0; 193 case 1: return this.wrapper1; 194 case 2: return this.wrapper2; 195 case 3: return this.wrapper3; 196 case 4: return this.wrapper4; 197 case 5: return this.wrapper5; 198 case 6: return this.wrapperr; 199 default: return OCamlUnit.WRAPPER; 200 } // end switch 201 } // end method 'getWrapper(int)' 202 203 /** 204 * Returns the closure to be executed from the OCaml runtime. 205 * @param w0 wrapper for first parameter - should not be {@code null} 206 * @param w1 wrapper for second parameter - should not be {@code null} 207 * @param w2 wrapper for third parameter - should not be {@code null} 208 * @param w3 wrapper for fourth parameter - should not be {@code null} 209 * @param w4 wrapper for fifth parameter - should not be {@code null} 210 * @param w5 wrapper for sixth parameter - should not be {@code null} 211 * @return the closure to be executed on the OCaml side 212 */ 213 public Value getClosure(final Wrapper<T0> w0, 214 final Wrapper<T1> w1, 215 final Wrapper<T2> w2, 216 final Wrapper<T3> w3, 217 final Wrapper<T4> w4, 218 final Wrapper<T5> w5) { 219 assert w0 != null : "null w0"; 220 assert w1 != null : "null w1"; 221 assert w2 != null : "null w2"; 222 assert w3 != null : "null w3"; 223 assert w4 != null : "null w4"; 224 assert w5 != null : "null w5"; 225 final OCamlFunction6Caller<T0, T1, T2, T3, T4, T5, TR> ofc = new OCamlFunction6Caller<>(w0, w1, w2, w3, w4, w5, this); 226 return Value.createClosure(OCamlFunction6.METHOD_HANDLE.bindTo(ofc), 6); 227 } // end method 'getClosure(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>)' 228 229 /** 230 * The actual implementation of the function 231 * @param p0 first parameter - should not be {@code null} 232 * @param p1 second parameter - should not be {@code null} 233 * @param p2 third parameter - should not be {@code null} 234 * @param p3 fourth parameter - should not be {@code null} 235 * @param p4 fifth parameter - should not be {@code null} 236 * @param p5 sixth parameter - should not be {@code null} 237 * @throws OCamlException if function fails 238 */ 239 public abstract TR execute(final T0 p0, 240 final T1 p1, 241 final T2 p2, 242 final T3 p3, 243 final T4 p4, 244 final T5 p5) 245 throws OCamlException; 246 247 /** 248 * {@inheritDoc} 249 */ 250 @Override 251 public final int hashCode() { 252 return super.hashCode(); 253 } // end method 'hashCode()' 254 255 /** 256 * {@inheritDoc} 257 */ 258 @Override 259 public final boolean equals(final Object obj) { 260 if (obj instanceof OCamlFunction6) { 261 final OCamlFunction6<?, ?, ?, ?, ?, ?, ?> that = (OCamlFunction6) obj; 262 return this == that; 263 } else { 264 return false; 265 } // end if/else 266 } // end method 'equals(Object)' 267 268 /** 269 * {@inheritDoc} 270 */ 271 @Override 272 public final String toString() { 273 return "OCamlFunction6(...)"; 274 } // end method 'toString()' 275 276 /** 277 * Wraps the passed value. 278 * @param w0 wrapper for first parameter - should not be {@code null} 279 * @param w1 wrapper for second parameter - should not be {@code null} 280 * @param w2 wrapper for third parameter - should not be {@code null} 281 * @param w3 wrapper for fourth parameter - should not be {@code null} 282 * @param w4 wrapper for fifth parameter - should not be {@code null} 283 * @param w5 wrapper for sixth parameter - should not be {@code null} 284 * @param wr wrapper for result - should not be {@code null} 285 * @param v value to wrap - should not be {@code null} 286 * @return a new {@code OCamlFunction6} instance wrapping the passed value 287 */ 288 public static <T0 extends OCamlValue, 289 T1 extends OCamlValue, 290 T2 extends OCamlValue, 291 T3 extends OCamlValue, 292 T4 extends OCamlValue, 293 T5 extends OCamlValue, 294 TR extends OCamlValue> 295 OCamlFunction6<T0, T1, T2, T3, T4, T5, TR> wrap(final Wrapper<T0> w0, 296 final Wrapper<T1> w1, 297 final Wrapper<T2> w2, 298 final Wrapper<T3> w3, 299 final Wrapper<T4> w4, 300 final Wrapper<T5> w5, 301 final Wrapper<TR> wr, 302 final Value v) { 303 assert w0 != null : "null w0"; 304 assert w1 != null : "null w1"; 305 assert w2 != null : "null w2"; 306 assert w3 != null : "null w3"; 307 assert w4 != null : "null w4"; 308 assert w5 != null : "null w5"; 309 assert wr != null : "null wr"; 310 assert v != null : "null v"; 311 return new OCamlFunction6Impl<T0, T1, T2, T3, T4, T5, TR>(w0, w1, w2, w3, w4, w5, wr, v); 312 } // end method 'wrap(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<TR>, Value)' 313 314 /** 315 * Returns a wrapper for {@code OCamlFunction6} values. 316 * @param w0 wrapper for first parameter - should not be {@code null} 317 * @param w1 wrapper for second parameter - should not be {@code null} 318 * @param w2 wrapper for third parameter - should not be {@code null} 319 * @param w3 wrapper for fourth parameter - should not be {@code null} 320 * @param w4 wrapper for fifth parameter - should not be {@code null} 321 * @param w5 wrapper for sixth parameter - should not be {@code null} 322 * @param wr wrapper for result - should not be {@code null} 323 * @return a wrapper for {@code OCamlFunction5} values 324 */ 325 @SuppressWarnings("unchecked") 326 public static <T0 extends OCamlValue, 327 T1 extends OCamlValue, 328 T2 extends OCamlValue, 329 T3 extends OCamlValue, 330 T4 extends OCamlValue, 331 T5 extends OCamlValue, 332 TR extends OCamlValue> 333 Wrapper<? extends OCamlFunction6<T0, T1, T2, T3, T4, T5, TR>> wrapper(final Wrapper<T0> w0, 334 final Wrapper<T1> w1, 335 final Wrapper<T2> w2, 336 final Wrapper<T3> w3, 337 final Wrapper<T4> w4, 338 final Wrapper<T5> w5, 339 final Wrapper<TR> wr) { 340 assert w0 != null : "null w0"; 341 assert w1 != null : "null w1"; 342 assert w2 != null : "null w2"; 343 assert w3 != null : "null w3"; 344 assert w4 != null : "null w4"; 345 assert w5 != null : "null w5"; 346 assert wr != null : "null wr"; 347 return new ComposedWrapper<OCamlFunction6<T0, T1, T2, T3, T4, T5, TR>>(w0, w1, w2, w3, w4, w5, wr) { 348 /** 349 * {@inheritDoc} 350 */ 351 @Override 352 public OCamlFunction6<T0, T1, T2, T3, T4, T5, TR> wrap(final Value v) { 353 return new OCamlFunction6Impl<T0, T1, T2, T3, T4, T5, TR>(w0, w1, w2, w3, w4, w5, wr, v); 354 } // end method 'wrap(Value)' 355 }; // end anonymous inner-class 356 } // end method 'wrapper(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<TR>)' 357 358} // end class 'OCamlFunction6'