jsv8.ecl 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /* Example of calling JavaScript (V8 engine) from ECL code via embedded C++
  2. *
  3. * This example evalues a JS expression within an ECL transform
  4. *
  5. */
  6. #option('linkOptions', '-lv8')
  7. // Embedded C++ that makes a evaluates the script passed to it
  8. string jseval(varstring script, varstring a, varstring b) := BEGINC++
  9. // This section of the code should probably move to a plugin, or somesuch
  10. /* Include the JSAPI header file to get access to SpiderMonkey. */
  11. #include "v8.h"
  12. #body
  13. using namespace v8;
  14. // extern void user1(size32_t & __lenResult,char * & __result, const char * script, const char *a, const char *b) {
  15. {
  16. Isolate* isolate = Isolate::New();
  17. {
  18. v8::Isolate::Scope iscope(isolate);
  19. // Create a stack-allocated handle scope.
  20. HandleScope handle_scope;
  21. Persistent<Context> context = Context::New();
  22. Context::Scope context_scope(context);
  23. // Bind the parameters into the context
  24. context->Global()->Set(String::New("a"), String::New(a));
  25. context->Global()->Set(String::New("b"), String::New(b));
  26. // Create a string containing the JavaScript source code.
  27. Handle<String> source = String::New(script);
  28. // Compile the source code.
  29. Handle<Script> script = Script::Compile(source);
  30. // Run the script to get the result.
  31. Handle<Value> result = script->Run();
  32. // Dispose the persistent context.
  33. context.Dispose();
  34. // Convert the result to an ASCII string and return it.
  35. String::AsciiValue ascii(result);
  36. const char *chars= *ascii;
  37. __lenResult = strlen(chars);
  38. __result = (char *)rtlMalloc(__lenResult);
  39. memcpy(__result, chars, __lenResult);
  40. }
  41. isolate->Dispose();
  42. }
  43. ENDC++;
  44. //--------------------------------------------------------
  45. // ECL code - an input dataset with 2 records, each containing 2 strings
  46. inrec := RECORD
  47. string f1;
  48. string f2;
  49. END;
  50. infile1 := DATASET([{'a', 'b'}, {'c', 'd'}], inrec);
  51. infile2 := DATASET([{'e', 'f'}, {'g', 'h'}], inrec);
  52. // Output record has just one string, filled in from the result of the JavaScript function
  53. outrec := RECORD
  54. string c;
  55. END;
  56. outrec t(inrec L) := TRANSFORM
  57. SELF.c := jseval('a + b', L.f1, L.f2) // Evaluates JavaScript expression to concatenate strings
  58. END;
  59. outfile := project(infile1, t(LEFT))+project(infile2, t(LEFT)); // threaded concat operation
  60. outfile;