2370.2.1
by Henrik Ingo
Adding new plugin "js_eval" that takes 1 or more strings as arguments |
1 |
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
|
2 |
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
|
|
3 |
*
|
|
2370.2.6
by Henrik Ingo
Change copyright from Sun Microsystems to myself :-) |
4 |
* Copyright (C) 2011, Henrik Ingo.
|
2370.2.1
by Henrik Ingo
Adding new plugin "js_eval" that takes 1 or more strings as arguments |
5 |
*
|
6 |
* This program is free software; you can redistribute it and/or modify
|
|
7 |
* it under the terms of the GNU General Public License as published by
|
|
8 |
* the Free Software Foundation; version 2 of the License.
|
|
9 |
*
|
|
10 |
* This program is distributed in the hope that it will be useful,
|
|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13 |
* GNU General Public License for more details.
|
|
14 |
*
|
|
15 |
* You should have received a copy of the GNU General Public License
|
|
16 |
* along with this program; if not, write to the Free Software
|
|
17 |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
18 |
*/
|
|
19 |
||
20 |
#include <config.h> |
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
21 |
#include <stdio.h> |
2370.2.1
by Henrik Ingo
Adding new plugin "js_eval" that takes 1 or more strings as arguments |
22 |
|
2370.2.7
by Henrik Ingo
Use my_error() to return v8 errors to the client instead of stdout/log. |
23 |
#include <drizzled/error.h> |
2370.2.1
by Henrik Ingo
Adding new plugin "js_eval" that takes 1 or more strings as arguments |
24 |
#include <drizzled/plugin/function.h> |
25 |
#include <drizzled/function/str/strfunc.h> |
|
2370.2.11
by Henrik Ingo
Arguments that are of type DATETIME are now created as JavaScript |
26 |
#include <drizzled/temporal.h> |
2370.2.1
by Henrik Ingo
Adding new plugin "js_eval" that takes 1 or more strings as arguments |
27 |
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
28 |
#include <v8.h> |
2370.2.3
by Henrik Ingo
Use v8::Locker to allow multiple threads to use v8 engine. |
29 |
#define JS_ENGINE "v8"
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
30 |
|
2370.2.1
by Henrik Ingo
Adding new plugin "js_eval" that takes 1 or more strings as arguments |
31 |
using namespace std; |
32 |
using namespace drizzled; |
|
33 |
||
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
34 |
|
2370.2.10
by Henrik Ingo
Change names and style of the v8 sample code to drizzle like code. |
35 |
namespace drizzle_plugin { |
36 |
namespace js { |
|
37 |
||
2370.2.3
by Henrik Ingo
Use v8::Locker to allow multiple threads to use v8 engine. |
38 |
v8::Handle<v8::Value> V8Version(const v8::Arguments& args); |
39 |
v8::Handle<v8::Value> JsEngine(const v8::Arguments& args); |
|
2370.2.10
by Henrik Ingo
Change names and style of the v8 sample code to drizzle like code. |
40 |
const char* v8_to_char(const v8::String::Utf8Value& value); |
41 |
void emit_drizzle_error(v8::TryCatch* try_catch); |
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
42 |
|
43 |
||
44 |
// TODO: So this is a function that returns strings?
|
|
45 |
// What is the class for functions that return mixed types?
|
|
2370.2.10
by Henrik Ingo
Change names and style of the v8 sample code to drizzle like code. |
46 |
// Or is this as it should be, apparently js('1') + js('2') does the right thing already.
|
2370.2.1
by Henrik Ingo
Adding new plugin "js_eval" that takes 1 or more strings as arguments |
47 |
|
2370.2.18
by Henrik Ingo
Small style fixes from Olaf's review (thanks). |
48 |
class JsFunction : public Item_str_func |
2370.2.1
by Henrik Ingo
Adding new plugin "js_eval" that takes 1 or more strings as arguments |
49 |
{
|
50 |
public: |
|
51 |
String *val_str(String *); |
|
52 |
||
53 |
const char *func_name() const |
|
54 |
{
|
|
2370.2.8
by Henrik Ingo
Change name from js_eval() to just js(), also change name of plugin itself. |
55 |
return "js"; |
2370.2.1
by Henrik Ingo
Adding new plugin "js_eval" that takes 1 or more strings as arguments |
56 |
}
|
57 |
||
58 |
void fix_length_and_dec() |
|
59 |
{
|
|
60 |
maybe_null= 1; |
|
61 |
max_length= MAX_BLOB_WIDTH; |
|
62 |
}
|
|
63 |
||
64 |
bool check_argument_count(int n) |
|
65 |
{
|
|
66 |
return (n >= 1); |
|
67 |
}
|
|
68 |
};
|
|
69 |
||
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
70 |
/**
|
2370.2.11
by Henrik Ingo
Arguments that are of type DATETIME are now created as JavaScript |
71 |
* @brief Extracts a C string from a V8 Utf8Value
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
72 |
*
|
2370.2.10
by Henrik Ingo
Change names and style of the v8 sample code to drizzle like code. |
73 |
* Idea copied from v8 sources, samples/shell.cc. Makes code easier to read than
|
74 |
* (char *)(*utf8value)
|
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
75 |
*/
|
2370.2.10
by Henrik Ingo
Change names and style of the v8 sample code to drizzle like code. |
76 |
const char* v8_to_char(const v8::String::Utf8Value& value) { |
77 |
return *value ? *value : "<javascript v8 string conversion failed>"; |
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
78 |
}
|
79 |
||
80 |
/**
|
|
2370.2.12
by Henrik Ingo
Add missing doxygen comments to a few helper functions. Cleanup |
81 |
* @brief Take v8 exception and emit Drizzle error to client
|
2370.2.10
by Henrik Ingo
Change names and style of the v8 sample code to drizzle like code. |
82 |
*
|
83 |
* This is adapted from ReportException() in v8 samples/shell.cc.
|
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
84 |
*/
|
2370.2.18
by Henrik Ingo
Small style fixes from Olaf's review (thanks). |
85 |
void emit_drizzle_error(v8::TryCatch* try_catch) |
86 |
{
|
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
87 |
v8::HandleScope handle_scope; |
88 |
v8::String::Utf8Value exception(try_catch->Exception()); |
|
2370.2.10
by Henrik Ingo
Change names and style of the v8 sample code to drizzle like code. |
89 |
const char* exception_string = v8_to_char(exception); |
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
90 |
v8::Handle<v8::Message> message = try_catch->Message(); |
91 |
if (message.IsEmpty()) { |
|
92 |
// V8 didn't provide any extra information about this error; just
|
|
93 |
// print the exception.
|
|
2370.2.7
by Henrik Ingo
Use my_error() to return v8 errors to the client instead of stdout/log. |
94 |
my_error(ER_SCRIPT, MYF(0), exception_string); |
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
95 |
} else { |
2370.2.10
by Henrik Ingo
Change names and style of the v8 sample code to drizzle like code. |
96 |
char buf[2048]; |
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
97 |
int linenum = message->GetLineNumber(); |
2370.2.10
by Henrik Ingo
Change names and style of the v8 sample code to drizzle like code. |
98 |
sprintf(buf, "At line %i: %.1900s (Do SHOW ERRORS for more information.)", linenum, exception_string); |
2370.2.7
by Henrik Ingo
Use my_error() to return v8 errors to the client instead of stdout/log. |
99 |
my_error(ER_SCRIPT, MYF(0), buf); |
2370.2.10
by Henrik Ingo
Change names and style of the v8 sample code to drizzle like code. |
100 |
// Print line of source code and where error happened.
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
101 |
v8::String::Utf8Value sourceline(message->GetSourceLine()); |
2370.2.10
by Henrik Ingo
Change names and style of the v8 sample code to drizzle like code. |
102 |
const char* sourceline_string = v8_to_char(sourceline); |
103 |
sprintf(buf, "Line %i: %.160s", linenum, sourceline_string); |
|
2370.2.7
by Henrik Ingo
Use my_error() to return v8 errors to the client instead of stdout/log. |
104 |
my_error(ER_SCRIPT, MYF(0), buf); |
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
105 |
int start = message->GetStartColumn(); |
2370.2.7
by Henrik Ingo
Use my_error() to return v8 errors to the client instead of stdout/log. |
106 |
sprintf(buf, "Check your script starting at: '%.50s'", &sourceline_string[start]); |
107 |
my_error(ER_SCRIPT, MYF(0), buf); |
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
108 |
v8::String::Utf8Value stack_trace(try_catch->StackTrace()); |
109 |
if (stack_trace.length() > 0) { |
|
2370.2.10
by Henrik Ingo
Change names and style of the v8 sample code to drizzle like code. |
110 |
const char* stack_trace_string = v8_to_char(stack_trace); |
2370.2.7
by Henrik Ingo
Use my_error() to return v8 errors to the client instead of stdout/log. |
111 |
my_error(ER_SCRIPT, MYF(0), stack_trace_string); |
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
112 |
}
|
113 |
}
|
|
114 |
}
|
|
115 |
||
116 |
/**
|
|
2370.2.11
by Henrik Ingo
Arguments that are of type DATETIME are now created as JavaScript |
117 |
* @brief Implements js() - execute JavaScript code
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
118 |
*
|
2370.2.13
by Henrik Ingo
Add 2 items to todo list. |
119 |
* @todo row_result types are not yet handled, what are they anyway?
|
120 |
* @todo Lot's of performance optimizations postponed for later version:
|
|
121 |
* * When available, use v8::Isolate instead of v8::Locker for multithreading
|
|
122 |
* (or a mix of both).
|
|
123 |
* * As part of this work, refactor v8 stuff into separate
|
|
2370.2.10
by Henrik Ingo
Change names and style of the v8 sample code to drizzle like code. |
124 |
* function, proxy, factory or something...
|
2370.2.13
by Henrik Ingo
Add 2 items to todo list. |
125 |
* * Save the compiled script so it can be used again if same script is run
|
126 |
* many times
|
|
127 |
* * Some of the v8 stuff should be done in initialize()
|
|
2370.2.7
by Henrik Ingo
Use my_error() to return v8 errors to the client instead of stdout/log. |
128 |
*
|
2370.2.10
by Henrik Ingo
Change names and style of the v8 sample code to drizzle like code. |
129 |
* @note DECIMAL_RESULT type is now a double in JavaScript. This could lose
|
130 |
* precision. But to send them as strings would also be awkward (+ operator will
|
|
131 |
* do unexpected things). In any case, we'd need some biginteger (bigdecimal?)
|
|
132 |
* kind of library to do anything with higher precision values anyway. If you
|
|
133 |
* want to keep the precision, you can cast your decimal values to strings
|
|
134 |
* explicitly when passing them as arguments.
|
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
135 |
*
|
136 |
* @param res Pointer to the drizzled::String object that will contain the result
|
|
137 |
* @return a drizzled::String containing the value returned by executed JavaScript code (value of last executed statement)
|
|
138 |
*/
|
|
2370.2.8
by Henrik Ingo
Change name from js_eval() to just js(), also change name of plugin itself. |
139 |
String *JsFunction::val_str( String *str ) |
2370.2.1
by Henrik Ingo
Adding new plugin "js_eval" that takes 1 or more strings as arguments |
140 |
{
|
2370.2.5
by Henrik Ingo
Honoring EcmaScript standard arguments are made available as arguments[] |
141 |
assert( fixed == 1 ); |
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
142 |
// If we return from any of the error conditions during method, then
|
143 |
// return value of the drizzle function is null.
|
|
144 |
null_value= true; |
|
145 |
||
146 |
String *source_str=NULL; |
|
2370.2.5
by Henrik Ingo
Honoring EcmaScript standard arguments are made available as arguments[] |
147 |
source_str = args[0]->val_str( str ); |
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
148 |
|
2370.2.3
by Henrik Ingo
Use v8::Locker to allow multiple threads to use v8 engine. |
149 |
// Need to use Locker in multi-threaded app. v8 is unlocked by the destructor
|
150 |
// when locker goes out of scope.
|
|
151 |
// TODO: Newer versions of v8 provide an Isolate class where you can get a
|
|
152 |
// separate instance of v8 (ie one per thread). v8 2.5.9.9 in Ubuntu 11.04 does
|
|
153 |
// not yet offer it.
|
|
154 |
v8::Locker locker; |
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
155 |
// Pass code and arguments into v8...
|
156 |
v8::HandleScope handle_scope; |
|
2370.2.3
by Henrik Ingo
Use v8::Locker to allow multiple threads to use v8 engine. |
157 |
// Create a template for the global object and populate a drizzle object.
|
158 |
v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); |
|
159 |
// Drizzle will contain API's to drizzle variables, functions and tables
|
|
2370.2.4
by Henrik Ingo
Arguments 2 to N are now passed to the js script in array argv. |
160 |
v8::Handle<v8::ObjectTemplate> db = v8::ObjectTemplate::New(); |
161 |
v8::Handle<v8::ObjectTemplate> js = v8::ObjectTemplate::New(); |
|
2370.2.3
by Henrik Ingo
Use v8::Locker to allow multiple threads to use v8 engine. |
162 |
// Bind the 'version' function
|
2370.2.5
by Henrik Ingo
Honoring EcmaScript standard arguments are made available as arguments[] |
163 |
global->Set( v8::String::New("db"), db ); |
164 |
db->Set( v8::String::New("js"), js ); |
|
165 |
js->Set( v8::String::New("version"), v8::FunctionTemplate::New(V8Version) ); |
|
166 |
js->Set( v8::String::New("engine"), v8::FunctionTemplate::New(JsEngine) ); |
|
2370.2.4
by Henrik Ingo
Arguments 2 to N are now passed to the js script in array argv. |
167 |
|
168 |
// Now bind the arguments into argv[]
|
|
169 |
// v8::Array can only be created when context is already entered (otherwise v8 segfaults!)
|
|
2370.2.5
by Henrik Ingo
Honoring EcmaScript standard arguments are made available as arguments[] |
170 |
v8::Persistent<v8::Context> context = v8::Context::New( NULL, global ); |
171 |
if ( context.IsEmpty() ) { |
|
2370.2.7
by Henrik Ingo
Use my_error() to return v8 errors to the client instead of stdout/log. |
172 |
char buf[100]; |
2370.2.8
by Henrik Ingo
Change name from js_eval() to just js(), also change name of plugin itself. |
173 |
sprintf(buf, "Error in js() while creating JavaScript context in %s.", JS_ENGINE); |
2370.2.7
by Henrik Ingo
Use my_error() to return v8 errors to the client instead of stdout/log. |
174 |
my_error(ER_SCRIPT, MYF(0), buf); |
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
175 |
return NULL; |
176 |
}
|
|
177 |
context->Enter(); |
|
2370.2.4
by Henrik Ingo
Arguments 2 to N are now passed to the js script in array argv. |
178 |
|
179 |
v8::Handle<v8::Array> a = v8::Array::New(arg_count-1); |
|
180 |
for( uint64_t n = 1; n < arg_count; n++ ) |
|
181 |
{
|
|
2370.2.5
by Henrik Ingo
Honoring EcmaScript standard arguments are made available as arguments[] |
182 |
// Need to do this differently for ints, doubles and strings
|
183 |
// TODO: There is also ROW_RESULT. Is that relevant here? What does it look like? I could pass rows as an array or object.
|
|
184 |
if( args[n]->result_type() == INT_RESULT ){ |
|
2370.2.15
by Henrik Ingo
Added tests for JS(). |
185 |
// TODO: Turns out Drizzle doesn't do unsigned. So this code path can never happen? (I can't test it at least...)
|
2370.2.5
by Henrik Ingo
Honoring EcmaScript standard arguments are made available as arguments[] |
186 |
if( args[n]->is_unsigned() ) { |
187 |
a->Set( n-1, v8::Integer::NewFromUnsigned( (uint32_t) args[n]->val_uint() ) ); |
|
188 |
} else { |
|
189 |
a->Set( n-1, v8::Integer::New((int32_t)args[n]->val_int() ) ); |
|
190 |
}
|
|
191 |
} else if ( args[n]->result_type() == REAL_RESULT || args[n]->result_type() == DECIMAL_RESULT ) { |
|
192 |
a->Set( n-1, v8::Number::New(args[n]->val_real() ) ); |
|
193 |
} else if ( true || args[n]->result_type() == STRING_RESULT ) { |
|
2370.2.11
by Henrik Ingo
Arguments that are of type DATETIME are now created as JavaScript |
194 |
if ( args[n]->is_datetime() ) { |
195 |
// DATE/TIME values are also STRING_RESULT, make them a Date type in v8
|
|
196 |
// Now we need to get the unix timestamp integer, surprisingly tricky...
|
|
197 |
// TODO: This should really be just args[n]->get_epoch_seconds(). I need to write a separate patch for Item class one of these days.
|
|
198 |
type::Time ltime; |
|
199 |
Timestamp temporal; |
|
200 |
args[n]->get_date(ltime, 0); |
|
201 |
temporal.set_years(ltime.year); |
|
202 |
temporal.set_months(ltime.month); |
|
203 |
temporal.set_days(ltime.day); |
|
204 |
temporal.set_hours(ltime.hour); |
|
205 |
temporal.set_minutes(ltime.minute); |
|
206 |
temporal.set_seconds(ltime.second); |
|
207 |
temporal.set_epoch_seconds(); |
|
208 |
if (temporal.is_valid()) |
|
209 |
{
|
|
210 |
time_t tmp; |
|
211 |
temporal.to_time_t(tmp); |
|
212 |
// Pay attention, Ecmascript defines a date as *milliseconds* since unix epoch
|
|
213 |
// Also, on platforms where time_t is 32 bit, we need explicit cast to 64 bit integer
|
|
214 |
a->Set( n-1, v8::Date::New(((uint64_t)tmp)*1000) ); |
|
215 |
} else { |
|
216 |
a->Set( n-1, v8::String::New(args[n]->val_str(str)->c_str() ) ); |
|
217 |
}
|
|
218 |
} else { |
|
219 |
// Default to creating string values in JavaScript
|
|
220 |
a->Set( n-1, v8::String::New(args[n]->val_str(str)->c_str() ) ); |
|
221 |
}
|
|
2370.2.5
by Henrik Ingo
Honoring EcmaScript standard arguments are made available as arguments[] |
222 |
}
|
223 |
// If user has given a name to the arguments, pass these as global variables
|
|
224 |
if( ! args[n]->is_autogenerated_name ) { |
|
225 |
if( args[n]->result_type() == INT_RESULT ){ |
|
226 |
if( args[n]->is_unsigned() ) { |
|
2370.2.11
by Henrik Ingo
Arguments that are of type DATETIME are now created as JavaScript |
227 |
context->Global()->Set( v8::String::New( args[n]->name ), v8::Integer::NewFromUnsigned( (uint32_t) args[n]->val_uint() ) ); |
2370.2.5
by Henrik Ingo
Honoring EcmaScript standard arguments are made available as arguments[] |
228 |
} else { |
2370.2.11
by Henrik Ingo
Arguments that are of type DATETIME are now created as JavaScript |
229 |
context->Global()->Set( v8::String::New( args[n]->name ), v8::Integer::New((int32_t)args[n]->val_int() ) ); |
2370.2.5
by Henrik Ingo
Honoring EcmaScript standard arguments are made available as arguments[] |
230 |
}
|
231 |
} else if ( args[n]->result_type() == REAL_RESULT || args[n]->result_type() == DECIMAL_RESULT ) { |
|
2370.2.11
by Henrik Ingo
Arguments that are of type DATETIME are now created as JavaScript |
232 |
context->Global()->Set( v8::String::New( args[n]->name ), v8::Number::New(args[n]->val_real() ) ); |
2370.2.5
by Henrik Ingo
Honoring EcmaScript standard arguments are made available as arguments[] |
233 |
} else if ( true || args[n]->result_type() == STRING_RESULT ) { |
2370.2.11
by Henrik Ingo
Arguments that are of type DATETIME are now created as JavaScript |
234 |
if ( args[n]->is_datetime() ) { |
235 |
// DATE/TIME values are also STRING_RESULT, make them a Date type in v8
|
|
236 |
// Now we need to get the unix timestamp integer, surprisingly tricky...
|
|
237 |
// TODO: This should really be just args[n]->get_epoch_seconds(). I need to write a separate patch for Item class one of these days.
|
|
238 |
type::Time ltime; |
|
239 |
Timestamp temporal; |
|
240 |
args[n]->get_date(ltime, 0); |
|
241 |
temporal.set_years(ltime.year); |
|
242 |
temporal.set_months(ltime.month); |
|
243 |
temporal.set_days(ltime.day); |
|
244 |
temporal.set_hours(ltime.hour); |
|
245 |
temporal.set_minutes(ltime.minute); |
|
246 |
temporal.set_seconds(ltime.second); |
|
247 |
temporal.set_epoch_seconds(); |
|
248 |
if (temporal.is_valid()) |
|
249 |
{
|
|
250 |
time_t tmp; |
|
251 |
temporal.to_time_t(tmp); |
|
252 |
// Pay attention, Ecmascript defines a date as *milliseconds* since unix epoch
|
|
253 |
// Also, on platforms where time_t is 32 bit, we need explicit cast to 64 bit integer
|
|
254 |
context->Global()->Set( v8::String::New( args[n]->name ), v8::Date::New(((uint64_t)tmp)*1000) ); |
|
255 |
} else { |
|
256 |
context->Global()->Set( v8::String::New( args[n]->name ), v8::String::New(args[n]->val_str(str)->c_str() ) ); |
|
257 |
}
|
|
258 |
} else { |
|
259 |
context->Global()->Set( v8::String::New( args[n]->name ), v8::String::New(args[n]->val_str(str)->c_str() ) ); |
|
260 |
}
|
|
2370.2.5
by Henrik Ingo
Honoring EcmaScript standard arguments are made available as arguments[] |
261 |
}
|
262 |
}
|
|
2370.2.4
by Henrik Ingo
Arguments 2 to N are now passed to the js script in array argv. |
263 |
}
|
264 |
//Need to fetch the global element back from context, global doesn't work anymore
|
|
2370.2.5
by Henrik Ingo
Honoring EcmaScript standard arguments are made available as arguments[] |
265 |
context->Global()->Set( v8::String::New("arguments"), a ); |
2370.2.4
by Henrik Ingo
Arguments 2 to N are now passed to the js script in array argv. |
266 |
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
267 |
|
268 |
||
269 |
// Compile the source code.
|
|
270 |
v8::TryCatch try_catch; |
|
271 |
v8::Handle<v8::Value> result; |
|
2370.2.4
by Henrik Ingo
Arguments 2 to N are now passed to the js script in array argv. |
272 |
// Create a v8 string containing the JavaScript source code.
|
273 |
// Convert from drizzled::String to char* string to v8::String.
|
|
274 |
v8::Handle<v8::String> source = v8::String::New(source_str->c_str()); |
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
275 |
v8::Handle<v8::Script> script = v8::Script::Compile(source); |
2370.2.5
by Henrik Ingo
Honoring EcmaScript standard arguments are made available as arguments[] |
276 |
if ( script.IsEmpty() ) { |
2370.2.10
by Henrik Ingo
Change names and style of the v8 sample code to drizzle like code. |
277 |
emit_drizzle_error(&try_catch); |
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
278 |
return NULL; |
279 |
} else { |
|
280 |
result = script->Run(); |
|
2370.2.5
by Henrik Ingo
Honoring EcmaScript standard arguments are made available as arguments[] |
281 |
if ( result.IsEmpty() ) { |
282 |
assert( try_catch.HasCaught() ); |
|
2370.2.10
by Henrik Ingo
Change names and style of the v8 sample code to drizzle like code. |
283 |
emit_drizzle_error( &try_catch ); |
2370.2.3
by Henrik Ingo
Use v8::Locker to allow multiple threads to use v8 engine. |
284 |
// Dispose of Persistent objects before returning. (Is it needed?)
|
285 |
context->Exit(); |
|
286 |
context.Dispose(); |
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
287 |
return NULL; |
288 |
} else { |
|
2370.2.5
by Henrik Ingo
Honoring EcmaScript standard arguments are made available as arguments[] |
289 |
assert( !try_catch.HasCaught() ); |
290 |
if ( result->IsUndefined() ) { |
|
291 |
// Nothing wrong here, but we return Undefined as NULL.
|
|
2370.2.3
by Henrik Ingo
Use v8::Locker to allow multiple threads to use v8 engine. |
292 |
// Dispose of Persistent objects before returning. (Is it needed?)
|
293 |
context->Exit(); |
|
294 |
context.Dispose(); |
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
295 |
return NULL; |
296 |
}
|
|
297 |
}
|
|
298 |
}
|
|
299 |
||
300 |
// Run the script to get the result.
|
|
301 |
//v8::Handle<v8::Value> foo = script->Run();
|
|
302 |
v8::Handle<v8::String> rstring = result->ToString(); |
|
303 |
||
304 |
// Convert the result to a drizzled::String and print it.
|
|
305 |
// Allocate space to the drizzled::String
|
|
2370.2.4
by Henrik Ingo
Arguments 2 to N are now passed to the js script in array argv. |
306 |
str->free(); //TODO: Check the source for alloc(), but apparently I don't need this line? |
2370.2.5
by Henrik Ingo
Honoring EcmaScript standard arguments are made available as arguments[] |
307 |
str->alloc( rstring->Utf8Length() ); |
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
308 |
// Now copy string from v8 heap to drizzled heap
|
2370.2.5
by Henrik Ingo
Honoring EcmaScript standard arguments are made available as arguments[] |
309 |
rstring->WriteUtf8( str->ptr() ); |
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
310 |
// drizzled::String doesn't actually set string length properly in alloc(), so set it now
|
2370.2.5
by Henrik Ingo
Honoring EcmaScript standard arguments are made available as arguments[] |
311 |
str->length( rstring->Utf8Length() ); |
2370.2.1
by Henrik Ingo
Adding new plugin "js_eval" that takes 1 or more strings as arguments |
312 |
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
313 |
context->Exit(); |
314 |
context.Dispose(); |
|
2370.2.1
by Henrik Ingo
Adding new plugin "js_eval" that takes 1 or more strings as arguments |
315 |
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
316 |
// There was no error and value returned is not undefined, so it's not null.
|
2370.2.1
by Henrik Ingo
Adding new plugin "js_eval" that takes 1 or more strings as arguments |
317 |
null_value= false; |
2370.2.4
by Henrik Ingo
Arguments 2 to N are now passed to the js script in array argv. |
318 |
return str; |
2370.2.1
by Henrik Ingo
Adding new plugin "js_eval" that takes 1 or more strings as arguments |
319 |
}
|
320 |
||
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
321 |
|
322 |
||
323 |
||
2370.2.8
by Henrik Ingo
Change name from js_eval() to just js(), also change name of plugin itself. |
324 |
plugin::Create_function<JsFunction> *js_function = NULL; |
2370.2.1
by Henrik Ingo
Adding new plugin "js_eval" that takes 1 or more strings as arguments |
325 |
|
2370.2.5
by Henrik Ingo
Honoring EcmaScript standard arguments are made available as arguments[] |
326 |
static int initialize( module::Context &context ) |
2370.2.1
by Henrik Ingo
Adding new plugin "js_eval" that takes 1 or more strings as arguments |
327 |
{
|
2370.2.8
by Henrik Ingo
Change name from js_eval() to just js(), also change name of plugin itself. |
328 |
js_function = new plugin::Create_function<JsFunction>("js"); |
329 |
context.add( js_function ); |
|
2370.2.3
by Henrik Ingo
Use v8::Locker to allow multiple threads to use v8 engine. |
330 |
// Initialize V8
|
331 |
v8::V8::Initialize(); |
|
2370.2.1
by Henrik Ingo
Adding new plugin "js_eval" that takes 1 or more strings as arguments |
332 |
return 0; |
333 |
}
|
|
334 |
||
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
335 |
|
2370.2.12
by Henrik Ingo
Add missing doxygen comments to a few helper functions. Cleanup |
336 |
/* Functions that are part of the JavaScript API ***************************/
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
337 |
|
2370.2.12
by Henrik Ingo
Add missing doxygen comments to a few helper functions. Cleanup |
338 |
/**
|
339 |
* @brief Binds as db.js.version() inside JavaScript.
|
|
340 |
* @return Version number of v8 engine
|
|
341 |
*/
|
|
2370.2.5
by Henrik Ingo
Honoring EcmaScript standard arguments are made available as arguments[] |
342 |
v8::Handle<v8::Value> V8Version( const v8::Arguments& ) { |
343 |
return v8::String::New( v8::V8::GetVersion() ); |
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
344 |
}
|
345 |
||
2370.2.12
by Henrik Ingo
Add missing doxygen comments to a few helper functions. Cleanup |
346 |
/**
|
347 |
* @brief Binds as db.js.engine() inside JavaScript.
|
|
348 |
* @return The string "v8"
|
|
349 |
*/
|
|
2370.2.5
by Henrik Ingo
Honoring EcmaScript standard arguments are made available as arguments[] |
350 |
v8::Handle<v8::Value> JsEngine( const v8::Arguments& ) { |
351 |
return v8::String::New( JS_ENGINE ); |
|
2370.2.3
by Henrik Ingo
Use v8::Locker to allow multiple threads to use v8 engine. |
352 |
}
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
353 |
|
2370.2.10
by Henrik Ingo
Change names and style of the v8 sample code to drizzle like code. |
354 |
} // namespace js |
355 |
||
356 |
} // namespace drizzle_plugin |
|
2370.2.2
by Henrik Ingo
js_eval() : Working execution of JavaScript code with the v8 engine. |
357 |
|
2370.2.1
by Henrik Ingo
Adding new plugin "js_eval" that takes 1 or more strings as arguments |
358 |
DRIZZLE_DECLARE_PLUGIN
|
359 |
{
|
|
360 |
DRIZZLE_VERSION_ID, |
|
2370.2.8
by Henrik Ingo
Change name from js_eval() to just js(), also change name of plugin itself. |
361 |
"js", |
2370.2.17
by Henrik Ingo
Wrote end user documentation for JS(). |
362 |
"0.9", |
2370.2.1
by Henrik Ingo
Adding new plugin "js_eval" that takes 1 or more strings as arguments |
363 |
"Henrik Ingo", |
364 |
"Execute JavaScript code with supplied arguments", |
|
365 |
PLUGIN_LICENSE_GPL, |
|
2370.2.10
by Henrik Ingo
Change names and style of the v8 sample code to drizzle like code. |
366 |
drizzle_plugin::js::initialize, /* Plugin Init */ |
2370.2.1
by Henrik Ingo
Adding new plugin "js_eval" that takes 1 or more strings as arguments |
367 |
NULL, /* depends */ |
368 |
NULL /* config options */ |
|
369 |
}
|
|
370 |
DRIZZLE_DECLARE_PLUGIN_END; |
|
371 |