Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(123)

Side by Side Diff: Source/WebCore/bindings/dart/DartUtilities.cpp

Issue 9188009: Things to unfork. (Closed) Base URL: svn://svn.chromium.org/multivm/trunk/webkit
Patch Set: Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2011, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 #include "config.h"
31 #include "DartUtilities.h"
32
33 #include "DartEventListener.h"
34 #include "DartIsolateState.h"
35 #include "DartMessagePort.h"
36 #include "DartNode.h"
37 #include "DOMWindow.h"
38 #include "Document.h"
39 #include "Frame.h"
40 #include "ScriptCallStack.h"
41 #include "ScriptArguments.h"
42 #include "SerializedScriptValue.h"
43 #include "V8Converter.h"
44 #include "V8Proxy.h"
45
46 #include <wtf/text/AtomicString.h>
47 #include <wtf/text/CString.h>
48
49 namespace WebCore {
50
51 const char* DartUtilities::domLibraryName = "dart:dom";
52
53 PassRefPtr<StringImpl> DartUtilities::toStringImpl(Dart_Handle object, Conversio nFlag flag, Dart_Handle& exception)
54 {
55 if (flag == ConvertNullToEmptyString && Dart_IsNull(object))
56 return 0;
57
58 if (!Dart_IsString(object)) {
59 exception = Dart_NewString("String expected");
60 return 0;
61 }
62 if (!Dart_IsString16(object)) {
63 // FIXME: consider convertion to UTF16 in this case.
64 exception = Dart_NewString("32-bit string met, cannot be used in DOM API ");
65 return 0;
66 }
67
68 if (Dart_IsExternalString(object)) {
69 void* peer = 0;
70 Dart_ExternalStringGetPeer(object, &peer);
71 ASSERT(peer);
72 StringImpl* stringImpl = reinterpret_cast<StringImpl*>(peer);
73 return stringImpl;
74 }
75
76 // Note: hopefully we should never overflow length as the string would be ju st too long to fit
77 // into memory.
78 intptr_t length = 0;
79 Dart_StringLength(object, &length);
80 UChar* buffer;
81 RefPtr<StringImpl> result = StringImpl::createUninitialized(length, buffer);
82 Dart_StringGet16(object, buffer, &length);
83 return result.release();
84 }
85
86 static void stringFinalizer(void* peer) {
87 StringImpl* stringImpl = reinterpret_cast<StringImpl*>(peer);
88 stringImpl->deref();
89 }
90
91 static Dart_Handle stringImplToDartString(StringImpl* stringImpl)
92 {
93 if (!stringImpl)
94 return Dart_NewString8(0, 0);
95
96 stringImpl->ref();
97 // FIXME: maybe it makes sense only externalize strings longer than certain threshold, such as 5 symbols.
98 return Dart_NewExternalString16(stringImpl->characters(), stringImpl->length (),
99 stringImpl, stringFinalizer);
100 }
101
102 Dart_Handle DartUtilities::stringToDartString(const String& str)
103 {
104 return stringImplToDartString(str.impl());
105 }
106
107 Dart_Handle DartUtilities::stringToDartString(const AtomicString& str)
108 {
109 return stringImplToDartString(str.impl());
110 }
111
112 template <typename Trait>
113 typename Trait::nativeType convert(Dart_Handle object, Dart_Handle& exception)
114 {
115 typename Trait::nativeType value;
116 return !Dart_IsError(Trait::convert(object, &value)) ? value : typename Trai t::nativeType();
117 }
118
119 struct IntegerTrait {
120 typedef int64_t nativeType;
121 static Dart_Handle convert(Dart_Handle object, int64_t* value)
122 {
123 return Dart_IntegerToInt64(object, value);
124 // FIXME: support bigints.
125 }
126 };
127
128 int64_t DartUtilities::toInteger(Dart_Handle object, Dart_Handle& exception)
129 {
130 return convert<IntegerTrait>(object, exception);
131 }
132
133 int64_t DartUtilities::toInteger(Dart_Handle object)
134 {
135 Dart_Handle exception = 0;
136 int64_t value = DartUtilities::toInteger(object, exception);
137 ASSERT(!exception);
138 return value;
139 }
140
141 struct DoubleTrait {
142 typedef double nativeType;
143 static Dart_Handle convert(Dart_Handle object, double* value)
144 {
145 if (!Dart_IsNumber(object))
146 return Dart_Error("the object !is Number");
147
148 object = Dart_InvokeDynamic(object, Dart_NewString("toDouble"), 0, 0);
149 if (Dart_IsError(object))
150 return object;
151
152 return Dart_DoubleValue(object, value);
153 }
154 };
155
156 double DartUtilities::toDouble(Dart_Handle object, Dart_Handle& exception)
157 {
158 return convert<DoubleTrait>(object, exception);
159 }
160
161 double DartUtilities::toDouble(Dart_Handle object)
162 {
163 Dart_Handle exception = 0;
164 double value = DartUtilities::toDouble(object, exception);
165 ASSERT(!exception);
166 return value;
167 }
168
169 struct BoolTrait {
170 typedef bool nativeType;
171 static Dart_Handle convert(Dart_Handle object, bool* value) { return Dart_Bo oleanValue(object, value); }
172 };
173
174 bool DartUtilities::toBool(Dart_Handle object, Dart_Handle& exception)
175 {
176 return convert<BoolTrait>(object, exception);
177 }
178
179 bool DartUtilities::toBool(Dart_Handle object)
180 {
181 Dart_Handle exception = 0;
182 bool value = DartUtilities::toBool(object, exception);
183 ASSERT(!exception);
184 return value;
185 }
186
187 PassRefPtr<EventListener> DartUtilities::toEventListener(Dart_Handle object, Dar t_Handle& exception)
188 {
189 if (Dart_IsNull(object)) {
190 exception = Dart_NewString("Null passed where Dart closure is expected") ;
191 return 0;
192 }
193
194 if (!Dart_IsClosure(object)) {
195 exception = Dart_NewString("Not a Dart closure passed");
196 return 0;
197 }
198
199 return DartEventListener::createOrFetch(object);
200 }
201
202 static v8::Local<v8::Context> currentV8Context()
203 {
204 Frame* frame = DartUtilities::domWindowForCurrentIsolate()->frame();
205 v8::Local<v8::Context> context = V8Proxy::mainWorldContext(frame);
206 ASSERT(!context.IsEmpty());
207 return context;
208 }
209
210 PassRefPtr<SerializedScriptValue> DartUtilities::toSerializedScriptValue(Dart_Ha ndle value, Dart_Handle& exception)
211 {
212 v8::HandleScope handleScope;
213 v8::Context::Scope scope(currentV8Context());
214
215 v8::Handle<v8::Value> v8Value = V8Converter::toV8(value, exception);
216 if (exception)
217 return 0;
218 return SerializedScriptValue::create(v8Value);
219 }
220
221 Dart_Handle DartUtilities::fromSerializedScriptValue(SerializedScriptValue* valu e)
222 {
223 v8::HandleScope handleScope;
224 v8::Context::Scope scope(currentV8Context());
225
226 // FIXME: better error handling.
227 Dart_Handle exception = 0;
228 return V8Converter::toDart(value->deserialize(), exception);
229 }
230
231 PassRefPtr<EventTarget> DartUtilities::toEventTarget(Dart_Handle object, Dart_Ha ndle& exception)
232 {
233 // FIXME: currently it's too risky to remove, but when Optional=CallWithDefa ultValue is
234 // implemented, we should give it a try and unify with the rest of conversio n.
235 if (Dart_IsNull(object))
236 return 0;
237
238 return DartNode::toNative(object, exception);
239 }
240
241 // FIXME: this function requires better testing. Currently blocking as new Messa geChannel hasn't been implemented yet.
242 void DartUtilities::toMessagePortArray(Dart_Handle value, MessagePortArray& port Array, Dart_Handle& exception)
243 {
244 Dart_Handle dom = Dart_LookupLibrary(Dart_NewString(DartUtilities::domLibrar yName));
245 ASSERT(!Dart_IsError(dom));
246
247 Dart_Handle asList = Dart_InvokeStatic(dom, Dart_NewString("Utils"), Dart_Ne wString("convertToList"), 1, &value);
248 if (Dart_IsError(asList)) {
249 DartUtilities::reportProblem(DartUtilities::scriptExecutionContext(), as List);
250 exception = DartDOMWrapper::exceptionCodeToDartException(INVALID_STATE_E RR);
251 return;
252 }
253 ASSERT(Dart_IsList(asList));
254
255 intptr_t length = 0;
256 Dart_ListLength(asList, &length);
257 portArray.resize(length);
258 for (int i = 0; i < length; i++) {
259 Dart_Handle element = Dart_ListGetAt(asList, i);
260 if (Dart_IsError(element)) {
261 exception = DartDOMWrapper::exceptionCodeToDartException(INVALID_STA TE_ERR);
262 return;
263 }
264
265 MessagePort* messagePort = DartMessagePort::toNative(element, exception) .get();
266 if (exception) {
267 exception = DartDOMWrapper::exceptionCodeToDartException(INVALID_STA TE_ERR);
268 return;
269 }
270
271 ASSERT(messagePort);
272 portArray[i] = messagePort;
273 }
274 }
275
276 class DartDOMData {
277 public:
278 DartDOMData()
279 : m_scriptExecutionContext(0)
280 , m_domWindow(0)
281 , m_recursion(0)
282 {
283 }
284
285 DartDOMData(ScriptExecutionContext* context)
286 : m_scriptExecutionContext(context)
287 , m_recursion(0)
288 {
289 ASSERT(context);
290 ASSERT(context->isDocument()); // WorkerContext is not supported yet.
291 Document* document = static_cast<Document*>(context);
292 m_domWindow = document->domWindow();
293 }
294
295 ScriptExecutionContext* scriptExecutionContext() { return m_scriptExecutionC ontext; }
296 DOMWindow* domWindow() { return m_domWindow; }
297 DartDOMMap* domMap() { return &m_domMap; }
298 int* recursion() { return &m_recursion; }
299
300 private:
301 ScriptExecutionContext* m_scriptExecutionContext;
302 DOMWindow* m_domWindow;
303 DartDOMMap m_domMap;
304 int m_recursion;
305 };
306
307 typedef HashMap<Dart_Isolate, DartDOMData*> IsolateToDartDOMDataMap;
308
309 static IsolateToDartDOMDataMap& isolateToDartDOMDataMap()
310 {
311 DEFINE_STATIC_LOCAL(IsolateToDartDOMDataMap, map, ());
312 return map;
313 }
314
315 static DartDOMData* domDataForIsolate(Dart_Isolate isolate)
316 {
317 IsolateToDartDOMDataMap::iterator it = isolateToDartDOMDataMap().find(isolat e);
318 ASSERT(it != isolateToDartDOMDataMap().end());
319 return it->second;
320 }
321
322 static DartDOMData* currentDOMData()
323 {
324 return domDataForIsolate(DartIsolateState::current());
325 }
326
327 void DartUtilities::registerIsolateContext(Dart_Isolate isolate, ScriptExecution Context* context)
328 {
329 ASSERT(!isolateToDartDOMDataMap().contains(isolate));
330 isolateToDartDOMDataMap().set(isolate, new DartDOMData(context));
331 }
332
333 ScriptExecutionContext* DartUtilities::isolateContext(Dart_Isolate isolate)
334 {
335 return domDataForIsolate(isolate)->scriptExecutionContext();
336 }
337
338 void DartUtilities::unregisterIsolateContext(Dart_Isolate isolate)
339 {
340 IsolateToDartDOMDataMap::iterator it = isolateToDartDOMDataMap().find(isolat e);
341 ASSERT(it != isolateToDartDOMDataMap().end());
342 delete it->second;
343 isolateToDartDOMDataMap().remove(it);
344 }
345
346 bool DartUtilities::isFullDomIsolate(Dart_Isolate isolate)
347 {
348 return isolateToDartDOMDataMap().contains(isolate);
349 }
350
351 DOMWindow* DartUtilities::domWindowForIsolate(Dart_Isolate isolate)
352 {
353 return domDataForIsolate(isolate)->domWindow();
354 }
355
356 DOMWindow* DartUtilities::domWindowForCurrentIsolate()
357 {
358 return currentDOMData()->domWindow();
359 }
360
361 Dart_Handle DartUtilities::domLibraryForCurrentIsolate()
362 {
363 // FIXME: Cache this on the isolate.
364 Dart_Handle library = Dart_LookupLibrary(Dart_NewString(domLibraryName));
365 ASSERT(!Dart_IsError(library));
366 return library;
367 }
368
369 DartDOMMap* DartUtilities::domMapForIsolate(Dart_Isolate isolate)
370 {
371 return domDataForIsolate(isolate)->domMap();
372 }
373
374 DartDOMMap* DartUtilities::domMapForCurrentIsolate()
375 {
376 return currentDOMData()->domMap();
377 }
378
379 int* DartUtilities::recursionForIsolate(Dart_Isolate isolate)
380 {
381 return domDataForIsolate(isolate)->recursion();
382 }
383
384 int* DartUtilities::recursionForCurrentIsolate()
385 {
386 return currentDOMData()->recursion();
387 }
388
389 ScriptExecutionContext* DartUtilities::scriptExecutionContext()
390 {
391 return currentDOMData()->scriptExecutionContext();
392 }
393
394 bool DartUtilities::processingUserGesture()
395 {
396 // FIXME: implement this.
397 return false;
398 }
399
400 PassRefPtr<ScriptArguments> DartUtilities::createScriptArguments(Dart_Handle arg ument, Dart_Handle& exception)
401 {
402 v8::Handle<v8::Value> v8Argument = V8Converter::toV8(argument, exception);
403 if (v8Argument->IsUndefined())
404 return 0;
405 Vector<ScriptValue> arguments;
406 arguments.append(v8Argument);
407 ScriptState* scriptState = ScriptState::forContext(currentV8Context());
408 return ScriptArguments::create(scriptState, arguments);
409 }
410
411 PassRefPtr<ScriptCallStack> DartUtilities::createScriptCallStack()
412 {
413 // FIXME: wrap current dart call stack as ScriptCallStack.
414 Vector<ScriptCallFrame> wrappedCallFrames;
415 wrappedCallFrames.append(ScriptCallFrame("undefined", "undefined", 0));
416 return ScriptCallStack::create(wrappedCallFrames);
417 }
418
419 const uint8_t* DartUtilities::fullSnapshot()
420 {
421 static const uint8_t snapshotBuffer[] = {
422 // DartSnapshot.bytes is generated by build system.
423 #include "DartSnapshot.bytes"
424 };
425 return snapshotBuffer;
426 }
427
428 void DartUtilities::reportProblem(ScriptExecutionContext* context, Dart_Handle r esult)
429 {
430 ASSERT(Dart_IsError(result));
431
432 const String internalErrorPrefix("Internal error: ");
433
434 String errorMessage;
435 // FIXME: source file info.
436 String sourceFile = "FIXME";
437 // FIXME: line number info.
438 int lineNumber = 0;
439 // FIXME: call stack info.
440 RefPtr<ScriptCallStack> callStack;
441
442 if (!Dart_ErrorHasException(result))
443 errorMessage = internalErrorPrefix + Dart_GetError(result);
444 else {
445 // Print the exception.
446 Dart_Handle exception = Dart_ErrorGetException(result);
447 ASSERT(!Dart_IsError(exception));
448
449 exception = Dart_ToString(exception);
450 if (Dart_IsError(exception))
451 errorMessage = String("Error converting exception to a string: ") + Dart_GetError(exception);
452 else
453 errorMessage = String("Exception: ") + DartUtilities::dartStringToSt ring(exception);
454
455 // FIXME: Fill in the callStack, sourceFile, and lineNumber
456 // and remove the below once the Dart APIs to iterate over the
457 // trace are available.
458
459 // Print the stack trace.
460 Dart_Handle stacktrace = Dart_ErrorGetStacktrace(result);
461 ASSERT(!Dart_IsError(stacktrace));
462
463 stacktrace = Dart_ToString(stacktrace);
464 if (Dart_IsError(stacktrace))
465 errorMessage += String("\nError converting stack trace to a string: ") + Dart_GetError(stacktrace);
466 else
467 errorMessage += String("\nStack Trace: ") + DartUtilities::dartStrin gToString(stacktrace);
468 }
469
470 if (context && context->isDocument())
471 static_cast<Document*>(context)->reportException(errorMessage, lineNumbe r, sourceFile, callStack);
472 }
473
474 }
OLDNEW
« no previous file with comments | « Source/WebCore/bindings/dart/DartUtilities.h ('k') | Source/WebCore/bindings/dart/ScriptControllerDelegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698