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

Side by Side Diff: Source/bindings/core/dart/DartJsInterop.cpp

Issue 1663753002: Apply all blink changes between @202695 and tip of trunk (Closed) Base URL: svn://svn.chromium.org/blink/branches/dart/2454_1
Patch Set: Created 4 years, 10 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
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 " else return new blob(makeSafeArg(array), options);" 140 " else return new blob(makeSafeArg(array), options);"
141 " };" 141 " };"
142 142
143 // Need to make sure that Array.isArray returns true for Dart lists. 143 // Need to make sure that Array.isArray returns true for Dart lists.
144 " Array.isArray = function(arr) {" 144 " Array.isArray = function(arr) {"
145 " return isArray(arr) || (arr instanceof $DartList);" 145 " return isArray(arr) || (arr instanceof $DartList);"
146 " };" 146 " };"
147 "})();"; 147 "})();";
148 148
149 static v8::Local<v8::FunctionTemplate> dartFunctionTemplate(); 149 static v8::Local<v8::FunctionTemplate> dartFunctionTemplate();
150 static v8::Local<v8::FunctionTemplate> dartFunctionTemplateNoWrap();
150 static v8::Local<v8::FunctionTemplate> dartObjectTemplate(); 151 static v8::Local<v8::FunctionTemplate> dartObjectTemplate();
151 static v8::Local<v8::FunctionTemplate> dartListTemplate(); 152 static v8::Local<v8::FunctionTemplate> dartListTemplate();
152 153
153 // TODO(jacobr): we should really be using this method everywhere instead of 154 // TODO(jacobr): we should really be using this method everywhere instead of
154 // sticking interop methods in the dart:html _Utils class. 155 // sticking interop methods in the dart:html _Utils class.
155 static Dart_Handle invokeTopLevelJsInteropMethod(DartDOMData* domData, const cha r* methodName, int argCount, Dart_Handle* args) 156 static Dart_Handle invokeTopLevelJsInteropMethod(DartDOMData* domData, const cha r* methodName, int argCount, Dart_Handle* args)
156 { 157 {
157 Dart_PersistentHandle library = domData->jsLibrary(); 158 Dart_PersistentHandle library = domData->jsLibrary();
158 ASSERT(!Dart_IsError(library)); 159 ASSERT(!Dart_IsError(library));
159 return Dart_Invoke(library, Dart_NewStringFromCString(methodName), argCount, args); 160 return Dart_Invoke(library, Dart_NewStringFromCString(methodName), argCount, args);
(...skipping 23 matching lines...) Expand all
183 DartDOMData* domData = DartDOMData::current(); 184 DartDOMData* domData = DartDOMData::current();
184 ASSERT(domData); 185 ASSERT(domData);
185 ASSERT(DartUtilities::isFunction(domData, handle)); 186 ASSERT(DartUtilities::isFunction(domData, handle));
186 187
187 Vector<Dart_Handle> dartFunctionArgs; 188 Vector<Dart_Handle> dartFunctionArgs;
188 ASSERT(args.Length() == 1 || args.Length() == 2); 189 ASSERT(args.Length() == 1 || args.Length() == 2);
189 // If there is 1 argument, we assume it is a v8:Array or arguments, if 190 // If there is 1 argument, we assume it is a v8:Array or arguments, if
190 // there are 2 arguments, the first argument is "this" and the second 191 // there are 2 arguments, the first argument is "this" and the second
191 // argument is an array of arguments. 192 // argument is an array of arguments.
192 if (args.Length() > 1) { 193 if (args.Length() > 1) {
193 dartFunctionArgs.append(JsInterop::toDart(args[0])); 194 dartFunctionArgs.append(JsInterop::toDart(args[0], true));
194 } 195 }
195 196
196 v8::Local<v8::Array> argsList = args[args.Length()-1].As<v8::Array>(); 197 v8::Local<v8::Array> argsList = args[args.Length()-1].As<v8::Array>();
197 uint32_t argsListLength = argsList->Length(); 198 uint32_t argsListLength = argsList->Length();
198 for (uint32_t i = 0; i < argsListLength; i++) { 199 for (uint32_t i = 0; i < argsListLength; i++) {
199 dartFunctionArgs.append(JsInterop::toDart(argsList->Get(i))); 200 dartFunctionArgs.append(JsInterop::toDart(argsList->Get(i), true));
200 } 201 }
201 202
202 setJsReturnValue(domData, args, Dart_InvokeClosure(handle, dartFunctionArgs. size(), dartFunctionArgs.data())); 203 setJsReturnValue(domData, args, Dart_InvokeClosure(handle, dartFunctionArgs. size(), dartFunctionArgs.data()));
203 } 204 }
204 205
206 static void functionInvocationCallbackNoWrap(const v8::FunctionCallbackInfo<v8:: Value>& args)
207 {
208 DartScopes scopes(args.Holder());
209 Dart_Handle handle = scopes.handle;
210 DartDOMData* domData = DartDOMData::current();
211 ASSERT(domData);
212 ASSERT(DartUtilities::isFunction(domData, handle));
213
214 Vector<Dart_Handle> dartFunctionArgs;
215 ASSERT(args.Length() == 1 || args.Length() == 2);
216 // If there is 1 argument, we assume it is a v8:Array or arguments, if
217 // there are 2 arguments, the first argument is "this" and the second
218 // argument is an array of arguments.
219 if (args.Length() > 1) {
220 dartFunctionArgs.append(JsInterop::toDart(args[0], false));
221 }
222
223 v8::Local<v8::Array> argsList = args[args.Length()-1].As<v8::Array>();
224 uint32_t argsListLength = argsList->Length();
225 for (uint32_t i = 0; i < argsListLength; i++) {
226 dartFunctionArgs.append(JsInterop::toDart(argsList->Get(i), false));
227 }
228
229 setJsReturnValue(domData, args, Dart_InvokeClosure(handle, dartFunctionArgs. size(), dartFunctionArgs.data()));
230 }
205 static v8::Local<v8::ObjectTemplate> setupInstanceTemplate(v8::Local<v8::Functio nTemplate> proxyTemplate) 231 static v8::Local<v8::ObjectTemplate> setupInstanceTemplate(v8::Local<v8::Functio nTemplate> proxyTemplate)
206 { 232 {
207 v8::Local<v8::ObjectTemplate> instanceTemplate = proxyTemplate->InstanceTemp late(); 233 v8::Local<v8::ObjectTemplate> instanceTemplate = proxyTemplate->InstanceTemp late();
208 instanceTemplate->SetInternalFieldCount(1); 234 instanceTemplate->SetInternalFieldCount(1);
209 return instanceTemplate; 235 return instanceTemplate;
210 } 236 }
211 237
238
212 static v8::Local<v8::FunctionTemplate> dartFunctionTemplate() 239 static v8::Local<v8::FunctionTemplate> dartFunctionTemplate()
213 { 240 {
214 DEFINE_STATIC_LOCAL(v8::Persistent<v8::FunctionTemplate>, proxyTemplate, ()) ; 241 DEFINE_STATIC_LOCAL(v8::Persistent<v8::FunctionTemplate>, proxyTemplate, ()) ;
215 v8::Local<v8::FunctionTemplate> proxyTemplateLocal; 242 v8::Local<v8::FunctionTemplate> proxyTemplateLocal;
216 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent(); 243 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent();
217 if (proxyTemplate.IsEmpty()) { 244 if (proxyTemplate.IsEmpty()) {
218 proxyTemplate.Reset(v8::Isolate::GetCurrent(), v8::FunctionTemplate::New (v8Isolate)); 245 proxyTemplate.Reset(v8::Isolate::GetCurrent(), v8::FunctionTemplate::New (v8Isolate));
219 proxyTemplateLocal = v8::Local<v8::FunctionTemplate>::New(v8Isolate, pro xyTemplate); 246 proxyTemplateLocal = v8::Local<v8::FunctionTemplate>::New(v8Isolate, pro xyTemplate);
220 v8::Local<v8::ObjectTemplate> instanceTemplate = setupInstanceTemplate(p roxyTemplateLocal); 247 v8::Local<v8::ObjectTemplate> instanceTemplate = setupInstanceTemplate(p roxyTemplateLocal);
221 248
222 instanceTemplate->SetCallAsFunctionHandler(&functionInvocationCallback); 249 instanceTemplate->SetCallAsFunctionHandler(&functionInvocationCallback);
223 } else { 250 } else {
224 proxyTemplateLocal = v8::Local<v8::FunctionTemplate>::New(v8Isolate, pro xyTemplate); 251 proxyTemplateLocal = v8::Local<v8::FunctionTemplate>::New(v8Isolate, pro xyTemplate);
225 } 252 }
226 return proxyTemplateLocal; 253 return proxyTemplateLocal;
227 } 254 }
228 255
229 static v8::Local<v8::FunctionTemplate> dartObjectTemplate() 256 static v8::Local<v8::FunctionTemplate> dartFunctionTemplateNoWrap()
230 { 257 {
231 DEFINE_STATIC_LOCAL(v8::Persistent<v8::FunctionTemplate>, proxyTemplate, ()) ; 258 DEFINE_STATIC_LOCAL(v8::Persistent<v8::FunctionTemplate>, proxyTemplate, ()) ;
232 v8::Local<v8::FunctionTemplate> proxyTemplateLocal; 259 v8::Local<v8::FunctionTemplate> proxyTemplateLocal;
233 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent(); 260 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent();
234 if (proxyTemplate.IsEmpty()) { 261 if (proxyTemplate.IsEmpty()) {
235 proxyTemplate.Reset(v8Isolate, v8::FunctionTemplate::New(v8Isolate)); 262 proxyTemplate.Reset(v8::Isolate::GetCurrent(), v8::FunctionTemplate::New (v8Isolate));
236 proxyTemplateLocal = v8::Local<v8::FunctionTemplate>::New(v8Isolate, pro xyTemplate); 263 proxyTemplateLocal = v8::Local<v8::FunctionTemplate>::New(v8Isolate, pro xyTemplate);
237 proxyTemplateLocal->SetClassName(v8::String::NewFromUtf8(v8Isolate, "Dar tObject")); 264 v8::Local<v8::ObjectTemplate> instanceTemplate = setupInstanceTemplate(p roxyTemplateLocal);
238 setupInstanceTemplate(proxyTemplateLocal); 265
266 instanceTemplate->SetCallAsFunctionHandler(&functionInvocationCallbackNo Wrap);
239 } else { 267 } else {
240 proxyTemplateLocal = v8::Local<v8::FunctionTemplate>::New(v8Isolate, pro xyTemplate); 268 proxyTemplateLocal = v8::Local<v8::FunctionTemplate>::New(v8Isolate, pro xyTemplate);
241 } 269 }
242 return proxyTemplateLocal; 270 return proxyTemplateLocal;
243 } 271 }
244 272
245 /** 273 /**
246 * Helper class to manage scopes needed for JSInterop code. 274 * Helper class to manage scopes needed for JSInterop code.
247 */ 275 */
248 class JsInteropScopes { 276 class JsInteropScopes {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 312
285 void setReturnValue(Dart_Handle ret) 313 void setReturnValue(Dart_Handle ret)
286 { 314 {
287 ASSERT(!tryCatch.HasCaught()); 315 ASSERT(!tryCatch.HasCaught());
288 Dart_SetReturnValue(args, ret); 316 Dart_SetReturnValue(args, ret);
289 } 317 }
290 318
291 void setReturnValue(v8::Local<v8::Value> ret) 319 void setReturnValue(v8::Local<v8::Value> ret)
292 { 320 {
293 ASSERT(!tryCatch.HasCaught()); 321 ASSERT(!tryCatch.HasCaught());
294 Dart_SetReturnValue(args, JsInterop::toDart(ret)); 322 Dart_SetReturnValue(args, JsInterop::toDart(ret, false));
295 ASSERT(!tryCatch.HasCaught()); 323 ASSERT(!tryCatch.HasCaught());
296 } 324 }
297 325
298 void setReturnValueInteger(int64_t ret) 326 void setReturnValueInteger(int64_t ret)
299 { 327 {
300 ASSERT(!tryCatch.HasCaught()); 328 ASSERT(!tryCatch.HasCaught());
301 Dart_SetIntegerReturnValue(args, ret); 329 Dart_SetIntegerReturnValue(args, ret);
302 } 330 }
303 }; 331 };
304 332
305 PassRefPtr<JsObject> JsObject::create(v8::Local<v8::Object> v8Handle) 333 PassRefPtr<JsObject> JsObject::create(v8::Local<v8::Object> v8Handle)
306 { 334 {
307 return adoptRef(new JsObject(v8Handle)); 335 return adoptRef(new JsObject(v8Handle));
308 } 336 }
309 337
310 v8::Local<v8::Value> JsInterop::fromDart(DartDOMData* domData, Dart_Handle handl e, Dart_Handle& exception) 338 v8::Local<v8::Value> JsInterop::fromDart(DartDOMData* domData, Dart_Handle handl e, Dart_Handle& exception)
311 { 339 {
312 v8::Handle<v8::Value> value = V8Converter::toV8IfPrimitive(domData, handle, exception); 340 v8::Handle<v8::Value> value = V8Converter::toV8IfPrimitive(domData, handle, exception);
313 if (!value.IsEmpty() || exception) 341 if (!value.IsEmpty() || exception)
314 return value; 342 return value;
343
344 Dart_Handle jso = invokeTopLevelJsInteropMethod(domData, "unwrap_jso", 1, &h andle);
345 ASSERT(!Dart_IsError(jso));
346 if (DartDOMWrapper::subtypeOf(jso, JsObject::dartClassId)) {
347 JsObject* object = DartDOMWrapper::unwrapDartWrapper<JsObject>(domData, jso, exception);
348 if (exception)
349 return v8::Local<v8::Value>();
350 return object->localV8Object();
351 }
315 // TODO(terry): START of uncommented block by Jacob, I've re-enabled for cla mped arrays... 352 // TODO(terry): START of uncommented block by Jacob, I've re-enabled for cla mped arrays...
316 value = V8Converter::toV8IfBrowserNative(domData, handle, exception); 353 value = V8Converter::toV8IfBrowserNative(domData, handle, exception);
317 if (!value.IsEmpty() || exception) 354 if (!value.IsEmpty() || exception)
318 return value; 355 return value;
319 // TODO(terry): END of uncommented block by Jacob.
320 if (DartDOMWrapper::subtypeOf(handle, JsObject::dartClassId)) {
321 JsObject* object = DartDOMWrapper::unwrapDartWrapper<JsObject>(domData, handle, exception);
322 if (exception)
323 return v8::Local<v8::Value>();
324 return object->localV8Object();
325 }
326 356
327 if (DartUtilities::isFunction(domData, handle)) { 357 if (DartUtilities::isFunction(domData, handle)) {
328 v8::Local<v8::Object> functionProxy = dartFunctionTemplate()->InstanceTe mplate()->NewInstance(); 358 v8::Local<v8::Object> functionProxy = dartFunctionTemplate()->InstanceTe mplate()->NewInstance();
329 DartHandleProxy::writePointerToProxy(functionProxy, handle); 359 DartHandleProxy::writePointerToProxy(functionProxy, handle);
330 // The raw functionProxy doesn't behave enough like a true JS function 360 // The raw functionProxy doesn't behave enough like a true JS function
331 // so we wrap it in a true JS function. 361 // so we wrap it in a true JS function.
332 return domData->jsInteropData()->wrapDartFunction()->Call(functionProxy, 0, 0); 362 return domData->jsInteropData()->wrapDartFunction()->Call(functionProxy, 0, 0);
333 } 363 }
334 364
335 v8::Local<v8::Object> proxy; 365 v8::Local<v8::Object> proxy;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 418 v8::Isolate* isolate = v8::Isolate::GetCurrent();
389 v8::Persistent<v8::Object> persistentHandle; 419 v8::Persistent<v8::Object> persistentHandle;
390 v8Object.Reset(isolate, v8Handle); 420 v8Object.Reset(isolate, v8Handle);
391 } 421 }
392 422
393 v8::Local<v8::Object> JsObject::localV8Object() 423 v8::Local<v8::Object> JsObject::localV8Object()
394 { 424 {
395 return v8::Local<v8::Object>::New(v8::Isolate::GetCurrent(), v8Object); 425 return v8::Local<v8::Object>::New(v8::Isolate::GetCurrent(), v8Object);
396 } 426 }
397 427
398 Dart_Handle JsInterop::toDart(v8::Local<v8::Value> v8Handle) 428 Dart_Handle JsInterop::toDart(v8::Local<v8::Value> v8Handle, bool sometimesUseHt ml)
399 { 429 {
400 Dart_Handle handle = V8Converter::toDartIfPrimitive(v8Handle); 430 Dart_Handle handle = V8Converter::toDartIfPrimitive(v8Handle);
401 if (handle) 431 if (handle)
402 return handle; 432 return handle;
403 433
404 ASSERT(v8Handle->IsObject()); 434 ASSERT(v8Handle->IsObject());
405 v8::Handle<v8::Object> object = v8Handle.As<v8::Object>(); 435 v8::Handle<v8::Object> object = v8Handle.As<v8::Object>();
406 // TODO(terry): START of uncommented block by Jacob, I've re-enabled for cla mped arrays... 436 // TODO(terry): START of uncommented block by Jacob, I've re-enabled for cla mped arrays...
407 Dart_Handle exception = 0; 437 Dart_Handle exception = 0;
408 handle = V8Converter::toDartIfBrowserNative(object, object->CreationContext( )->GetIsolate(), exception); 438 handle = V8Converter::toDartIfBrowserNative(object, object->CreationContext( )->GetIsolate(), exception);
(...skipping 10 matching lines...) Expand all
419 DartPersistentValue* scriptValue = DartHandleProxy::readPointerFromProxy (v8Handle); 449 DartPersistentValue* scriptValue = DartHandleProxy::readPointerFromProxy (v8Handle);
420 ASSERT(scriptValue->isIsolateAlive()); 450 ASSERT(scriptValue->isIsolateAlive());
421 // If the isolate does not match we fall back to using the existing JS 451 // If the isolate does not match we fall back to using the existing JS
422 // wrapper for the Dart object so that simple cases that would work in 452 // wrapper for the Dart object so that simple cases that would work in
423 // Dart2Js work. We could alternately throw an exception here. 453 // Dart2Js work. We could alternately throw an exception here.
424 if (scriptValue->isolate() == Dart_CurrentIsolate()) { 454 if (scriptValue->isolate() == Dart_CurrentIsolate()) {
425 return scriptValue->value(); 455 return scriptValue->value();
426 } 456 }
427 } 457 }
428 458
429 return JsObject::toDart(object); 459 return JsObject::toDart(object, sometimesUseHtml);
430 } 460 }
431 461
432 Dart_Handle JsObject::toDart(v8::Local<v8::Object> object) 462 Dart_Handle JsObject::toDart(v8::Local<v8::Object> object, bool sometimesUseHtml )
433 { 463 {
434 // FIXME: perform caching so that === can be used. 464 Dart_Handle wrapper;
465 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent();
466 DartDOMData* domData = DartDOMData::current();
467 DartJsInteropData* interopData = domData->jsInteropData();
468 v8::Local<v8::String> existingDartWrapperKey = interopData->existingDartWrap perHiddenField(v8Isolate);
469
470 // TODO(alanknight): This will fail for multiple isolates referencing the sa me JS object.
471 // We probably need to use a different property name for different isolates.
472 v8::Local<v8::Value> hiddenValue = object->GetHiddenValue(existingDartWrappe rKey);
473
474 if (*hiddenValue && hiddenValue->IsObject()) {
475 DartPersistentValue* scriptValue = DartHandleProxy::readPointerFromProxy (hiddenValue.As<v8::Object>());
476 ASSERT(scriptValue->isIsolateAlive());
477 // If the isolate does not match we fall back to using the existing JS
478 // wrapper for the Dart object so that simple cases that would work in
479 // Dart2Js work. We could alternately throw an exception here.
480 if (scriptValue->isolate() == Dart_CurrentIsolate()) {
481 Dart_Handle wrapper = scriptValue->value();
482 if (sometimesUseHtml) {
483 wrapper = invokeTopLevelJsInteropMethod(domData, "_maybeWrap", 1 , &wrapper);
484 }
485 return wrapper;
486 }
487 }
488
489 Dart_Handle ret = 0;
435 if (object->IsFunction()) { 490 if (object->IsFunction()) {
436 RefPtr<JsFunction> jsFunction = JsFunction::create(object.As<v8::Functio n>()); 491 RefPtr<JsFunction> jsFunction = JsFunction::create(object.As<v8::Functio n>());
437 return JsFunction::toDart(jsFunction); 492 wrapper = JsFunction::toDart(jsFunction);
493 } else if (object->IsArray()
494 // Check for Dart List objects from different Dart isolates.
495 // In dart2js the List from a different isolate would just be a regular
496 // JS Array so it can be treated as a JS Array.
497 || dartListTemplate()->HasInstance(object)) {
498 RefPtr<JsArray> jsArray = JsArray::create(object);
499 wrapper = JsArray::toDart(jsArray);
500 } else {
501 RefPtr<JsObject> jsObject = JsObject::create(object);
502 wrapper = JsObject::toDart(jsObject);
503 if (sometimesUseHtml) {
504 ret = invokeTopLevelJsInteropMethod(DartDOMData::current(), "_maybeW rap", 1, &wrapper);
505 }
438 } 506 }
439 507
440 if (object->IsArray()) { 508 v8::Local<v8::Object> proxy;
441 RefPtr<JsArray> jsArray = JsArray::create(object.As<v8::Array>()); 509
442 return JsArray::toDart(jsArray); 510 // Prevent creation of cross frame dart:html objects for classes other than Window.
511 // Verify that the object is from the same context using the same check
512 // we used to use in V8Converter.
513 if (!object->CreationContext()->Global()->StrictEquals(DartUtilities::curren tV8Context()->Global())) {
514 // Short circuit creating dart:html wrappers for cross frame objects
515 // other than window.
516 // TODO(jacobr): handle cross frame Window objects differently to more
517 // exactly match existing dart:html semantics.
518 if (!object->CreationContext()->Global()->StrictEquals(object)) {
519 Dart_SetField(wrapper, Dart_NewStringFromCString("_dartHtmlWrapper") , wrapper);
520 }
443 } 521 }
444 522 ASSERT(Dart_IsInstance(wrapper));
445 RefPtr<JsObject> jsObject = JsObject::create(object); 523 // Simulate the behavior of the Dart dev compiler where new List() is
446 return JsObject::toDart(jsObject); 524 // equivalent to a JavaScript array. We accomplish this by creating a
525 // JavaScript object that fakes that it is a JavaScript array but is
526 // actually backed by a Dart list. This is not a breaking change as
527 // existing Dart-JS interop passed arrays as opaque Dart handles.
528 // The jsify method can still be called if you wish to create a copy
529 // of a json like Dart data structure.
530 proxy = dartObjectTemplate()->InstanceTemplate()->NewInstance();
531 DartHandleProxy::writePointerToProxy(proxy, wrapper);
532 object->SetHiddenValue(existingDartWrapperKey, proxy);
533 return ret != 0 ? ret : wrapper;
447 } 534 }
448 535
449 static void maybeCreateJsObjectImplClass(DartDOMData* domData) 536 void JsInterop::buildInteropPatchFiles(DartDOMData* domData, Vector<InteropPatch File>* patches, Dart_Handle& exception)
537 {
538 // Build patch files implementing all external methods specified with new
539 // style JS interop and JsObjectImpl, JsFunctionImpl, and JsArrayImpl
540 // classes that implement all Dart types annoted with @Js.
541 // The sole purpose of these classes is to ensure that checked mode
542 // allows casting a JsObject to all types implemented by a JsObject.
543 Dart_Handle externals = invokeTopLevelJsInteropMethod(domData, "_generateInt eropPatchFiles", 0, 0);
544 if (Dart_IsError(externals)) {
545 exception = externals;
546 return;
547 }
548 ASSERT(Dart_IsList(externals));
549 intptr_t externalsLength = 0;
550 Dart_ListLength(externals, &externalsLength);
551 ASSERT(externalsLength % 3 == 0);
552
553 for (intptr_t i = 0; i < externalsLength; i += 3) {
554 InteropPatchFile patch;
555
556 Dart_Handle libraryUri = Dart_ListGetAt(externals, i);
557 Dart_Handle patchFileUri = Dart_ListGetAt(externals, i + 1);
558 Dart_Handle source = Dart_ListGetAt(externals, i + 2);
559 ASSERT(Dart_IsString(libraryUri));
560 ASSERT(Dart_IsString(patchFileUri));
561 ASSERT(Dart_IsString(source));
562 patch.libraryUri = DartUtilities::toString(libraryUri);
563 patch.patchFileUri = DartUtilities::toString(patchFileUri);
564 patch.source = DartUtilities::toString(source);
565 patches->append(patch);
566 }
567 }
568
569 void JsInterop::initializeJsInterop(DartDOMData* domData, const Vector<InteropPa tchFile>& patches, Dart_Handle& exception)
450 { 570 {
451 DartJsInteropData* interopData = domData->jsInteropData(); 571 DartJsInteropData* interopData = domData->jsInteropData();
452 // Skip if the JSObjectImpl class has already been defined. 572 // Skip if the JSObjectImpl class has already been defined.
453 if (interopData->jsObjectImplDefined()) { 573 if (interopData->jsObjectImplDefined()) {
454 return; 574 return;
455 } 575 }
456 // Helper method that generates boilerplate source code for 576 // Helper method that generates boilerplate source code for
457 // JsObjectImpl, JsFunctionImpl, and JsArrayImpl classes that implement 577 // JsObjectImpl, JsFunctionImpl, and JsArrayImpl classes that implement
458 // all Dart types that have been passed to the dart:js registerJsInterfaces 578 // all Dart types that have been passed to the dart:js registerJsInterfaces
459 // method. The sole purpose of these classes is to ensure that checked mode 579 // method. The sole purpose of these classes is to ensure that checked mode
460 // allows casting a JsObject to all types implemented by a JsObject. 580 // allows casting a JsObject to all types implemented by a JsObject.
461 Dart_Handle source = invokeTopLevelJsInteropMethod(domData, "_generateJsObje ctImplPart", 0, 0);
462 ASSERT(Dart_IsString(source));
463 581
464 Dart_Handle ret = Dart_LibraryLoadPatch(domData->jsLibrary(), Dart_NewString FromCString("JsInteropImpl.dart"), source); 582 Dart_Handle ret;
465 ALLOW_UNUSED_LOCAL(ret); 583 for (size_t i = 0; i < patches.size(); ++i) {
466 ASSERT(!Dart_IsError(ret)); 584 const InteropPatchFile& patch = patches[i];
585 Dart_Handle library = Dart_LookupLibrary(DartUtilities::safeStringToDart String(patch.libraryUri));
586 ASSERT(Dart_IsLibrary(library));
587 Dart_Handle patchFileUri = DartUtilities::safeStringToDartString(patch.p atchFileUri);
588 Dart_Handle source = DartUtilities::safeStringToDartString(patch.source) ;
589 ret = Dart_LibraryLoadPatch(library, patchFileUri, source);
590 if (Dart_IsError(ret)) {
591 exception = ret;
592 return;
593 }
594 }
467 ret = Dart_FinalizeLoading(false); 595 ret = Dart_FinalizeLoading(false);
468 ASSERT(!Dart_IsError(ret)); 596 if (Dart_IsError(ret)) {
597 exception = ret;
598 return;
599 }
469 600
470 interopData->setJsObjectImplDefined(); 601 interopData->setJsObjectImplDefined();
471 602
472 // Start of polyfill work to make Dart List proxies behave like JavaScript 603 if (domData->isDOMEnabled()) {
473 // Arrays by monkey patching JavaScript Array and the List JavaScript 604 // Start of polyfill work to make Dart List proxies behave like JavaScri pt
474 // proxies as needed. 605 // Arrays by monkey patching JavaScript Array and the List JavaScript
475 v8::Context::Scope scope(DartUtilities::currentV8Context()); 606 // proxies as needed.
607 v8::Context::Scope scope(DartUtilities::currentV8Context());
476 608
477 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent(); 609 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent();
478 610
479 v8::Local<v8::Function> dartArrayConstructor = dartListTemplate()->GetFuncti on(); 611 v8::Local<v8::Function> dartArrayConstructor = dartListTemplate()->GetFu nction();
480 612
481 DartUtilities::currentV8Context()->Global()->Set(v8::String::NewFromUtf8(v8I solate, "$DartList"), 613 DartUtilities::currentV8Context()->Global()->Set(v8::String::NewFromUtf8 (v8Isolate, "$DartList"),
482 dartArrayConstructor); 614 dartArrayConstructor);
483 V8ScriptRunner::compileAndRunInternalScript(v8::String::NewFromUtf8(v8Isolat e, dartArrayPolyfill), v8Isolate); 615 V8ScriptRunner::compileAndRunInternalScript(v8::String::NewFromUtf8(v8Is olate, dartArrayPolyfill), v8Isolate);
616
617 ret = Dart_Invoke(domData->jsLibrary(), Dart_NewStringFromCString("_regi sterAllJsInterfaces"), 0, 0);
618 if (Dart_IsError(ret)) {
619 exception = ret;
620 return;
621 }
622 }
484 } 623 }
485 624
486 Dart_Handle JsObject::toDart(PassRefPtr<JsObject> jsObject) 625 Dart_Handle JsObject::toDart(PassRefPtr<JsObject> jsObject)
487 { 626 {
488 DartDOMData* domData = DartDOMData::current(); 627 DartDOMData* domData = DartDOMData::current();
489 // We need to ensure JsObjectImpl exists before creating the wrapper. 628 // We need to ensure JsObjectImpl exists before creating the wrapper.
490 maybeCreateJsObjectImplClass(domData);
491 return DartDOMWrapper::createWrapper<JsObject>(domData, jsObject.get(), JsOb ject::dartClassId); 629 return DartDOMWrapper::createWrapper<JsObject>(domData, jsObject.get(), JsOb ject::dartClassId);
492 } 630 }
493 631
494 JsObject::~JsObject() 632 JsObject::~JsObject()
495 { 633 {
496 v8Object.Reset(); 634 v8Object.Reset();
497 } 635 }
498 636
499 Dart_Handle JsFunction::toDart(PassRefPtr<JsFunction> jsFunction) 637 Dart_Handle JsFunction::toDart(PassRefPtr<JsFunction> jsFunction)
500 { 638 {
501 DartDOMData* domData = DartDOMData::current(); 639 DartDOMData* domData = DartDOMData::current();
502 // We need to ensure JsObjectImpl exists before creating the wrapper. 640 // We need to ensure JsObjectImpl exists before creating the wrapper.
503 maybeCreateJsObjectImplClass(domData);
504 return DartDOMWrapper::createWrapper<JsFunction>(domData, jsFunction.get(), JsFunction::dartClassId); 641 return DartDOMWrapper::createWrapper<JsFunction>(domData, jsFunction.get(), JsFunction::dartClassId);
505 } 642 }
506 643
507 JsFunction::JsFunction(v8::Local<v8::Function> v8Handle) : JsObject(v8Handle) { } 644 JsFunction::JsFunction(v8::Local<v8::Function> v8Handle) : JsObject(v8Handle) { }
508 645
509 PassRefPtr<JsFunction> JsFunction::create(v8::Local<v8::Function> v8Handle) 646 PassRefPtr<JsFunction> JsFunction::create(v8::Local<v8::Function> v8Handle)
510 { 647 {
511 return adoptRef(new JsFunction(v8Handle)); 648 return adoptRef(new JsFunction(v8Handle));
512 } 649 }
513 650
514 v8::Local<v8::Function> JsFunction::localV8Function() 651 v8::Local<v8::Function> JsFunction::localV8Function()
515 { 652 {
516 return localV8Object().As<v8::Function>(); 653 return localV8Object().As<v8::Function>();
517 } 654 }
518 655
519 Dart_Handle JsArray::toDart(PassRefPtr<JsArray> jsArray) 656 Dart_Handle JsArray::toDart(PassRefPtr<JsArray> jsArray)
520 { 657 {
521 DartDOMData* domData = DartDOMData::current(); 658 DartDOMData* domData = DartDOMData::current();
522 // We need to ensure JsArrayImpl exists before creating the wrapper. 659 // We need to ensure JsArrayImpl exists before creating the wrapper.
523 maybeCreateJsObjectImplClass(domData);
524 return DartDOMWrapper::createWrapper<JsArray>(domData, jsArray.get(), JsArra y::dartClassId); 660 return DartDOMWrapper::createWrapper<JsArray>(domData, jsArray.get(), JsArra y::dartClassId);
525 } 661 }
526 662
527 JsArray::JsArray(v8::Local<v8::Array> v8Handle) : JsObject(v8Handle) { } 663 JsArray::JsArray(v8::Local<v8::Object> v8Handle) : JsObject(v8Handle) { }
528 664
529 PassRefPtr<JsArray> JsArray::create(v8::Local<v8::Array> v8Handle) 665 PassRefPtr<JsArray> JsArray::create(v8::Local<v8::Object> v8Handle)
530 { 666 {
531 return adoptRef(new JsArray(v8Handle)); 667 return adoptRef(new JsArray(v8Handle));
532 } 668 }
533 669
534 v8::Local<v8::Array> JsArray::localV8Array()
535 {
536 return localV8Object().As<v8::Array>();
537 }
538
539 namespace JsInteropInternal { 670 namespace JsInteropInternal {
540 671
541 typedef HashMap<Dart_Handle, v8::Handle<v8::Value> > DartHandleToV8Map; 672 typedef HashMap<Dart_Handle, v8::Handle<v8::Value> > DartHandleToV8Map;
542 v8::Handle<v8::Value> jsifyHelper(DartDOMData*, Dart_Handle value, DartHandleToV 8Map&, Dart_Handle& exception); 673 v8::Handle<v8::Value> jsifyHelper(DartDOMData*, Dart_Handle value, DartHandleToV 8Map&, Dart_Handle& exception);
543 674
544 void argsListToV8(DartDOMData* domData, Dart_Handle args, Vector<v8::Local<v8::V alue> >* v8Args, Dart_Handle& exception) 675 void argsListToV8(DartDOMData* domData, Dart_Handle args, Vector<v8::Local<v8::V alue> >* v8Args, Dart_Handle& exception)
545 { 676 {
546 if (Dart_IsNull(args)) 677 if (Dart_IsNull(args))
547 return; 678 return;
548 679
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 v8::Local<v8::Value> ret = constructorArg.As<v8::Function>()->CallAsCons tructor(v8Args.size(), v8Args.data()); 729 v8::Local<v8::Value> ret = constructorArg.As<v8::Function>()->CallAsCons tructor(v8Args.size(), v8Args.data());
599 crashIfV8IsDead(); 730 crashIfV8IsDead();
600 731
601 if (scopes.handleJsException(&exception)) 732 if (scopes.handleJsException(&exception))
602 goto fail; 733 goto fail;
603 734
604 // Intentionally skip auto-conversion in this case as the user expects 735 // Intentionally skip auto-conversion in this case as the user expects
605 // a JSObject. FIXME: evaluate if this is the right solution. 736 // a JSObject. FIXME: evaluate if this is the right solution.
606 // Alternately, we could throw an exception. 737 // Alternately, we could throw an exception.
607 if (ret->IsObject()) { 738 if (ret->IsObject()) {
608 scopes.setReturnValue(JsObject::toDart(ret.As<v8::Object>())); 739 scopes.setReturnValue(JsObject::toDart(ret.As<v8::Object>(), false)) ;
609 } else { 740 } else {
610 // This will throw an exception in Dart checked mode. 741 // This will throw an exception in Dart checked mode.
611 scopes.setReturnValue(ret); 742 scopes.setReturnValue(ret);
612 } 743 }
613 return; 744 return;
614 } 745 }
615 746
616 fail: 747 fail:
617 Dart_ThrowException(exception); 748 Dart_ThrowException(exception);
618 ASSERT_NOT_REACHED(); 749 ASSERT_NOT_REACHED();
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
865 } 996 }
866 997
867 fail: 998 fail:
868 Dart_ThrowException(exception); 999 Dart_ThrowException(exception);
869 ASSERT_NOT_REACHED(); 1000 ASSERT_NOT_REACHED();
870 } 1001 }
871 1002
872 static void newJsArrayCallback(Dart_NativeArguments args) 1003 static void newJsArrayCallback(Dart_NativeArguments args)
873 { 1004 {
874 JsInteropScopes scopes(args); 1005 JsInteropScopes scopes(args);
875 scopes.setReturnValue(JsObject::toDart(v8::Array::New(v8::Isolate::GetCurren t()))); 1006 scopes.setReturnValue(JsObject::toDart(v8::Array::New(v8::Isolate::GetCurren t()), false));
876 return; 1007 return;
877 } 1008 }
878 1009
879 static void newJsArrayFromSafeListCallback(Dart_NativeArguments args) 1010 static void newJsArrayFromSafeListCallback(Dart_NativeArguments args)
880 { 1011 {
881 Dart_Handle exception = 0; 1012 Dart_Handle exception = 0;
882 { 1013 {
883 JsInteropScopes scopes(args); 1014 JsInteropScopes scopes(args);
884 DartDOMData* domData = static_cast<DartDOMData*>(Dart_GetNativeIsolateDa ta(args)); 1015 DartDOMData* domData = static_cast<DartDOMData*>(Dart_GetNativeIsolateDa ta(args));
885 Dart_Handle list = Dart_GetNativeArgument(args, 0); 1016 Dart_Handle list = Dart_GetNativeArgument(args, 0);
(...skipping 23 matching lines...) Expand all
909 ASSERT_NOT_REACHED(); 1040 ASSERT_NOT_REACHED();
910 } 1041 }
911 1042
912 1043
913 static void jsArrayLengthCallback(Dart_NativeArguments args) 1044 static void jsArrayLengthCallback(Dart_NativeArguments args)
914 { 1045 {
915 Dart_Handle exception = 0; 1046 Dart_Handle exception = 0;
916 { 1047 {
917 JsInteropScopes scopes(args); 1048 JsInteropScopes scopes(args);
918 JsArray* receiver = DartDOMWrapper::receiver<JsArray>(args); 1049 JsArray* receiver = DartDOMWrapper::receiver<JsArray>(args);
919 uint32_t length = receiver->localV8Array()->Length(); 1050 v8::Local<v8::Value> length = receiver->localV8Object()->Get(v8::String: :NewFromUtf8(v8::Isolate::GetCurrent(), "length"));
920 if (scopes.handleJsException(&exception)) 1051 if (scopes.handleJsException(&exception))
921 goto fail; 1052 goto fail;
922 scopes.setReturnValueInteger(length); 1053 scopes.setReturnValue(length);
923 return; 1054 return;
924 } 1055 }
925 1056
926 fail: 1057 fail:
927 Dart_ThrowException(exception); 1058 Dart_ThrowException(exception);
928 ASSERT_NOT_REACHED(); 1059 ASSERT_NOT_REACHED();
929 } 1060 }
930 1061
931 static void fromBrowserObjectCallback(Dart_NativeArguments args) 1062 static void fromBrowserObjectCallback(Dart_NativeArguments args)
932 { 1063 {
933 Dart_Handle exception = 0; 1064 Dart_Handle exception = 0;
934 { 1065 {
935 JsInteropScopes scopes(args); 1066 JsInteropScopes scopes(args);
936 DartDOMData* domData = static_cast<DartDOMData*>(Dart_GetNativeIsolateDa ta(args)); 1067 DartDOMData* domData = static_cast<DartDOMData*>(Dart_GetNativeIsolateDa ta(args));
937 1068
938 v8::Local<v8::Value> ret = V8Converter::toV8IfBrowserNative(domData, Dar t_GetNativeArgument(args, 0), exception); 1069 v8::Local<v8::Value> ret = V8Converter::toV8IfBrowserNative(domData, Dar t_GetNativeArgument(args, 0), exception);
939 if (ret.IsEmpty()) { 1070 if (ret.IsEmpty()) {
940 exception = Dart_NewStringFromCString("object must be an Node, Array Buffer, Blob, ImageData, or IDBKeyRange"); 1071 exception = Dart_NewStringFromCString("object must be an Node, Array Buffer, Blob, ImageData, or IDBKeyRange");
941 goto fail; 1072 goto fail;
942 } 1073 }
943 if (exception) 1074 if (exception)
944 goto fail; 1075 goto fail;
945 ASSERT(ret->IsObject()); 1076 ASSERT(ret->IsObject());
946 if (scopes.handleJsException(&exception)) 1077 if (scopes.handleJsException(&exception))
947 goto fail; 1078 goto fail;
948 scopes.setReturnValue(JsObject::toDart(ret.As<v8::Object>())); 1079 scopes.setReturnValue(JsObject::toDart(ret.As<v8::Object>(), false));
949 return; 1080 return;
950 } 1081 }
951 1082
952 fail: 1083 fail:
953 Dart_ThrowException(exception); 1084 Dart_ThrowException(exception);
954 ASSERT_NOT_REACHED(); 1085 ASSERT_NOT_REACHED();
955 } 1086 }
956 1087
957 static void applyCallback(Dart_NativeArguments args) 1088 static void applyCallback(Dart_NativeArguments args)
958 { 1089 {
959 Dart_Handle exception = 0; 1090 Dart_Handle exception = 0;
960 { 1091 {
961 JsInteropScopes scopes(args); 1092 JsInteropScopes scopes(args);
962 DartDOMData* domData = static_cast<DartDOMData*>(Dart_GetNativeIsolateDa ta(args)); 1093 DartDOMData* domData = static_cast<DartDOMData*>(Dart_GetNativeIsolateDa ta(args));
963 JsFunction* receiver = DartDOMWrapper::receiver<JsFunction>(args); 1094 JsFunction* receiver = DartDOMWrapper::receiver<JsFunction>(args);
964 1095
965 Vector<v8::Local<v8::Value> > v8Args; 1096 Vector<v8::Local<v8::Value> > v8Args;
966 argsListToV8(domData, Dart_GetNativeArgument(args, 1), &v8Args, exceptio n); 1097 argsListToV8(domData, Dart_GetNativeArgument(args, 1), &v8Args, exceptio n);
967 if (exception) 1098 if (exception)
968 goto fail; 1099 goto fail;
969 1100
970 v8::Local<v8::Value> thisArg; 1101 v8::Local<v8::Value> thisArg;
971 Dart_Handle thisArgDart = Dart_GetNativeArgument(args, 2); 1102 Dart_Handle thisArgDart = Dart_GetNativeArgument(args, 2);
972 if (Dart_IsNull(thisArgDart)) { 1103 if (Dart_IsNull(thisArgDart)) {
973 // Use the global v8 object if no Dart thisArg was passed in. 1104 // Use the global v8 object if no Dart thisArg was passed in.
974 thisArg = DartUtilities::currentV8Context()->Global(); 1105 thisArg = DartUtilities::currentV8Context()->Global();
975 } else { 1106 } else {
976 Dart_Handle jso = Dart_GetField(thisArgDart, Dart_NewStringFromCStri ng("blink_jsObject")); 1107 thisArg = JsInterop::fromDart(domData, thisArgDart, exception);
977 if (!Dart_IsError(jso) && DartDOMWrapper::subtypeOf(jso, JsObject::d artClassId)) { 1108 if (exception)
978 // Use the blink JS Interop object. 1109 goto fail;
979 JsObject* object = DartDOMWrapper::unwrapDartWrapper<JsObject>(d omData, jso, exception);
980 if (exception)
981 thisArg = v8::Local<v8::Value>();
982 thisArg = object->localV8Object();
983 } else {
984 thisArg = JsInterop::fromDart(domData, thisArgDart, exception);
985 if (exception)
986 goto fail;
987 }
988 if (!thisArg->IsObject()) { 1110 if (!thisArg->IsObject()) {
989 exception = Dart_NewStringFromCString("thisArg is not an object" ); 1111 exception = Dart_NewStringFromCString("thisArg is not an object" );
990 goto fail; 1112 goto fail;
991 } 1113 }
992 } 1114 }
993 1115
994 v8::Local<v8::Value> ret = V8ScriptRunner::callFunction(receiver->localV 8Function(), 1116 v8::Local<v8::Value> ret = V8ScriptRunner::callFunction(receiver->localV 8Function(),
995 DartUtilities::scriptExecutionContext(), 1117 DartUtilities::scriptExecutionContext(),
996 thisArg.As<v8::Object>(), 1118 thisArg.As<v8::Object>(),
997 v8Args.size(), 1119 v8Args.size(),
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1075 } 1197 }
1076 fail: 1198 fail:
1077 Dart_ThrowException(exception); 1199 Dart_ThrowException(exception);
1078 ASSERT_NOT_REACHED(); 1200 ASSERT_NOT_REACHED();
1079 } 1201 }
1080 1202
1081 static void contextCallback(Dart_NativeArguments args) 1203 static void contextCallback(Dart_NativeArguments args)
1082 { 1204 {
1083 v8::Local<v8::Context> v8Context = DartUtilities::currentV8Context(); 1205 v8::Local<v8::Context> v8Context = DartUtilities::currentV8Context();
1084 v8::Context::Scope scope(v8Context); 1206 v8::Context::Scope scope(v8Context);
1085 Dart_SetReturnValue(args, JsObject::toDart(v8Context->Global())); 1207 Dart_SetReturnValue(args, JsObject::toDart(v8Context->Global(), false));
1086 } 1208 }
1087 1209
1088 static void finalizeJsInterfacesCallback(Dart_NativeArguments args) 1210 static void finalizeJsInterfacesCallback(Dart_NativeArguments args)
1089 { 1211 {
1090 DartDOMData* domData = static_cast<DartDOMData*>(Dart_GetNativeIsolateData(a rgs)); 1212 // Obsolete.
1091 maybeCreateJsObjectImplClass(domData);
1092 } 1213 }
1093 1214
1094 static void interfacesFinalizedCallback(Dart_NativeArguments args) 1215 static void interfacesFinalizedCallback(Dart_NativeArguments args)
1095 { 1216 {
1096 DartDOMData* domData = static_cast<DartDOMData*>(Dart_GetNativeIsolateData(a rgs)); 1217 DartDOMData* domData = static_cast<DartDOMData*>(Dart_GetNativeIsolateData(a rgs));
1097 DartJsInteropData* interopData = domData->jsInteropData(); 1218 DartJsInteropData* interopData = domData->jsInteropData();
1098 // Skip if the JSObjectImpl class has already been defined. 1219 // Skip if the JSObjectImpl class has already been defined.
1099 Dart_SetBooleanReturnValue(args, interopData->jsObjectImplDefined()); 1220 Dart_SetBooleanReturnValue(args, interopData->jsObjectImplDefined());
1100 } 1221 }
1101 1222
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1190 v8::Local<v8::Value> ret = jsifyHelper(domData, value, map, exception); 1311 v8::Local<v8::Value> ret = jsifyHelper(domData, value, map, exception);
1191 if (exception) 1312 if (exception)
1192 goto fail; 1313 goto fail;
1193 1314
1194 if (scopes.handleJsException(&exception)) 1315 if (scopes.handleJsException(&exception))
1195 goto fail; 1316 goto fail;
1196 // Intentionally skip auto-conversion in this case as the user expects 1317 // Intentionally skip auto-conversion in this case as the user expects
1197 // a JSObject. FIXME: evaluate if this is the right solution. 1318 // a JSObject. FIXME: evaluate if this is the right solution.
1198 // Alternately, we could throw an exception. 1319 // Alternately, we could throw an exception.
1199 if (ret->IsObject()) { 1320 if (ret->IsObject()) {
1200 scopes.setReturnValue(JsObject::toDart(ret.As<v8::Object>())); 1321 scopes.setReturnValue(JsObject::toDart(ret.As<v8::Object>(), false)) ;
1201 } else { 1322 } else {
1202 // This will throw an exception in Dart checked mode. 1323 // This will throw an exception in Dart checked mode.
1203 scopes.setReturnValue(ret); 1324 scopes.setReturnValue(ret);
1204 } 1325 }
1205 return; 1326 return;
1206 } 1327 }
1207 fail: 1328 fail:
1208 Dart_ThrowException(exception); 1329 Dart_ThrowException(exception);
1209 ASSERT_NOT_REACHED(); 1330 ASSERT_NOT_REACHED();
1210 } 1331 }
(...skipping 15 matching lines...) Expand all
1226 if (scopes.handleJsException(&exception)) 1347 if (scopes.handleJsException(&exception))
1227 goto fail; 1348 goto fail;
1228 scopes.setReturnValue(ret); 1349 scopes.setReturnValue(ret);
1229 return; 1350 return;
1230 } 1351 }
1231 fail: 1352 fail:
1232 Dart_ThrowException(exception); 1353 Dart_ThrowException(exception);
1233 ASSERT_NOT_REACHED(); 1354 ASSERT_NOT_REACHED();
1234 } 1355 }
1235 1356
1357
1358 static void withThisCallbackNoWrap(Dart_NativeArguments args)
1359 {
1360 Dart_Handle exception = 0;
1361 {
1362 JsInteropScopes scopes(args);
1363 Dart_Handle function = Dart_GetNativeArgument(args, 0);
1364 DartDOMData* domData = static_cast<DartDOMData*>(Dart_GetNativeIsolateDa ta(args));
1365 ASSERT(DartUtilities::isFunction(domData, function));
1366
1367 v8::Local<v8::Object> proxy = dartFunctionTemplateNoWrap()->InstanceTemp late()->NewInstance();
1368 DartHandleProxy::writePointerToProxy(proxy, function);
1369
1370 v8::Local<v8::Function> ret = v8::Local<v8::Function>::Cast(domData->jsI nteropData()->captureThisFunction()->Call(proxy, 0, 0));
1371
1372 if (scopes.handleJsException(&exception))
1373 goto fail;
1374 scopes.setReturnValue(ret);
1375 return;
1376 }
1377 fail:
1378 Dart_ThrowException(exception);
1379 ASSERT_NOT_REACHED();
1380 }
1381
1236 } 1382 }
1237 1383
1238 static DartNativeEntry nativeEntries[] = { 1384 static DartNativeEntry nativeEntries[] = {
1239 { JsInteropInternal::jsObjectConstructorCallback, 2, "JsObject_constructorCa llback" }, 1385 { JsInteropInternal::jsObjectConstructorCallback, 2, "JsObject_constructorCa llback" },
1240 { JsInterop::jsInteropContextCallback, 0, "Js_context_Callback" }, 1386 { JsInterop::jsInteropContextCallback, 0, "Js_context_Callback" },
1241 { JsInteropInternal::finalizeJsInterfacesCallback, 0, "Js_finalizeJsInterfac es" }, 1387 { JsInteropInternal::finalizeJsInterfacesCallback, 0, "Js_finalizeJsInterfac es" },
1242 { JsInteropInternal::interfacesFinalizedCallback, 0, "Js_interfacesFinalized _Callback" }, 1388 { JsInteropInternal::interfacesFinalizedCallback, 0, "Js_interfacesFinalized _Callback" },
1243 { JsInteropInternal::jsifyCallback, 1, "JsObject_jsify" }, 1389 { JsInteropInternal::jsifyCallback, 1, "JsObject_jsify" },
1244 { JsInteropInternal::withThisCallback, 1, "JsFunction_withThis" }, 1390 { JsInteropInternal::withThisCallback, 1, "JsFunction_withThis" },
1391 { JsInteropInternal::withThisCallbackNoWrap, 1, "JsFunction_withThisNoWrap" },
1245 { JsInterop::jsInteropGetterCallback, 2, "JsObject_[]" }, 1392 { JsInterop::jsInteropGetterCallback, 2, "JsObject_[]" },
1246 { JsInteropInternal::setterCallback, 3, "JsObject_[]=" }, 1393 { JsInteropInternal::setterCallback, 3, "JsObject_[]=" },
1247 { JsInteropInternal::hashCodeCallback, 1, "JsObject_hashCode" }, 1394 { JsInteropInternal::hashCodeCallback, 1, "JsObject_hashCode" },
1248 { JsInterop::jsInteropCallMethodCallback, 3, "JsObject_callMethod" }, 1395 { JsInterop::jsInteropCallMethodCallback, 3, "JsObject_callMethod" },
1249 { JsInteropInternal::toStringCallback, 1, "JsObject_toString" }, 1396 { JsInteropInternal::toStringCallback, 1, "JsObject_toString" },
1250 { JsInteropInternal::identityEqualityCallback, 2, "JsObject_identityEquality " }, 1397 { JsInteropInternal::identityEqualityCallback, 2, "JsObject_identityEquality " },
1251 { JsInteropInternal::hasPropertyCallback, 2, "JsObject_hasProperty" }, 1398 { JsInteropInternal::hasPropertyCallback, 2, "JsObject_hasProperty" },
1252 { JsInteropInternal::deletePropertyCallback, 2, "JsObject_deleteProperty" }, 1399 { JsInteropInternal::deletePropertyCallback, 2, "JsObject_deleteProperty" },
1253 { JsInteropInternal::instanceofCallback, 2, "JsObject_instanceof" }, 1400 { JsInteropInternal::instanceofCallback, 2, "JsObject_instanceof" },
1254 { JsInteropInternal::applyCallback, 3, "JsFunction_apply" }, 1401 { JsInteropInternal::applyCallback, 3, "JsFunction_apply" },
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
1417 if (handleNonDartProxyThis(info, jsMethodName)) { 1564 if (handleNonDartProxyThis(info, jsMethodName)) {
1418 return; 1565 return;
1419 } 1566 }
1420 DartScopes scopes(info.Holder()); 1567 DartScopes scopes(info.Holder());
1421 DartDOMData* domData = DartDOMData::current(); 1568 DartDOMData* domData = DartDOMData::current();
1422 Dart_Handle handle = scopes.handle; 1569 Dart_Handle handle = scopes.handle;
1423 Dart_Handle e; 1570 Dart_Handle e;
1424 if (info.Length() == 0) { 1571 if (info.Length() == 0) {
1425 e = Dart_Null(); 1572 e = Dart_Null();
1426 } else { 1573 } else {
1427 e = JsInterop::toDart(info[0]); 1574 e = JsInterop::toDart(info[0], false);
1428 } 1575 }
1429 Dart_Handle args[2] = { handle, e }; 1576 Dart_Handle args[2] = { handle, e };
1430 Dart_Handle ret = Dart_Invoke(domData->jsLibrary(), Dart_NewStringFromCStrin g(methodName), 2, args); 1577 Dart_Handle ret = Dart_Invoke(domData->jsLibrary(), Dart_NewStringFromCStrin g(methodName), 2, args);
1431 setJsReturnValue(domData, info, ret); 1578 setJsReturnValue(domData, info, ret);
1432 } 1579 }
1433 1580
1434 void arrayHelperWithArgsAsList(const v8::FunctionCallbackInfo<v8::Value>& info, const char* methodName, const char* jsMethodName) 1581 void arrayHelperWithArgsAsList(const v8::FunctionCallbackInfo<v8::Value>& info, const char* methodName, const char* jsMethodName)
1435 { 1582 {
1436 if (handleNonDartProxyThis(info, jsMethodName)) { 1583 if (handleNonDartProxyThis(info, jsMethodName)) {
1437 return; 1584 return;
1438 } 1585 }
1439 DartScopes scopes(info.Holder()); 1586 DartScopes scopes(info.Holder());
1440 DartDOMData* domData = DartDOMData::current(); 1587 DartDOMData* domData = DartDOMData::current();
1441 Dart_Handle handle = scopes.handle; 1588 Dart_Handle handle = scopes.handle;
1442 int length = info.Length(); 1589 int length = info.Length();
1443 Dart_Handle argsList = Dart_NewList(length); 1590 Dart_Handle argsList = Dart_NewList(length);
1444 for (int i = 0; i < length; ++i) { 1591 for (int i = 0; i < length; ++i) {
1445 Dart_ListSetAt(argsList, i, JsInterop::toDart(info[i])); 1592 Dart_ListSetAt(argsList, i, JsInterop::toDart(info[i], false));
1446 } 1593 }
1447 // Note: this is also just info.Holder(). 1594 // Note: this is also just info.Holder().
1448 Dart_Handle args[2] = { handle, argsList }; 1595 Dart_Handle args[2] = { handle, argsList };
1449 setJsReturnValue(domData, info, Dart_Invoke(domData->jsLibrary(), Dart_NewSt ringFromCString(methodName), 2, args)); 1596 setJsReturnValue(domData, info, Dart_Invoke(domData->jsLibrary(), Dart_NewSt ringFromCString(methodName), 2, args));
1450 } 1597 }
1451 1598
1452 static void arrayNamedPropertyGetter(v8::Local<v8::String> name, const v8::Prope rtyCallbackInfo<v8::Value>& info) 1599 static void arrayNamedPropertyGetter(v8::Local<v8::String> name, const v8::Prope rtyCallbackInfo<v8::Value>& info)
1453 { 1600 {
1454 if (!DartHandleProxy::isDartProxy(info.Holder())) { 1601 if (!DartHandleProxy::isDartProxy(info.Holder())) {
1455 // I don't think this case can occur but avoid crashing if there is an 1602 // I don't think this case can occur but avoid crashing if there is an
(...skipping 22 matching lines...) Expand all
1478 } 1625 }
1479 1626
1480 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent(); 1627 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent();
1481 if (!property->Equals(v8::String::NewFromUtf8(v8Isolate, "length"))) { 1628 if (!property->Equals(v8::String::NewFromUtf8(v8Isolate, "length"))) {
1482 return; 1629 return;
1483 } 1630 }
1484 1631
1485 DartScopes scopes(info.Holder()); 1632 DartScopes scopes(info.Holder());
1486 Dart_Handle handle = scopes.handle; 1633 Dart_Handle handle = scopes.handle;
1487 DartDOMData* domData = DartDOMData::current(); 1634 DartDOMData* domData = DartDOMData::current();
1488 Dart_Handle args[2] = { handle, JsInterop::toDart(value) }; 1635 Dart_Handle args[2] = { handle, JsInterop::toDart(value, true) };
1489 Dart_Handle ret = Dart_Invoke(domData->jsLibrary(), Dart_NewStringFromCStrin g("_setListLength"), 2, args); 1636 Dart_Handle ret = Dart_Invoke(domData->jsLibrary(), Dart_NewStringFromCStrin g("_setListLength"), 2, args);
1490 setJsReturnValue(domData, info, ret); 1637 setJsReturnValue(domData, info, ret);
1491 } 1638 }
1492 1639
1493 static void arrayQueryProperty(v8::Local<v8::String> name, const v8::PropertyCal lbackInfo<v8::Integer>& info) 1640 static void arrayQueryProperty(v8::Local<v8::String> name, const v8::PropertyCal lbackInfo<v8::Integer>& info)
1494 { 1641 {
1495 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent(); 1642 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent();
1496 if (name->Equals(v8::String::NewFromUtf8(v8Isolate, "length"))) { 1643 if (name->Equals(v8::String::NewFromUtf8(v8Isolate, "length"))) {
1497 v8SetReturnValueInt(info, v8::DontEnum | v8::DontDelete); 1644 v8SetReturnValueInt(info, v8::DontEnum | v8::DontDelete);
1498 } 1645 }
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1611 1758
1612 v8::Local<v8::ObjectTemplate> instanceTemplate = setupInstanceTemplate(p roxyTemplateLocal); 1759 v8::Local<v8::ObjectTemplate> instanceTemplate = setupInstanceTemplate(p roxyTemplateLocal);
1613 instanceTemplate->SetIndexedPropertyHandler(&indexedGetterArray, &indexe dSetterArray, 0, 0, &indexedEnumeratorArray); 1760 instanceTemplate->SetIndexedPropertyHandler(&indexedGetterArray, &indexe dSetterArray, 0, 0, &indexedEnumeratorArray);
1614 instanceTemplate->SetNamedPropertyHandler(&arrayNamedPropertyGetter, &ar rayNamedPropertySetter, &arrayQueryProperty, &arrayDeleteProperty, 0); 1761 instanceTemplate->SetNamedPropertyHandler(&arrayNamedPropertyGetter, &ar rayNamedPropertySetter, &arrayQueryProperty, &arrayDeleteProperty, 0);
1615 } else { 1762 } else {
1616 proxyTemplateLocal = v8::Local<v8::FunctionTemplate>::New(v8Isolate, pro xyTemplate); 1763 proxyTemplateLocal = v8::Local<v8::FunctionTemplate>::New(v8Isolate, pro xyTemplate);
1617 } 1764 }
1618 return proxyTemplateLocal; 1765 return proxyTemplateLocal;
1619 } 1766 }
1620 1767
1768 void dartObjectToStringCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
1769 {
1770 if (handleNonDartProxyThis(info, "toString")) {
1771 return;
1772 }
1773 DartScopes scopes(info.Holder());
1774 DartDOMData* domData = DartDOMData::current();
1775 Dart_Handle handle = scopes.handle;
1776 setJsReturnValue(domData, info, Dart_ToString(handle));
1777 }
1778
1779 static v8::Local<v8::FunctionTemplate> dartObjectTemplate()
1780 {
1781 DEFINE_STATIC_LOCAL(v8::Persistent<v8::FunctionTemplate>, proxyTemplate, ()) ;
1782 v8::Local<v8::FunctionTemplate> proxyTemplateLocal;
1783 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent();
1784 if (proxyTemplate.IsEmpty()) {
1785 proxyTemplate.Reset(v8Isolate, v8::FunctionTemplate::New(v8Isolate));
1786 proxyTemplateLocal = v8::Local<v8::FunctionTemplate>::New(v8Isolate, pro xyTemplate);
1787 v8::Local<v8::ObjectTemplate> protoTemplate = proxyTemplateLocal->Proto typeTemplate();
1788 protoTemplate->Set(v8::String::NewFromUtf8(v8Isolate, "toString"), v8::F unctionTemplate::New(v8Isolate, dartObjectToStringCallback));
1789
1790 proxyTemplateLocal->SetClassName(v8::String::NewFromUtf8(v8Isolate, "Dar tObject"));
1791 setupInstanceTemplate(proxyTemplateLocal);
1792 } else {
1793 proxyTemplateLocal = v8::Local<v8::FunctionTemplate>::New(v8Isolate, pro xyTemplate);
1794 }
1795 return proxyTemplateLocal;
1796 }
1797
1621 void JsInterop::jsInteropGetterCallback(Dart_NativeArguments args) 1798 void JsInterop::jsInteropGetterCallback(Dart_NativeArguments args)
1622 { 1799 {
1623 JsInteropInternal::getterCallback(args); 1800 JsInteropInternal::getterCallback(args);
1624 } 1801 }
1625 1802
1626 void JsInterop::jsInteropCallMethodCallback(Dart_NativeArguments args) 1803 void JsInterop::jsInteropCallMethodCallback(Dart_NativeArguments args)
1627 { 1804 {
1628 JsInteropInternal::callMethodCallback(args); 1805 JsInteropInternal::callMethodCallback(args);
1629 } 1806 }
1630 1807
1631 void JsInterop::jsInteropContextCallback(Dart_NativeArguments args) 1808 void JsInterop::jsInteropContextCallback(Dart_NativeArguments args)
1632 { 1809 {
1633 return JsInteropInternal::contextCallback(args); 1810 return JsInteropInternal::contextCallback(args);
1634 } 1811 }
1635 1812
1636 } 1813 }
OLDNEW
« no previous file with comments | « Source/bindings/core/dart/DartJsInterop.h ('k') | Source/bindings/core/dart/DartJsInteropData.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698