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 OCamlFunction8} class represent an OCaml function taking eight 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 OCamlFunction8<T0 extends OCamlValue, 036 T1 extends OCamlValue, 037 T2 extends OCamlValue, 038 T3 extends OCamlValue, 039 T4 extends OCamlValue, 040 T5 extends OCamlValue, 041 T6 extends OCamlValue, 042 T7 extends OCamlValue, 043 TR extends OCamlValue> extends OCamlValue { 044 045 /** Wrapper for first parameter. */ 046 protected final Wrapper<T0> wrapper0; 047 048 /** Wrapper for second parameter. */ 049 protected final Wrapper<T1> wrapper1; 050 051 /** Wrapper for third parameter. */ 052 protected final Wrapper<T2> wrapper2; 053 054 /** Wrapper for fourth parameter. */ 055 protected final Wrapper<T3> wrapper3; 056 057 /** Wrapper for fifth parameter. */ 058 protected final Wrapper<T4> wrapper4; 059 060 /** Wrapper for sixth parameter. */ 061 protected final Wrapper<T5> wrapper5; 062 063 /** Wrapper for seventh parameter. */ 064 protected final Wrapper<T6> wrapper6; 065 066 /** Wrapper for eighth parameter. */ 067 protected final Wrapper<T7> wrapper7; 068 069 /** Wrapper for return value. */ 070 protected final Wrapper<TR> wrapperr; 071 072 /** Method handle for function actually called from the OCaml runtime. */ 073 private static final MethodHandle METHOD_HANDLE; 074 075 static { 076 MethodHandle mh; 077 try { 078 final MethodHandles.Lookup lookup = MethodHandles.lookup(); 079 final MethodType mt = MethodType.methodType(Value.class, 080 Value.class, 081 Value.class, 082 Value.class, 083 Value.class, 084 Value.class, 085 Value.class, 086 Value.class, 087 Value.class); 088 mh = lookup.findVirtual(OCamlFunction8Caller.class, "called", mt); 089 } catch (final NoSuchMethodException | IllegalAccessException e) { 090 assert false : "OCamlFunction8: unable to get method handle"; 091 mh = null; 092 } // end try/catch 093 METHOD_HANDLE = mh; 094 } // end static block 095 096 /** 097 * Constructs a new instance. <br/> 098 * To be used by Java implementations. 099 * @param w0 wrapper for first parameter - should not be {@code null} 100 * @param w1 wrapper for second parameter - should not be {@code null} 101 * @param w2 wrapper for third parameter - should not be {@code null} 102 * @param w3 wrapper for fourth parameter - should not be {@code null} 103 * @param w4 wrapper for fifth parameter - should not be {@code null} 104 * @param w5 wrapper for sixth parameter - should not be {@code null} 105 * @param w6 wrapper for seventh parameter - should not be {@code null} 106 * @param w7 wrapper for eigth parameter - should not be {@code null} 107 * @param wr wrapper for result - should not be {@code null} 108 */ 109 public OCamlFunction8(final Wrapper<T0> w0, 110 final Wrapper<T1> w1, 111 final Wrapper<T2> w2, 112 final Wrapper<T3> w3, 113 final Wrapper<T4> w4, 114 final Wrapper<T5> w5, 115 final Wrapper<T6> w6, 116 final Wrapper<T7> w7, 117 final Wrapper<TR> wr) { 118 super(Value.UNIT); 119 assert w0 != null : "null w0"; 120 assert w1 != null : "null w1"; 121 assert w2 != null : "null w2"; 122 assert w3 != null : "null w3"; 123 assert w4 != null : "null w4"; 124 assert w5 != null : "null w5"; 125 assert w6 != null : "null w6"; 126 assert w7 != null : "null w7"; 127 assert wr != null : "null wr"; 128 this.wrapper0 = w0; 129 this.wrapper1 = w1; 130 this.wrapper2 = w2; 131 this.wrapper3 = w3; 132 this.wrapper4 = w4; 133 this.wrapper5 = w5; 134 this.wrapper6 = w6; 135 this.wrapper7 = w7; 136 this.wrapperr = wr; 137 } // end constructor(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<T6>, Wrapper<T7>, Wrapper<TR>) 138 139 /** 140 * Constructs a new instance. <br/> 141 * To be used by Java implementations. 142 */ 143 @SuppressWarnings("unchecked") 144 public OCamlFunction8() { 145 this((Wrapper<T0>) OCamlValue.WRAPPER, 146 (Wrapper<T1>) OCamlValue.WRAPPER, 147 (Wrapper<T2>) OCamlValue.WRAPPER, 148 (Wrapper<T3>) OCamlValue.WRAPPER, 149 (Wrapper<T4>) OCamlValue.WRAPPER, 150 (Wrapper<T5>) OCamlValue.WRAPPER, 151 (Wrapper<T6>) OCamlValue.WRAPPER, 152 (Wrapper<T7>) OCamlValue.WRAPPER, 153 (Wrapper<TR>) OCamlValue.WRAPPER); 154 } // end empty constructor 155 156 /** 157 * Constructs a new instance from a value. <br/> 158 * To be used by OCaml implementations. 159 * @param w0 wrapper for first parameter - should not be {@code null} 160 * @param w1 wrapper for second parameter - should not be {@code null} 161 * @param w2 wrapper for third parameter - should not be {@code null} 162 * @param w3 wrapper for fourth parameter - should not be {@code null} 163 * @param w4 wrapper for fifth parameter - should not be {@code null} 164 * @param w5 wrapper for fifth parameter - should not be {@code null} 165 * @param w6 wrapper for fifth parameter - should not be {@code null} 166 * @param w7 wrapper for fifth parameter - should not be {@code null} 167 * @param wr wrapper for result - should not be {@code null} 168 */ 169 OCamlFunction8(final Value v, 170 final Wrapper<T0> w0, 171 final Wrapper<T1> w1, 172 final Wrapper<T2> w2, 173 final Wrapper<T3> w3, 174 final Wrapper<T4> w4, 175 final Wrapper<T5> w5, 176 final Wrapper<T6> w6, 177 final Wrapper<T7> w7, 178 final Wrapper<TR> wr) { 179 super(v); 180 assert w0 != null : "null w0"; 181 assert w1 != null : "null w1"; 182 assert w2 != null : "null w2"; 183 assert w3 != null : "null w3"; 184 assert w4 != null : "null w4"; 185 assert w5 != null : "null w5"; 186 assert w6 != null : "null w6"; 187 assert w7 != null : "null w7"; 188 assert wr != null : "null wr"; 189 this.wrapper0 = w0; 190 this.wrapper1 = w1; 191 this.wrapper2 = w2; 192 this.wrapper3 = w3; 193 this.wrapper4 = w4; 194 this.wrapper5 = w5; 195 this.wrapper6 = w6; 196 this.wrapper7 = w7; 197 this.wrapperr = wr; 198 } // end constructor(Value, Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<T6>, Wrapper<T7>, Wrapper<TR>) 199 200 /** 201 * {@inheritDoc} 202 */ 203 @Override 204 public final Wrapper<? extends OCamlFunction8<T0, T1, T2, T3, T4, T5, T6, T7, TR>> getWrapper() { 205 return OCamlFunction8.wrapper(this.wrapper0, 206 this.wrapper1, 207 this.wrapper2, 208 this.wrapper3, 209 this.wrapper4, 210 this.wrapper5, 211 this.wrapper6, 212 this.wrapper7, 213 this.wrapperr); 214 } // end method 'getWrapper()' 215 216 /** 217 * {@inheritDoc} 218 */ 219 @Override 220 public Wrapper<? extends OCamlValue> getWrapper(final int idx) { 221 switch (idx) { 222 case 0: return this.wrapper0; 223 case 1: return this.wrapper1; 224 case 2: return this.wrapper2; 225 case 3: return this.wrapper3; 226 case 4: return this.wrapper4; 227 case 5: return this.wrapper5; 228 case 6: return this.wrapper6; 229 case 7: return this.wrapper7; 230 case 8: return this.wrapperr; 231 default: return OCamlUnit.WRAPPER; 232 } // end switch 233 } // end method 'getWrapper(int)' 234 235 /** 236 * Returns the closure to be executed from the OCaml runtime. 237 * @param w0 wrapper for first parameter - should not be {@code null} 238 * @param w1 wrapper for second parameter - should not be {@code null} 239 * @param w2 wrapper for third parameter - should not be {@code null} 240 * @param w3 wrapper for fourth parameter - should not be {@code null} 241 * @param w4 wrapper for fifth parameter - should not be {@code null} 242 * @param w5 wrapper for sixth parameter - should not be {@code null} 243 * @param w6 wrapper for seventh parameter - should not be {@code null} 244 * @param w7 wrapper for eighth parameter - should not be {@code null} 245 * @return the closure to be executed on the OCaml side 246 */ 247 public Value getClosure(final Wrapper<T0> w0, 248 final Wrapper<T1> w1, 249 final Wrapper<T2> w2, 250 final Wrapper<T3> w3, 251 final Wrapper<T4> w4, 252 final Wrapper<T5> w5, 253 final Wrapper<T6> w6, 254 final Wrapper<T7> w7) { 255 assert w0 != null : "null w0"; 256 assert w1 != null : "null w1"; 257 assert w2 != null : "null w2"; 258 assert w3 != null : "null w3"; 259 assert w4 != null : "null w4"; 260 assert w5 != null : "null w5"; 261 assert w6 != null : "null w6"; 262 assert w7 != null : "null w7"; 263 final OCamlFunction8Caller<T0, T1, T2, T3, T4, T5, T6, T7, TR> ofc = new OCamlFunction8Caller<>(w0, w1, w2, w3, w4, w5, w6, w7, this); 264 return Value.createClosure(OCamlFunction8.METHOD_HANDLE.bindTo(ofc), 8); 265 } // end method 'getClosure(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<T6>, Wrapper<T7>)' 266 267 /** 268 * The actual implementation of the function 269 * @param p0 first parameter - should not be {@code null} 270 * @param p1 second parameter - should not be {@code null} 271 * @param p2 third parameter - should not be {@code null} 272 * @param p3 fourth parameter - should not be {@code null} 273 * @param p4 fifth parameter - should not be {@code null} 274 * @param p5 sixth parameter - should not be {@code null} 275 * @param p6 seventh parameter - should not be {@code null} 276 * @param p7 eighth parameter - should not be {@code null} 277 * @throws OCamlException if function fails 278 */ 279 public abstract TR execute(final T0 p0, 280 final T1 p1, 281 final T2 p2, 282 final T3 p3, 283 final T4 p4, 284 final T5 p5, 285 final T6 p6, 286 final T7 p7) 287 throws OCamlException; 288 289 /** 290 * {@inheritDoc} 291 */ 292 @Override 293 public final int hashCode() { 294 return super.hashCode(); 295 } // end method 'hashCode()' 296 297 /** 298 * {@inheritDoc} 299 */ 300 @Override 301 public final boolean equals(final Object obj) { 302 if (obj instanceof OCamlFunction8) { 303 final OCamlFunction8<?, ?, ?, ?, ?, ?, ?, ?, ?> that = (OCamlFunction8) obj; 304 return this == that; 305 } else { 306 return false; 307 } // end if/else 308 } // end method 'equals(Object)' 309 310 /** 311 * {@inheritDoc} 312 */ 313 @Override 314 public final String toString() { 315 return "OCamlFunction8(...)"; 316 } // end method 'toString()' 317 318 /** 319 * Wraps the passed value. 320 * @param w0 wrapper for first parameter - should not be {@code null} 321 * @param w1 wrapper for second parameter - should not be {@code null} 322 * @param w2 wrapper for third parameter - should not be {@code null} 323 * @param w3 wrapper for fourth parameter - should not be {@code null} 324 * @param w4 wrapper for fifth parameter - should not be {@code null} 325 * @param w5 wrapper for sixth parameter - should not be {@code null} 326 * @param w6 wrapper for seventh parameter - should not be {@code null} 327 * @param w7 wrapper for eighth parameter - should not be {@code null} 328 * @param wr wrapper for result - should not be {@code null} 329 * @param v value to wrap - should not be {@code null} 330 * @return a new {@code OCamlFunction8} instance wrapping the passed value 331 */ 332 public static <T0 extends OCamlValue, 333 T1 extends OCamlValue, 334 T2 extends OCamlValue, 335 T3 extends OCamlValue, 336 T4 extends OCamlValue, 337 T5 extends OCamlValue, 338 T6 extends OCamlValue, 339 T7 extends OCamlValue, 340 TR extends OCamlValue> 341 OCamlFunction8<T0, T1, T2, T3, T4, T5, T6, T7, TR> wrap(final Wrapper<T0> w0, 342 final Wrapper<T1> w1, 343 final Wrapper<T2> w2, 344 final Wrapper<T3> w3, 345 final Wrapper<T4> w4, 346 final Wrapper<T5> w5, 347 final Wrapper<T6> w6, 348 final Wrapper<T7> w7, 349 final Wrapper<TR> wr, 350 final Value v) { 351 assert w0 != null : "null w0"; 352 assert w1 != null : "null w1"; 353 assert w2 != null : "null w2"; 354 assert w3 != null : "null w3"; 355 assert w4 != null : "null w4"; 356 assert w5 != null : "null w5"; 357 assert w6 != null : "null w6"; 358 assert w7 != null : "null w7"; 359 assert wr != null : "null wr"; 360 assert v != null : "null v"; 361 return new OCamlFunction8Impl<T0, T1, T2, T3, T4, T5, T6, T7, TR>(w0, w1, w2, w3, w4, w5, w6, w7, wr, v); 362 } // end method 'wrap(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<T6>, Wrapper<T7>, Wrapper<TR>, Value)' 363 364 /** 365 * Returns a wrapper for {@code OCamlFunction8} values. 366 * @param w0 wrapper for first parameter - should not be {@code null} 367 * @param w1 wrapper for second parameter - should not be {@code null} 368 * @param w2 wrapper for third parameter - should not be {@code null} 369 * @param w3 wrapper for fourth parameter - should not be {@code null} 370 * @param w4 wrapper for fifth parameter - should not be {@code null} 371 * @param w5 wrapper for sixth parameter - should not be {@code null} 372 * @param w6 wrapper for seventh parameter - should not be {@code null} 373 * @param w7 wrapper for eighth parameter - should not be {@code null} 374 * @param wr wrapper for result - should not be {@code null} 375 * @return a wrapper for {@code OCamlFunction5} values 376 */ 377 @SuppressWarnings("unchecked") 378 public static <T0 extends OCamlValue, 379 T1 extends OCamlValue, 380 T2 extends OCamlValue, 381 T3 extends OCamlValue, 382 T4 extends OCamlValue, 383 T5 extends OCamlValue, 384 T6 extends OCamlValue, 385 T7 extends OCamlValue, 386 TR extends OCamlValue> 387 Wrapper<? extends OCamlFunction8<T0, T1, T2, T3, T4, T5, T6, T7, TR>> wrapper(final Wrapper<T0> w0, 388 final Wrapper<T1> w1, 389 final Wrapper<T2> w2, 390 final Wrapper<T3> w3, 391 final Wrapper<T4> w4, 392 final Wrapper<T5> w5, 393 final Wrapper<T6> w6, 394 final Wrapper<T7> w7, 395 final Wrapper<TR> wr) { 396 assert w0 != null : "null w0"; 397 assert w1 != null : "null w1"; 398 assert w2 != null : "null w2"; 399 assert w3 != null : "null w3"; 400 assert w4 != null : "null w4"; 401 assert w5 != null : "null w5"; 402 assert w6 != null : "null w6"; 403 assert w7 != null : "null w7"; 404 assert wr != null : "null wr"; 405 return new ComposedWrapper<OCamlFunction8<T0, T1, T2, T3, T4, T5, T6, T7, TR>>(w0, w1, w2, w3, w4, w5, w6, w7, wr) { 406 /** 407 * {@inheritDoc} 408 */ 409 @Override 410 public OCamlFunction8<T0, T1, T2, T3, T4, T5, T6, T7, TR> wrap(final Value v) { 411 return new OCamlFunction8Impl<T0, T1, T2, T3, T4, T5, T6, T7, TR>(w0, w1, w2, w3, w4, w5, w6, w7, wr, v); 412 } // end method 'wrap(Value)' 413 }; // end anonymous inner-class 414 } // end method 'wrapper(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<T6>, Wrapper<T7>, Wrapper<TR>)' 415 416} // end class 'OCamlFunction8'