| Index: Source/bindings/dart/DartHandleProxy.cpp
|
| diff --git a/Source/bindings/dart/DartHandleProxy.cpp b/Source/bindings/dart/DartHandleProxy.cpp
|
| index 7a4c587878a9e4880eb367d83cb749500b104225..3b354578130a299a398227a031fba8b5d480abd4 100644
|
| --- a/Source/bindings/dart/DartHandleProxy.cpp
|
| +++ b/Source/bindings/dart/DartHandleProxy.cpp
|
| @@ -30,17 +30,30 @@
|
| #include "config.h"
|
| #include "bindings/dart/DartHandleProxy.h"
|
|
|
| +#include "DartNode.h"
|
| #include "bindings/dart/DartScriptValue.h"
|
| #include "bindings/dart/DartUtilities.h"
|
| #include "bindings/dart/V8Converter.h"
|
| +#include "bindings/v8/PageScriptDebugServer.h"
|
| +#include "bindings/v8/ScriptController.h"
|
| +#include "bindings/v8/ScriptState.h"
|
| +#include "bindings/v8/V8Binding.h"
|
| +
|
| +#include "wtf/StdLibExtras.h"
|
|
|
| #include <dart_debugger_api.h>
|
|
|
| namespace WebCore {
|
|
|
| -static v8::Persistent<v8::FunctionTemplate> proxyTemplate();
|
| +typedef HashMap<String, v8::Persistent<v8::FunctionTemplate> > FunctionTemplateMap;
|
| +
|
| +static v8::Persistent<v8::FunctionTemplate> objectProxyTemplate(Dart_Handle instance);
|
| +static v8::Persistent<v8::FunctionTemplate> functionProxyTemplate();
|
| +static v8::Persistent<v8::FunctionTemplate> libraryProxyTemplate();
|
| +static v8::Persistent<v8::FunctionTemplate> typeProxyTemplate(Dart_Handle type);
|
| +static v8::Persistent<v8::FunctionTemplate> frameProxyTemplate();
|
|
|
| -static DartScriptValue* readPointerFromProxy(v8::Handle<v8::Value> proxy)
|
| +DartScriptValue* readPointerFromProxy(v8::Handle<v8::Value> proxy)
|
| {
|
| void* pointer = proxy.As<v8::Object>()->GetAlignedPointerFromInternalField(0);
|
| return static_cast<DartScriptValue*>(pointer);
|
| @@ -52,320 +65,990 @@ static void weakCallback(v8::Isolate* isolate, v8::Persistent<v8::Object>* proxy
|
| proxy->Dispose(isolate);
|
| }
|
|
|
| -v8::Handle<v8::Value> DartHandleProxy::create(Dart_Handle value)
|
| +static Dart_Handle unwrapValue(v8::Handle<v8::Value> value)
|
| {
|
| - v8::Context::Scope scope(DartUtilities::currentV8Context());
|
| + if (DartHandleProxy::isDartProxy(value))
|
| + return Dart_HandleFromPersistent(readPointerFromProxy(value)->value());
|
|
|
| - if (Dart_IsNull(value))
|
| - return v8::Null();
|
| - if (Dart_IsString(value))
|
| - return V8Converter::stringToV8(value);
|
| - if (Dart_IsBoolean(value))
|
| - return V8Converter::booleanToV8(value);
|
| - if (Dart_IsNumber(value))
|
| - return V8Converter::numberToV8(value);
|
| + Dart_Handle exception = 0;
|
| + Dart_Handle handle = V8Converter::toDart(value, exception);
|
| + ASSERT(!exception);
|
| + return handle;
|
| +}
|
|
|
| - v8::Local<v8::Object> proxy = proxyTemplate()->InstanceTemplate()->NewInstance();
|
| - proxy->SetAlignedPointerInInternalField(0, new DartScriptValue(value));
|
| - v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
| - v8::Persistent<v8::Object> persistentHandle = v8::Persistent<v8::Object>::New(isolate, proxy);
|
| - persistentHandle.MakeWeak<v8::Object, void>(0, &weakCallback);
|
| - proxy->Set(v8::String::New("isProxy"), v8::Boolean::New(true));
|
| - return proxy;
|
| +bool libraryHasMember(Dart_Handle library, Dart_Handle name)
|
| +{
|
| + return !Dart_IsError(Dart_GetField(library, name))
|
| + || !Dart_IsError(Dart_GetClass(library, name))
|
| + || Dart_IsFunction(Dart_LookupFunction(library, name));
|
| }
|
|
|
| -v8::Handle<v8::Value> DartHandleProxy::createForLibrary(intptr_t libraryId)
|
| +bool typeHasMember(Dart_Handle type, Dart_Handle name)
|
| {
|
| - Dart_Handle libraryURL = Dart_GetLibraryURL(libraryId);
|
| - ASSERT(!Dart_IsError(libraryURL));
|
| - Dart_Handle library = Dart_LookupLibrary(libraryURL);
|
| - v8::Handle<v8::Object> libraryProxy = create(library)->ToObject();
|
| - libraryProxy->SetHiddenValue(v8::String::New("libraryId"), v8::Number::New(libraryId));
|
| - return libraryProxy;
|
| + return !Dart_IsError(Dart_GetField(type, name)) || Dart_IsFunction(Dart_LookupFunction(type, name));
|
| }
|
|
|
| -class DartReceiverScope {
|
| -public:
|
| - DartReceiverScope(const v8::Arguments& args)
|
| - : m_receiver(readPointerFromProxy(args[0]))
|
| - , m_isolateScope(m_receiver->isolate())
|
| - , m_apiScope()
|
| - {
|
| - }
|
| +Dart_Handle getEncodedMapKeyList(Dart_Handle object)
|
| +{
|
| + return DartUtilities::invokeUtilsMethod("getEncodedMapKeyList", 1, &object);
|
| +}
|
|
|
| - Dart_Handle receiver() { return Dart_HandleFromPersistent(m_receiver->value()); }
|
| +Dart_Handle stripTrailingDot(Dart_Handle str)
|
| +{
|
| + return DartUtilities::invokeUtilsMethod("stripTrailingDot", 1, &str);
|
| +}
|
|
|
| -private:
|
| - DartScriptValue* m_receiver;
|
| - DartIsolateScope m_isolateScope;
|
| - DartApiScope m_apiScope;
|
| -};
|
| +Dart_Handle addTrailingDot(Dart_Handle str)
|
| +{
|
| + return DartUtilities::invokeUtilsMethod("addTrailingDot", 1, &str);
|
| +}
|
|
|
| -static v8::Persistent<v8::FunctionTemplate> proxyTemplate()
|
| +Dart_Handle lookupValueForEncodedMapKey(Dart_Handle object, Dart_Handle key)
|
| {
|
| - static v8::Persistent<v8::FunctionTemplate> proxyTemplate;
|
| - if (proxyTemplate.IsEmpty()) {
|
| - proxyTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::GetCurrent(), v8::FunctionTemplate::New());
|
| - v8::Local<v8::ObjectTemplate> instanceTemplate = proxyTemplate->InstanceTemplate();
|
| - instanceTemplate->SetInternalFieldCount(1);
|
| - }
|
| - return proxyTemplate;
|
| + Dart_Handle args[] = {object, key};
|
| + return DartUtilities::invokeUtilsMethod("lookupValueForEncodedMapKey", 2, args);
|
| }
|
|
|
| -static Dart_Handle unwrapValue(v8::Handle<v8::Value> value)
|
| +Dart_Handle buildConstructorName(Dart_Handle typeName, Dart_Handle constructorName)
|
| {
|
| - if (proxyTemplate()->HasInstance(value))
|
| - return Dart_HandleFromPersistent(readPointerFromProxy(value)->value());
|
| + Dart_Handle args[] = {typeName, constructorName};
|
| + return DartUtilities::invokeUtilsMethod("buildConstructorName", 2, args);
|
| +}
|
| +
|
| +Dart_Handle stripClassName(Dart_Handle str, Dart_Handle typeName)
|
| +{
|
| + Dart_Handle args[] = {str, typeName};
|
| + return DartUtilities::invokeUtilsMethod("stripClassName", 2, args);
|
| +}
|
| +
|
| +bool isNode(Dart_Handle type)
|
| +{
|
| + // We have to check that toNativeNode does not return null because
|
| + // non-native types can implement the Node interface.
|
| Dart_Handle exception = 0;
|
| - Dart_Handle handle = V8Converter::toDart(value, exception);
|
| + bool ret = DartUtilities::dartToBool(DartUtilities::invokeUtilsMethod("isNode", 1, &type), exception);
|
| ASSERT(!exception);
|
| - return handle;
|
| + if (!ret)
|
| + return false;
|
| + if (!DartNode::toNative(type, exception))
|
| + return false;
|
| + return true;
|
| +}
|
| +
|
| +Dart_Handle createLocalVariablesMap(Dart_Handle localVariablesList)
|
| +{
|
| + return DartUtilities::invokeUtilsMethod("createLocalVariablesMap", 1, &localVariablesList);
|
| +}
|
| +
|
| +Dart_Handle getMapKeyList(Dart_Handle localVariablesMap)
|
| +{
|
| + return DartUtilities::invokeUtilsMethod("getMapKeyList", 1, &localVariablesMap);
|
| +}
|
| +
|
| +bool mapContainsKey(Dart_Handle map, Dart_Handle key)
|
| +{
|
| + Dart_Handle exception = 0;
|
| + return DartUtilities::dartToBool(Dart_Invoke(map, Dart_NewStringFromCString("containsKey"), 1, &key), exception);
|
| +}
|
| +
|
| +void addFunctionNames(Dart_Handle handle, v8::Local<v8::Array>& properties, intptr_t* count, bool isInstance, bool noMethods)
|
| +{
|
| + intptr_t length = 0;
|
| + Dart_Handle functionNames = Dart_GetFunctionNames(handle);
|
| + ASSERT(!Dart_IsError(functionNames));
|
| + bool isLibrary = Dart_IsLibrary(handle);
|
| + Dart_ListLength(functionNames, &length);
|
| + for (intptr_t i = 0; i < length; i++) {
|
| + Dart_Handle functionName = Dart_ListGetAt(functionNames, i);
|
| + Dart_Handle function = Dart_LookupFunction(handle, functionName);
|
| + bool isStatic = false;
|
| + Dart_FunctionIsStatic(function, &isStatic);
|
| +
|
| + bool isConstructor = false;
|
| + Dart_FunctionIsConstructor(function, &isConstructor);
|
| +
|
| + if (!isLibrary) {
|
| + if (isInstance == (isStatic || isConstructor))
|
| + continue;
|
| +
|
| + bool isSetter = false;
|
| + Dart_FunctionIsSetter(function, &isSetter);
|
| + bool isGetter = false;
|
| + Dart_FunctionIsGetter(function, &isGetter);
|
| +
|
| + if (noMethods && !isSetter && !isGetter)
|
| + continue;
|
| + }
|
| +
|
| + // Strip off the leading typename from constructor name.
|
| + if (isConstructor)
|
| + functionName = stripClassName(functionName, Dart_ClassName(handle));
|
| +
|
| + properties->Set(*count, V8Converter::stringToV8(functionName));
|
| + *count = *count + 1;
|
| + }
|
| +}
|
| +
|
| +void addClassNames(Dart_Handle library, v8::Local<v8::Array>& properties, intptr_t* count)
|
| +{
|
| + intptr_t length = 0;
|
| + Dart_Handle typeNames = Dart_LibraryGetClassNames(library);
|
| + ASSERT(!Dart_IsNull(typeNames));
|
| + ASSERT(Dart_IsList(typeNames));
|
| + Dart_ListLength(typeNames, &length);
|
| + for (intptr_t i = 0; i < length; i++) {
|
| + Dart_Handle typeName = Dart_ListGetAt(typeNames, i);
|
| + properties->Set(*count, V8Converter::stringToV8(typeName));
|
| + *count = *count + 1;
|
| + }
|
| +}
|
| +
|
| +void addFieldNames(Dart_Handle fieldNames, v8::Local<v8::Array>& properties, intptr_t* count)
|
| +{
|
| + ASSERT(!Dart_IsApiError(fieldNames));
|
| + ASSERT(Dart_IsList(fieldNames));
|
| + intptr_t length = 0;
|
| + Dart_ListLength(fieldNames, &length);
|
| + for (intptr_t i = 0; i < length; i += 2) {
|
| + Dart_Handle fieldName = Dart_ListGetAt(fieldNames, i);
|
| + properties->Set(*count, V8Converter::stringToV8(fieldName));
|
| + *count = *count + 1;
|
| + }
|
| }
|
|
|
| static v8::Handle<v8::Value> convertResult(Dart_Handle result)
|
| {
|
| if (Dart_IsError(result)) {
|
| - // Consider wrapping not as a string, but as dedicated
|
| - // exception wrapper.
|
| - return v8::String::New("<Exception thrown>");
|
| + // FIXME: we would really prefer to call the following however it has
|
| + // bad unintended consequences as then JS cannot catch the thrown exception.
|
| + // DartUtilities::reportProblem(DartUtilities::scriptExecutionContext(), result);
|
| + // return v8::Undefined();
|
| +
|
| + return v8::ThrowException(v8::String::New(Dart_GetError(result)));
|
| }
|
| return DartHandleProxy::create(result);
|
| }
|
|
|
| -// --- Objects ----
|
| +void setDartHandleInternalField(v8::Local<v8::Object> proxy, Dart_Handle value)
|
| +{
|
| + proxy->SetAlignedPointerInInternalField(0, new DartScriptValue(value));
|
| + v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
| + v8::Persistent<v8::Object> persistentHandle = v8::Persistent<v8::Object>::New(isolate, proxy);
|
| + persistentHandle.MakeWeak<v8::Object, void>(0, &weakCallback);
|
| +}
|
|
|
| -static v8::Handle<v8::Value> instanceGetClass(const v8::Arguments& args)
|
| +intptr_t getLibraryId(v8::Local<v8::Object> proxy)
|
| {
|
| - DartReceiverScope scope(args);
|
| - return convertResult(Dart_InstanceGetClass(scope.receiver()));
|
| + return (intptr_t)proxy.As<v8::Object>()->GetHiddenValue(v8::String::NewSymbol("libraryId"))->Int32Value();
|
| }
|
|
|
| -// --- Lists ---
|
| +// Returns a String of the library prefix or Dart_Null if no prefix is found.
|
| +Dart_Handle getLibraryPrefix(v8::Local<v8::Object> proxy)
|
| +{
|
| + v8::Local<v8::Value> prefix = proxy.As<v8::Object>()->GetHiddenValue(v8::String::NewSymbol("prefix"));
|
| + if (*prefix && prefix->IsString())
|
| + return V8Converter::stringToDart(prefix);
|
| + return Dart_Null();
|
| +}
|
|
|
| -static v8::Handle<v8::Value> isList(const v8::Arguments& args)
|
| +static v8::Handle<v8::Value> functionNamedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
|
| {
|
| - DartReceiverScope scope(args);
|
| - return v8::Boolean::New(Dart_IsList(scope.receiver()));
|
| + DartScriptValue* scriptValue = readPointerFromProxy(info.This());
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| +
|
| + Dart_Handle ret;
|
| + ASSERT(Dart_IsFunction(handle) || Dart_IsClosure(handle));
|
| +
|
| + ret = Dart_Invoke(handle, V8Converter::stringToDart(v8::String::Concat(v8::String::New("get:"), name)), 0, 0);
|
| + if (Dart_IsError(ret) && name->Equals(v8::String::NewSymbol("__proto__")))
|
| + return v8::Undefined();
|
| +
|
| + return convertResult(ret);
|
| }
|
|
|
| -static v8::Handle<v8::Value> listGetAt(const v8::Arguments& args)
|
| +static v8::Handle<v8::Value> functionNamedPropertySetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
|
| {
|
| - DartReceiverScope scope(args);
|
| - return convertResult(Dart_ListGetAt(scope.receiver(), args[1]->Int32Value()));
|
| + return throwError(v8ReferenceError, "Dart functions do not have writeable properties", v8::Isolate::GetCurrent());
|
| }
|
|
|
| -static v8::Handle<v8::Value> listSetAt(const v8::Arguments& args)
|
| +static v8::Handle<v8::Value> functionInvocationCallback(v8::Arguments const& args)
|
| {
|
| - DartReceiverScope scope(args);
|
| - return convertResult(Dart_ListSetAt(scope.receiver(), args[1]->Int32Value(), unwrapValue(args[2])));
|
| + DartScriptValue* scriptValue = readPointerFromProxy(args.Holder());
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| +
|
| + ASSERT(Dart_IsFunction(handle) || Dart_IsClosure(handle));
|
| + bool isConstructor = false;
|
| + Dart_FunctionIsConstructor(handle, &isConstructor);
|
| + if (args.IsConstructCall() != isConstructor) {
|
| + return throwError(v8ReferenceError,
|
| + isConstructor ? "Constructor called without new" : "Regular function called as constructor",
|
| + v8::Isolate::GetCurrent());
|
| + }
|
| +
|
| + Vector<Dart_Handle> dartFunctionArgs;
|
| + for (uint32_t i = 0; i < args.Length(); ++i)
|
| + dartFunctionArgs.append(unwrapValue(args[i]));
|
| +
|
| + if (Dart_IsClosure(handle))
|
| + return convertResult(Dart_InvokeClosure(handle, dartFunctionArgs.size(), dartFunctionArgs.data()));
|
| + Dart_Handle type = Dart_FunctionOwner(handle);
|
| + if (isConstructor)
|
| + // FIXME: this seems like an overly complex way to have to invoke a constructor.
|
| + return convertResult(
|
| + Dart_New(type, stripClassName(Dart_FunctionName(handle), Dart_ClassName(type)),
|
| + dartFunctionArgs.size(), dartFunctionArgs.data()));
|
| + else
|
| + return convertResult(
|
| + Dart_Invoke(type, Dart_FunctionName(handle), dartFunctionArgs.size(), dartFunctionArgs.data()));
|
| }
|
|
|
| -// --- Classes and Interfaces ---
|
| +static v8::Handle<v8::Value> typeProxyConstructorInvocationCallback(v8::Arguments const& args)
|
| +{
|
| + DartScriptValue* scriptValue = readPointerFromProxy(args.Holder());
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| +
|
| + ASSERT(Dart_IsType(handle));
|
|
|
| -static v8::Handle<v8::Value> className(const v8::Arguments& args)
|
| + if (!args.IsConstructCall())
|
| + return throwError(v8SyntaxError, "Constructors can only be invoked with 'new'", v8::Isolate::GetCurrent());
|
| +
|
| + Vector<Dart_Handle> dartFunctionArgs;
|
| + for (uint32_t i = 0; i < args.Length(); ++i)
|
| + dartFunctionArgs.append(unwrapValue(args[i]));
|
| +
|
| + return convertResult(Dart_New(handle, Dart_Null(), dartFunctionArgs.size(), dartFunctionArgs.data()));
|
| +}
|
| +
|
| +void getImportedLibrariesMatchingPrefix(int32_t libraryId, Dart_Handle prefix, Vector<std::pair<Dart_Handle, intptr_t> >* libraries)
|
| {
|
| - DartReceiverScope scope(args);
|
| - return convertResult(Dart_ClassName(scope.receiver()));
|
| + Dart_Handle imports = Dart_GetLibraryImports(libraryId);
|
| + ASSERT(!Dart_IsError(imports));
|
| + // Unfortunately dart_debugger_api.h adds a trailing dot to import prefixes.
|
| + if (!Dart_IsNull(prefix))
|
| + prefix = addTrailingDot(prefix);
|
| + intptr_t length = 0;
|
| + Dart_ListLength(imports, &length);
|
| + for (intptr_t i = 0; i < length; i += 2) {
|
| + Dart_Handle importPrefix = Dart_ListGetAt(imports, i);
|
| + ASSERT(Dart_IsNull(importPrefix) || Dart_IsString(importPrefix));
|
| + bool equals = false;
|
| + Dart_Handle result = Dart_ObjectEquals(prefix, importPrefix, &equals);
|
| + ASSERT(!Dart_IsError(result));
|
| + if (equals) {
|
| + Dart_Handle importedLibraryIdHandle = Dart_ListGetAt(imports, i + 1);
|
| + ASSERT(Dart_IsInteger(importedLibraryIdHandle));
|
| + int64_t importedLibraryId;
|
| + Dart_IntegerToInt64(importedLibraryIdHandle, &importedLibraryId);
|
| + Dart_Handle libraryURL = Dart_GetLibraryURL(importedLibraryId);
|
| + ASSERT(!Dart_IsError(libraryURL));
|
| + Dart_Handle library = Dart_LookupLibrary(libraryURL);
|
| + ASSERT(Dart_IsLibrary(library));
|
| + libraries->append(std::pair<Dart_Handle, intptr_t>(library, importedLibraryId));
|
| + }
|
| + }
|
| }
|
|
|
| -static v8::Handle<v8::Value> classGetLibrary(const v8::Arguments& args)
|
| +static v8::Handle<v8::Value> libraryNamedPropertyGetterHelper(Dart_Handle library, Dart_Handle dartName, bool* handled)
|
| {
|
| - DartReceiverScope scope(args);
|
| - return convertResult(Dart_ClassGetLibrary(scope.receiver()));
|
| + Dart_Handle ret;
|
| + ret = Dart_GetField(library, dartName);
|
| + if (!Dart_IsApiError(ret)) {
|
| + *handled = true;
|
| + return convertResult(ret);
|
| + }
|
| +
|
| + ret = Dart_GetType(library, dartName, 0, 0);
|
| + if (!Dart_IsError(ret)) {
|
| + *handled = true;
|
| + return DartHandleProxy::createTypeProxy(ret, true);
|
| + }
|
| +
|
| + ret = Dart_LookupFunction(library, dartName);
|
| + if (!Dart_IsNull(ret) && !Dart_IsError(ret)) {
|
| + *handled = true;
|
| + return convertResult(ret);
|
| + }
|
| + return v8::Undefined();
|
| }
|
|
|
| -static v8::Handle<v8::Value> getSuperclass(const v8::Arguments& args)
|
| +static v8::Handle<v8::Value> libraryNamedPropertyGetterHelper(v8::Local<v8::String> name,
|
| + const v8::AccessorInfo& info, bool* handled)
|
| {
|
| - DartReceiverScope scope(args);
|
| - return convertResult(Dart_GetSuperclass(scope.receiver()));
|
| + DartScriptValue* scriptValue = readPointerFromProxy(info.This());
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| +
|
| + Dart_Handle ret;
|
| + ASSERT(Dart_IsLibrary(handle));
|
| + intptr_t libraryId = getLibraryId(info.This());
|
| + Dart_Handle dartName = V8Converter::stringToDart(name);
|
| + Dart_Handle prefix = getLibraryPrefix(info.This());
|
| + bool hasLibraryPrefix = !Dart_IsNull(prefix) && Dart_IsString(prefix);
|
| +
|
| + if (hasLibraryPrefix) {
|
| + Vector<std::pair<Dart_Handle, intptr_t> > libraries;
|
| + getImportedLibrariesMatchingPrefix(libraryId, prefix, &libraries);
|
| + for (size_t i = 0; i < libraries.size(); i++) {
|
| + v8::Handle<v8::Value> returnValue = libraryNamedPropertyGetterHelper(libraries[i].first, dartName, handled);
|
| + if (*handled)
|
| + return returnValue;
|
| + }
|
| + } else {
|
| + v8::Handle<v8::Value> returnValue = libraryNamedPropertyGetterHelper(handle, dartName, handled);
|
| + if (*handled)
|
| + return returnValue;
|
| +
|
| + // Check whether there is at least one library imported with the specified prefix.
|
| + Vector<std::pair<Dart_Handle, intptr_t> > libraries;
|
| + getImportedLibrariesMatchingPrefix(libraryId, dartName, &libraries);
|
| + if (libraries.size() > 0) {
|
| + *handled = true;
|
| + return DartHandleProxy::createLibraryProxy(handle, libraryId, dartName);
|
| + }
|
| + }
|
| +
|
| + if (name->Equals(v8::String::NewSymbol("__proto__"))) {
|
| + *handled = true;
|
| + return v8::Null();
|
| + }
|
| + return v8::Undefined();
|
| }
|
|
|
| -// --- Function and Variable Declarations ---
|
| +static v8::Handle<v8::Value> libraryNamedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
|
| +{
|
| + bool handled = false;
|
| + v8::Handle<v8::Value> ret = libraryNamedPropertyGetterHelper(name, info, &handled);
|
| + if (handled)
|
| + return ret;
|
| + return v8::ThrowException(v8::Exception::ReferenceError(v8::String::Concat(name, v8::String::New(" is not defined"))));
|
| +}
|
|
|
| -static v8::Handle<v8::Value> getFunctionNames(const v8::Arguments& args)
|
| +// FIXME: we need to handle prefixes when setting library properties as well
|
| +// for completness. Postponing implementing this for now as we hope Dart_Invoke
|
| +// can just be fixed to handle libraries correctly.
|
| +static v8::Handle<v8::Value> libraryNamedPropertySetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
|
| {
|
| - DartReceiverScope scope(args);
|
| - return V8Converter::listToV8(Dart_GetFunctionNames(scope.receiver()));
|
| + DartScriptValue* scriptValue = readPointerFromProxy(info.This());
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| +
|
| + Dart_Handle ret;
|
| + ASSERT(Dart_IsLibrary(handle));
|
| + Dart_Handle dartValue = unwrapValue(value);
|
| + ret = Dart_SetField(handle, V8Converter::stringToDart(property), dartValue);
|
| + return convertResult(ret);
|
| }
|
|
|
| -static v8::Handle<v8::Value> getClassNames(const v8::Arguments& args)
|
| +static v8::Handle<v8::Integer> libraryQueryProperty(v8::Local<v8::String> name, const v8::AccessorInfo& info)
|
| {
|
| - DartReceiverScope scope(args);
|
| - Dart_Handle classNames = Dart_LibraryGetClassNames(scope.receiver());
|
| - ASSERT(!Dart_IsError(classNames) && !Dart_IsNull(classNames));
|
| - return V8Converter::listToV8(classNames);
|
| + bool handled = false;
|
| + libraryNamedPropertyGetterHelper(name, info, &handled);
|
| + return handled ? v8Integer(0, info.GetIsolate()) : v8::Handle<v8::Integer>();
|
| }
|
|
|
| -static v8::Handle<v8::Value> lookupClass(const v8::Arguments& args)
|
| +void libraryEnumerateHelper(Dart_Handle library, intptr_t libraryId, v8::Local<v8::Array> properties, intptr_t* count)
|
| {
|
| - DartReceiverScope scope(args);
|
| - return convertResult(Dart_GetClass(scope.receiver(), V8Converter::stringToDart(args[1])));
|
| + addFunctionNames(library, properties, count, false, false);
|
| + addClassNames(library, properties, count);
|
| + addFieldNames(Dart_GetLibraryFields(libraryId), properties, count);
|
| }
|
|
|
| -static v8::Handle<v8::Value> lookupFunction(const v8::Arguments& args)
|
| +static v8::Handle<v8::Array> libraryPropertyEnumerator(const v8::AccessorInfo& info)
|
| {
|
| - DartReceiverScope scope(args);
|
| + DartScriptValue* scriptValue = readPointerFromProxy(info.This());
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
|
|
| - Dart_Handle function = Dart_LookupFunction(scope.receiver(), V8Converter::stringToDart(args[1]));
|
| - ASSERT(!Dart_IsError(function) && !Dart_IsNull(function));
|
| + intptr_t libraryId = getLibraryId(info.This());
|
| + ASSERT(Dart_IsLibrary(handle));
|
| + v8::Local<v8::Array> cachedProperties = info.This().As<v8::Object>()->GetHiddenValue(v8::String::NewSymbol("cache")).As<v8::Array>();
|
| + if (*cachedProperties)
|
| + return cachedProperties;
|
|
|
| - Dart_Handle result;
|
| - UNUSED_PARAM(result);
|
| + Dart_Handle prefix = getLibraryPrefix(info.This());
|
| + bool hasLibraryPrefix = Dart_IsString(prefix);
|
|
|
| - bool isAbstract;
|
| - result = Dart_FunctionIsAbstract(function, &isAbstract);
|
| - ASSERT(!Dart_IsError(result));
|
| - bool isStatic;
|
| - result = Dart_FunctionIsStatic(function, &isStatic);
|
| - ASSERT(!Dart_IsError(result));
|
| - bool isConstructor;
|
| - result = Dart_FunctionIsConstructor(function, &isConstructor);
|
| - ASSERT(!Dart_IsError(result));
|
| - bool isGetter;
|
| - result = Dart_FunctionIsGetter(function, &isGetter);
|
| - ASSERT(!Dart_IsError(result));
|
| - bool isSetter;
|
| - result = Dart_FunctionIsSetter(function, &isSetter);
|
| - ASSERT(!Dart_IsError(result));
|
| - int64_t fixedParameterCount;
|
| - int64_t optionalParamerterCount;
|
| - result = Dart_FunctionParameterCounts(function, &fixedParameterCount, &optionalParamerterCount);
|
| - ASSERT(!Dart_IsError(result));
|
| + v8::Local<v8::Array> properties = v8::Array::New();
|
| + intptr_t count = 0;
|
|
|
| - v8::Handle<v8::Object> description = v8::Object::New();
|
| - description->Set(v8::String::New("isAbstract"), v8::Boolean::New(isAbstract));
|
| - description->Set(v8::String::New("isStatic"), v8::Boolean::New(isStatic));
|
| - description->Set(v8::String::New("isConstructor"), v8::Boolean::New(isConstructor));
|
| - description->Set(v8::String::New("isGetter"), v8::Boolean::New(isGetter));
|
| - description->Set(v8::String::New("isSetter"), v8::Boolean::New(isSetter));
|
| - description->Set(v8::String::New("fixedParameterCount"), v8::Integer::New(fixedParameterCount));
|
| - description->Set(v8::String::New("optionalParamerterCount"), v8::Integer::New(optionalParamerterCount));
|
| - return description;
|
| + if (hasLibraryPrefix) {
|
| + Vector<std::pair<Dart_Handle, intptr_t> > libraries;
|
| + getImportedLibrariesMatchingPrefix(libraryId, prefix, &libraries);
|
| + for (intptr_t i = 0; i < libraries.size(); i++)
|
| + libraryEnumerateHelper(libraries[i].first, libraries[i].second, properties, &count);
|
| + } else {
|
| + libraryEnumerateHelper(handle, libraryId, properties, &count);
|
| + // Add all library prefixes of imports to the library.
|
| + Dart_Handle imports = Dart_GetLibraryImports(libraryId);
|
| + ASSERT(!Dart_IsError(imports));
|
| + intptr_t length = 0;
|
| + Dart_ListLength(imports, &length);
|
| + for (intptr_t i = 0; i < length; i += 2) {
|
| + Dart_Handle importPrefix = Dart_ListGetAt(imports, i);
|
| + if (!Dart_IsNull(importPrefix)) {
|
| + ASSERT(Dart_IsString(importPrefix));
|
| + properties->Set(count, V8Converter::stringToV8(
|
| + stripTrailingDot(importPrefix)));
|
| + count++;
|
| + }
|
| + bool equals = false;
|
| + }
|
| + }
|
| + info.This()->SetHiddenValue(v8::String::NewSymbol("cache"), properties);
|
| + return properties;
|
| }
|
|
|
| -static v8::Handle<v8::Value> getVariableNames(const v8::Arguments& args)
|
| +bool isShowStatics(v8::Handle<v8::Value> value)
|
| {
|
| - DartReceiverScope scope(args);
|
| - return V8Converter::listToV8(Dart_GetVariableNames(scope.receiver()));
|
| + v8::Local<v8::Value> showStatics = value.As<v8::Object>()->GetHiddenValue(v8::String::NewSymbol("showStatics"));
|
| + ASSERT(*showStatics && showStatics->IsBoolean());
|
| + return showStatics->BooleanValue();
|
| }
|
|
|
| -static v8::Handle<v8::Value> lookupVariable(const v8::Arguments& args)
|
| +static v8::Handle<v8::Value> typeNamedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
|
| {
|
| - DartReceiverScope scope(args);
|
| - Dart_Handle variable = Dart_LookupVariable(scope.receiver(), V8Converter::stringToDart(args[1]));
|
| - ASSERT(!Dart_IsError(variable) && !Dart_IsNull(variable));
|
| + DartScriptValue* scriptValue = readPointerFromProxy(info.This());
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| +
|
| + Dart_Handle ret;
|
| + ASSERT(Dart_IsType(handle));
|
| +
|
| + if (name->Equals(v8::String::NewSymbol("__proto__"))) {
|
| + // Due to Dart semantics, if we are showing statics, we need to
|
| + // not link types up to their superclasses as statics in superclasses
|
| + // are not visible in subclasses.
|
| + /*
|
| + if (isShowStatics(info.This()))
|
| + return v8::Null();
|
| + */
|
|
|
| - Dart_Handle result;
|
| - UNUSED_PARAM(result);
|
| + Dart_Handle supertype = Dart_GetSupertype(handle);
|
| + if (!Dart_IsNull(supertype))
|
| + return DartHandleProxy::createTypeProxy(supertype, false);
|
| + return v8::Null();
|
| + }
|
|
|
| - bool isStatic;
|
| - result = Dart_VariableIsStatic(variable, &isStatic);
|
| - ASSERT(!Dart_IsError(result));
|
| - bool isFinal;
|
| - result = Dart_VariableIsFinal(variable, &isFinal);
|
| - ASSERT(!Dart_IsError(result));
|
| + Dart_Handle dartName = V8Converter::stringToDart(name);
|
| + ret = Dart_GetField(handle, dartName);
|
| + if (!Dart_IsError(ret))
|
| + return convertResult(ret);
|
| + ret = Dart_LookupFunction(handle, dartName);
|
| + if (!Dart_IsNull(ret) && !Dart_IsError(ret))
|
| + return convertResult(ret);
|
|
|
| - v8::Local<v8::Object> description = v8::Object::New();
|
| - description->Set(v8::String::New("isStatic"), v8::Boolean::New(isStatic));
|
| - description->Set(v8::String::New("isFinal"), v8::Boolean::New(isFinal));
|
| - return description;
|
| + Dart_Handle typeName = Dart_ClassName(handle);
|
| + ASSERT(Dart_IsString(typeName));
|
| + Dart_Handle constructorName = buildConstructorName(typeName, V8Converter::stringToDart(name));
|
| + ret = Dart_LookupFunction(handle, constructorName);
|
| + if (!Dart_IsNull(ret) && !Dart_IsError(ret))
|
| + return convertResult(ret);
|
| +
|
| + return v8::ThrowException(v8::Exception::ReferenceError(v8::String::Concat(name, v8::String::New(" is not defined"))));
|
| }
|
|
|
| -// --- Constructors, Methods, and Fields ---
|
| +static v8::Handle<v8::Value> typeNamedPropertySetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
|
| +{
|
| + DartScriptValue* scriptValue = readPointerFromProxy(info.This());
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| +
|
| + Dart_Handle ret;
|
| + ASSERT(Dart_IsType(handle));
|
| + Dart_Handle dartValue = unwrapValue(value);
|
| + ret = Dart_Invoke(handle, V8Converter::stringToDart(v8::String::Concat(v8::String::New("set:"), property)), 1, &dartValue);
|
| + return convertResult(ret);
|
| +}
|
|
|
| -static v8::Handle<v8::Value> invoke(const v8::Arguments& args)
|
| +static v8::Handle<v8::Integer> typeQueryProperty(v8::Local<v8::String> name, const v8::AccessorInfo& info)
|
| {
|
| - DartReceiverScope scope(args);
|
| - Vector<Dart_Handle> dartFunctionArgs;
|
| - v8::Handle<v8::Array> v8FunctionArgs = args[2].As<v8::Array>();
|
| - for (uint32_t i = 0; i < v8FunctionArgs->Length(); ++i)
|
| - dartFunctionArgs.append(unwrapValue(v8FunctionArgs->Get(i)));
|
| - return convertResult(Dart_Invoke(scope.receiver(), V8Converter::stringToDart(args[1]), dartFunctionArgs.size(), dartFunctionArgs.data()));
|
| + DartScriptValue* scriptValue = readPointerFromProxy(info.This());
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| +
|
| + Dart_Handle ret;
|
| + ASSERT(Dart_IsType(handle));
|
| + if (name->Equals(v8::String::NewSymbol("__proto__"))
|
| + || typeHasMember(handle, V8Converter::stringToDart(name)))
|
| + return v8Integer(0, info.GetIsolate());
|
| + return v8::Handle<v8::Integer>();
|
| +}
|
| +
|
| +static v8::Handle<v8::Array> typePropertyEnumerator(const v8::AccessorInfo& info)
|
| +{
|
| + DartScriptValue* scriptValue = readPointerFromProxy(info.This());
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| + bool showStatics = isShowStatics(info.This());
|
| +
|
| + ASSERT(Dart_IsType(handle));
|
| +
|
| + v8::Local<v8::Array> properties = v8::Array::New();
|
| + intptr_t count = 0;
|
| + addFunctionNames(handle, properties, &count, !showStatics, false);
|
| + if (showStatics)
|
| + addFieldNames(Dart_GetStaticFields(handle), properties, &count);
|
| +
|
| + return properties;
|
| }
|
|
|
| -static v8::Handle<v8::Value> dartNew(const v8::Arguments& args)
|
| +static v8::Handle<v8::Value> frameNamedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
|
| {
|
| - DartReceiverScope scope(args);
|
| - Vector<Dart_Handle> dartConstructorArgs;
|
| - v8::Handle<v8::Array> v8ConstructorArgs = args[2].As<v8::Array>();
|
| - for (uint32_t i = 0; i < v8ConstructorArgs->Length(); ++i)
|
| - dartConstructorArgs.append(unwrapValue(v8ConstructorArgs->Get(i)));
|
| - return convertResult(Dart_New(scope.receiver(), V8Converter::stringToDart(args[1]), dartConstructorArgs.size(), dartConstructorArgs.data()));
|
| + DartScriptValue* scriptValue = readPointerFromProxy(info.This());
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| +
|
| + Dart_Handle dartName = dartName;
|
| + if (mapContainsKey(handle, V8Converter::stringToDart(name))) {
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| + Dart_Handle indexedGetterOperator = Dart_NewStringFromCString("[]");
|
| + Dart_Handle dartName = V8Converter::stringToDart(name);
|
| + return convertResult(Dart_Invoke(handle, indexedGetterOperator, 1, &dartName));
|
| + }
|
| + if (name->Equals(v8::String::NewSymbol("this")))
|
| + return v8::Undefined();
|
| + return v8::ThrowException(v8::Exception::ReferenceError(v8::String::Concat(name, v8::String::New(" is not defined"))));
|
| +}
|
| +
|
| +static v8::Handle<v8::Value> frameNamedPropertySetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
|
| +{
|
| + return throwError(v8ReferenceError, "Dart does not yet provide a debugger api for setting local fields", v8::Isolate::GetCurrent());
|
| }
|
|
|
| -static v8::Handle<v8::Value> getField(const v8::Arguments& args)
|
| +static v8::Handle<v8::Integer> frameQueryProperty(v8::Local<v8::String> name, const v8::AccessorInfo& info)
|
| {
|
| - DartReceiverScope scope(args);
|
| + DartScriptValue* scriptValue = readPointerFromProxy(info.This());
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
|
|
| - return convertResult(Dart_GetField(scope.receiver(), V8Converter::stringToDart(args[1])));
|
| + return mapContainsKey(handle, V8Converter::stringToDart(name)) ? v8Integer(v8::ReadOnly, info.GetIsolate()) : v8::Handle<v8::Integer>();
|
| }
|
|
|
| -static v8::Handle<v8::Value> setField(const v8::Arguments& args)
|
| +static v8::Handle<v8::Array> framePropertyEnumerator(const v8::AccessorInfo& info)
|
| {
|
| - DartReceiverScope scope(args);
|
| - v8::Handle<v8::Array> v8FunctionArgs = args[2].As<v8::Array>();
|
| - ASSERT(v8FunctionArgs->Length() == 1);
|
| - return convertResult(Dart_SetField(scope.receiver(), V8Converter::stringToDart(args[1]), unwrapValue(v8FunctionArgs->Get(0))));
|
| + DartScriptValue* scriptValue = readPointerFromProxy(info.This());
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle keyList = getMapKeyList(Dart_HandleFromPersistent(scriptValue->value()));
|
| + ASSERT(!Dart_IsError(keyList));
|
| + ASSERT(Dart_IsList(keyList));
|
| +
|
| + intptr_t length = 0;
|
| + Dart_ListLength(keyList, &length);
|
| + v8::Local<v8::Array> properties = v8::Array::New(length);
|
| + for (intptr_t i = 0; i < length; i ++)
|
| + properties->Set(i, V8Converter::stringToV8(Dart_ListGetAt(keyList, i)));
|
| + return properties;
|
| }
|
|
|
| -// --- Scripts and Libraries ---
|
| +static v8::Handle<v8::Value> namedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
|
| +{
|
| + DartScriptValue* scriptValue = readPointerFromProxy(info.This());
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| +
|
| + ASSERT(Dart_IsInstance(handle));
|
| + if (name->Equals(v8::String::NewSymbol("__proto__")))
|
| + return DartHandleProxy::createTypeProxy(Dart_InstanceGetType(handle), false);
|
|
|
| -static v8::Handle<v8::Value> libraryName(const v8::Arguments& args)
|
| + v8::String::Utf8Value stringName(name);
|
| + const char* data = *stringName;
|
| + if (data[0] == ':' || data[0] == '#') {
|
| + // Look up a map key instead of a regular property as regular dart property names
|
| + // cannot start with these symbols.
|
| + return convertResult(
|
| + lookupValueForEncodedMapKey(handle, V8Converter::stringToDart(name)));
|
| + }
|
| + // Prefix for metadata used only by the Dart Editor debugger.
|
| + if (data[0] == '@') {
|
| + if (name->Equals(v8::String::New("@staticFields")))
|
| + return DartHandleProxy::createTypeProxy(Dart_InstanceGetType(handle), true);
|
| + }
|
| +
|
| + return convertResult(Dart_Invoke(handle, V8Converter::stringToDart(v8::String::Concat(v8::String::New("get:"), name)), 0, 0));
|
| +}
|
| +
|
| +static v8::Handle<v8::Value> namedPropertySetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
|
| {
|
| - DartReceiverScope scope(args);
|
| - return convertResult(Dart_LibraryName(scope.receiver()));
|
| + DartScriptValue* scriptValue = readPointerFromProxy(info.This());
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| +
|
| + Dart_Handle dartValue = unwrapValue(value);
|
| + return convertResult(Dart_Invoke(handle, V8Converter::stringToDart(v8::String::Concat(v8::String::New("set:"), property)), 1, &dartValue));
|
| }
|
|
|
| -static v8::Handle<v8::Value> libraryUrl(const v8::Arguments& args)
|
| +static v8::Handle<v8::Integer> objectQueryProperty(v8::Local<v8::String> name, const v8::AccessorInfo& info)
|
| {
|
| - DartReceiverScope scope(args);
|
| - return convertResult(Dart_LibraryUrl(scope.receiver()));
|
| + DartScriptValue* scriptValue = readPointerFromProxy(info.This());
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| +
|
| + Dart_Handle ret;
|
| + ASSERT(Dart_IsInstance(handle));
|
| + v8::String::Utf8Value stringName(name);
|
| + const char* data = *stringName;
|
| +
|
| + // Looking up a map key instead of a regular property... as regular dart property names
|
| + // cannot start with these symbols.
|
| + if (data[0] == ':' || data[0] == '#')
|
| + return v8Integer(v8::ReadOnly, info.GetIsolate());
|
| + if (data[0] =='@')
|
| + return v8Integer(v8::DontEnum, info.GetIsolate());
|
| +
|
| + ret = Dart_Invoke(handle, V8Converter::stringToDart(v8::String::Concat(v8::String::New("get:"), name)), 0, 0);
|
| + if (Dart_IsError(ret)) {
|
| + if (name->Equals(v8::String::NewSymbol("__proto__")))
|
| + return v8Integer(0, info.GetIsolate());
|
| + return v8::Handle<v8::Integer>();
|
| + }
|
| + return v8Integer(0, info.GetIsolate());
|
| }
|
|
|
| -static v8::Handle<v8::Value> libraryImports(const v8::Arguments& args)
|
| +static v8::Handle<v8::Array> objectPropertyEnumerator(const v8::AccessorInfo& info)
|
| {
|
| - DartReceiverScope scope(args);
|
| - int32_t libraryId = args[0].As<v8::Object>()->GetHiddenValue(v8::String::New("libraryId"))->Int32Value();
|
| - Dart_Handle imports = Dart_GetLibraryImports(libraryId);
|
| - ASSERT(!Dart_IsError(imports));
|
| + DartScriptValue* scriptValue = readPointerFromProxy(info.This());
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| +
|
| + ASSERT(Dart_IsInstance(handle));
|
| +
|
| + Dart_Handle typeHandle;
|
| + if (Dart_IsInstance(handle))
|
| + typeHandle = Dart_InstanceGetType(handle);
|
| + else
|
| + typeHandle = handle;
|
| +
|
| + v8::Local<v8::Array> properties = v8::Array::New();
|
| + intptr_t count = 0;
|
| + Dart_Handle mapKeys = getEncodedMapKeyList(handle);
|
| + if (Dart_IsList(mapKeys)) {
|
| + // If the object has map keys, add them all as properties at the start
|
| + // of the list. This aids for debugging although it risks confusing
|
| + // users.
|
| + intptr_t length = 0;
|
| + Dart_ListLength(mapKeys, &length);
|
| + for (intptr_t i = 0; i < length; i++) {
|
| + properties->Set(count, V8Converter::stringToV8(Dart_ListGetAt(mapKeys, i)));
|
| + count++;
|
| + }
|
| + }
|
| +
|
| + Dart_Handle instanceFields = Dart_GetInstanceFields(handle);
|
| intptr_t length = 0;
|
| - Dart_ListLength(imports, &length);
|
| - v8::Handle<v8::Array> result = v8::Array::New();
|
| + Dart_ListLength(instanceFields, &length);
|
| for (intptr_t i = 0; i < length; i += 2) {
|
| - Dart_Handle prefix = Dart_ListGetAt(imports, i);
|
| - result->Set(i, DartHandleProxy::create(prefix));
|
| - Dart_Handle importedLibraryIdHandle = Dart_ListGetAt(imports, i + 1);
|
| - ASSERT(Dart_IsInteger(importedLibraryIdHandle));
|
| - int64_t importedLibraryId;
|
| - Dart_IntegerToInt64(importedLibraryIdHandle, &importedLibraryId);
|
| - result->Set(i + 1, DartHandleProxy::createForLibrary(importedLibraryId));
|
| + properties->Set(count, DartHandleProxy::create(
|
| + Dart_ListGetAt(instanceFields, i)));
|
| + count++;
|
| }
|
| - return result;
|
| -}
|
| -
|
| -void DartHandleProxy::getMirrorAPI(v8::Handle<v8::Object> container)
|
| -{
|
| - V8Scope v8scope;
|
| - container->Set(v8::String::New("instanceGetClass"), v8::FunctionTemplate::New(&instanceGetClass)->GetFunction());
|
| - container->Set(v8::String::New("isList"), v8::FunctionTemplate::New(&isList)->GetFunction());
|
| - container->Set(v8::String::New("listGetAt"), v8::FunctionTemplate::New(&listGetAt)->GetFunction());
|
| - container->Set(v8::String::New("listSetAt"), v8::FunctionTemplate::New(&listSetAt)->GetFunction());
|
| - container->Set(v8::String::New("className"), v8::FunctionTemplate::New(&className)->GetFunction());
|
| - container->Set(v8::String::New("classGetLibrary"), v8::FunctionTemplate::New(&classGetLibrary)->GetFunction());
|
| - container->Set(v8::String::New("getSuperclass"), v8::FunctionTemplate::New(&getSuperclass)->GetFunction());
|
| - container->Set(v8::String::New("getFunctionNames"), v8::FunctionTemplate::New(&getFunctionNames)->GetFunction());
|
| - container->Set(v8::String::New("getClassNames"), v8::FunctionTemplate::New(&getClassNames)->GetFunction());
|
| - container->Set(v8::String::New("lookupFunction"), v8::FunctionTemplate::New(&lookupFunction)->GetFunction());
|
| - container->Set(v8::String::New("lookupClass"), v8::FunctionTemplate::New(&lookupClass)->GetFunction());
|
| - container->Set(v8::String::New("getVariableNames"), v8::FunctionTemplate::New(&getVariableNames)->GetFunction());
|
| - container->Set(v8::String::New("lookupVariable"), v8::FunctionTemplate::New(&lookupVariable)->GetFunction());
|
| - container->Set(v8::String::New("invoke"), v8::FunctionTemplate::New(&invoke)->GetFunction());
|
| - container->Set(v8::String::New("dartNew"), v8::FunctionTemplate::New(&dartNew)->GetFunction());
|
| - container->Set(v8::String::New("getField"), v8::FunctionTemplate::New(&getField)->GetFunction());
|
| - container->Set(v8::String::New("setField"), v8::FunctionTemplate::New(&setField)->GetFunction());
|
| - container->Set(v8::String::New("libraryName"), v8::FunctionTemplate::New(&libraryName)->GetFunction());
|
| - container->Set(v8::String::New("libraryUrl"), v8::FunctionTemplate::New(&libraryUrl)->GetFunction());
|
| - container->Set(v8::String::New("libraryImports"), v8::FunctionTemplate::New(&libraryImports)->GetFunction());
|
| +
|
| + while (!Dart_IsError(typeHandle) && !Dart_IsNull(typeHandle)) {
|
| + addFunctionNames(typeHandle, properties, &count, true, true);
|
| + typeHandle = Dart_GetSupertype(typeHandle);
|
| + }
|
| +
|
| + properties->Set(count, v8::String::New("@staticFields"));
|
| + count++;
|
| + return properties;
|
| +}
|
| +
|
| +static v8::Handle<v8::Value> indexedGetter(uint32_t index, const v8::AccessorInfo& info)
|
| +{
|
| + DartScriptValue* scriptValue = readPointerFromProxy(info.This());
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| +
|
| + Dart_Handle ret = 0;
|
| + if (Dart_IsList(handle))
|
| + ret = Dart_ListGetAt(handle, index);
|
| + else
|
| + ret = Dart_Null();
|
| +
|
| + return convertResult(ret);
|
| +}
|
| +
|
| +static v8::Handle<v8::Value> indexedSetter(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
|
| +{
|
| + DartScriptValue* scriptValue = readPointerFromProxy(info.This());
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| +
|
| + Dart_Handle ret = 0;
|
| + if (Dart_IsList(handle))
|
| + ret = Dart_ListSetAt(handle, index, unwrapValue(value));
|
| + else
|
| + ret = Dart_Null();
|
| +
|
| + return convertResult(ret);
|
| +}
|
| +
|
| +static v8::Handle<v8::Array> indexedEnumerator(const v8::AccessorInfo& info)
|
| +{
|
| + DartScriptValue* scriptValue = readPointerFromProxy(info.This());
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| +
|
| + intptr_t length = 0;
|
| + if (Dart_IsList(handle))
|
| + Dart_ListLength(handle, &length);
|
| +
|
| + v8::Local<v8::Array> indexes = v8::Array::New(length);
|
| + for (int i = 0; i < length; i++)
|
| + indexes->Set(i, v8::Integer::New(i));
|
| +
|
| + return indexes;
|
| +}
|
| +
|
| +static v8::Local<v8::ObjectTemplate> setupInstanceTemplate(v8::Persistent<v8::FunctionTemplate> proxyTemplate)
|
| +{
|
| + v8::Local<v8::ObjectTemplate> instanceTemplate = proxyTemplate->InstanceTemplate();
|
| + instanceTemplate->SetInternalFieldCount(1);
|
| + return instanceTemplate;
|
| +}
|
| +
|
| +static v8::Persistent<v8::FunctionTemplate> objectProxyTemplate(Dart_Handle instance)
|
| +{
|
| + DEFINE_STATIC_LOCAL(FunctionTemplateMap, map, ());
|
| + Dart_Handle dartType = Dart_InstanceGetType(instance);
|
| + ASSERT(!Dart_IsError(dartType));
|
| + Dart_Handle typeNameHandle = Dart_ClassName(dartType);
|
| + ASSERT(!Dart_IsError(typeNameHandle));
|
| + v8::Handle<v8::String> typeNameV8 = V8Converter::stringToV8(typeNameHandle);
|
| + String typeName = toWebCoreString(typeNameV8);
|
| + v8::Persistent<v8::FunctionTemplate> proxyTemplate = map.get(typeName);
|
| +
|
| + if (proxyTemplate.IsEmpty()) {
|
| + proxyTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::GetCurrent(), v8::FunctionTemplate::New());
|
| + proxyTemplate->SetClassName(typeNameV8);
|
| + map.set(typeName, proxyTemplate);
|
| + v8::Local<v8::ObjectTemplate> instanceTemplate = setupInstanceTemplate(proxyTemplate);
|
| + instanceTemplate->SetIndexedPropertyHandler(&indexedGetter, &indexedSetter, 0, 0, &indexedEnumerator);
|
| + instanceTemplate->SetNamedPropertyHandler(&namedPropertyGetter, &namedPropertySetter, &objectQueryProperty, 0, &objectPropertyEnumerator);
|
| + }
|
| + return proxyTemplate;
|
| +}
|
| +
|
| +static v8::Persistent<v8::FunctionTemplate> functionProxyTemplate()
|
| +{
|
| + static v8::Persistent<v8::FunctionTemplate> proxyTemplate;
|
| + if (proxyTemplate.IsEmpty()) {
|
| + proxyTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::GetCurrent(), v8::FunctionTemplate::New());
|
| + proxyTemplate->SetClassName(v8::String::New("[Dart Function]"));
|
| + v8::Local<v8::ObjectTemplate> instanceTemplate = setupInstanceTemplate(proxyTemplate);
|
| + instanceTemplate->SetNamedPropertyHandler(&functionNamedPropertyGetter, &functionNamedPropertySetter);
|
| + instanceTemplate->SetCallAsFunctionHandler(&functionInvocationCallback);
|
| + }
|
| + return proxyTemplate;
|
| +}
|
| +
|
| +static v8::Persistent<v8::FunctionTemplate> libraryProxyTemplate()
|
| +{
|
| + static v8::Persistent<v8::FunctionTemplate> proxyTemplate;
|
| + if (proxyTemplate.IsEmpty()) {
|
| + proxyTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::GetCurrent(), v8::FunctionTemplate::New());
|
| + proxyTemplate->SetClassName(v8::String::New("[Dart Library]"));
|
| + v8::Local<v8::ObjectTemplate> instanceTemplate = setupInstanceTemplate(proxyTemplate);
|
| + instanceTemplate->SetNamedPropertyHandler(&libraryNamedPropertyGetter, &libraryNamedPropertySetter, &libraryQueryProperty, 0, &libraryPropertyEnumerator);
|
| + }
|
| + return proxyTemplate;
|
| +}
|
| +
|
| +static v8::Persistent<v8::FunctionTemplate> typeProxyTemplate(Dart_Handle type)
|
| +{
|
| + DEFINE_STATIC_LOCAL(FunctionTemplateMap, map, ());
|
| + Dart_Handle typeNameHandle = Dart_ClassName(type);
|
| + ASSERT(!Dart_IsError(typeNameHandle));
|
| + v8::Handle<v8::String> typeNameV8 = V8Converter::stringToV8(typeNameHandle);
|
| + String typeName = toWebCoreString(typeNameV8);
|
| +
|
| + v8::Persistent<v8::FunctionTemplate> proxyTemplate = map.get(typeName);
|
| + if (proxyTemplate.IsEmpty()) {
|
| + proxyTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::GetCurrent(), v8::FunctionTemplate::New());
|
| + proxyTemplate->SetClassName(typeNameV8);
|
| + v8::Local<v8::ObjectTemplate> instanceTemplate = setupInstanceTemplate(proxyTemplate);
|
| + instanceTemplate->SetNamedPropertyHandler(&typeNamedPropertyGetter, &typeNamedPropertySetter, &typeQueryProperty, 0, &typePropertyEnumerator);
|
| + instanceTemplate->SetCallAsFunctionHandler(&typeProxyConstructorInvocationCallback);
|
| + map.set(typeName, proxyTemplate);
|
| + }
|
| + return proxyTemplate;
|
| +}
|
| +
|
| +static v8::Persistent<v8::FunctionTemplate> frameProxyTemplate()
|
| +{
|
| + static v8::Persistent<v8::FunctionTemplate> proxyTemplate;
|
| + if (proxyTemplate.IsEmpty()) {
|
| + proxyTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::GetCurrent(), v8::FunctionTemplate::New());
|
| + proxyTemplate->SetClassName(v8::String::New("[Dart Frame]"));
|
| + v8::Local<v8::ObjectTemplate> instanceTemplate = setupInstanceTemplate(proxyTemplate);
|
| + instanceTemplate->SetNamedPropertyHandler(&frameNamedPropertyGetter, &frameNamedPropertySetter, &frameQueryProperty, 0, &framePropertyEnumerator);
|
| + }
|
| + return proxyTemplate;
|
| +}
|
| +
|
| +v8::Handle<v8::Value> DartHandleProxy::create(Dart_Handle value)
|
| +{
|
| + v8::Context::Scope scope(DartUtilities::currentV8Context());
|
| +
|
| + if (Dart_IsNull(value))
|
| + return v8::Null();
|
| + if (Dart_IsString(value))
|
| + return V8Converter::stringToV8(value);
|
| + if (Dart_IsBoolean(value))
|
| + return V8Converter::booleanToV8(value);
|
| + if (Dart_IsNumber(value))
|
| + return V8Converter::numberToV8(value);
|
| + v8::Local<v8::Object> proxy;
|
| + // We could unwrap Dart DOM types to native types and then rewrap them as
|
| + // JS DOM types but currently we choose not to instead returning JS
|
| + // proxies for the Dart DOM types so that the Dart DOM APIs for DOM types
|
| + // are exposed in the debugger instead of the JS APIs.
|
| + // We attempt to get the best of both worlds by providing the method
|
| + // getJavaScriptType to let debugger APIs treat these Dart proxies for
|
| + // DOM types like native DOM types for cases such as visual Node
|
| + // highlighting.
|
| +
|
| + if (Dart_IsFunction(value) || Dart_IsClosure(value))
|
| + proxy = functionProxyTemplate()->InstanceTemplate()->NewInstance();
|
| + else {
|
| + ASSERT(Dart_IsInstance(value));
|
| + proxy = objectProxyTemplate(value)->InstanceTemplate()->NewInstance();
|
| + }
|
| + setDartHandleInternalField(proxy, value);
|
| + proxy->SetHiddenValue(v8::String::NewSymbol("dartProxy"), v8::Boolean::New(true));
|
| +
|
| + return proxy;
|
| +}
|
| +
|
| +v8::Handle<v8::Value> DartHandleProxy::createTypeProxy(Dart_Handle value, bool showStatics)
|
| +{
|
| + ASSERT(Dart_IsType(value));
|
| + v8::Local<v8::Object> proxy = typeProxyTemplate(value)->InstanceTemplate()->NewInstance();
|
| + setDartHandleInternalField(proxy, value);
|
| + proxy->SetHiddenValue(v8::String::NewSymbol("dartProxy"), v8::Boolean::New(true));
|
| + proxy->SetHiddenValue(v8::String::NewSymbol("showStatics"), v8::Boolean::New(showStatics));
|
| + return proxy;
|
| +}
|
| +
|
| +bool DartHandleProxy::isDartProxy(v8::Handle<v8::Value> value)
|
| +{
|
| + if (value->IsObject()) {
|
| + v8::Local<v8::Value> hiddenValue = value.As<v8::Object>()->GetHiddenValue(v8::String::NewSymbol("dartProxy"));
|
| + return *hiddenValue && hiddenValue->IsBoolean();
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +/**
|
| + * Returns the JavaScript type name following the Chrome debugger conventions
|
| + * for Dart objects that have natural JavaScript analogs.
|
| + * This enables visually consistent display of Dart Lists and JavaScript arrays,
|
| + * functions, and DOM nodes.
|
| + */
|
| +const char* DartHandleProxy::getJavaScriptType(v8::Handle<v8::Value> value)
|
| +{
|
| + DartScriptValue* scriptValue = readPointerFromProxy(value);
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| +
|
| + if (Dart_IsInstance(handle)) {
|
| + if (Dart_IsList(handle))
|
| + return "array";
|
| +
|
| + if (Dart_IsFunction(handle))
|
| + return "function";
|
| +
|
| + if (isNode(handle))
|
| + return "node";
|
| + }
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +Node* DartHandleProxy::toNativeNode(v8::Handle<v8::Value> value)
|
| +{
|
| + DartScriptValue* scriptValue = readPointerFromProxy(value);
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + DartIsolateScope scope(scriptValue->isolate());
|
| + DartApiScope apiScope;
|
| + Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| + Dart_Handle exception = 0;
|
| + Node* node = DartNode::toNative(handle, exception);
|
| + ASSERT(!exception);
|
| + return node;
|
| +}
|
| +
|
| +/**
|
| + * Creates a proxy for a Dart library.
|
| + * If a string prefix is specified, we similuate that all requests to the library start with
|
| + * the specified prefix.
|
| + */
|
| +v8::Handle<v8::Value> DartHandleProxy::createLibraryProxy(Dart_Handle value, int32_t libraryId, Dart_Handle prefix)
|
| +{
|
| + v8::Context::Scope scope(DartUtilities::currentV8Context());
|
| + ASSERT(Dart_IsLibrary(value));
|
| + v8::Local<v8::Object> proxy = libraryProxyTemplate()->InstanceTemplate()->NewInstance();
|
| + setDartHandleInternalField(proxy, value);
|
| + proxy->SetHiddenValue(v8::String::NewSymbol("libraryId"), v8::Number::New(libraryId));
|
| + if (Dart_IsString(prefix))
|
| + proxy->SetHiddenValue(v8::String::NewSymbol("prefix"), V8Converter::stringToV8(prefix));
|
| +
|
| + proxy->SetHiddenValue(v8::String::NewSymbol("dartProxy"), v8::Boolean::New(true));
|
| + return proxy;
|
| +}
|
| +
|
| +v8::Handle<v8::Value> DartHandleProxy::createLocalScopeProxy(Dart_Handle localVariables)
|
| +{
|
| + v8::Local<v8::Object> proxy = frameProxyTemplate()->InstanceTemplate()->NewInstance();
|
| + Dart_Handle localScopeVariableMap = createLocalVariablesMap(localVariables);
|
| + ASSERT(!Dart_IsError(localScopeVariableMap));
|
| + setDartHandleInternalField(proxy, localScopeVariableMap);
|
| + proxy->SetHiddenValue(v8::String::NewSymbol("dartProxy"), v8::Boolean::New(true));
|
| + return proxy;
|
| }
|
|
|
| }
|
|
|