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