| Index: Source/bindings/dart/DartHandleProxy.cpp
|
| diff --git a/Source/bindings/dart/DartHandleProxy.cpp b/Source/bindings/dart/DartHandleProxy.cpp
|
| index 65267c79ff281e02c45d4cebc6301667e90b767d..d1269aedfce40a2edec1e585793dfa2a800dec97 100644
|
| --- a/Source/bindings/dart/DartHandleProxy.cpp
|
| +++ b/Source/bindings/dart/DartHandleProxy.cpp
|
| @@ -59,6 +59,39 @@ DartScriptValue* readPointerFromProxy(v8::Handle<v8::Value> proxy)
|
| return static_cast<DartScriptValue*>(pointer);
|
| }
|
|
|
| +/**
|
| + * Helper class to manage all scopes that must be entered to safely invoke Dart
|
| + * code.
|
| + */
|
| +class DartScopes {
|
| +private:
|
| + DartScriptValue* scriptValue;
|
| + DartIsolateScope scope;
|
| + DartApiScope apiScope;
|
| + Dart_ExceptionPauseInfo previousPauseInfo;
|
| +
|
| +public:
|
| + Dart_Handle handle;
|
| +
|
| + DartScopes(v8::Local<v8::Object> v8Handle) :
|
| + scriptValue(readPointerFromProxy(v8Handle)),
|
| + scope(scriptValue->isolate())
|
| + {
|
| + ASSERT(scriptValue->isIsolateAlive());
|
| + handle = Dart_HandleFromPersistent(scriptValue->value());
|
| + previousPauseInfo = Dart_GetExceptionPauseInfo();
|
| + // FIXME: it is not clear this is the right long term solution but for
|
| + // now we prevent pausing on exceptions when executing Dart code to
|
| + // avoid crashing when handling an exception triggers an exception.
|
| + Dart_SetExceptionPauseInfo(kNoPauseOnExceptions);
|
| + }
|
| +
|
| + ~DartScopes()
|
| + {
|
| + Dart_SetExceptionPauseInfo(previousPauseInfo);
|
| + }
|
| +};
|
| +
|
| static void weakCallback(v8::Isolate* isolate, v8::Persistent<v8::Object>* proxy, DartScriptValue* value)
|
| {
|
| delete value;
|
| @@ -135,6 +168,14 @@ bool isNode(Dart_Handle type)
|
| return true;
|
| }
|
|
|
| +bool isNoSuchMethodError(Dart_Handle type)
|
| +{
|
| + Dart_Handle exception = 0;
|
| + bool ret = DartUtilities::dartToBool(DartUtilities::invokeUtilsMethod("isNoSuchMethodError", 1, &type), exception);
|
| + ASSERT(!exception);
|
| + return ret;
|
| +}
|
| +
|
| Dart_Handle createLocalVariablesMap(Dart_Handle localVariablesList)
|
| {
|
| return DartUtilities::invokeUtilsMethod("createLocalVariablesMap", 1, &localVariablesList);
|
| @@ -161,6 +202,15 @@ void addFunctionNames(Dart_Handle handle, v8::Local<v8::Array>& properties, intp
|
| for (intptr_t i = 0; i < length; i++) {
|
| Dart_Handle functionName = Dart_ListGetAt(functionNames, i);
|
| Dart_Handle function = Dart_LookupFunction(handle, functionName);
|
| +
|
| + // FIXME: the DartVM doesn't correctly handle invoking properties with
|
| + // private names. For now, skip private function names.
|
| + intptr_t functionNameLength = 0;
|
| + uint8_t* functionNameData;
|
| + Dart_StringToUTF8(functionName, &functionNameData, &functionNameLength);
|
| + if (functionNameLength > 0 && functionNameData[0] == '_')
|
| + continue;
|
| +
|
| bool isStatic = false;
|
| Dart_FunctionIsStatic(function, &isStatic);
|
|
|
| @@ -178,6 +228,11 @@ void addFunctionNames(Dart_Handle handle, v8::Local<v8::Array>& properties, intp
|
|
|
| if (noMethods && !isSetter && !isGetter)
|
| continue;
|
| +
|
| + // Skip setters as any setter we care to enumerate should have a matching getter.
|
| + // Setters without matching getters will still be callable but won't be enumerated.
|
| + if (isSetter)
|
| + continue;
|
| }
|
|
|
| // Strip off the leading typename from constructor name.
|
| @@ -255,11 +310,8 @@ Dart_Handle getLibraryPrefix(v8::Local<v8::Object> proxy)
|
|
|
| static v8::Handle<v8::Value> functionNamedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
|
| {
|
| - DartScriptValue* scriptValue = readPointerFromProxy(info.Holder());
|
| - ASSERT(scriptValue->isIsolateAlive());
|
| - DartIsolateScope scope(scriptValue->isolate());
|
| - DartApiScope apiScope;
|
| - Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| + DartScopes scopes(info.Holder());
|
| + Dart_Handle handle = scopes.handle;
|
|
|
| Dart_Handle ret;
|
| ASSERT(Dart_IsFunction(handle) || Dart_IsClosure(handle));
|
| @@ -278,11 +330,8 @@ static v8::Handle<v8::Value> functionNamedPropertySetter(v8::Local<v8::String> p
|
|
|
| static v8::Handle<v8::Value> functionInvocationCallback(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());
|
| + DartScopes scopes(args.Holder());
|
| + Dart_Handle handle = scopes.handle;
|
|
|
| ASSERT(Dart_IsFunction(handle) || Dart_IsClosure(handle));
|
| bool isConstructor = false;
|
| @@ -312,11 +361,8 @@ static v8::Handle<v8::Value> functionInvocationCallback(v8::Arguments const& arg
|
|
|
| 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());
|
| + DartScopes scopes(args.Holder());
|
| + Dart_Handle handle = scopes.handle;
|
|
|
| ASSERT(Dart_IsType(handle));
|
|
|
| @@ -385,11 +431,8 @@ static v8::Handle<v8::Value> libraryNamedPropertyGetterHelper(Dart_Handle librar
|
| static v8::Handle<v8::Value> libraryNamedPropertyGetterHelper(v8::Local<v8::String> name,
|
| const v8::AccessorInfo& info, bool* handled)
|
| {
|
| - DartScriptValue* scriptValue = readPointerFromProxy(info.Holder());
|
| - ASSERT(scriptValue->isIsolateAlive());
|
| - DartIsolateScope scope(scriptValue->isolate());
|
| - DartApiScope apiScope;
|
| - Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| + DartScopes scopes(info.Holder());
|
| + Dart_Handle handle = scopes.handle;
|
|
|
| Dart_Handle ret;
|
| ASSERT(Dart_IsLibrary(handle));
|
| @@ -433,7 +476,7 @@ static v8::Handle<v8::Value> libraryNamedPropertyGetter(v8::Local<v8::String> na
|
| 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"))));
|
| + return v8::Undefined();
|
| }
|
|
|
| // FIXME: we need to handle prefixes when setting library properties as well
|
| @@ -441,11 +484,8 @@ static v8::Handle<v8::Value> libraryNamedPropertyGetter(v8::Local<v8::String> na
|
| // 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)
|
| {
|
| - DartScriptValue* scriptValue = readPointerFromProxy(info.Holder());
|
| - ASSERT(scriptValue->isIsolateAlive());
|
| - DartIsolateScope scope(scriptValue->isolate());
|
| - DartApiScope apiScope;
|
| - Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| + DartScopes scopes(info.Holder());
|
| + Dart_Handle handle = scopes.handle;
|
|
|
| Dart_Handle ret;
|
| ASSERT(Dart_IsLibrary(handle));
|
| @@ -470,11 +510,8 @@ void libraryEnumerateHelper(Dart_Handle library, intptr_t libraryId, v8::Local<v
|
|
|
| static v8::Handle<v8::Array> libraryPropertyEnumerator(const v8::AccessorInfo& info)
|
| {
|
| - DartScriptValue* scriptValue = readPointerFromProxy(info.Holder());
|
| - ASSERT(scriptValue->isIsolateAlive());
|
| - DartIsolateScope scope(scriptValue->isolate());
|
| - DartApiScope apiScope;
|
| - Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| + DartScopes scopes(info.Holder());
|
| + Dart_Handle handle = scopes.handle;
|
|
|
| intptr_t libraryId = getLibraryId(info.Holder());
|
| ASSERT(Dart_IsLibrary(handle));
|
| @@ -524,11 +561,8 @@ bool isShowStatics(v8::Handle<v8::Value> value)
|
|
|
| static v8::Handle<v8::Value> typeNamedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
|
| {
|
| - DartScriptValue* scriptValue = readPointerFromProxy(info.Holder());
|
| - ASSERT(scriptValue->isIsolateAlive());
|
| - DartIsolateScope scope(scriptValue->isolate());
|
| - DartApiScope apiScope;
|
| - Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| + DartScopes scopes(info.Holder());
|
| + Dart_Handle handle = scopes.handle;
|
|
|
| Dart_Handle ret;
|
| ASSERT(Dart_IsType(handle));
|
| @@ -560,17 +594,13 @@ static v8::Handle<v8::Value> typeNamedPropertyGetter(v8::Local<v8::String> 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"))));
|
| + return v8::Undefined();
|
| }
|
|
|
| static v8::Handle<v8::Value> typeNamedPropertySetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
|
| {
|
| - DartScriptValue* scriptValue = readPointerFromProxy(info.Holder());
|
| - ASSERT(scriptValue->isIsolateAlive());
|
| - DartIsolateScope scope(scriptValue->isolate());
|
| - DartApiScope apiScope;
|
| - Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| + DartScopes scopes(info.Holder());
|
| + Dart_Handle handle = scopes.handle;
|
|
|
| Dart_Handle ret;
|
| ASSERT(Dart_IsType(handle));
|
| @@ -581,11 +611,8 @@ static v8::Handle<v8::Value> typeNamedPropertySetter(v8::Local<v8::String> prope
|
|
|
| static v8::Handle<v8::Integer> typeQueryProperty(v8::Local<v8::String> name, const v8::AccessorInfo& info)
|
| {
|
| - DartScriptValue* scriptValue = readPointerFromProxy(info.Holder());
|
| - ASSERT(scriptValue->isIsolateAlive());
|
| - DartIsolateScope scope(scriptValue->isolate());
|
| - DartApiScope apiScope;
|
| - Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| + DartScopes scopes(info.Holder());
|
| + Dart_Handle handle = scopes.handle;
|
|
|
| Dart_Handle ret;
|
| ASSERT(Dart_IsType(handle));
|
| @@ -597,11 +624,8 @@ static v8::Handle<v8::Integer> typeQueryProperty(v8::Local<v8::String> name, con
|
|
|
| static v8::Handle<v8::Array> typePropertyEnumerator(const v8::AccessorInfo& info)
|
| {
|
| - DartScriptValue* scriptValue = readPointerFromProxy(info.Holder());
|
| - ASSERT(scriptValue->isIsolateAlive());
|
| - DartIsolateScope scope(scriptValue->isolate());
|
| - DartApiScope apiScope;
|
| - Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| + DartScopes scopes(info.Holder());
|
| + Dart_Handle handle = scopes.handle;
|
| bool showStatics = isShowStatics(info.Holder());
|
|
|
| ASSERT(Dart_IsType(handle));
|
| @@ -617,22 +641,16 @@ static v8::Handle<v8::Array> typePropertyEnumerator(const v8::AccessorInfo& info
|
|
|
| static v8::Handle<v8::Value> frameNamedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
|
| {
|
| - DartScriptValue* scriptValue = readPointerFromProxy(info.Holder());
|
| - ASSERT(scriptValue->isIsolateAlive());
|
| - DartIsolateScope scope(scriptValue->isolate());
|
| - DartApiScope apiScope;
|
| - Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| + DartScopes scopes(info.Holder());
|
| + Dart_Handle handle = scopes.handle;
|
|
|
| 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"))));
|
| + return v8::Undefined();
|
| }
|
|
|
| static v8::Handle<v8::Value> frameNamedPropertySetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
|
| @@ -642,22 +660,15 @@ static v8::Handle<v8::Value> frameNamedPropertySetter(v8::Local<v8::String> prop
|
|
|
| static v8::Handle<v8::Integer> frameQueryProperty(v8::Local<v8::String> name, const v8::AccessorInfo& info)
|
| {
|
| - DartScriptValue* scriptValue = readPointerFromProxy(info.Holder());
|
| - ASSERT(scriptValue->isIsolateAlive());
|
| - DartIsolateScope scope(scriptValue->isolate());
|
| - DartApiScope apiScope;
|
| - Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| + DartScopes scopes(info.Holder());
|
|
|
| - return mapContainsKey(handle, V8Converter::stringToDart(name)) ? v8::Integer::New(0, info.GetIsolate()) : v8::Handle<v8::Integer>();
|
| + return mapContainsKey(scopes.handle, V8Converter::stringToDart(name)) ? v8::Integer::New(0, info.GetIsolate()) : v8::Handle<v8::Integer>();
|
| }
|
|
|
| static v8::Handle<v8::Array> framePropertyEnumerator(const v8::AccessorInfo& info)
|
| {
|
| - DartScriptValue* scriptValue = readPointerFromProxy(info.Holder());
|
| - ASSERT(scriptValue->isIsolateAlive());
|
| - DartIsolateScope scope(scriptValue->isolate());
|
| - DartApiScope apiScope;
|
| - Dart_Handle keyList = getMapKeyList(Dart_HandleFromPersistent(scriptValue->value()));
|
| + DartScopes scopes(info.Holder());
|
| + Dart_Handle keyList = getMapKeyList(scopes.handle);
|
| ASSERT(!Dart_IsError(keyList));
|
| ASSERT(Dart_IsList(keyList));
|
|
|
| @@ -671,11 +682,8 @@ static v8::Handle<v8::Array> framePropertyEnumerator(const v8::AccessorInfo& inf
|
|
|
| static v8::Handle<v8::Value> namedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
|
| {
|
| - DartScriptValue* scriptValue = readPointerFromProxy(info.Holder());
|
| - ASSERT(scriptValue->isIsolateAlive());
|
| - DartIsolateScope scope(scriptValue->isolate());
|
| - DartApiScope apiScope;
|
| - Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| + DartScopes scopes(info.Holder());
|
| + Dart_Handle handle = scopes.handle;
|
|
|
| ASSERT(Dart_IsInstance(handle));
|
| if (name->Equals(v8::String::NewSymbol("__proto__")))
|
| @@ -695,16 +703,22 @@ static v8::Handle<v8::Value> namedPropertyGetter(v8::Local<v8::String> name, con
|
| return DartHandleProxy::createTypeProxy(Dart_InstanceGetType(handle), true);
|
| }
|
|
|
| - return convertResult(Dart_Invoke(handle, V8Converter::stringToDart(v8::String::Concat(v8::String::New("get:"), name)), 0, 0));
|
| + Dart_Handle result = Dart_Invoke(handle, V8Converter::stringToDart(v8::String::Concat(v8::String::New("get:"), name)), 0, 0);
|
| + if (Dart_IsError(result)) {
|
| + // To match JS conventions, we should just return undefined if a
|
| + // property does not exist rather than throwing.
|
| + if (Dart_ErrorHasException(result) && isNoSuchMethodError(Dart_ErrorGetException(result)))
|
| + return v8::Undefined();
|
| +
|
| + return v8::ThrowException(v8::String::New(Dart_GetError(result)));
|
| + }
|
| + return DartHandleProxy::create(result);
|
| }
|
|
|
| static v8::Handle<v8::Value> namedPropertySetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
|
| {
|
| - DartScriptValue* scriptValue = readPointerFromProxy(info.Holder());
|
| - ASSERT(scriptValue->isIsolateAlive());
|
| - DartIsolateScope scope(scriptValue->isolate());
|
| - DartApiScope apiScope;
|
| - Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| + DartScopes scopes(info.Holder());
|
| + Dart_Handle handle = scopes.handle;
|
|
|
| Dart_Handle dartValue = unwrapValue(value);
|
| return convertResult(Dart_Invoke(handle, V8Converter::stringToDart(v8::String::Concat(v8::String::New("set:"), property)), 1, &dartValue));
|
| @@ -712,11 +726,8 @@ static v8::Handle<v8::Value> namedPropertySetter(v8::Local<v8::String> property,
|
|
|
| static v8::Handle<v8::Integer> objectQueryProperty(v8::Local<v8::String> name, const v8::AccessorInfo& info)
|
| {
|
| - DartScriptValue* scriptValue = readPointerFromProxy(info.Holder());
|
| - ASSERT(scriptValue->isIsolateAlive());
|
| - DartIsolateScope scope(scriptValue->isolate());
|
| - DartApiScope apiScope;
|
| - Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| + DartScopes scopes(info.Holder());
|
| + Dart_Handle handle = scopes.handle;
|
|
|
| Dart_Handle ret;
|
| ASSERT(Dart_IsInstance(handle));
|
| @@ -727,7 +738,7 @@ static v8::Handle<v8::Integer> objectQueryProperty(v8::Local<v8::String> name, c
|
| // cannot start with these symbols.
|
| if (data[0] == ':' || data[0] == '#')
|
| return v8::Integer::New(v8::ReadOnly, info.GetIsolate());
|
| - if (data[0] =='@')
|
| + if (data[0] == '@')
|
| return v8::Integer::New(v8::DontEnum, info.GetIsolate());
|
|
|
| ret = Dart_Invoke(handle, V8Converter::stringToDart(v8::String::Concat(v8::String::New("get:"), name)), 0, 0);
|
| @@ -741,11 +752,8 @@ static v8::Handle<v8::Integer> objectQueryProperty(v8::Local<v8::String> name, c
|
|
|
| static v8::Handle<v8::Array> objectPropertyEnumerator(const v8::AccessorInfo& info)
|
| {
|
| - DartScriptValue* scriptValue = readPointerFromProxy(info.Holder());
|
| - ASSERT(scriptValue->isIsolateAlive());
|
| - DartIsolateScope scope(scriptValue->isolate());
|
| - DartApiScope apiScope;
|
| - Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| + DartScopes scopes(info.Holder());
|
| + Dart_Handle handle = scopes.handle;
|
|
|
| ASSERT(Dart_IsInstance(handle));
|
|
|
| @@ -787,11 +795,8 @@ static v8::Handle<v8::Array> objectPropertyEnumerator(const v8::AccessorInfo& in
|
|
|
| static v8::Handle<v8::Value> indexedGetter(uint32_t index, const v8::AccessorInfo& info)
|
| {
|
| - DartScriptValue* scriptValue = readPointerFromProxy(info.Holder());
|
| - ASSERT(scriptValue->isIsolateAlive());
|
| - DartIsolateScope scope(scriptValue->isolate());
|
| - DartApiScope apiScope;
|
| - Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| + DartScopes scopes(info.Holder());
|
| + Dart_Handle handle = scopes.handle;
|
|
|
| Dart_Handle ret = 0;
|
| if (Dart_IsList(handle))
|
| @@ -804,11 +809,8 @@ static v8::Handle<v8::Value> indexedGetter(uint32_t index, const v8::AccessorInf
|
|
|
| static v8::Handle<v8::Value> indexedSetter(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
|
| {
|
| - DartScriptValue* scriptValue = readPointerFromProxy(info.Holder());
|
| - ASSERT(scriptValue->isIsolateAlive());
|
| - DartIsolateScope scope(scriptValue->isolate());
|
| - DartApiScope apiScope;
|
| - Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| + DartScopes scopes(info.Holder());
|
| + Dart_Handle handle = scopes.handle;
|
|
|
| Dart_Handle ret = 0;
|
| if (Dart_IsList(handle))
|
| @@ -821,11 +823,8 @@ static v8::Handle<v8::Value> indexedSetter(uint32_t index, v8::Local<v8::Value>
|
|
|
| static v8::Handle<v8::Array> indexedEnumerator(const v8::AccessorInfo& info)
|
| {
|
| - DartScriptValue* scriptValue = readPointerFromProxy(info.Holder());
|
| - ASSERT(scriptValue->isIsolateAlive());
|
| - DartIsolateScope scope(scriptValue->isolate());
|
| - DartApiScope apiScope;
|
| - Dart_Handle handle = Dart_HandleFromPersistent(scriptValue->value());
|
| + DartScopes scopes(info.Holder());
|
| + Dart_Handle handle = scopes.handle;
|
|
|
| intptr_t length = 0;
|
| if (Dart_IsList(handle))
|
|
|