void MetadataNode::InjectPrototype(Handle<Object>& target, Handle<Object>& implementationObject) { auto isolate = Isolate::GetCurrent(); implementationObject->SetAccessor(ConvertToV8String("super"), SuperAccessorGetterCallback, nullptr, implementationObject); implementationObject->SetPrototype(target->GetPrototype()); target->SetPrototype(implementationObject); }
Handle<Object> V8Context::blessed2object(SV *sv) { Handle<Object> object = Object::New(); object->SetPrototype(get_prototype(sv)); return (new PerlObjectData(this, object, sv))->object; }
PerlObjectData* V8Context::blessed2object_convert(SV* sv) { Handle<Object> object = Object::New(); Handle<Object> prototype = get_prototype(sv); object->SetPrototype(prototype); return new PerlObjectData(this, object, sv); }
void MetadataNode::InterfaceConstructorCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { SET_PROFILER_FRAME(); auto thiz = info.This(); auto node = reinterpret_cast<MetadataNode*>(info.Data().As<External>()->Value()); Handle<Object> implementationObject; Handle<String> v8ExtendName; string extendLocation; bool extendLocationFound = GetExtendLocation(extendLocation); if (info.Length() == 1) { if (!extendLocationFound) { ASSERT_FAIL("Invalid extend() call. No name specified for extend. Location: %s", extendLocation.c_str()); } ASSERT_MESSAGE(info[0]->IsObject(), "Invalid extend() call. No implementation object specified. Location: %s", extendLocation.c_str()); implementationObject = info[0]->ToObject(); } else if (info.Length() == 2) { ASSERT_MESSAGE(info[0]->IsString(), "Invalid extend() call. No name for extend specified. Location: %s", extendLocation.c_str()); ASSERT_MESSAGE(info[1]->IsObject(), "Invalid extend() call. Named extend should be called with second object parameter containing overridden methods. Location: %s", extendLocation.c_str()); DEBUG_WRITE("InterfaceConstructorCallback: getting extend name"); v8ExtendName = info[0]->ToString(); implementationObject = info[1]->ToObject(); } else { ASSERT_FAIL("Invalid extend() call. Location: %s", extendLocation.c_str()); } auto className = node->m_implType; auto extendName = ConvertToString(v8ExtendName); auto extendNameAndLocation = extendLocation + extendName; SetInstanceMetadata(info.GetIsolate(), implementationObject, node); //@@@ Refactor string fullClassName = CreateFullClassName(className, extendNameAndLocation); thiz->SetHiddenValue(ConvertToV8String("implClassName"), ConvertToV8String(fullClassName)); // jclass generatedClass = s_resolveClass(fullClassName, implementationObject); implementationObject->SetHiddenValue(ConvertToV8String(fullClassName), External::New(Isolate::GetCurrent(), generatedClass));// implementationObject->SetPrototype(thiz->GetPrototype()); thiz->SetPrototype(implementationObject); thiz->SetHiddenValue(ConvertToV8String("t::implObj"), implementationObject); ArgsWrapper argWrapper(info, ArgType::Interface, Handle<Object>()); auto success = s_registerInstance(thiz, fullClassName, argWrapper, implementationObject, true); assert(success); }
Handle<Object> MetadataNode::CreateExtendedJSWrapper(Isolate *isolate, const string& proxyClassName) { Handle<Object> extInstance; auto cacheData = GetCachedExtendedClassData(isolate, proxyClassName); if (cacheData.node != nullptr) { extInstance = Object::New(isolate); auto extdCtorFunc = Local<Function>::New(isolate, *cacheData.extendedCtorFunction); extInstance->SetPrototype(extdCtorFunc->Get(ConvertToV8String("prototype"))); SetInstanceMetadata(isolate, extInstance, cacheData.node); extInstance->SetHiddenValue(ConvertToV8String("implClassName"), ConvertToV8String(cacheData.extendedName)); } return extInstance; }
//Used to make a new vector object Handle<Object> vectorTemplate::makeVectorObject(vector<double>* instVect){ HandleScope scope; //This is the prototype for the object Handle<Object> objProto = vectorObjTemp->NewInstance(); //This is the vector data that will be associated with this object Handle<External> data = External::New(reinterpret_cast<void *>(instVect)); Handle<ObjectTemplate> vectOjbTempInst = ObjectTemplate::New(); //Set up the setters vectOjbTempInst->SetAccessor(String::New("x"), getVectorX, setVectorX, data); vectOjbTempInst->SetAccessor(String::New("y"), getVectorY, setVectorY, data); Handle<Object> obj = vectOjbTempInst->NewInstance(); obj->SetPrototype(objProto); return scope.Close(obj); }
Handle<Object> MetadataNode::CreateJSWrapper(Isolate *isolate) { Handle<Object> obj; if (m_isArray) { obj = CreateArrayWrapper(isolate); } else { auto ctorFunc = GetConstructorFunction(isolate); obj = Object::New(isolate); obj->Set(ConvertToV8String("constructor"), ctorFunc); obj->SetPrototype(ctorFunc->Get(ConvertToV8String("prototype"))); SetInstanceMetadata(isolate, obj, this); } return obj; }
void MetadataNode::ExtendCallMethodHandler(const v8::FunctionCallbackInfo<v8::Value>& info) { if (info.IsConstructCall()) { string exMsg("Cannot call 'extend' as constructor"); ExceptionUtil::GetInstance()->ThrowExceptionToJs(exMsg); return; } SET_PROFILER_FRAME(); Handle<Object> implementationObject; Handle<String> extendName; string extendLocation; auto validArgs = ValidateExtendArguments(info, extendLocation, extendName, implementationObject); if (!validArgs) return; auto node = reinterpret_cast<MetadataNode*>(info.Data().As<External>()->Value()); DEBUG_WRITE("ExtendsCallMethodHandler: called with %s", ConvertToString(extendName).c_str()); string extendNameAndLocation = extendLocation + ConvertToString(extendName); auto fullClassName = TNS_PREFIX + CreateFullClassName(node->m_name, extendNameAndLocation); // JEnv env; //resolve class (pre-generated or generated runtime from dex generator) jclass generatedClass = s_resolveClass(fullClassName, implementationObject); //resolve class returns GlobalRef std::string generatedFullClassName = s_objectManager->GetClassName(generatedClass); // auto fullExtendedName = generatedFullClassName; DEBUG_WRITE("ExtendsCallMethodHandler: extend full name %s", fullClassName.c_str()); auto isolate = info.GetIsolate(); auto cachedData = GetCachedExtendedClassData(isolate, fullExtendedName); if (cachedData.extendedCtorFunction != nullptr) { auto cachedExtendedCtorFunc = Local<Function>::New(isolate, *cachedData.extendedCtorFunction); info.GetReturnValue().Set(cachedExtendedCtorFunc); return; } auto implementationObjectPropertyName = V8StringConstants::GetClassImplementationObject(); //reuse validation - checks that implementationObject is not reused for different classes auto implementationObjectProperty = implementationObject->GetHiddenValue(implementationObjectPropertyName).As<String>(); if (implementationObjectProperty.IsEmpty()) { //mark the implementationObject as such and set a pointer to it's class node inside it for reuse validation later implementationObject->SetHiddenValue(implementationObjectPropertyName, String::NewFromUtf8(isolate, fullExtendedName.c_str())); //append resolved class to implementation object implementationObject->SetHiddenValue(ConvertToV8String(fullExtendedName), External::New(Isolate::GetCurrent(), generatedClass)); } else { string usedClassName = ConvertToString(implementationObjectProperty); stringstream s; s << "This object is used to extend another class '" << usedClassName << "'"; ExceptionUtil::GetInstance()->ThrowExceptionToJs(s.str()); return; } auto baseClassCtorFunc = node->GetConstructorFunction(isolate); auto extendData = External::New(isolate, new ExtendedClassData(node, extendNameAndLocation, implementationObject, fullExtendedName)); auto extendFuncTemplate = FunctionTemplate::New(isolate, ExtendedClassConstructorCallback, extendData); auto extendFunc = extendFuncTemplate->GetFunction(); auto prototypeName = ConvertToV8String("prototype"); implementationObject->SetPrototype(baseClassCtorFunc->Get(prototypeName)); implementationObject->SetAccessor(ConvertToV8String("super"), SuperAccessorGetterCallback, nullptr, implementationObject); extendFunc->Set(prototypeName, implementationObject); extendFunc->SetPrototype(baseClassCtorFunc); SetClassAccessor(extendFunc); SetTypeMetadata(isolate, extendFunc, new TypeMetadata(fullExtendedName)); info.GetReturnValue().Set(extendFunc); s_name2NodeCache.insert(make_pair(fullExtendedName, node)); ExtendedClassCacheData cacheData(extendFunc, fullExtendedName, node); s_extendedCtorFuncCache.insert(make_pair(fullExtendedName, cacheData)); }