From a4e0f997e4a8a58673610931bb498f58aa5663e3 Mon Sep 17 00:00:00 2001 From: Peter Kanev Date: Wed, 6 Sep 2017 16:38:48 +0300 Subject: [PATCH] throw exception when incorrectly calling interface/extended class ctors --- runtime/src/main/jni/MetadataNode.cpp | 21 ++++++++++++------- .../assets/app/tests/extendedClassesTests.js | 8 +++++++ .../app/tests/testInterfaceImplementation.js | 4 ++++ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/runtime/src/main/jni/MetadataNode.cpp b/runtime/src/main/jni/MetadataNode.cpp index d65fb41b5..92063f5ab 100644 --- a/runtime/src/main/jni/MetadataNode.cpp +++ b/runtime/src/main/jni/MetadataNode.cpp @@ -655,15 +655,10 @@ void MetadataNode::SetInnerTypes(Isolate* isolate, Local& ctorFunction if (treeNode->children != nullptr) { const auto& children = *treeNode->children; -// // prototype of outer class -// auto prototypeTemplate2 = ctorFunction->Get(V8StringConstants::GetPrototype(isolate)).As(); - for (auto curChild : children) { auto childNode = GetOrCreateInternal(curChild); - auto type = s_metadataReader.GetNodeType(curChild); - auto isStatic = s_metadataReader.IsNodeTypeStatic(type); - + // The call to GetConstructorFunctionTemplate bootstraps the ctor function for the childNode auto innerTypeCtorFuncTemplate = childNode->GetConstructorFunctionTemplate(isolate, curChild); auto innerTypeCtorFunc = Local::New(isolate, *GetOrCreateInternal(curChild)->GetPersistentConstructorFunction(isolate)); auto innerTypeName = ArgConverter::ConvertToV8String(isolate, curChild->name); @@ -684,6 +679,8 @@ Local MetadataNode::GetConstructorFunctionTemplate(Isolate* is SET_PROFILER_FRAME(); tns::instrumentation::Frame frame; + v8::HandleScope handleScope(isolate); + //try get cached "ctorFuncTemplate" Local ctorFuncTemplate; auto cache = GetMetadataNodeCache(isolate); @@ -817,12 +814,16 @@ void MetadataNode::ExtendedClassConstructorCallback(const v8::FunctionCallbackIn try { SET_PROFILER_FRAME(); - assert(info.IsConstructCall()); + if (!info.IsConstructCall()) { + throw NativeScriptException(string("Incorrectly calling a Java class as a method. Class must be created by invoking its constructor with the `new` keyword.")); + } auto isolate = info.GetIsolate(); auto thiz = info.This(); auto extData = reinterpret_cast(info.Data().As()->Value()); + v8::HandleScope handleScope(isolate); + auto implementationObject = Local::New(isolate, *extData->implementationObject); const auto& extendName = extData->extendedName; @@ -854,10 +855,16 @@ void MetadataNode::InterfaceConstructorCallback(const v8::FunctionCallbackInfo(info.Data().As()->Value()); + v8::HandleScope handleScope(isolate); + Local implementationObject; Local v8ExtendName; diff --git a/test-app/app/src/main/assets/app/tests/extendedClassesTests.js b/test-app/app/src/main/assets/app/tests/extendedClassesTests.js index d9b6086a4..3bf97ddd8 100644 --- a/test-app/app/src/main/assets/app/tests/extendedClassesTests.js +++ b/test-app/app/src/main/assets/app/tests/extendedClassesTests.js @@ -73,4 +73,12 @@ describe("Tests extended classes ", function () { expect(labelgetIMAGE_ID_PROP1).toBe(labelgetIMAGE_ID_PROP2); }); + + it("should not crash with no exception when incorrectly calling extended class constructor", function () { + let MyObj = java.lang.Object.extend({ + toString: () => { return "It's MyObj" } + }); + + expect(() => { myObj() }).toThrow(); + }); }); \ No newline at end of file diff --git a/test-app/app/src/main/assets/app/tests/testInterfaceImplementation.js b/test-app/app/src/main/assets/app/tests/testInterfaceImplementation.js index 9f9d4b9af..261a6e329 100644 --- a/test-app/app/src/main/assets/app/tests/testInterfaceImplementation.js +++ b/test-app/app/src/main/assets/app/tests/testInterfaceImplementation.js @@ -27,4 +27,8 @@ describe("Tests Java interfaces are implemented correctly", function () { expect(callClose).toBe(true); }); + + it("should not crash with no exception when calling interface incorrectly", function () { + expect(() => { java.lang.Runnable({ run: () => { android.util.Log.d("Log", ""); } }) }).toThrow(); + }); }); \ No newline at end of file