| Index: Source/bindings/dart/DartJsInterop.cpp
|
| diff --git a/Source/bindings/dart/DartJsInterop.cpp b/Source/bindings/dart/DartJsInterop.cpp
|
| index ba91725a100f51edf6d2faf6e136f438f1d9ab7d..063acfce671c07fbb4edc9686f7ab845f2c945bd 100644
|
| --- a/Source/bindings/dart/DartJsInterop.cpp
|
| +++ b/Source/bindings/dart/DartJsInterop.cpp
|
| @@ -80,23 +80,27 @@ static void functionInvocationCallback(const v8::FunctionCallbackInfo<v8::Value>
|
| DartDOMData* domData = DartDOMData::current();
|
| ASSERT(domData);
|
| ASSERT(DartUtilities::isFunction(domData, handle));
|
| -
|
| - Vector<Dart_Handle> dartFunctionArgs;
|
| ASSERT(args.Length() == 1 || args.Length() == 2);
|
| +
|
| + v8::Local<v8::Array> argsList = args[args.Length()-1].As<v8::Array>();
|
| + uint32_t argsListLength = argsList->Length();
|
| + Dart_Handle dartFunctionArgs;
|
| + uint32_t offset = 0;
|
| // If there is 1 argument, we assume it is a v8:Array or arguments, if
|
| // there are 2 arguments, the first argument is "this" and the second
|
| // argument is an array of arguments.
|
| - if (args.Length() > 1) {
|
| - dartFunctionArgs.append(JsInterop::toDart(args[0]));
|
| + if (args.Length() == 1) {
|
| + dartFunctionArgs = Dart_NewList(argsListLength);
|
| + } else {
|
| + dartFunctionArgs = Dart_NewList(argsListLength + 1);
|
| + Dart_ListSetAt(dartFunctionArgs, offset++, JsInterop::toDart(args[0]));
|
| }
|
|
|
| - v8::Local<v8::Array> argsList = args[args.Length()-1].As<v8::Array>();
|
| - uint32_t argsListLength = argsList->Length();
|
| for (uint32_t i = 0; i < argsListLength; i++) {
|
| - dartFunctionArgs.append(JsInterop::toDart(argsList->Get(i)));
|
| + Dart_ListSetAt(dartFunctionArgs, i + offset, JsInterop::toDart(argsList->Get(i)));
|
| }
|
|
|
| - setJsReturnValue(domData, args, Dart_InvokeClosure(handle, dartFunctionArgs.size(), dartFunctionArgs.data()));
|
| + setJsReturnValue(domData, args, Dart_InvokeClosure(handle, 1, &dartFunctionArgs));
|
| }
|
|
|
| static v8::Local<v8::ObjectTemplate> setupInstanceTemplate(v8::Local<v8::FunctionTemplate> proxyTemplate)
|
| @@ -216,12 +220,20 @@ v8::Local<v8::Value> JsInterop::fromDart(DartDOMData* domData, Dart_Handle handl
|
| return object->localV8Object();
|
| }
|
|
|
| - if (DartUtilities::isFunction(domData, handle)) {
|
| + // call _wrapToJs
|
| + Dart_Handle wrappedValue = Dart_Invoke(domData->jsLibrary(), Dart_NewStringFromCString("_wrapToJs"), 1, &handle);
|
| +
|
| + if (DartUtilities::isFunction(domData, wrappedValue)) {
|
| v8::Local<v8::Object> functionProxy = dartFunctionTemplate()->InstanceTemplate()->NewInstance();
|
| - DartHandleProxy::writePointerToProxy(functionProxy, handle);
|
| + DartHandleProxy::writePointerToProxy(functionProxy, wrappedValue);
|
| // The raw functionProxy doesn't behave enough like a true JS function
|
| // so we wrap it in a true JS function.
|
| - return domData->jsInteropData()->wrapDartFunction()->Call(functionProxy, 0, 0);
|
| + v8::Local<v8::Function> jsFunction = v8::Local<v8::Function>::Cast(domData->jsInteropData()->wrapDartFunction()->Call(functionProxy, 0, 0));
|
| + v8::Isolate* v8Isolate = v8::Isolate::GetCurrent();
|
| + jsFunction->SetHiddenValue(v8::String::NewFromUtf8(v8Isolate, "dartProxy"), v8::Boolean::New(v8Isolate, true));
|
| + v8::Local<v8::External> external = v8::External::New(v8Isolate, wrappedValue);
|
| + jsFunction->SetHiddenValue(v8::String::NewFromUtf8(v8Isolate, "dartFunction"), external);
|
| + return jsFunction;
|
| }
|
|
|
| v8::Local<v8::Object> proxy;
|
| @@ -260,17 +272,18 @@ Dart_Handle JsInterop::toDart(v8::Local<v8::Value> v8Handle)
|
| if (handle)
|
| return handle;
|
|
|
| - // Unwrap objects passed from Dart to JS that are being passed back to
|
| - // Dart. FIXME: we do not yet handle unwrapping JS functions passed
|
| - // from Dart to JS as we have to wrap them with true JS Function objects.
|
| - // If this use case is important we can support it at the cost of hanging
|
| - // an extra expando off the JS function wrapping the Dart function.
|
| + // Unwrap objects passed from Dart to JS that are being passed back to Dart.
|
| if (DartHandleProxy::isDartProxy(v8Handle)) {
|
| + v8::Isolate* v8Isolate = v8::Isolate::GetCurrent();
|
| + v8::Local<v8::Value> hiddenValue = v8Handle.As<v8::Object>()->GetHiddenValue(v8::String::NewFromUtf8(v8Isolate, "dartFunction"));
|
| + if (*hiddenValue && hiddenValue->IsExternal()) {
|
| + Dart_Handle dartHandle = static_cast<Dart_Handle>(v8::External::Cast(*hiddenValue)->Value());
|
| + return dartHandle;
|
| + }
|
| DartScriptValue* scriptValue = DartHandleProxy::readPointerFromProxy(v8Handle);
|
| ASSERT(scriptValue->isIsolateAlive());
|
| return scriptValue->value();
|
| }
|
| -
|
| return JsObject::toDart(object);
|
| }
|
|
|
|
|